Compare commits
	
		
			No commits in common. "c8" and "c9" have entirely different histories.
		
	
	
		
	
		
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,3 @@ | |||||||
| SOURCES/DJM-GPG-KEY.gpg | SOURCES/gpgkey-736060BA.gpg | ||||||
| SOURCES/openssh-8.0p1.tar.gz | SOURCES/openssh-8.7p1.tar.gz | ||||||
| SOURCES/pam_ssh_agent_auth-0.10.3.tar.bz2 | SOURCES/pam_ssh_agent_auth-0.10.4.tar.gz | ||||||
|  | |||||||
| @ -1,3 +1,3 @@ | |||||||
| bed7240bb17840b451b8f8457791c33456814d93 SOURCES/DJM-GPG-KEY.gpg | dbb35b4e9ae3f72b930a82c6fd5e83e9dcd7b193 SOURCES/gpgkey-736060BA.gpg | ||||||
| 756dbb99193f9541c9206a667eaa27b0fa184a4f SOURCES/openssh-8.0p1.tar.gz | 8719032c1e47732c8fdb14adfb24b5e9e71de802 SOURCES/openssh-8.7p1.tar.gz | ||||||
| a4482a050fdad1d012427e45799564136708cf6b SOURCES/pam_ssh_agent_auth-0.10.3.tar.bz2 | 66dd8274346fd006ff40f525c082cfb701085b5f SOURCES/pam_ssh_agent_auth-0.10.4.tar.gz | ||||||
|  | |||||||
| @ -1,12 +1,11 @@ | |||||||
| diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-7.4p1/contrib/gnome-ssh-askpass2.c
 | diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/contrib/gnome-ssh-askpass2.c
 | ||||||
| --- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.grab-info	2016-12-23 13:31:22.645213115 +0100
 | --- openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info	2021-04-19 13:57:11.720113536 +0200
 | ||||||
| +++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c	2016-12-23 13:31:40.997216691 +0100
 | +++ openssh-8.6p1/contrib/gnome-ssh-askpass2.c	2021-04-19 13:59:29.842163204 +0200
 | ||||||
| @@ -65,9 +65,12 @@ report_failed_grab (GtkWidget *parent_wi
 | @@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_wi
 | ||||||
|  |   | ||||||
|  	err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0, |  	err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0, | ||||||
|  				     GTK_MESSAGE_ERROR, |  	    GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, | ||||||
|  				     GTK_BUTTONS_CLOSE, | -	    "Could not grab %s. A malicious client may be eavesdropping "
 | ||||||
| -				     "Could not grab %s. "
 |  | ||||||
| -				     "A malicious client may be eavesdropping "
 |  | ||||||
| -	    "on your session.", what);
 | -	    "on your session.", what);
 | ||||||
| +	    "SSH password dialog could not grab the %s input.\n"
 | +	    "SSH password dialog could not grab the %s input.\n"
 | ||||||
| +	    "This might be caused by application such as screensaver, "
 | +	    "This might be caused by application such as screensaver, "
 | ||||||
|  | |||||||
| @ -2,15 +2,15 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr | |||||||
| --- 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.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
 | +++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c	2016-12-23 13:31:16.545211926 +0100
 | ||||||
| @@ -53,6 +53,7 @@
 | @@ -53,6 +53,7 @@
 | ||||||
|  #include <string.h> |  | ||||||
|  #include <unistd.h> |  #include <unistd.h> | ||||||
|  |   | ||||||
|  #include <X11/Xlib.h> |  #include <X11/Xlib.h> | ||||||
| +#include <glib.h>
 | +#include <glib.h>
 | ||||||
|  #include <gtk/gtk.h> |  #include <gtk/gtk.h> | ||||||
|  #include <gdk/gdkx.h> |  #include <gdk/gdkx.h> | ||||||
|   |  #include <gdk/gdkkeysyms.h> | ||||||
| @@ -81,13 +82,24 @@ ok_dialog(GtkWidget *entry, gpointer dia
 | @@ -81,14 +82,25 @@ ok_dialog(GtkWidget *entry, gpointer dia
 | ||||||
|  	gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); |  	return 1; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| +static void
 | +static void
 | ||||||
| @ -25,57 +25,59 @@ diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contr | |||||||
| +}
 | +}
 | ||||||
| +
 | +
 | ||||||
|  static int |  static int | ||||||
|  passphrase_dialog(char *message) |  passphrase_dialog(char *message, int prompt_type) | ||||||
|  { |  { | ||||||
|  	const char *failed; |  	const char *failed; | ||||||
|  	char *passphrase, *local; |  	char *passphrase, *local; | ||||||
|  	int result, grab_tries, grab_server, grab_pointer; |  	int result, grab_tries, grab_server, grab_pointer; | ||||||
|  |  	int buttons, default_response; | ||||||
| -	GtkWidget *parent_window, *dialog, *entry;
 | -	GtkWidget *parent_window, *dialog, *entry;
 | ||||||
| +	GtkWidget *parent_window, *dialog, *entry, *progress, *hbox;
 | +	GtkWidget *parent_window, *dialog, *entry, *progress, *hbox;
 | ||||||
|  	GdkGrabStatus status; |  	GdkGrabStatus status; | ||||||
|  |  	GdkColor fg, bg; | ||||||
|  |  	int fg_set = 0, bg_set = 0; | ||||||
|  | @@ -104,14 +116,19 @@ passphrase_dialog(char *message)
 | ||||||
|  |  		gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &bg); | ||||||
|   |   | ||||||
|  	grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); |  	if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) { | ||||||
| @@ -104,14 +116,32 @@ passphrase_dialog(char *message)
 |  | ||||||
|  					"%s", |  | ||||||
|  					message); |  | ||||||
|   |  | ||||||
| +		hbox = gtk_hbox_new(FALSE, 0);
 | +		hbox = gtk_hbox_new(FALSE, 0);
 | ||||||
| +		gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
 | +		gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
 | ||||||
| +		    FALSE, 0);
 | +		    FALSE, 0);
 | ||||||
| +		gtk_widget_show(hbox);
 | +		gtk_widget_show(hbox);
 | ||||||
| +
 | +
 | ||||||
| 		entry = gtk_entry_new(); | 		entry = gtk_entry_new(); | ||||||
|  | 		if (fg_set) | ||||||
|  | 			gtk_widget_modify_fg(entry, GTK_STATE_NORMAL, &fg); | ||||||
|  | 		if (bg_set) | ||||||
|  | 			gtk_widget_modify_bg(entry, GTK_STATE_NORMAL, &bg); | ||||||
| 		gtk_box_pack_start( | 		gtk_box_pack_start( | ||||||
| -	    GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry,
 | -		    GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
 | ||||||
| -	    FALSE, FALSE, 0);
 | -		    entry, FALSE, FALSE, 0);
 | ||||||
| +	    GTK_BOX(hbox), entry,
 | +		    GTK_BOX(hbox), entry, TRUE, FALSE, 0);
 | ||||||
| +	    TRUE, FALSE, 0);
 |  | ||||||
| +		gtk_entry_set_width_chars(GTK_ENTRY(entry), 2);
 | +		gtk_entry_set_width_chars(GTK_ENTRY(entry), 2);
 | ||||||
|  		gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); |  		gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); | ||||||
|  		gtk_widget_grab_focus(entry); |  		gtk_widget_grab_focus(entry); | ||||||
|  	gtk_widget_show(entry); |  		if (prompt_type == PROMPT_ENTRY) { | ||||||
|   | @@ -130,6 +145,22 @@ passphrase_dialog(char *message)
 | ||||||
|  |  			g_signal_connect(G_OBJECT(entry), "key_press_event", | ||||||
|  |  			    G_CALLBACK(check_none), dialog); | ||||||
|  |  		} | ||||||
|  | +
 | ||||||
| +		hbox = gtk_hbox_new(FALSE, 0);
 | +		hbox = gtk_hbox_new(FALSE, 0);
 | ||||||
| +	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
 | +		gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
 | ||||||
| +	    FALSE, 8);
 | +		    hbox, FALSE, FALSE, 8);
 | ||||||
| +		gtk_widget_show(hbox);
 | +		gtk_widget_show(hbox);
 | ||||||
| +
 | +
 | ||||||
| +		progress = gtk_progress_bar_new();
 | +		progress = gtk_progress_bar_new();
 | ||||||
| +
 | +
 | ||||||
| +	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "Passphrase length hidden intentionally");
 | +		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),
 | ||||||
|  | +		    "Passphrase length hidden intentionally");
 | ||||||
| +		gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE,
 | +		gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE,
 | ||||||
| +		    TRUE, 5);
 | +		    TRUE, 5);
 | ||||||
| +		gtk_widget_show(progress);
 | +		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_signal_connect(G_OBJECT(entry), "changed",
 | ||||||
| +				 G_CALLBACK(move_progress), progress);
 | +				 G_CALLBACK(move_progress), progress);
 | ||||||
|  | +
 | ||||||
|  |  	} | ||||||
|   |   | ||||||
|  	gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); |  	/* Grab focus */ | ||||||
|   |  | ||||||
|  | |||||||
| @ -1,19 +1,19 @@ | |||||||
| diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c
 | diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c
 | ||||||
| --- openssh-7.4p1/log.c.log-in-chroot	2016-12-19 05:59:41.000000000 +0100
 | --- openssh-8.6p1/log.c.log-in-chroot	2021-04-16 05:55:25.000000000 +0200
 | ||||||
| +++ openssh-7.4p1/log.c	2016-12-23 15:14:33.330168088 +0100
 | +++ openssh-8.6p1/log.c	2021-05-06 11:32:25.179006811 +0200
 | ||||||
| @@ -250,6 +250,11 @@ debug3(const char *fmt,...)
 | @@ -194,6 +194,11 @@ void
 | ||||||
|  void |  log_init(const char *av0, LogLevel level, SyslogFacility facility, | ||||||
|  log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) |      int on_stderr) | ||||||
|  { |  { | ||||||
| +	log_init_handler(av0, level, facility, on_stderr, 1);
 | +	log_init_handler(av0, level, facility, on_stderr, 1);
 | ||||||
| +}
 | +}
 | ||||||
| +
 | +
 | ||||||
| +void
 | +void
 | ||||||
| +log_init_handler(char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) {
 | +log_init_handler(const char *av0, LogLevel level, SyslogFacility facility, int on_stderr, int reset_handler) {
 | ||||||
|  #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) |  #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) | ||||||
|  	struct syslog_data sdata = SYSLOG_DATA_INIT; |  	struct syslog_data sdata = SYSLOG_DATA_INIT; | ||||||
|  #endif |  #endif | ||||||
| @@ -273,8 +278,10 @@ log_init(char *av0, LogLevel level, Sysl
 | @@ -206,8 +211,10 @@ log_init(const char *av0, LogLevel level
 | ||||||
|  		exit(1); |  		exit(1); | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @ -26,21 +26,21 @@ diff -up openssh-7.4p1/log.c.log-in-chroot openssh-7.4p1/log.c | |||||||
|   |   | ||||||
|  	log_on_stderr = on_stderr; |  	log_on_stderr = on_stderr; | ||||||
|  	if (on_stderr) |  	if (on_stderr) | ||||||
| diff -up openssh-7.4p1/log.h.log-in-chroot openssh-7.4p1/log.h
 | diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h
 | ||||||
| --- openssh-7.4p1/log.h.log-in-chroot	2016-12-19 05:59:41.000000000 +0100
 | --- openssh-8.6p1/log.h.log-in-chroot	2021-05-06 11:32:25.179006811 +0200
 | ||||||
| +++ openssh-7.4p1/log.h	2016-12-23 15:14:33.330168088 +0100
 | +++ openssh-8.6p1/log.h	2021-05-06 11:34:22.349925757 +0200
 | ||||||
| @@ -49,6 +49,7 @@ typedef enum {
 | @@ -52,6 +52,7 @@ typedef enum {
 | ||||||
|  typedef void (log_handler_fn)(LogLevel, const char *, void *); |  typedef void (log_handler_fn)(LogLevel, int, const char *, void *); | ||||||
|   |   | ||||||
|  void     log_init(char *, LogLevel, SyslogFacility, int); |  void     log_init(const char *, LogLevel, SyslogFacility, int); | ||||||
| +void     log_init_handler(char *, LogLevel, SyslogFacility, int, int);
 | +void     log_init_handler(const char *, LogLevel, SyslogFacility, int, int);
 | ||||||
|  LogLevel log_level_get(void); |  LogLevel log_level_get(void); | ||||||
|  int      log_change_level(LogLevel); |  int      log_change_level(LogLevel); | ||||||
|  int      log_is_on_stderr(void); |  int      log_is_on_stderr(void); | ||||||
| diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c
 | diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c
 | ||||||
| --- openssh-7.4p1/monitor.c.log-in-chroot	2016-12-23 15:14:33.311168085 +0100
 | --- openssh-8.6p1/monitor.c.log-in-chroot	2021-05-06 11:32:25.153006607 +0200
 | ||||||
| +++ openssh-7.4p1/monitor.c	2016-12-23 15:16:42.154193100 +0100
 | +++ openssh-8.6p1/monitor.c	2021-05-06 11:33:37.671575348 +0200
 | ||||||
| @@ -307,6 +307,8 @@ monitor_child_preauth(Authctxt *_authctx
 | @@ -297,6 +297,8 @@ monitor_child_preauth(struct ssh *ssh, s
 | ||||||
|  		close(pmonitor->m_log_sendfd); |  		close(pmonitor->m_log_sendfd); | ||||||
|  	pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; |  	pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; | ||||||
|   |   | ||||||
| @ -49,25 +49,25 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c | |||||||
|  	authctxt = (Authctxt *)ssh->authctxt; |  	authctxt = (Authctxt *)ssh->authctxt; | ||||||
|  	memset(authctxt, 0, sizeof(*authctxt)); |  	memset(authctxt, 0, sizeof(*authctxt)); | ||||||
|  	ssh->authctxt = authctxt; |  	ssh->authctxt = authctxt; | ||||||
| @@ -405,6 +407,8 @@ monitor_child_postauth(struct monitor *p
 | @@ -408,6 +410,8 @@ monitor_child_postauth(struct ssh *ssh,
 | ||||||
|  	close(pmonitor->m_recvfd); |  	close(pmonitor->m_recvfd); | ||||||
|  	pmonitor->m_recvfd = -1; |  	pmonitor->m_recvfd = -1; | ||||||
|   |   | ||||||
| +	pmonitor->m_state = "postauth";
 | +	pmonitor->m_state = "postauth";
 | ||||||
| +
 | +
 | ||||||
|  	monitor_set_child_handler(pmonitor->m_pid); |  	monitor_set_child_handler(pmonitor->m_pid); | ||||||
|  	signal(SIGHUP, &monitor_child_handler); |  	ssh_signal(SIGHUP, &monitor_child_handler); | ||||||
|  	signal(SIGTERM, &monitor_child_handler); |  	ssh_signal(SIGTERM, &monitor_child_handler); | ||||||
| @@ -472,7 +476,7 @@ monitor_read_log(struct monitor *pmonito
 | @@ -480,7 +484,7 @@ monitor_read_log(struct monitor *pmonito
 | ||||||
|  |  	/* Log it */ | ||||||
|  	if (log_level_name(level) == NULL) |  	if (log_level_name(level) == NULL) | ||||||
|  		fatal("%s: invalid log level %u (corrupted message?)", |  		fatal_f("invalid log level %u (corrupted message?)", level); | ||||||
|  		    __func__, level); | -	sshlogdirect(level, forced, "%s [preauth]", msg);
 | ||||||
| -	do_log2(level, "%s [preauth]", msg);
 | +	sshlogdirect(level, forced, "%s [%s]", msg, pmonitor->m_state);
 | ||||||
| +	do_log2(level, "%s [%s]", msg, pmonitor->m_state);
 |  | ||||||
|   |   | ||||||
|  	sshbuf_free(logmsg); |  	sshbuf_free(logmsg); | ||||||
|  	free(msg); |  	free(msg); | ||||||
| @@ -1719,13 +1723,28 @@ monitor_init(void)
 | @@ -1868,13 +1872,28 @@ monitor_init(void)
 | ||||||
|  	mon = xcalloc(1, sizeof(*mon)); |  	mon = xcalloc(1, sizeof(*mon)); | ||||||
|  	monitor_openfds(mon, 1); |  	monitor_openfds(mon, 1); | ||||||
|   |   | ||||||
| @ -89,7 +89,7 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c | |||||||
| +		xasprintf(&dev_log_path, "%s/dev/log", chroot_dir);
 | +		xasprintf(&dev_log_path, "%s/dev/log", chroot_dir);
 | ||||||
| +
 | +
 | ||||||
| +		if (stat(dev_log_path, &dev_log_stat) != 0) {
 | +		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);
 | +			debug_f("/dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", chroot_dir);
 | ||||||
| +			do_logfds = 1;
 | +			do_logfds = 1;
 | ||||||
| +		}
 | +		}
 | ||||||
| +		free(dev_log_path);
 | +		free(dev_log_path);
 | ||||||
| @ -98,10 +98,10 @@ diff -up openssh-7.4p1/monitor.c.log-in-chroot openssh-7.4p1/monitor.c | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  #ifdef GSSAPI |  #ifdef GSSAPI | ||||||
| diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h
 | diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h
 | ||||||
| --- openssh-7.4p1/monitor.h.log-in-chroot	2016-12-23 15:14:33.330168088 +0100
 | --- openssh-8.6p1/monitor.h.log-in-chroot	2021-05-06 11:32:25.153006607 +0200
 | ||||||
| +++ openssh-7.4p1/monitor.h	2016-12-23 15:16:28.372190424 +0100
 | +++ openssh-8.6p1/monitor.h	2021-05-06 11:32:25.180006819 +0200
 | ||||||
| @@ -83,10 +83,11 @@ struct monitor {
 | @@ -80,10 +80,11 @@ struct monitor {
 | ||||||
|  	int			 m_log_sendfd; |  	int			 m_log_sendfd; | ||||||
|  	struct kex		**m_pkex; |  	struct kex		**m_pkex; | ||||||
|  	pid_t			 m_pid; |  	pid_t			 m_pid; | ||||||
| @ -114,9 +114,9 @@ diff -up openssh-7.4p1/monitor.h.log-in-chroot openssh-7.4p1/monitor.h | |||||||
|   |   | ||||||
|  struct Authctxt; |  struct Authctxt; | ||||||
|  void monitor_child_preauth(struct ssh *, struct monitor *); |  void monitor_child_preauth(struct ssh *, struct monitor *); | ||||||
| diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c
 | diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c
 | ||||||
| --- openssh-7.4p1/session.c.log-in-chroot	2016-12-23 15:14:33.319168086 +0100
 | --- openssh-8.6p1/session.c.log-in-chroot	2021-05-06 11:32:25.166006709 +0200
 | ||||||
| +++ openssh-7.4p1/session.c	2016-12-23 15:18:18.742211853 +0100
 | +++ openssh-8.6p1/session.c	2021-05-06 11:32:25.181006827 +0200
 | ||||||
| @@ -160,6 +160,7 @@ login_cap_t *lc;
 | @@ -160,6 +160,7 @@ login_cap_t *lc;
 | ||||||
|   |   | ||||||
|  static int is_child = 0; |  static int is_child = 0; | ||||||
| @ -125,7 +125,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c | |||||||
|   |   | ||||||
|  /* File containing userauth info, if ExposeAuthInfo set */ |  /* File containing userauth info, if ExposeAuthInfo set */ | ||||||
|  static char *auth_info_file = NULL; |  static char *auth_info_file = NULL; | ||||||
| @@ -619,6 +620,7 @@ do_exec(Session *s, const char *command)
 | @@ -661,6 +662,7 @@ do_exec(struct ssh *ssh, Session *s, con
 | ||||||
|  	int ret; |  	int ret; | ||||||
|  	const char *forced = NULL, *tty = NULL; |  	const char *forced = NULL, *tty = NULL; | ||||||
|  	char session_type[1024]; |  	char session_type[1024]; | ||||||
| @ -133,7 +133,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c | |||||||
|   |   | ||||||
|  	if (options.adm_forced_command) { |  	if (options.adm_forced_command) { | ||||||
|  		original_command = command; |  		original_command = command; | ||||||
| @@ -676,6 +678,10 @@ do_exec(Session *s, const char *command)
 | @@ -720,6 +722,10 @@ do_exec(struct ssh *ssh, Session *s, con
 | ||||||
|  			tty += 5; |  			tty += 5; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @ -144,10 +144,10 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c | |||||||
|  	verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", |  	verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", | ||||||
|  	    session_type, |  	    session_type, | ||||||
|  	    tty == NULL ? "" : " on ", |  	    tty == NULL ? "" : " on ", | ||||||
| @@ -1486,14 +1492,6 @@ child_close_fds(void)
 | @@ -1524,14 +1530,6 @@ child_close_fds(struct ssh *ssh)
 | ||||||
|  	 * descriptors left by system functions.  They will be closed later. |   | ||||||
|  	 */ |  	/* Stop directing logs to a high-numbered fd before we close it */ | ||||||
|  	endpwent(); |  	log_redirect_stderr_to(NULL); | ||||||
| -
 | -
 | ||||||
| -	/*
 | -	/*
 | ||||||
| -	 * Close any extra open file descriptors so that we don't have them
 | -	 * Close any extra open file descriptors so that we don't have them
 | ||||||
| @ -159,7 +159,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  /* |  /* | ||||||
| @@ -1629,8 +1627,6 @@ do_child(Session *s, const char *command
 | @@ -1665,8 +1663,6 @@ do_child(struct ssh *ssh, Session *s, co
 | ||||||
|  			exit(1); |  			exit(1); | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @ -168,7 +168,7 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c | |||||||
|  	do_rc_files(ssh, s, shell); |  	do_rc_files(ssh, s, shell); | ||||||
|   |   | ||||||
|  	/* restore SIGPIPE for child */ |  	/* restore SIGPIPE for child */ | ||||||
| @@ -1653,9 +1649,17 @@ do_child(Session *s, const char *command
 | @@ -1691,9 +1687,17 @@ do_child(struct ssh *ssh, Session *s, co
 | ||||||
|  		argv[i] = NULL; |  		argv[i] = NULL; | ||||||
|  		optind = optreset = 1; |  		optind = optreset = 1; | ||||||
|  		__progname = argv[0]; |  		__progname = argv[0]; | ||||||
| @ -187,9 +187,9 @@ diff -up openssh-7.4p1/session.c.log-in-chroot openssh-7.4p1/session.c | |||||||
|  	fflush(NULL); |  	fflush(NULL); | ||||||
|   |   | ||||||
|  	/* Get the last component of the shell name. */ |  	/* Get the last component of the shell name. */ | ||||||
| diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h
 | diff -up openssh-8.6p1/sftp.h.log-in-chroot openssh-8.6p1/sftp.h
 | ||||||
| --- openssh-7.4p1/sftp.h.log-in-chroot	2016-12-19 05:59:41.000000000 +0100
 | --- openssh-8.6p1/sftp.h.log-in-chroot	2021-04-16 05:55:25.000000000 +0200
 | ||||||
| +++ openssh-7.4p1/sftp.h	2016-12-23 15:14:33.331168088 +0100
 | +++ openssh-8.6p1/sftp.h	2021-05-06 11:32:25.181006827 +0200
 | ||||||
| @@ -97,5 +97,5 @@
 | @@ -97,5 +97,5 @@
 | ||||||
|   |   | ||||||
|  struct passwd; |  struct passwd; | ||||||
| @ -197,10 +197,10 @@ diff -up openssh-7.4p1/sftp.h.log-in-chroot openssh-7.4p1/sftp.h | |||||||
| -int	sftp_server_main(int, char **, struct passwd *);
 | -int	sftp_server_main(int, char **, struct passwd *);
 | ||||||
| +int	sftp_server_main(int, char **, struct passwd *, int);
 | +int	sftp_server_main(int, char **, struct passwd *, int);
 | ||||||
|  void	sftp_server_cleanup_exit(int) __attribute__((noreturn)); |  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
 | diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c
 | ||||||
| --- openssh-7.4p1/sftp-server.c.log-in-chroot	2016-12-19 05:59:41.000000000 +0100
 | --- openssh-8.6p1/sftp-server.c.log-in-chroot	2021-04-16 05:55:25.000000000 +0200
 | ||||||
| +++ openssh-7.4p1/sftp-server.c	2016-12-23 15:14:33.331168088 +0100
 | +++ openssh-8.6p1/sftp-server.c	2021-05-06 11:32:25.181006827 +0200
 | ||||||
| @@ -1497,7 +1497,7 @@ sftp_server_usage(void)
 | @@ -1644,7 +1644,7 @@ sftp_server_usage(void)
 | ||||||
|  } |  } | ||||||
|   |   | ||||||
|  int |  int | ||||||
| @ -209,16 +209,16 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c | |||||||
|  { |  { | ||||||
|  	fd_set *rset, *wset; |  	fd_set *rset, *wset; | ||||||
|  	int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; |  	int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; | ||||||
| @@ -1511,7 +1511,7 @@ sftp_server_main(int argc, char **argv,
 | @@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv,
 | ||||||
|  |  	extern char *__progname; | ||||||
|   |   | ||||||
|  	ssh_malloc_init();	/* must be called before any mallocs */ |  | ||||||
|  	__progname = ssh_get_progname(argv[0]); |  	__progname = ssh_get_progname(argv[0]); | ||||||
| -	log_init(__progname, log_level, log_facility, log_stderr);
 | -	log_init(__progname, log_level, log_facility, log_stderr);
 | ||||||
| +	log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
 | +	log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
 | ||||||
|   |   | ||||||
|  	pw = pwcopy(user_pw); |  	pw = pwcopy(user_pw); | ||||||
|   |   | ||||||
| @@ -1582,7 +1582,7 @@ sftp_server_main(int argc, char **argv,
 | @@ -1730,7 +1730,7 @@ sftp_server_main(int argc, char **argv,
 | ||||||
|  		} |  		} | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @ -227,20 +227,20 @@ diff -up openssh-7.4p1/sftp-server.c.log-in-chroot openssh-7.4p1/sftp-server.c | |||||||
|   |   | ||||||
|  	/* |  	/* | ||||||
|  	 * On platforms where we can, avoid making /proc/self/{mem,maps} |  	 * 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
 | diff -up openssh-8.6p1/sftp-server-main.c.log-in-chroot openssh-8.6p1/sftp-server-main.c
 | ||||||
| --- openssh-7.4p1/sftp-server-main.c.log-in-chroot	2016-12-19 05:59:41.000000000 +0100
 | --- openssh-8.6p1/sftp-server-main.c.log-in-chroot	2021-04-16 05:55:25.000000000 +0200
 | ||||||
| +++ openssh-7.4p1/sftp-server-main.c	2016-12-23 15:14:33.331168088 +0100
 | +++ openssh-8.6p1/sftp-server-main.c	2021-05-06 11:32:25.181006827 +0200
 | ||||||
| @@ -49,5 +49,5 @@ main(int argc, char **argv)
 | @@ -50,5 +50,5 @@ main(int argc, char **argv)
 | ||||||
|  		return 1; |  		return 1; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| -	return (sftp_server_main(argc, argv, user_pw));
 | -	return (sftp_server_main(argc, argv, user_pw));
 | ||||||
| +	return (sftp_server_main(argc, argv, user_pw, 0));
 | +	return (sftp_server_main(argc, argv, user_pw, 0));
 | ||||||
|  } |  } | ||||||
| diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c
 | diff -up openssh-8.6p1/sshd.c.log-in-chroot openssh-8.6p1/sshd.c
 | ||||||
| --- openssh-7.4p1/sshd.c.log-in-chroot	2016-12-23 15:14:33.328168088 +0100
 | --- openssh-8.6p1/sshd.c.log-in-chroot	2021-05-06 11:32:25.177006795 +0200
 | ||||||
| +++ openssh-7.4p1/sshd.c	2016-12-23 15:14:33.332168088 +0100
 | +++ openssh-8.6p1/sshd.c	2021-05-06 11:32:25.182006834 +0200
 | ||||||
| @@ -650,7 +650,7 @@ privsep_postauth(Authctxt *authctxt)
 | @@ -559,7 +559,7 @@ privsep_postauth(struct ssh *ssh, Authct
 | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	/* New socket pair */ |  	/* New socket pair */ | ||||||
| @ -249,7 +249,7 @@ diff -up openssh-7.4p1/sshd.c.log-in-chroot openssh-7.4p1/sshd.c | |||||||
|   |   | ||||||
|  	pmonitor->m_pid = fork(); |  	pmonitor->m_pid = fork(); | ||||||
|  	if (pmonitor->m_pid == -1) |  	if (pmonitor->m_pid == -1) | ||||||
| @@ -668,6 +668,11 @@ privsep_postauth(Authctxt *authctxt)
 | @@ -578,6 +578,11 @@ privsep_postauth(struct ssh *ssh, Authct
 | ||||||
|   |   | ||||||
|  	close(pmonitor->m_sendfd); |  	close(pmonitor->m_sendfd); | ||||||
|  	pmonitor->m_sendfd = -1; |  	pmonitor->m_sendfd = -1; | ||||||
|  | |||||||
| @ -10,5 +10,5 @@ | |||||||
| +		}
 | +		}
 | ||||||
|  		omode = mode; |  		omode = mode; | ||||||
|  		mode |= S_IWUSR; |  		mode |= S_IWUSR; | ||||||
|  		if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { |  		if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { | ||||||
| -- 
 | -- 
 | ||||||
|  | |||||||
| @ -34,19 +34,19 @@ index 8f32464..18a2ca4 100644 | |||||||
| +
 | +
 | ||||||
| +	contexts_path = selinux_openssh_contexts_path();
 | +	contexts_path = selinux_openssh_contexts_path();
 | ||||||
| +	if (contexts_path == NULL) {
 | +	if (contexts_path == NULL) {
 | ||||||
| +		debug3("%s: Failed to get the path to SELinux context", __func__);
 | +		debug3_f("Failed to get the path to SELinux context");
 | ||||||
| +		return;
 | +		return;
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
| +	if ((contexts_file = fopen(contexts_path, "r")) == NULL) {
 | +	if ((contexts_file = fopen(contexts_path, "r")) == NULL) {
 | ||||||
| +		debug("%s: Failed to open SELinux context file", __func__);
 | +		debug_f("Failed to open SELinux context file");
 | ||||||
| +		return;
 | +		return;
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
| +	if (fstat(fileno(contexts_file), &sb) != 0 ||
 | +	if (fstat(fileno(contexts_file), &sb) != 0 ||
 | ||||||
| +	    sb.st_uid != 0 || (sb.st_mode & 022) != 0) {
 | +	    sb.st_uid != 0 || (sb.st_mode & 022) != 0) {
 | ||||||
| +		logit("%s: SELinux context file needs to be owned by root"
 | +		logit_f("SELinux context file needs to be owned by root"
 | ||||||
| +		    " and not writable by anyone else", __func__);
 | +		    " and not writable by anyone else");
 | ||||||
| +		fclose(contexts_file);
 | +		fclose(contexts_file);
 | ||||||
| +		return;
 | +		return;
 | ||||||
| +	}
 | +	}
 | ||||||
| @ -70,7 +70,7 @@ index 8f32464..18a2ca4 100644 | |||||||
| +		if (arg && strcmp(arg, "privsep_preauth") == 0) {
 | +		if (arg && strcmp(arg, "privsep_preauth") == 0) {
 | ||||||
| +			arg = strdelim(&cp);
 | +			arg = strdelim(&cp);
 | ||||||
| +			if (!arg || *arg == '\0') {
 | +			if (!arg || *arg == '\0') {
 | ||||||
| +				debug("%s: privsep_preauth is empty", __func__);
 | +				debug_f("privsep_preauth is empty");
 | ||||||
| +				fclose(contexts_file);
 | +				fclose(contexts_file);
 | ||||||
| +				return;
 | +				return;
 | ||||||
| +			}
 | +			}
 | ||||||
| @ -80,8 +80,8 @@ index 8f32464..18a2ca4 100644 | |||||||
| +	fclose(contexts_file);
 | +	fclose(contexts_file);
 | ||||||
| +
 | +
 | ||||||
| +	if (preauth_context == NULL) {
 | +	if (preauth_context == NULL) {
 | ||||||
| +		debug("%s: Unable to find 'privsep_preauth' option in"
 | +		debug_f("Unable to find 'privsep_preauth' option in"
 | ||||||
| +		    " SELinux context file", __func__);
 | +		    " SELinux context file");
 | ||||||
| +		return;
 | +		return;
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
| @ -101,10 +101,11 @@ index 22ea8ef..1fc963d 100644 | |||||||
|  	if ((cx = index(cx + 1, ':'))) |  	if ((cx = index(cx + 1, ':'))) | ||||||
|  		strlcat(newctx, cx, newlen); |  		strlcat(newctx, cx, newlen); | ||||||
| -	debug3("%s: setting context from '%s' to '%s'", __func__,
 | -	debug3("%s: setting context from '%s' to '%s'", __func__,
 | ||||||
| +	debug("%s: setting context from '%s' to '%s'", __func__,
 | +	debug_f("setting context from '%s' to '%s'",
 | ||||||
|  	    oldctx, newctx); |  	    oldctx, newctx); | ||||||
|  	if (setcon(newctx) < 0) |  	if (setcon(newctx) < 0) | ||||||
|  		switchlog("%s: setcon %s from %s failed with %s", __func__, |  		do_log2(log_level, "%s: setcon %s from %s failed with %s", | ||||||
|  | 		    __func__, newctx, oldctx, strerror(errno)); | ||||||
| diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
 | diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
 | ||||||
| index cb51f99..8b7cda2 100644
 | index cb51f99..8b7cda2 100644
 | ||||||
| --- a/openbsd-compat/port-linux.h
 | --- a/openbsd-compat/port-linux.h
 | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c | |||||||
| +	options->enable_k5users = -1;
 | +	options->enable_k5users = -1;
 | ||||||
|  	options->password_authentication = -1; |  	options->password_authentication = -1; | ||||||
|  	options->kbd_interactive_authentication = -1; |  	options->kbd_interactive_authentication = -1; | ||||||
|  	options->challenge_response_authentication = -1; | 	options->permit_empty_passwd = -1; | ||||||
| @@ -345,6 +346,8 @@ fill_default_server_options(ServerOption
 | @@ -345,6 +346,8 @@ fill_default_server_options(ServerOption
 | ||||||
|  #endif |  #endif | ||||||
|  	if (options->use_kuserok == -1) |  	if (options->use_kuserok == -1) | ||||||
| @ -39,8 +39,8 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c | |||||||
|  		options->password_authentication = 1; |  		options->password_authentication = 1; | ||||||
|  	if (options->kbd_interactive_authentication == -1) |  	if (options->kbd_interactive_authentication == -1) | ||||||
| @@ -418,7 +421,7 @@ typedef enum {
 | @@ -418,7 +421,7 @@ typedef enum {
 | ||||||
|  	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, |  	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, | ||||||
|  	sHostKeyAlgorithms, |  	sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, | ||||||
|  	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, |  	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, | ||||||
| -	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
 | -	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
 | ||||||
| +	sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
 | +	sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
 | ||||||
| @ -72,9 +72,9 @@ diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c | |||||||
| +		intptr = &options->enable_k5users;
 | +		intptr = &options->enable_k5users;
 | ||||||
| +		goto parse_flag;
 | +		goto parse_flag;
 | ||||||
| +
 | +
 | ||||||
|  	case sPermitListen: | 	case sMatch: | ||||||
|  	case sPermitOpen: | 		if (cmdline) | ||||||
|  		if (opcode == sPermitListen) { | 			fatal("Match directive not supported as a command-line " | ||||||
| @@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d
 | @@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d
 | ||||||
|  	M_CP_INTOPT(ip_qos_interactive); |  	M_CP_INTOPT(ip_qos_interactive); | ||||||
|  	M_CP_INTOPT(ip_qos_bulk); |  	M_CP_INTOPT(ip_qos_bulk); | ||||||
| @ -122,7 +122,7 @@ diff -up openssh-7.4p1/sshd_config.GSSAPIEnablek5users openssh-7.4p1/sshd_config | |||||||
| --- openssh-7.4p1/sshd_config.GSSAPIEnablek5users	2016-12-23 15:18:40.616216100 +0100
 | --- openssh-7.4p1/sshd_config.GSSAPIEnablek5users	2016-12-23 15:18:40.616216100 +0100
 | ||||||
| +++ openssh-7.4p1/sshd_config	2016-12-23 15:18:40.631216103 +0100
 | +++ openssh-7.4p1/sshd_config	2016-12-23 15:18:40.631216103 +0100
 | ||||||
| @@ -80,6 +80,7 @@ GSSAPIAuthentication yes
 | @@ -80,6 +80,7 @@ GSSAPIAuthentication yes
 | ||||||
|  GSSAPICleanupCredentials no |  #GSSAPICleanupCredentials yes | ||||||
|  #GSSAPIStrictAcceptorCheck yes |  #GSSAPIStrictAcceptorCheck yes | ||||||
|  #GSSAPIKeyExchange no |  #GSSAPIKeyExchange no | ||||||
| +#GSSAPIEnablek5users no
 | +#GSSAPIEnablek5users no
 | ||||||
|  | |||||||
| @ -1,257 +0,0 @@ | |||||||
| 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@
 |  | ||||||
|  MKDIR_P=@MKDIR_P@ |  | ||||||
|  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)
 |  | ||||||
|   |  | ||||||
|  XMSS_OBJS=\ |  | ||||||
|  	ssh-xmss.o \ |  | ||||||
| @@ -194,6 +195,9 @@ ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) l
 |  | ||||||
|  ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o |  | ||||||
|  	$(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS) |  | ||||||
|   |  | ||||||
| +ctr-cavstest$(EXEEXT): $(LIBCOMPAT) libssh.a ctr-cavstest.o
 |  | ||||||
| +	$(LD) -o $@ ctr-cavstest.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(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,215 @@
 |  | ||||||
| +/*
 |  | ||||||
| + *
 |  | ||||||
| + * 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 "ssherr.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, r;
 |  | ||||||
| +        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();
 |  | ||||||
| +        }
 |  | ||||||
| +
 |  | ||||||
| +	OpenSSL_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;
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +	if ((r = cipher_init(&cc, c, key, keylen, iv, ivlen, encrypt)) != 0) {
 |  | ||||||
| +		fprintf(stderr, "Error: cipher_init failed: %s\n", ssh_err(r));
 |  | ||||||
| +		return 2;
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +	free(key);
 |  | ||||||
| +	free(iv);
 |  | ||||||
| +
 |  | ||||||
| +	outdata = malloc(datalen);
 |  | ||||||
| +	if(outdata == NULL) {
 |  | ||||||
| +		fprintf(stderr, "Error: memory allocation failure\n");
 |  | ||||||
| +		return 2;
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +	if ((r = cipher_crypt(cc, 0, outdata, data, datalen, 0, 0)) != 0) {
 |  | ||||||
| +		fprintf(stderr, "Error: cipher_crypt failed: %s\n", ssh_err(r));
 |  | ||||||
| +		return 2;
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +	free(data);
 |  | ||||||
| +
 |  | ||||||
| +	cipher_free(cc);
 |  | ||||||
| +
 |  | ||||||
| +        for (p = outdata; datalen > 0; ++p, --datalen) {
 |  | ||||||
| +		printf("%02X", (unsigned char)*p);
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +        free(outdata);
 |  | ||||||
| +
 |  | ||||||
| +        printf("\n");
 |  | ||||||
| +        return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| @ -1,10 +1,10 @@ | |||||||
| diff -up openssh/auth.c.keycat openssh/misc.c
 | diff -up openssh/misc.c.keycat openssh/misc.c
 | ||||||
| --- openssh/auth.c.keycat	2015-06-24 10:57:50.158849606 +0200
 | --- openssh/misc.c.keycat	2015-06-24 10:57:50.158849606 +0200
 | ||||||
| +++ openssh/auth.c	2015-06-24 11:04:23.989868638 +0200
 | +++ openssh/misc.c	2015-06-24 11:04:23.989868638 +0200
 | ||||||
| @@ -966,6 +966,14 @@ subprocess(const char *tag, struct passw
 | @@ -966,6 +966,13 @@ subprocess(const char *tag, struct passw
 | ||||||
|  |  			error("%s: dup2: %s", tag, strerror(errno)); | ||||||
|  			_exit(1); |  			_exit(1); | ||||||
|  		} |  		} | ||||||
|   |  | ||||||
| +#ifdef WITH_SELINUX
 | +#ifdef WITH_SELINUX
 | ||||||
| +		if (sshd_selinux_setup_env_variables() < 0) {
 | +		if (sshd_selinux_setup_env_variables() < 0) {
 | ||||||
| +			error ("failed to copy environment:  %s",
 | +			error ("failed to copy environment:  %s",
 | ||||||
| @ -12,10 +12,9 @@ diff -up openssh/auth.c.keycat openssh/misc.c | |||||||
| +			_exit(127);
 | +			_exit(127);
 | ||||||
| +		}
 | +		}
 | ||||||
| +#endif
 | +#endif
 | ||||||
| +
 |  		if (env != NULL) | ||||||
|  		execve(av[0], av, child_env); |  			execve(av[0], av, env); | ||||||
|  		error("%s exec \"%s\": %s", tag, command, strerror(errno)); |  		else | ||||||
|  		_exit(127); |  | ||||||
| diff -up openssh/HOWTO.ssh-keycat.keycat openssh/HOWTO.ssh-keycat
 | diff -up openssh/HOWTO.ssh-keycat.keycat openssh/HOWTO.ssh-keycat
 | ||||||
| --- openssh/HOWTO.ssh-keycat.keycat	2015-06-24 10:57:50.157849608 +0200
 | --- openssh/HOWTO.ssh-keycat.keycat	2015-06-24 10:57:50.157849608 +0200
 | ||||||
| +++ openssh/HOWTO.ssh-keycat	2015-06-24 10:57:50.157849608 +0200
 | +++ openssh/HOWTO.ssh-keycat	2015-06-24 10:57:50.157849608 +0200
 | ||||||
| @ -36,44 +35,44 @@ diff -up openssh/Makefile.in.keycat openssh/Makefile.in | |||||||
| --- openssh/Makefile.in.keycat	2015-06-24 10:57:50.152849621 +0200
 | --- openssh/Makefile.in.keycat	2015-06-24 10:57:50.152849621 +0200
 | ||||||
| +++ openssh/Makefile.in	2015-06-24 10:57:50.157849608 +0200
 | +++ openssh/Makefile.in	2015-06-24 10:57:50.157849608 +0200
 | ||||||
| @@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server
 | @@ -27,6 +27,7 @@ SFTP_SERVER=$(libexecdir)/sftp-server
 | ||||||
|  |  ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass | ||||||
|  |  SFTP_SERVER=$(libexecdir)/sftp-server | ||||||
|  SSH_KEYSIGN=$(libexecdir)/ssh-keysign |  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_KEYCAT=$(libexecdir)/ssh-keycat
 | ||||||
|  SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper |  SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper | ||||||
|  |  SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper | ||||||
|  PRIVSEP_PATH=@PRIVSEP_PATH@ |  PRIVSEP_PATH=@PRIVSEP_PATH@ | ||||||
|  SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ |  | ||||||
| @@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@
 | @@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@
 | ||||||
|  |  K5LIBS=@K5LIBS@ | ||||||
|  GSSLIBS=@GSSLIBS@ |  GSSLIBS=@GSSLIBS@ | ||||||
|  SSHLIBS=@SSHLIBS@ |  | ||||||
|  SSHDLIBS=@SSHDLIBS@ |  SSHDLIBS=@SSHDLIBS@ | ||||||
| +KEYCATLIBS=@KEYCATLIBS@
 | +KEYCATLIBS=@KEYCATLIBS@
 | ||||||
|  LIBEDIT=@LIBEDIT@ |  LIBEDIT=@LIBEDIT@ | ||||||
|  |  LIBFIDO2=@LIBFIDO2@ | ||||||
|  AR=@AR@ |  AR=@AR@ | ||||||
|  AWK=@AWK@ |  | ||||||
| @@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@
 | @@ -65,7 +66,7 @@ EXEEXT=@EXEEXT@
 | ||||||
|  MKDIR_P=@MKDIR_P@ |  | ||||||
|  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)
 |  .SUFFIXES: .lo | ||||||
| +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-sk-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-sk-helper$(EXEEXT) ssh-keycat$(EXEEXT)
 | ||||||
|   |   | ||||||
|  XMSS_OBJS=\ |  XMSS_OBJS=\ | ||||||
|  	ssh-xmss.o \ |  	ssh-xmss.o \ | ||||||
| @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
 | @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
 | ||||||
|  ssh-ldap-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o |  ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) | ||||||
|  	$(LD) -o $@ ldapconf.o ldapbody.o ldapmisc.o ldap-helper.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LDAPLIBS) |  	$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) | ||||||
|   |   | ||||||
| +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o
 | +ssh-keycat$(EXEEXT): $(LIBCOMPAT) $(SSHDOBJS) libssh.a ssh-keycat.o uidswap.o
 | ||||||
| +	$(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
 | +	$(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
 | ||||||
| +
 | +
 | ||||||
|  ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o |  ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) | ||||||
|  	$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) |  	$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) | ||||||
|   |   | ||||||
| @@ -321,6 +325,7 @@ install-files:
 | @@ -321,6 +325,7 @@ install-files:
 | ||||||
|  		$(INSTALL) -m 0700 $(STRIP_OPT) ssh-ldap-helper $(DESTDIR)$(SSH_LDAP_HELPER) ; \ |  	$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) | ||||||
|  		$(INSTALL) -m 0700 ssh-ldap-wrapper $(DESTDIR)$(SSH_LDAP_WRAPPER) ; \ |  	$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) | ||||||
|  	fi |  	$(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) | ||||||
| +	$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keycat$(EXEEXT) $(DESTDIR)$(libexecdir)/ssh-keycat$(EXEEXT)
 | +	$(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$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) | ||||||
|  	$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) |  	$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) | ||||||
| @ -466,16 +465,16 @@ index 3bbccfd..6481f1f 100644 | |||||||
|  				esac |  				esac | ||||||
|  			fi |  			fi | ||||||
| @@ -4042,6 +4044,7 @@ AC_ARG_WITH([selinux],
 | @@ -4042,6 +4044,7 @@ AC_ARG_WITH([selinux],
 | ||||||
|  |  	fi ] | ||||||
|  ) |  ) | ||||||
|  AC_SUBST([SSHLIBS]) |  | ||||||
|  AC_SUBST([SSHDLIBS]) |  AC_SUBST([SSHDLIBS]) | ||||||
| +AC_SUBST([KEYCATLIBS])
 | +AC_SUBST([KEYCATLIBS])
 | ||||||
|   |   | ||||||
|  # Check whether user wants Kerberos 5 support |  # Check whether user wants Kerberos 5 support | ||||||
|  KRB5_MSG="no" |  KRB5_MSG="no" | ||||||
| @@ -5031,6 +5034,9 @@ fi
 | @@ -5031,6 +5034,9 @@ fi
 | ||||||
|  if test ! -z "${SSHLIBS}"; then |  if test ! -z "${SSHDLIBS}"; then | ||||||
|  echo "          +for ssh: ${SSHLIBS}" |  echo "         +for sshd: ${SSHDLIBS}" | ||||||
|  fi |  fi | ||||||
| +if test ! -z "${KEYCATLIBS}"; then
 | +if test ! -z "${KEYCATLIBS}"; then
 | ||||||
| +echo "   +for ssh-keycat: ${KEYCATLIBS}"
 | +echo "   +for ssh-keycat: ${KEYCATLIBS}"
 | ||||||
|  | |||||||
| @ -1,8 +1,7 @@ | |||||||
| diff --git a/authfile.c b/authfile.c
 | diff -up openssh-8.2p1/authfile.c.keyperm openssh-8.2p1/authfile.c
 | ||||||
| index e93d867..4fc5b3d 100644
 | --- openssh-8.2p1/authfile.c.keyperm	2020-02-14 01:40:54.000000000 +0100
 | ||||||
| --- a/authfile.c
 | +++ openssh-8.2p1/authfile.c	2020-02-17 11:55:12.841729758 +0100
 | ||||||
| +++ b/authfile.c
 | @@ -31,6 +31,7 @@
 | ||||||
| @@ -32,6 +32,7 @@
 |  | ||||||
|   |   | ||||||
|  #include <errno.h> |  #include <errno.h> | ||||||
|  #include <fcntl.h> |  #include <fcntl.h> | ||||||
| @ -10,17 +9,23 @@ index e93d867..4fc5b3d 100644 | |||||||
|  #include <stdio.h> |  #include <stdio.h> | ||||||
|  #include <stdarg.h> |  #include <stdarg.h> | ||||||
|  #include <stdlib.h> |  #include <stdlib.h> | ||||||
| @@ -207,6 +208,13 @@ sshkey_perm_ok(int fd, const char *filename)
 | @@ -101,7 +102,19 @@ sshkey_perm_ok(int fd, const char *filen
 | ||||||
|  #ifdef HAVE_CYGWIN |  #ifdef HAVE_CYGWIN | ||||||
|  	if (check_ntsec(filename)) |  	if (check_ntsec(filename)) | ||||||
|  #endif |  #endif | ||||||
|  | +
 | ||||||
|  |  	if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { | ||||||
| +		if (st.st_mode & 040) {
 | +		if (st.st_mode & 040) {
 | ||||||
| +			struct group *gr;
 | +			struct group *gr;
 | ||||||
| +
 | +
 | ||||||
| +		if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid))
 | +			if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid)) {
 | ||||||
| +			st.st_mode &= ~040;
 | +				/* The only additional bit is read
 | ||||||
|  | +				 * for ssh_keys group, which is fine */
 | ||||||
|  | +				if ((st.st_mode & 077) == 040 ) {
 | ||||||
|  | +					return 0;
 | ||||||
|  | +				}
 | ||||||
|  | +			}
 | ||||||
| +		}
 | +		}
 | ||||||
| +
 |  | ||||||
|  	if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { |  | ||||||
|  		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); |  		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); | ||||||
|  		error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @"); |  		error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @"); | ||||||
|  |  		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); | ||||||
|  | |||||||
| @ -182,7 +182,7 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c | |||||||
| +	options->use_kuserok = -1;
 | +	options->use_kuserok = -1;
 | ||||||
|  	options->password_authentication = -1; |  	options->password_authentication = -1; | ||||||
|  	options->kbd_interactive_authentication = -1; |  	options->kbd_interactive_authentication = -1; | ||||||
|  	options->challenge_response_authentication = -1; | 	options->permit_empty_passwd = -1; | ||||||
| @@ -278,6 +279,8 @@ fill_default_server_options(ServerOption
 | @@ -278,6 +279,8 @@ fill_default_server_options(ServerOption
 | ||||||
|  	if (options->gss_kex_algorithms == NULL) |  	if (options->gss_kex_algorithms == NULL) | ||||||
|  		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); |  		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); | ||||||
| @ -193,8 +193,8 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c | |||||||
|  		options->password_authentication = 1; |  		options->password_authentication = 1; | ||||||
|  	if (options->kbd_interactive_authentication == -1) |  	if (options->kbd_interactive_authentication == -1) | ||||||
| @@ -399,7 +402,7 @@ typedef enum {
 | @@ -399,7 +402,7 @@ typedef enum {
 | ||||||
|  	sPermitRootLogin, sLogFacility, sLogLevel, | 	sPort, sHostKeyFile, sLoginGraceTime, | ||||||
|  	sRhostsRSAAuthentication, sRSAAuthentication, | 	sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, | ||||||
| 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, | 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, | ||||||
| -	sKerberosGetAFSToken, sKerberosUniqueCCache,
 | -	sKerberosGetAFSToken, sKerberosUniqueCCache,
 | ||||||
| +	sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok,
 | +	sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok,
 | ||||||
| @ -217,16 +217,16 @@ diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c | |||||||
|  	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, |  	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, | ||||||
|  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, |  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, | ||||||
| @@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions
 | @@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions
 | ||||||
|  		*activep = value; | 		} | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| +	case sKerberosUseKuserok:
 | +	case sKerberosUseKuserok:
 | ||||||
| +		intptr = &options->use_kuserok;
 | +		intptr = &options->use_kuserok;
 | ||||||
| +		goto parse_flag;
 | +		goto parse_flag;
 | ||||||
| +
 | +
 | ||||||
|  	case sPermitListen: | 	case sMatch: | ||||||
|  	case sPermitOpen: | 		if (cmdline) | ||||||
|  		if (opcode == sPermitListen) { | 			fatal("Match directive not supported as a command-line " | ||||||
| @@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d
 | @@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d
 | ||||||
|  	M_CP_INTOPT(client_alive_interval); |  	M_CP_INTOPT(client_alive_interval); | ||||||
|  	M_CP_INTOPT(ip_qos_interactive); |  	M_CP_INTOPT(ip_qos_interactive); | ||||||
| @ -286,4 +286,4 @@ diff -up openssh-7.4p1/sshd_config.kuserok openssh-7.4p1/sshd_config | |||||||
| +#KerberosUseKuserok yes
 | +#KerberosUseKuserok yes
 | ||||||
|   |   | ||||||
|  # GSSAPI options |  # GSSAPI options | ||||||
|  GSSAPIAuthentication yes |  #GSSAPIAuthentication no | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh- | |||||||
| --- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux	2016-12-23 18:58:52.973122201 +0100
 | --- openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux	2016-12-23 18:58:52.973122201 +0100
 | ||||||
| +++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c	2016-12-23 18:58:52.974122201 +0100
 | +++ openssh-7.4p1/openbsd-compat/port-linux-sshd.c	2016-12-23 18:58:52.974122201 +0100
 | ||||||
| @@ -419,6 +419,28 @@ sshd_selinux_setup_exec_context(char *pw
 | @@ -419,6 +419,28 @@ sshd_selinux_setup_exec_context(char *pw
 | ||||||
|  	debug3("%s: done", __func__); |  	debug3_f("done"); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| +void
 | +void
 | ||||||
| @ -25,15 +25,15 @@ diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh- | |||||||
| +		return;
 | +		return;
 | ||||||
| +
 | +
 | ||||||
| +	if (getexeccon((security_context_t *)&ctx) != 0) {
 | +	if (getexeccon((security_context_t *)&ctx) != 0) {
 | ||||||
| +		logit("%s: getexeccon failed with %s", __func__, strerror(errno));
 | +		logit_f("getexeccon failed with %s", strerror(errno));
 | ||||||
| +		return;
 | +		return;
 | ||||||
| +	}
 | +	}
 | ||||||
| +	if (ctx != NULL) {
 | +	if (ctx != NULL) {
 | ||||||
| +		/* unset exec context before we will lose this capabililty */
 | +		/* unset exec context before we will lose this capabililty */
 | ||||||
| +		if (setexeccon(NULL) != 0)
 | +		if (setexeccon(NULL) != 0)
 | ||||||
| +			fatal("%s: setexeccon failed with %s", __func__, strerror(errno));
 | +			fatal_f("setexeccon failed with %s", strerror(errno));
 | ||||||
| +		if (setcon(ctx) != 0)
 | +		if (setcon(ctx) != 0)
 | ||||||
| +			fatal("%s: setcon failed with %s", __func__, strerror(errno));
 | +			fatal_f("setcon failed with %s", strerror(errno));
 | ||||||
| +		freecon(ctx);
 | +		freecon(ctx);
 | ||||||
| +	}
 | +	}
 | ||||||
| +}
 | +}
 | ||||||
|  | |||||||
| @ -1,29 +1,205 @@ | |||||||
| diff -up openssh-8.0p1/channels.c.coverity openssh-8.0p1/channels.c
 | diff -up openssh-8.5p1/addr.c.coverity openssh-8.5p1/addr.c
 | ||||||
| --- openssh-8.0p1/channels.c.coverity	2021-06-21 10:59:17.297473319 +0200
 | --- openssh-8.5p1/addr.c.coverity	2021-03-02 11:31:47.000000000 +0100
 | ||||||
| +++ openssh-8.0p1/channels.c	2021-06-21 11:11:32.467290400 +0200
 | +++ openssh-8.5p1/addr.c	2021-03-24 12:03:33.782968159 +0100
 | ||||||
| @@ -341,15 +341,15 @@ channel_register_fds(struct ssh *ssh, Ch
 | @@ -312,8 +312,10 @@ addr_pton(const char *p, struct xaddr *n
 | ||||||
|  		 * restore their blocking state on exit to avoid interfering |  	if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) | ||||||
|  		 * with other programs that follow. |  		return -1; | ||||||
|  |   | ||||||
|  | -	if (ai == NULL || ai->ai_addr == NULL)
 | ||||||
|  | +	if (ai == NULL || ai->ai_addr == NULL) {
 | ||||||
|  | +		freeaddrinfo(ai);
 | ||||||
|  |  		return -1; | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, | ||||||
|  |  	    n) == -1) { | ||||||
|  | @@ -336,12 +338,16 @@ addr_sa_pton(const char *h, const char *
 | ||||||
|  |  	if (h == NULL || getaddrinfo(h, s, &hints, &ai) != 0) | ||||||
|  |  		return -1; | ||||||
|  |   | ||||||
|  | -	if (ai == NULL || ai->ai_addr == NULL)
 | ||||||
|  | +	if (ai == NULL || ai->ai_addr == NULL) {
 | ||||||
|  | +		freeaddrinfo(ai);
 | ||||||
|  |  		return -1; | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	if (sa != NULL) { | ||||||
|  | -		if (slen < ai->ai_addrlen)
 | ||||||
|  | +		if (slen < ai->ai_addrlen) {
 | ||||||
|  | +			freeaddrinfo(ai);
 | ||||||
|  |  			return -1; | ||||||
|  | +		}
 | ||||||
|  |  		memcpy(sa, &ai->ai_addr, ai->ai_addrlen); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | diff -up openssh-8.5p1/auth-krb5.c.coverity openssh-8.5p1/auth-krb5.c
 | ||||||
|  | --- openssh-8.5p1/auth-krb5.c.coverity	2021-03-24 12:03:33.724967756 +0100
 | ||||||
|  | +++ openssh-8.5p1/auth-krb5.c	2021-03-24 12:03:33.782968159 +0100
 | ||||||
|  | @@ -426,6 +426,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx,
 | ||||||
|  |  		umask(old_umask); | ||||||
|  |  		if (tmpfd == -1) { | ||||||
|  |  			logit("mkstemp(): %.100s", strerror(oerrno)); | ||||||
|  | +			free(ccname);
 | ||||||
|  |  			return oerrno; | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  | @@ -433,6 +434,7 @@ ssh_krb5_cc_new_unique(krb5_context ctx,
 | ||||||
|  |  			oerrno = errno; | ||||||
|  |  			logit("fchmod(): %.100s", strerror(oerrno)); | ||||||
|  |  			close(tmpfd); | ||||||
|  | +			free(ccname);
 | ||||||
|  |  			return oerrno; | ||||||
|  |  		} | ||||||
|  |  		/* make sure the KRB5CCNAME is set for non-standard location */ | ||||||
|  | diff -up openssh-8.5p1/auth-options.c.coverity openssh-8.5p1/auth-options.c
 | ||||||
|  | --- openssh-8.5p1/auth-options.c.coverity	2021-03-02 11:31:47.000000000 +0100
 | ||||||
|  | +++ openssh-8.5p1/auth-options.c	2021-03-24 12:03:33.782968159 +0100
 | ||||||
|  | @@ -706,6 +708,7 @@ serialise_array(struct sshbuf *m, char *
 | ||||||
|  |  		return r; | ||||||
|  |  	} | ||||||
|  |  	/* success */ | ||||||
|  | +	sshbuf_free(b);
 | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | diff -up openssh-7.4p1/channels.c.coverity openssh-7.4p1/channels.c
 | ||||||
|  | --- openssh-7.4p1/channels.c.coverity	2016-12-23 16:40:26.881788686 +0100
 | ||||||
|  | +++ openssh-7.4p1/channels.c	2016-12-23 16:42:36.244818763 +0100
 | ||||||
|  | @@ -1875,7 +1875,7 @@ channel_post_connecting(struct ssh *ssh,
 | ||||||
|  |  		debug("channel %d: connection failed: %s", | ||||||
|  |  		    c->self, strerror(err)); | ||||||
|  |  		/* Try next address, if any */ | ||||||
|  | -		if ((sock = connect_next(&c->connect_ctx)) > 0) {
 | ||||||
|  | +		if ((sock = connect_next(&c->connect_ctx)) >= 0) {
 | ||||||
|  |  			close(c->sock); | ||||||
|  |  			c->sock = c->rfd = c->wfd = sock; | ||||||
|  |  			channel_find_maxfd(ssh->chanctxt); | ||||||
|  | diff -up openssh-8.5p1/dns.c.coverity openssh-8.5p1/dns.c
 | ||||||
|  | --- openssh-8.5p1/dns.c.coverity	2021-03-02 11:31:47.000000000 +0100
 | ||||||
|  | +++ openssh-8.5p1/dns.c	2021-03-24 12:03:33.783968166 +0100
 | ||||||
|  | @@ -282,6 +282,7 @@ verify_host_key_dns(const char *hostname
 | ||||||
|  | 		    &hostkey_digest, &hostkey_digest_len, hostkey)) { | ||||||
|  | 			error("Error calculating key fingerprint."); | ||||||
|  | 			freerrset(fingerprints); | ||||||
|  | +				free(dnskey_digest);
 | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | diff -up openssh-8.5p1/gss-genr.c.coverity openssh-8.5p1/gss-genr.c
 | ||||||
|  | --- openssh-8.5p1/gss-genr.c.coverity	2021-03-26 11:52:46.613942552 +0100
 | ||||||
|  | +++ openssh-8.5p1/gss-genr.c	2021-03-26 11:54:37.881726318 +0100
 | ||||||
|  | @@ -167,8 +167,9 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
 | ||||||
|  |  			enclen = __b64_ntop(digest, | ||||||
|  |  			    ssh_digest_bytes(SSH_DIGEST_MD5), encoded, | ||||||
|  |  			    ssh_digest_bytes(SSH_DIGEST_MD5) * 2); | ||||||
|  | -
 | ||||||
|  | +#pragma GCC diagnostic ignored "-Wstringop-overflow"
 | ||||||
|  |  			cp = strncpy(s, kex, strlen(kex)); | ||||||
|  | +#pragma pop
 | ||||||
|  |  			for ((p = strsep(&cp, ",")); p && *p != '\0'; | ||||||
|  |  				(p = strsep(&cp, ","))) { | ||||||
|  |  				if (sshbuf_len(buf) != 0 && | ||||||
|  | diff -up openssh-8.5p1/krl.c.coverity openssh-8.5p1/krl.c
 | ||||||
|  | --- openssh-8.5p1/krl.c.coverity	2021-03-02 11:31:47.000000000 +0100
 | ||||||
|  | +++ openssh-8.5p1/krl.c	2021-03-24 12:03:33.783968166 +0100
 | ||||||
|  | @@ -1209,6 +1209,7 @@ ssh_krl_from_blob(struct sshbuf *buf, st
 | ||||||
|  |  	sshkey_free(key); | ||||||
|  |  	sshbuf_free(copy); | ||||||
|  |  	sshbuf_free(sect); | ||||||
|  | +	/* coverity[leaked_storage : FALSE] */
 | ||||||
|  |  	return r; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -1261,6 +1262,7 @@ is_key_revoked(struct ssh_krl *krl, cons
 | ||||||
|  |  		return r; | ||||||
|  |  	erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); | ||||||
|  |  	free(rb.blob); | ||||||
|  | +	rb.blob = NULL; /* make coverity happy */
 | ||||||
|  |  	if (erb != NULL) { | ||||||
|  |  		KRL_DBG(("revoked by key SHA1")); | ||||||
|  |  		return SSH_ERR_KEY_REVOKED; | ||||||
|  | @@ -1271,6 +1273,7 @@ is_key_revoked(struct ssh_krl *krl, cons
 | ||||||
|  |  		return r; | ||||||
|  |  	erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha256s, &rb); | ||||||
|  |  	free(rb.blob); | ||||||
|  | +	rb.blob = NULL; /* make coverity happy */
 | ||||||
|  |  	if (erb != NULL) { | ||||||
|  |  		KRL_DBG(("revoked by key SHA256")); | ||||||
|  |  		return SSH_ERR_KEY_REVOKED; | ||||||
|  | @@ -1282,6 +1285,7 @@ is_key_revoked(struct ssh_krl *krl, cons
 | ||||||
|  |  		return r; | ||||||
|  |  	erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); | ||||||
|  |  	free(rb.blob); | ||||||
|  | +	rb.blob = NULL; /* make coverity happy */
 | ||||||
|  |  	if (erb != NULL) { | ||||||
|  |  		KRL_DBG(("revoked by explicit key")); | ||||||
|  |  		return SSH_ERR_KEY_REVOKED; | ||||||
|  | diff -up openssh-8.5p1/loginrec.c.coverity openssh-8.5p1/loginrec.c
 | ||||||
|  | --- openssh-8.5p1/loginrec.c.coverity	2021-03-24 13:18:53.793225885 +0100
 | ||||||
|  | +++ openssh-8.5p1/loginrec.c	2021-03-24 13:21:27.948404751 +0100
 | ||||||
|  | @@ -690,9 +690,11 @@ construct_utmp(struct logininfo *li,
 | ||||||
|  	 */ |  	 */ | ||||||
| -		if (rfd != -1 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) {
 |   | ||||||
| +		if (rfd >= 0 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) {
 |  	/* Use strncpy because we don't necessarily want null termination */ | ||||||
|  			c->restore_block |= CHANNEL_RESTORE_RFD; | +	/* coverity[buffer_size_warning : FALSE] */
 | ||||||
|  			set_nonblock(rfd); |  	strncpy(ut->ut_name, li->username, | ||||||
|  |  	    MIN_SIZEOF(ut->ut_name, li->username)); | ||||||
|  |  # ifdef HAVE_HOST_IN_UTMP | ||||||
|  | +	/* coverity[buffer_size_warning : FALSE] */
 | ||||||
|  |  	strncpy(ut->ut_host, li->hostname, | ||||||
|  |  	    MIN_SIZEOF(ut->ut_host, li->hostname)); | ||||||
|  |  # endif | ||||||
|  | @@ -1690,6 +1692,7 @@ record_failed_login(struct ssh *ssh, con
 | ||||||
|  |   | ||||||
|  |  	memset(&ut, 0, sizeof(ut)); | ||||||
|  |  	/* strncpy because we don't necessarily want nul termination */ | ||||||
|  | +	/* coverity[buffer_size_warning : FALSE] */
 | ||||||
|  |  	strncpy(ut.ut_user, username, sizeof(ut.ut_user)); | ||||||
|  |  	strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line)); | ||||||
|  |   | ||||||
|  | @@ -1699,6 +1702,7 @@ record_failed_login(struct ssh *ssh, con
 | ||||||
|  |  	ut.ut_pid = getpid(); | ||||||
|  |   | ||||||
|  |  	/* strncpy because we don't necessarily want nul termination */ | ||||||
|  | +	/* coverity[buffer_size_warning : FALSE] */
 | ||||||
|  |  	strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); | ||||||
|  |   | ||||||
|  |  	if (ssh_packet_connection_is_on_socket(ssh) && | ||||||
|  | diff -up openssh-8.5p1/misc.c.coverity openssh-8.5p1/misc.c
 | ||||||
|  | --- openssh-8.5p1/misc.c.coverity	2021-03-24 12:03:33.745967902 +0100
 | ||||||
|  | +++ openssh-8.5p1/misc.c	2021-03-24 13:31:47.037079617 +0100
 | ||||||
|  | @@ -1425,6 +1425,8 @@ sanitise_stdfd(void)
 | ||||||
|  	} |  	} | ||||||
| -		if (wfd != -1 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) {
 |  	if (nullfd > STDERR_FILENO) | ||||||
| +		if (wfd >= 0 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) {
 |  		close(nullfd); | ||||||
|  			c->restore_block |= CHANNEL_RESTORE_WFD; | +	/* coverity[leaked_handle : FALSE]*/
 | ||||||
|  			set_nonblock(wfd); | +	/* coverity[leaked_handle : FALSE]*/
 | ||||||
|  } |  } | ||||||
| -		if (efd != -1 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) {
 |   | ||||||
| +		if (efd >= 0 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) {
 |  char * | ||||||
|  			c->restore_block |= CHANNEL_RESTORE_EFD; | @@ -2511,6 +2513,7 @@ stdfd_devnull(int do_stdin, int do_stdou
 | ||||||
|  			set_nonblock(efd); |  | ||||||
|  	} |  	} | ||||||
| diff -up openssh-8.0p1/monitor.c.coverity openssh-8.0p1/monitor.c
 |  	if (devnull > STDERR_FILENO) | ||||||
| --- openssh-8.0p1/monitor.c.coverity	2021-06-21 10:59:17.282473202 +0200
 |  		close(devnull); | ||||||
| +++ openssh-8.0p1/monitor.c	2021-06-21 10:59:17.297473319 +0200
 | +	/* coverity[leaked_handle : FALSE]*/
 | ||||||
| @@ -401,7 +401,7 @@ monitor_child_preauth(struct ssh *ssh, s
 |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | diff -up openssh-8.5p1/moduli.c.coverity openssh-8.5p1/moduli.c
 | ||||||
|  | --- openssh-8.5p1/moduli.c.coverity	2021-03-02 11:31:47.000000000 +0100
 | ||||||
|  | +++ openssh-8.5p1/moduli.c	2021-03-24 12:03:33.784968173 +0100
 | ||||||
|  | @@ -476,6 +476,7 @@ write_checkpoint(char *cpfile, u_int32_t
 | ||||||
|  |  	else | ||||||
|  |  		logit("failed to write to checkpoint file '%s': %s", cpfile, | ||||||
|  |  		    strerror(errno)); | ||||||
|  | +	/* coverity[leaked_storage : FALSE] */
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static unsigned long | ||||||
|  | diff -up openssh-7.4p1/monitor.c.coverity openssh-7.4p1/monitor.c
 | ||||||
|  | --- openssh-7.4p1/monitor.c.coverity	2016-12-23 16:40:26.888788688 +0100
 | ||||||
|  | +++ openssh-7.4p1/monitor.c	2016-12-23 16:40:26.900788691 +0100
 | ||||||
|  | @@ -411,7 +411,7 @@ monitor_child_preauth(Authctxt *_authctx
 | ||||||
|  	mm_get_keystate(ssh, pmonitor); |  	mm_get_keystate(ssh, pmonitor); | ||||||
|   |   | ||||||
|  	/* Drain any buffered messages from the child */ |  	/* Drain any buffered messages from the child */ | ||||||
| @ -32,13 +208,22 @@ diff -up openssh-8.0p1/monitor.c.coverity openssh-8.0p1/monitor.c | |||||||
|  		; |  		; | ||||||
|   |   | ||||||
|  	if (pmonitor->m_recvfd >= 0) |  	if (pmonitor->m_recvfd >= 0) | ||||||
|  | @@ -1678,7 +1678,7 @@ mm_answer_pty(struct ssh *ssh, int sock,
 | ||||||
|  |  	s->ptymaster = s->ptyfd; | ||||||
|  |   | ||||||
|  |  	debug3_f("tty %s ptyfd %d", s->tty, s->ttyfd); | ||||||
|  | -
 | ||||||
|  | +	/* coverity[leaked_handle : FALSE] */
 | ||||||
|  |  	return (0); | ||||||
|  |   | ||||||
|  |   error: | ||||||
| diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c
 | diff -up openssh-7.4p1/monitor_wrap.c.coverity openssh-7.4p1/monitor_wrap.c
 | ||||||
| --- openssh-7.4p1/monitor_wrap.c.coverity	2016-12-23 16:40:26.892788689 +0100
 | --- openssh-7.4p1/monitor_wrap.c.coverity	2016-12-23 16:40:26.892788689 +0100
 | ||||||
| +++ openssh-7.4p1/monitor_wrap.c	2016-12-23 16:40:26.900788691 +0100
 | +++ openssh-7.4p1/monitor_wrap.c	2016-12-23 16:40:26.900788691 +0100
 | ||||||
| @@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd,
 | @@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd,
 | ||||||
|  	if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || |  	if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || | ||||||
|  	    (tmp2 = dup(pmonitor->m_recvfd)) == -1) { |  	    (tmp2 = dup(pmonitor->m_recvfd)) == -1) { | ||||||
|  		error("%s: cannot allocate fds for pty", __func__); |  		error_f("cannot allocate fds for pty"); | ||||||
| -		if (tmp1 > 0)
 | -		if (tmp1 > 0)
 | ||||||
| +		if (tmp1 >= 0)
 | +		if (tmp1 >= 0)
 | ||||||
|  			close(tmp1); |  			close(tmp1); | ||||||
| @ -61,30 +246,67 @@ diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/open | |||||||
|  	int i; |  	int i; | ||||||
|   |   | ||||||
|  	if (sa == NULL) { |  	if (sa == NULL) { | ||||||
| diff -up openssh-7.4p1/scp.c.coverity openssh-7.4p1/scp.c
 | diff -up openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity openssh-8.7p1/openbsd-compat/bsd-pselect.c
 | ||||||
| --- openssh-7.4p1/scp.c.coverity	2016-12-23 16:40:26.856788681 +0100
 | --- openssh-8.7p1/openbsd-compat/bsd-pselect.c.coverity	2021-08-30 16:36:11.357288009 +0200
 | ||||||
| +++ openssh-7.4p1/scp.c	2016-12-23 16:40:26.901788691 +0100
 | +++ openssh-8.7p1/openbsd-compat/bsd-pselect.c	2021-08-30 16:37:21.791897976 +0200
 | ||||||
| @@ -157,7 +157,7 @@ killchild(int signo)
 | @@ -113,13 +113,13 @@ pselect_notify_setup(void)
 | ||||||
|  |  static void | ||||||
|  |  pselect_notify_parent(void) | ||||||
|  |  { | ||||||
|  | -	if (notify_pipe[1] != -1)
 | ||||||
|  | +	if (notify_pipe[1] >= 0)
 | ||||||
|  |  		(void)write(notify_pipe[1], "", 1); | ||||||
|  |  } | ||||||
|  |  static void | ||||||
|  |  pselect_notify_prepare(fd_set *readset) | ||||||
|  |  { | ||||||
|  | -	if (notify_pipe[0] != -1)
 | ||||||
|  | +	if (notify_pipe[0] >= 0)
 | ||||||
|  |  		FD_SET(notify_pipe[0], readset); | ||||||
|  |  } | ||||||
|  |  static void | ||||||
|  | @@ -127,8 +127,8 @@ pselect_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_f("reading"); | ||||||
|  |  		FD_CLR(notify_pipe[0], readset); | ||||||
|  |  	} | ||||||
|  | diff -up openssh-8.5p1/readconf.c.coverity openssh-8.5p1/readconf.c
 | ||||||
|  | --- openssh-8.5p1/readconf.c.coverity	2021-03-24 12:03:33.778968131 +0100
 | ||||||
|  | +++ openssh-8.5p1/readconf.c	2021-03-24 12:03:33.785968180 +0100
 | ||||||
|  | @@ -1847,6 +1847,7 @@ parse_pubkey_algos:
 | ||||||
|  |  			} else if (r != 0) { | ||||||
|  |  				error("%.200s line %d: glob failed for %s.", | ||||||
|  |  				    filename, linenum, arg2); | ||||||
|  | +				free(arg2);
 | ||||||
|  |  				goto out; | ||||||
|  |  			} | ||||||
|  |  			free(arg2); | ||||||
|  | diff -up openssh-8.7p1/scp.c.coverity openssh-8.7p1/scp.c
 | ||||||
|  | --- openssh-8.7p1/scp.c.coverity	2021-08-30 16:23:35.389741329 +0200
 | ||||||
|  | +++ openssh-8.7p1/scp.c	2021-08-30 16:27:04.854555296 +0200
 | ||||||
|  | @@ -186,11 +186,11 @@ killchild(int signo)
 | ||||||
|  { |  { | ||||||
|  	if (do_cmd_pid > 1) { |  	if (do_cmd_pid > 1) { | ||||||
|  		kill(do_cmd_pid, signo ? signo : SIGTERM); |  		kill(do_cmd_pid, signo ? signo : SIGTERM); | ||||||
| -		waitpid(do_cmd_pid, NULL, 0);
 | -		waitpid(do_cmd_pid, NULL, 0);
 | ||||||
| +		(void) waitpid(do_cmd_pid, NULL, 0);
 | +		(void) waitpid(do_cmd_pid, NULL, 0);
 | ||||||
|  	} |  	} | ||||||
|  |  	if (do_cmd_pid2 > 1) { | ||||||
|  |  		kill(do_cmd_pid2, signo ? signo : SIGTERM); | ||||||
|  | -		waitpid(do_cmd_pid2, NULL, 0);
 | ||||||
|  | +		(void) waitpid(do_cmd_pid2, NULL, 0);
 | ||||||
|  |  	} | ||||||
|   |   | ||||||
|  	if (signo) |  	if (signo) | ||||||
| diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c
 | diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c
 | ||||||
| --- openssh-7.4p1/servconf.c.coverity	2016-12-23 16:40:26.896788690 +0100
 | --- openssh-7.4p1/servconf.c.coverity	2016-12-23 16:40:26.896788690 +0100
 | ||||||
| +++ openssh-7.4p1/servconf.c	2016-12-23 16:40:26.901788691 +0100
 | +++ openssh-7.4p1/servconf.c	2016-12-23 16:40:26.901788691 +0100
 | ||||||
| @@ -1547,7 +1547,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++) |  | ||||||
| @@ -1638,8 +1638,9 @@ process_server_config_line(ServerOptions
 | @@ -1638,8 +1638,9 @@ process_server_config_line(ServerOptions
 | ||||||
|  		if (*activep && *charptr == NULL) { |  		if (*activep && *charptr == NULL) { | ||||||
|  			*charptr = tilde_expand_filename(arg, getuid()); |  			*charptr = tilde_expand_filename(arg, getuid()); | ||||||
| @ -97,38 +319,11 @@ diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c | |||||||
|  		} |  		} | ||||||
|  		break; |  		break; | ||||||
|   |   | ||||||
| diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c
 | diff -up openssh-8.7p1/serverloop.c.coverity openssh-8.7p1/serverloop.c
 | ||||||
| --- openssh-7.4p1/serverloop.c.coverity	2016-12-19 05:59:41.000000000 +0100
 | --- openssh-8.7p1/serverloop.c.coverity	2021-08-20 06:03:49.000000000 +0200
 | ||||||
| +++ openssh-7.4p1/serverloop.c	2016-12-23 16:40:26.902788691 +0100
 | +++ openssh-8.7p1/serverloop.c	2021-08-30 16:28:22.416226981 +0200
 | ||||||
| @@ -125,13 +125,13 @@ notify_setup(void)
 | @@ -547,7 +547,7 @@ server_request_tun(struct ssh *ssh)
 | ||||||
|  static void |  		debug_f("invalid tun"); | ||||||
|  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("%s: reading", __func__); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -518,7 +518,7 @@ server_request_tun(void)
 |  | ||||||
|  		debug("%s: invalid tun", __func__); |  | ||||||
|  		goto done; |  		goto done; | ||||||
|  	} |  	} | ||||||
| -	if (auth_opts->force_tun_device != -1) {
 | -	if (auth_opts->force_tun_device != -1) {
 | ||||||
| @ -136,9 +331,98 @@ diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c | |||||||
|  		if (tun != SSH_TUNID_ANY && |  		if (tun != SSH_TUNID_ANY && | ||||||
|  		    auth_opts->force_tun_device != (int)tun) |  		    auth_opts->force_tun_device != (int)tun) | ||||||
|  			goto done; |  			goto done; | ||||||
|  | diff -up openssh-8.5p1/session.c.coverity openssh-8.5p1/session.c
 | ||||||
|  | --- openssh-8.5p1/session.c.coverity	2021-03-24 12:03:33.777968124 +0100
 | ||||||
|  | +++ openssh-8.5p1/session.c	2021-03-24 12:03:33.786968187 +0100
 | ||||||
|  | @@ -1223,12 +1223,14 @@ do_setup_env(struct ssh *ssh, Session *s
 | ||||||
|  |  	/* Environment specified by admin */ | ||||||
|  |  	for (i = 0; i < options.num_setenv; i++) { | ||||||
|  |  		cp = xstrdup(options.setenv[i]); | ||||||
|  | +		/* coverity[overwrite_var : FALSE] */
 | ||||||
|  |  		if ((value = strchr(cp, '=')) == NULL) { | ||||||
|  |  			/* shouldn't happen; vars are checked in servconf.c */ | ||||||
|  |  			fatal("Invalid config SetEnv: %s", options.setenv[i]); | ||||||
|  |  		} | ||||||
|  |  		*value++ = '\0'; | ||||||
|  |  		child_set_env(&env, &envsize, cp, value); | ||||||
|  | +		free(cp);
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	/* SSH_CLIENT deprecated */ | ||||||
|  | --- a/sftp.c	2022-06-30 10:43:13.914058913 +0200
 | ||||||
|  | +++ b/sftp.c	2022-06-30 10:48:17.243997888 +0200
 | ||||||
|  | @@ -222,7 +222,7 @@ killchild(int signo)
 | ||||||
|  |  	pid = sshpid; | ||||||
|  |  	if (pid > 1) { | ||||||
|  |  		kill(pid, SIGTERM); | ||||||
|  | -		waitpid(pid, NULL, 0);
 | ||||||
|  | +		(void) waitpid(pid, NULL, 0);
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	_exit(1); | ||||||
|  | @@ -768,6 +768,8 @@ process_put(struct sftp_conn *conn, cons
 | ||||||
|  |  			    fflag || global_fflag, 0) == -1) | ||||||
|  |  				err = -1; | ||||||
|  |  		} | ||||||
|  | +		free(abs_dst);
 | ||||||
|  | +		abs_dst = NULL;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  out: | ||||||
|  | @@ -991,6 +993,7 @@ do_globbed_ls(struct sftp_conn *conn, co
 | ||||||
|  |  		if (lflag & LS_LONG_VIEW) { | ||||||
|  |  			if (g.gl_statv[i] == NULL) { | ||||||
|  |  				error("no stat information for %s", fname); | ||||||
|  | +				free(fname);
 | ||||||
|  |  				continue; | ||||||
|  |  			} | ||||||
|  |  			lname = ls_file(fname, g.gl_statv[i], 1, | ||||||
|  | diff --git a/sftp-client.c b/sftp-client.c
 | ||||||
|  | index 9de9afa20f..ea98d9f8d0 100644
 | ||||||
|  | --- a/sftp-client.c
 | ||||||
|  | +++ b/sftp-client.c
 | ||||||
|  | @@ -2195,6 +2195,7 @@ handle_dest_replies(struct sftp_conn *to, const char *to_path, int synchronous,
 | ||||||
|  |  		(*nreqsp)--; | ||||||
|  |  	} | ||||||
|  |  	debug3_f("done: %u outstanding replies", *nreqsp); | ||||||
|  | +	sshbuf_free(msg);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int | ||||||
|  | diff --git a/sftp-server.c b/sftp-server.c
 | ||||||
|  | index 18d1949112..6380c4dd23 100644
 | ||||||
|  | --- a/sftp-server.c
 | ||||||
|  | +++ b/sftp-server.c
 | ||||||
|  | @@ -1553,6 +1553,7 @@ process_extended_expand(u_int32_t id)
 | ||||||
|  |  			npath = xstrdup(path + 2); | ||||||
|  |  			free(path); | ||||||
|  |  			xasprintf(&path, "%s/%s", cwd, npath); | ||||||
|  | +			free(npath);
 | ||||||
|  |  		} else { | ||||||
|  |  			/* ~user expansions */ | ||||||
|  |  			if (tilde_expand(path, pw->pw_uid, &npath) != 0) { | ||||||
|  | diff -up openssh-8.5p1/sk-usbhid.c.coverity openssh-8.5p1/sk-usbhid.c
 | ||||||
|  | --- openssh-8.5p1/sk-usbhid.c.coverity	2021-03-02 11:31:47.000000000 +0100
 | ||||||
|  | +++ openssh-8.5p1/sk-usbhid.c	2021-03-24 12:03:33.786968187 +0100
 | ||||||
|  | @@ -1256,6 +1256,7 @@ sk_load_resident_keys(const char *pin, s
 | ||||||
|  |  		freezero(rks[i], sizeof(*rks[i])); | ||||||
|  |  	} | ||||||
|  |  	free(rks); | ||||||
|  | +	free(device);
 | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
| diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c
 | diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c
 | ||||||
| --- openssh-7.4p1/ssh-agent.c.coverity	2016-12-19 05:59:41.000000000 +0100
 | --- openssh-7.4p1/ssh-agent.c.coverity	2016-12-19 05:59:41.000000000 +0100
 | ||||||
| +++ openssh-7.4p1/ssh-agent.c	2016-12-23 16:40:26.903788691 +0100
 | +++ openssh-7.4p1/ssh-agent.c	2016-12-23 16:40:26.903788691 +0100
 | ||||||
|  | @@ -869,6 +869,7 @@ sanitize_pkcs11_provider(const char *pro
 | ||||||
|  |   | ||||||
|  |  		if (pkcs11_uri_parse(provider, uri) != 0) { | ||||||
|  |  			error("Failed to parse PKCS#11 URI"); | ||||||
|  | +			pkcs11_uri_cleanup(uri);
 | ||||||
|  |  			return NULL; | ||||||
|  |  		} | ||||||
|  |  		/* validate also provider from URI */ | ||||||
| @@ -1220,8 +1220,8 @@ main(int ac, char **av)
 | @@ -1220,8 +1220,8 @@ main(int ac, char **av)
 | ||||||
|  	sanitise_stdfd(); |  	sanitise_stdfd(); | ||||||
|   |   | ||||||
| @ -150,6 +434,17 @@ diff -up openssh-7.4p1/ssh-agent.c.coverity openssh-7.4p1/ssh-agent.c | |||||||
|   |   | ||||||
|  	platform_disable_tracing(0);	/* strict=no */ |  	platform_disable_tracing(0);	/* strict=no */ | ||||||
|   |   | ||||||
|  | diff -up openssh-8.5p1/ssh.c.coverity openssh-8.5p1/ssh.c
 | ||||||
|  | --- openssh-8.5p1/ssh.c.coverity	2021-03-24 12:03:33.779968138 +0100
 | ||||||
|  | +++ openssh-8.5p1/ssh.c	2021-03-24 12:03:33.786968187 +0100
 | ||||||
|  | @@ -1746,6 +1746,7 @@ control_persist_detach(void)
 | ||||||
|  |  		close(muxserver_sock); | ||||||
|  |  		muxserver_sock = -1; | ||||||
|  |  		options.control_master = SSHCTL_MASTER_NO; | ||||||
|  | +		/* coverity[leaked_handle: FALSE]*/
 | ||||||
|  |  		muxclient(options.control_path); | ||||||
|  |  		/* muxclient() doesn't return on success. */ | ||||||
|  |  		fatal("Failed to connect to new control master"); | ||||||
| diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
 | diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c
 | ||||||
| --- openssh-7.4p1/sshd.c.coverity	2016-12-23 16:40:26.897788690 +0100
 | --- openssh-7.4p1/sshd.c.coverity	2016-12-23 16:40:26.897788690 +0100
 | ||||||
| +++ openssh-7.4p1/sshd.c	2016-12-23 16:40:26.904788692 +0100
 | +++ openssh-7.4p1/sshd.c	2016-12-23 16:40:26.904788692 +0100
 | ||||||
| @ -175,3 +470,58 @@ diff -up openssh-7.4p1/sshd.c.coverity openssh-7.4p1/sshd.c | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  /* |  /* | ||||||
|  | @@ -2519,8 +2524,11 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||||
|  |   | ||||||
|  |  	if (newstr) | ||||||
|  |  		myproposal[PROPOSAL_KEX_ALGS] = newstr; | ||||||
|  | -	else
 | ||||||
|  | +	else {
 | ||||||
|  |  		fatal("No supported key exchange algorithms"); | ||||||
|  | +		free(gss);
 | ||||||
|  | +	     }
 | ||||||
|  | +	     /* coverity[leaked_storage: FALSE]*/
 | ||||||
|  |  	} | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | diff -up openssh-8.5p1/ssh-keygen.c.coverity openssh-8.5p1/ssh-keygen.c
 | ||||||
|  | --- openssh-8.5p1/ssh-keygen.c.coverity	2021-03-24 12:03:33.780968145 +0100
 | ||||||
|  | +++ openssh-8.5p1/ssh-keygen.c	2021-03-24 12:03:33.787968194 +0100
 | ||||||
|  | @@ -2332,6 +2332,9 @@ update_krl_from_file(struct passwd *pw,
 | ||||||
|  |  			r = ssh_krl_revoke_key_sha256(krl, blob, blen); | ||||||
|  |  			if (r != 0) | ||||||
|  |  				fatal_fr(r, "revoke key failed"); | ||||||
|  | +			freezero(blob, blen);
 | ||||||
|  | +			blob = NULL;
 | ||||||
|  | +			blen = 0;
 | ||||||
|  |  		} else { | ||||||
|  |  			if (strncasecmp(cp, "key:", 4) == 0) { | ||||||
|  |  				cp += 4; | ||||||
|  | @@ -2879,6 +2882,7 @@ do_moduli_screen(const char *out_file, c
 | ||||||
|  |  		} else if (strncmp(opts[i], "start-line=", 11) == 0) { | ||||||
|  |  			start_lineno = strtoul(opts[i]+11, NULL, 10); | ||||||
|  |  		} else if (strncmp(opts[i], "checkpoint=", 11) == 0) { | ||||||
|  | +			free(checkpoint);
 | ||||||
|  |  			checkpoint = xstrdup(opts[i]+11); | ||||||
|  |  		} else if (strncmp(opts[i], "generator=", 10) == 0) { | ||||||
|  |  			generator_wanted = (u_int32_t)strtonum( | ||||||
|  | @@ -2920,6 +2924,9 @@ do_moduli_screen(const char *out_file, c
 | ||||||
|  |  #else /* WITH_OPENSSL */ | ||||||
|  |  	fatal("Moduli screening is not supported"); | ||||||
|  |  #endif /* WITH_OPENSSL */ | ||||||
|  | +	free(checkpoint);
 | ||||||
|  | +	if (in != stdin)
 | ||||||
|  | +		fclose(in);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static char * | ||||||
|  | diff -up openssh-8.5p1/sshsig.c.coverity openssh-8.5p1/sshsig.c
 | ||||||
|  | --- openssh-8.5p1/sshsig.c.coverity	2021-03-02 11:31:47.000000000 +0100
 | ||||||
|  | +++ openssh-8.5p1/sshsig.c	2021-03-24 12:03:33.787968194 +0100
 | ||||||
|  | @@ -515,6 +515,7 @@ hash_file(int fd, const char *hashalg, s
 | ||||||
|  |  			oerrno = errno; | ||||||
|  |  			error_f("read: %s", strerror(errno)); | ||||||
|  |  			ssh_digest_free(ctx); | ||||||
|  | +			ctx = NULL;
 | ||||||
|  |  			errno = oerrno; | ||||||
|  |  			r = SSH_ERR_SYSTEM_ERROR; | ||||||
|  |  			goto out; | ||||||
|  | |||||||
| @ -1,618 +0,0 @@ | |||||||
| 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@
 |  | ||||||
|  MKDIR_P=@MKDIR_P@ |  | ||||||
|  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)
 |  | ||||||
|   |  | ||||||
|  XMSS_OBJS=\ |  | ||||||
|  	ssh-xmss.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 $(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,387 @@
 |  | ||||||
| +/*
 |  | ||||||
| + * 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 "sshbuf.h"
 |  | ||||||
| +#include "sshkey.h"
 |  | ||||||
| +#include "cipher.h"
 |  | ||||||
| +#include "kex.h"
 |  | ||||||
| +#include "packet.h"
 |  | ||||||
| +#include "digest.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;
 |  | ||||||
| +	struct sshbuf *Kb = NULL;
 |  | ||||||
| +	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;
 |  | ||||||
| +	}
 |  | ||||||
| +	Kb = sshbuf_new();
 |  | ||||||
| +	if (!Kb) {
 |  | ||||||
| +		printf("cannot convert K into sshbuf\n");
 |  | ||||||
| +		ret = 1;
 |  | ||||||
| +		goto out;
 |  | ||||||
| +	}
 |  | ||||||
| +	sshbuf_put_bignum2(Kb, Kbn);
 |  | ||||||
| +
 |  | ||||||
| +	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 = SSH_DIGEST_SHA1;
 |  | ||||||
| +			break;
 |  | ||||||
| +		case 32:
 |  | ||||||
| +			kex.hash_alg = SSH_DIGEST_SHA256;
 |  | ||||||
| +			break;
 |  | ||||||
| +		case 48:
 |  | ||||||
| +			kex.hash_alg = SSH_DIGEST_SHA384;
 |  | ||||||
| +			break;
 |  | ||||||
| +		case 64:
 |  | ||||||
| +			kex.hash_alg = SSH_DIGEST_SHA512;
 |  | ||||||
| +			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(ssh, test->H, test->Hlen, Kb);
 |  | ||||||
| +
 |  | ||||||
| +	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 (Kb)
 |  | ||||||
| +		sshbuf_free(Kb);
 |  | ||||||
| +	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;
 |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,15 +1,15 @@ | |||||||
| diff --color -ru a/sftp-server.8 b/sftp-server.8
 | diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8
 | ||||||
| --- a/sftp-server.8	2019-04-18 00:52:57.000000000 +0200
 | --- openssh-7.2p2/sftp-server.8.sftp-force-mode	2016-03-09 19:04:48.000000000 +0100
 | ||||||
| +++ b/sftp-server.8	2022-06-20 16:03:47.892540068 +0200
 | +++ openssh-7.2p2/sftp-server.8	2016-06-23 16:18:20.463854117 +0200
 | ||||||
| @@ -38,6 +38,7 @@
 | @@ -38,6 +38,7 @@
 | ||||||
|  .Op Fl P Ar blacklisted_requests |  .Op Fl P Ar denied_requests | ||||||
|  .Op Fl p Ar whitelisted_requests |  .Op Fl p Ar allowed_requests | ||||||
|  .Op Fl u Ar umask |  .Op Fl u Ar umask | ||||||
| +.Op Fl m Ar force_file_perms
 | +.Op Fl m Ar force_file_perms
 | ||||||
|  .Ek |  .Ek | ||||||
|  .Nm |  .Nm | ||||||
|  .Fl Q Ar protocol_feature |  .Fl Q Ar protocol_feature | ||||||
| @@ -138,6 +139,12 @@
 | @@ -138,6 +139,12 @@ Sets an explicit
 | ||||||
|  .Xr umask 2 |  .Xr umask 2 | ||||||
|  to be applied to newly-created files and directories, instead of the |  to be applied to newly-created files and directories, instead of the | ||||||
|  user's default mask. |  user's default mask. | ||||||
| @ -22,10 +22,10 @@ diff --color -ru a/sftp-server.8 b/sftp-server.8 | |||||||
|  .El |  .El | ||||||
|  .Pp |  .Pp | ||||||
|  On some systems, |  On some systems, | ||||||
| diff --color -ru a/sftp-server.c b/sftp-server.c
 | diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
 | ||||||
| --- a/sftp-server.c	2022-06-20 16:01:26.183793633 +0200
 | --- openssh-7.2p2/sftp-server.c.sftp-force-mode	2016-06-23 16:18:20.446854128 +0200
 | ||||||
| +++ b/sftp-server.c	2022-06-20 16:02:12.442690608 +0200
 | +++ openssh-7.2p2/sftp-server.c	2016-06-23 16:20:37.950766082 +0200
 | ||||||
| @@ -65,6 +65,10 @@
 | @@ -69,6 +69,10 @@ struct sshbuf *oqueue;
 | ||||||
|  /* Version of client */ |  /* Version of client */ | ||||||
|  static u_int version; |  static u_int version; | ||||||
|   |   | ||||||
| @ -36,7 +36,7 @@ diff --color -ru a/sftp-server.c b/sftp-server.c | |||||||
|  /* SSH2_FXP_INIT received */ |  /* SSH2_FXP_INIT received */ | ||||||
|  static int init_done; |  static int init_done; | ||||||
|   |   | ||||||
| @@ -683,6 +687,7 @@
 | @@ -683,6 +687,7 @@ process_open(u_int32_t id)
 | ||||||
|  	Attrib a; |  	Attrib a; | ||||||
|  	char *name; |  	char *name; | ||||||
|  	int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; |  	int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; | ||||||
| @ -44,7 +44,7 @@ diff --color -ru a/sftp-server.c b/sftp-server.c | |||||||
|   |   | ||||||
|  	if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || |  	if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || | ||||||
|  	    (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ |  	    (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ | ||||||
| @@ -692,6 +697,10 @@
 | @@ -692,6 +697,10 @@ process_open(u_int32_t id)
 | ||||||
|  	debug3("request %u: open flags %d", id, pflags); |  	debug3("request %u: open flags %d", id, pflags); | ||||||
|  	flags = flags_from_portable(pflags); |  	flags = flags_from_portable(pflags); | ||||||
|  	mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; |  	mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; | ||||||
| @ -55,7 +55,7 @@ diff --color -ru a/sftp-server.c b/sftp-server.c | |||||||
|  	logit("open \"%s\" flags %s mode 0%o", |  	logit("open \"%s\" flags %s mode 0%o", | ||||||
|  	    name, string_from_portable(pflags), mode); |  	    name, string_from_portable(pflags), mode); | ||||||
|  	if (readonly && |  	if (readonly && | ||||||
| @@ -713,6 +722,8 @@
 | @@ -713,6 +722,8 @@ process_open(u_int32_t id)
 | ||||||
|  			} |  			} | ||||||
|  		} |  		} | ||||||
|  	} |  	} | ||||||
| @ -64,16 +64,16 @@ diff --color -ru a/sftp-server.c b/sftp-server.c | |||||||
|  	if (status != SSH2_FX_OK) |  	if (status != SSH2_FX_OK) | ||||||
|  		send_status(id, status); |  		send_status(id, status); | ||||||
|  	free(name); |  	free(name); | ||||||
| @@ -1555,7 +1566,7 @@
 | @@ -1494,7 +1505,7 @@ sftp_server_usage(void)
 | ||||||
|  	fprintf(stderr, |  	fprintf(stderr, | ||||||
|  	    "usage: %s [-ehR] [-d start_directory] [-f log_facility] " |  	    "usage: %s [-ehR] [-d start_directory] [-f log_facility] " | ||||||
|  	    "[-l log_level]\n\t[-P blacklisted_requests] " |  	    "[-l log_level]\n\t[-P denied_requests] " | ||||||
| -	    "[-p whitelisted_requests] [-u umask]\n"
 | -	    "[-p allowed_requests] [-u umask]\n"
 | ||||||
| +	    "[-p whitelisted_requests] [-u umask] [-m force_file_perms]\n"
 | +	    "[-p allowed_requests] [-u umask] [-m force_file_perms]\n"
 | ||||||
|  	    "       %s -Q protocol_feature\n", |  	    "       %s -Q protocol_feature\n", | ||||||
|  	    __progname, __progname); |  	    __progname, __progname); | ||||||
|  	exit(1); |  	exit(1); | ||||||
| @@ -1581,7 +1592,7 @@
 | @@ -1520,7 +1531,7 @@ sftp_server_main(int argc, char **argv,
 | ||||||
|  	pw = pwcopy(user_pw); |  	pw = pwcopy(user_pw); | ||||||
|   |   | ||||||
|  	while (!skipargs && (ch = getopt(argc, argv, |  	while (!skipargs && (ch = getopt(argc, argv, | ||||||
| @ -82,7 +82,7 @@ diff --color -ru a/sftp-server.c b/sftp-server.c | |||||||
|  		switch (ch) { |  		switch (ch) { | ||||||
|  		case 'Q': |  		case 'Q': | ||||||
|  			if (strcasecmp(optarg, "requests") != 0) { |  			if (strcasecmp(optarg, "requests") != 0) { | ||||||
| @@ -1643,6 +1654,15 @@
 | @@ -1580,6 +1591,15 @@ sftp_server_main(int argc, char **argv,
 | ||||||
|  				fatal("Invalid umask \"%s\"", optarg); |  				fatal("Invalid umask \"%s\"", optarg); | ||||||
|  			(void)umask((mode_t)mask); |  			(void)umask((mode_t)mask); | ||||||
|  			break; |  			break; | ||||||
|  | |||||||
| @ -3,8 +3,8 @@ diff -up openssh/servconf.c.sshdt openssh/servconf.c | |||||||
| +++ openssh/servconf.c	2015-06-24 11:44:39.734745802 +0200
 | +++ openssh/servconf.c	2015-06-24 11:44:39.734745802 +0200
 | ||||||
| @@ -2317,7 +2317,7 @@ dump_config(ServerOptions *o)
 | @@ -2317,7 +2317,7 @@ dump_config(ServerOptions *o)
 | ||||||
|  	dump_cfg_string(sXAuthLocation, o->xauth_location); |  	dump_cfg_string(sXAuthLocation, o->xauth_location); | ||||||
|  	dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); |  	dump_cfg_string(sCiphers, o->ciphers); | ||||||
|  	dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); |  	dump_cfg_string(sMacs, o->macs); | ||||||
| -	dump_cfg_string(sBanner, o->banner);
 | -	dump_cfg_string(sBanner, o->banner);
 | ||||||
| +	dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none");
 | +	dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none");
 | ||||||
|  	dump_cfg_string(sForceCommand, o->adm_forced_command); |  	dump_cfg_string(sForceCommand, o->adm_forced_command); | ||||||
|  | |||||||
| @ -1,12 +0,0 @@ | |||||||
| diff -up openssh-7.0p1/sshd_config.root-login openssh-7.0p1/sshd_config
 |  | ||||||
| --- openssh-7.0p1/sshd_config.root-login	2015-08-12 11:29:12.919269245 +0200
 |  | ||||||
| +++ openssh-7.0p1/sshd_config	2015-08-12 11:31:03.653096466 +0200
 |  | ||||||
| @@ -46,7 +46,7 @@ SyslogFacility AUTHPRIV
 |  | ||||||
|  # Authentication: |  | ||||||
|   |  | ||||||
|  #LoginGraceTime 2m |  | ||||||
| -#PermitRootLogin prohibit-password
 |  | ||||||
| +PermitRootLogin yes
 |  | ||||||
|  #StrictModes yes |  | ||||||
|  #MaxAuthTries 6 |  | ||||||
|  #MaxSessions 10 |  | ||||||
| @ -13,33 +13,33 @@ diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c | |||||||
| +	struct sshbuf *m;
 | +	struct sshbuf *m;
 | ||||||
| +	int r, ret = 0;
 | +	int r, ret = 0;
 | ||||||
| +
 | +
 | ||||||
| +	debug3("%s: entering", __func__);
 | +	debug3_f("entering");
 | ||||||
| +	if ((m = sshbuf_new()) == NULL)
 | +	if ((m = sshbuf_new()) == NULL)
 | ||||||
| + 		fatal("%s: sshbuf_new failed", __func__);
 | + 		fatal_f("sshbuf_new failed");
 | ||||||
| +	do {
 | +	do {
 | ||||||
| +		blen = atomicio(read, fdin, buf, sizeof(buf));
 | +		blen = atomicio(read, fdin, buf, sizeof(buf));
 | ||||||
| +		if (blen == 0) /* closed pipe */
 | +		if (blen == 0) /* closed pipe */
 | ||||||
| +			break;
 | +			break;
 | ||||||
| +		if (blen != sizeof(buf)) {
 | +		if (blen != sizeof(buf)) {
 | ||||||
| +			error("%s: Failed to read the buffer from child", __func__);
 | +			error_f("Failed to read the buffer from child");
 | ||||||
| +			ret = -1;
 | +			ret = -1;
 | ||||||
| +			break;
 | +			break;
 | ||||||
| +		}
 | +		}
 | ||||||
| +
 | +
 | ||||||
| +		msg_len = get_u32(buf);
 | +		msg_len = get_u32(buf);
 | ||||||
| +		if (msg_len > 256 * 1024)
 | +		if (msg_len > 256 * 1024)
 | ||||||
| +			fatal("%s: read: bad msg_len %d", __func__, msg_len);
 | +			fatal_f("read: bad msg_len %d", msg_len);
 | ||||||
| +		sshbuf_reset(m);
 | +		sshbuf_reset(m);
 | ||||||
| +		if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0)
 | +		if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0)
 | ||||||
| +			fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | +			fatal_fr(r, "buffer error");
 | ||||||
| +		if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
 | +		if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
 | ||||||
| +			error("%s: Failed to read the the buffer content from the child", __func__);
 | +			error_f("Failed to read the the buffer content from the child");
 | ||||||
| +			ret = -1;
 | +			ret = -1;
 | ||||||
| +			break;
 | +			break;
 | ||||||
| +		}
 | +		}
 | ||||||
| +		if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen || 
 | +		if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen || 
 | ||||||
| +		    atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
 | +		    atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
 | ||||||
| +			error("%s: Failed to write the message to the monitor", __func__);
 | +			error_f("Failed to write the message to the monitor");
 | ||||||
| +			ret = -1;
 | +			ret = -1;
 | ||||||
| +			break;
 | +			break;
 | ||||||
| +		}
 | +		}
 | ||||||
| @ -137,7 +137,7 @@ diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c | |||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -1538,6 +1565,34 @@ child_close_fds(void)
 | @@ -1538,6 +1565,34 @@ child_close_fds(void)
 | ||||||
|  	endpwent(); |  	log_redirect_stderr_to(NULL); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| +void
 | +void
 | ||||||
|  | |||||||
| @ -28,14 +28,15 @@ diff --git a/auth.h b/auth.h | |||||||
| index f9d191c..c432d2f 100644
 | index f9d191c..c432d2f 100644
 | ||||||
| --- a/auth.h
 | --- a/auth.h
 | ||||||
| +++ b/auth.h
 | +++ b/auth.h
 | ||||||
| @@ -222,5 +222,7 @@ int	 sys_auth_passwd(Authctxt *, const char *);
 | @@ -222,6 +222,8 @@ int	 sys_auth_passwd(Authctxt *, const char *);
 | ||||||
|  |   | ||||||
|  #if defined(KRB5) && !defined(HEIMDAL) |  #if defined(KRB5) && !defined(HEIMDAL) | ||||||
|  #include <krb5.h> |  | ||||||
|  krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); |  krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); | ||||||
| +krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx,
 | +krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx,
 | ||||||
| +	char **k5login_directory);
 | +	char **k5login_directory);
 | ||||||
|  #endif |  #endif | ||||||
|  #endif |   | ||||||
|  |  #endif /* AUTH_H */ | ||||||
| diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
 | diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
 | ||||||
| index a7c0c5f..df8cc9a 100644
 | index a7c0c5f..df8cc9a 100644
 | ||||||
| --- a/gss-serv-krb5.c
 | --- a/gss-serv-krb5.c
 | ||||||
| @ -48,7 +49,7 @@ index a7c0c5f..df8cc9a 100644 | |||||||
| +	int ret = 0;
 | +	int ret = 0;
 | ||||||
| +
 | +
 | ||||||
| +	ret = ssh_krb5_get_k5login_directory(krb_context, &k5login_directory);
 | +	ret = ssh_krb5_get_k5login_directory(krb_context, &k5login_directory);
 | ||||||
| +	debug3("%s: k5login_directory = %s (rv=%d)", __func__, k5login_directory, ret);
 | +	debug3_f("k5login_directory = %s (rv=%d)", k5login_directory, ret);
 | ||||||
| +	if (k5login_directory == NULL || ret != 0) {
 | +	if (k5login_directory == NULL || ret != 0) {
 | ||||||
| +		/* If not set, the library will look for  k5login
 | +		/* If not set, the library will look for  k5login
 | ||||||
| +		 * files in the user's home directory, with the filename  .k5login.
 | +		 * files in the user's home directory, with the filename  .k5login.
 | ||||||
| @ -63,7 +64,7 @@ index a7c0c5f..df8cc9a 100644 | |||||||
| +			k5login_directory[strlen(k5login_directory)-1] != '/' ? "/" : "",
 | +			k5login_directory[strlen(k5login_directory)-1] != '/' ? "/" : "",
 | ||||||
| +			pw->pw_name);
 | +			pw->pw_name);
 | ||||||
| +	}
 | +	}
 | ||||||
| +	debug("%s: Checking existence of file %s", __func__, file);
 | +	debug_f("Checking existence of file %s", file);
 | ||||||
|   |   | ||||||
| -	snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
 | -	snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
 | ||||||
|  	return access(file, F_OK) == 0; |  	return access(file, F_OK) == 0; | ||||||
|  | |||||||
| @ -48,5 +48,5 @@ Author: Harald Freudenberger <freude@de.ibm.com> | |||||||
| +#endif
 | +#endif
 | ||||||
|  	} |  	} | ||||||
|  	(void) closedir(dirp); |  	(void) closedir(dirp); | ||||||
|      } else |  	return; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c | |||||||
| +	if (len <= 0)
 | +	if (len <= 0)
 | ||||||
| +		return -1;
 | +		return -1;
 | ||||||
|  	sock = socket(AF_UNIX, SOCK_STREAM, 0); |  	sock = socket(AF_UNIX, SOCK_STREAM, 0); | ||||||
|  	if (sock < 0) |  	if (sock == -1) | ||||||
|  		error("socket: %.100s", strerror(errno)); |  		error("socket: %.100s", strerror(errno)); | ||||||
|  	memset(&addr, 0, sizeof(addr)); |  	memset(&addr, 0, sizeof(addr)); | ||||||
|  	addr.sun_family = AF_UNIX; |  	addr.sun_family = AF_UNIX; | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c | |||||||
|  		ssh_gai_strerror(gaierr)); |  		ssh_gai_strerror(gaierr)); | ||||||
| @@ -4457,7 +4463,7 @@ x11_connect_display(void)
 | @@ -4457,7 +4463,7 @@ x11_connect_display(void)
 | ||||||
|  		/* Connect it to the display. */ |  		/* Connect it to the display. */ | ||||||
|  		if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { |  		if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { | ||||||
|  			debug2("connect %.100s port %u: %.100s", buf, |  			debug2("connect %.100s port %u: %.100s", buf, | ||||||
| -			    6000 + display_number, strerror(errno));
 | -			    6000 + display_number, strerror(errno));
 | ||||||
| +			    X11_PORT_MIN + display_number, strerror(errno));
 | +			    X11_PORT_MIN + display_number, strerror(errno));
 | ||||||
| @ -197,7 +197,7 @@ diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5 | |||||||
| +.Cm X11MaxDisplays ,
 | +.Cm X11MaxDisplays ,
 | ||||||
|  .Cm X11Forwarding |  .Cm X11Forwarding | ||||||
|  and |  and | ||||||
|  .Cm X11UseLocalHost . |  .Cm X11UseLocalhost . | ||||||
| @@ -1566,6 +1567,12 @@ Specifies the first display number avail
 | @@ -1566,6 +1567,12 @@ Specifies the first display number avail
 | ||||||
|  X11 forwarding. |  X11 forwarding. | ||||||
|  This prevents sshd from interfering with real X11 servers. |  This prevents sshd from interfering with real X11 servers. | ||||||
|  | |||||||
| @ -69,29 +69,6 @@ index 6e7de31..e86aa2c 100644 | |||||||
|  	SC_ALLOW(__NR_getrandom), |  	SC_ALLOW(__NR_getrandom), | ||||||
|  #endif |  #endif | ||||||
| -- 1.9.1
 | -- 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(__NR_ioctl, 1, Z90STAT_STATUS_MASK), |  | ||||||
|  	SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO), |  | ||||||
|  	SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), |  | ||||||
| +	/* Allow ioctls for EP11 crypto card on s390 */
 |  | ||||||
| +	SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB),
 |  | ||||||
|  #endif |  | ||||||
|  #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) |  | ||||||
|  	/* |  | ||||||
| -- 
 |  | ||||||
| 1.9.1 | 1.9.1 | ||||||
| diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-seccomp-filter.c
 | diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-seccomp-filter.c
 | ||||||
| --- openssh-7.6p1/sandbox-seccomp-filter.c.sandbox	2017-12-12 13:59:30.563874059 +0100
 | --- openssh-7.6p1/sandbox-seccomp-filter.c.sandbox	2017-12-12 13:59:30.563874059 +0100
 | ||||||
| @ -107,40 +84,3 @@ diff -up openssh-7.6p1/sandbox-seccomp-filter.c.sandbox openssh-7.6p1/sandbox-se | |||||||
|  	SC_ALLOW(__NR_getrandom), |  	SC_ALLOW(__NR_getrandom), | ||||||
|  #endif |  #endif | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| From ef34ea4521b042dd8a9c4c7455f5d1a8f8ee5bb2 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Harald Freudenberger <freude@linux.ibm.com> |  | ||||||
| Date: Fri, 24 May 2019 10:11:15 +0200 |  | ||||||
| Subject: [PATCH] allow s390 specific ioctl for ecc hardware support |  | ||||||
| 
 |  | ||||||
| Adding another s390 specific ioctl to be able to support ECC hardware acceleration |  | ||||||
| to the sandbox seccomp filter rules. |  | ||||||
| 
 |  | ||||||
| Now the ibmca openssl engine provides elliptic curve cryptography support with the |  | ||||||
| help of libica and CCA crypto cards. This is done via jet another ioctl call to the zcrypt |  | ||||||
| device driver and so there is a need to enable this on the openssl sandbox. |  | ||||||
| 
 |  | ||||||
| Code is s390 specific and has been tested, verified and reviewed. |  | ||||||
| 
 |  | ||||||
| Please note that I am also the originator of the previous changes in that area. |  | ||||||
| I posted these changes to Eduardo and he forwarded the patches to the openssl |  | ||||||
| community. |  | ||||||
| 
 |  | ||||||
| Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> |  | ||||||
| Reviewed-by: Joerg Schmidbauer <jschmidb@de.ibm.com> |  | ||||||
| ---
 |  | ||||||
|  sandbox-seccomp-filter.c | 1 + |  | ||||||
|  1 file changed, 1 insertion(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
 |  | ||||||
| index 5edbc6946..56eb9317f 100644
 |  | ||||||
| --- a/sandbox-seccomp-filter.c
 |  | ||||||
| +++ b/sandbox-seccomp-filter.c
 |  | ||||||
| @@ -252,6 +252,7 @@ static const struct sock_filter preauth_insns[] = {
 |  | ||||||
|  	SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), |  | ||||||
|  	/* Allow ioctls for EP11 crypto card on s390 */ |  | ||||||
|  	SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB), |  | ||||||
| +	SC_ALLOW_ARG(__NR_ioctl, 1, ZSECSENDCPRB),
 |  | ||||||
|  #endif |  | ||||||
|  #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) |  | ||||||
|  	/* |  | ||||||
|  | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -2,9 +2,9 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c | |||||||
| --- openssh/auth2-pubkey.c.refactor	2019-04-04 13:19:12.188821236 +0200
 | --- openssh/auth2-pubkey.c.refactor	2019-04-04 13:19:12.188821236 +0200
 | ||||||
| +++ openssh/auth2-pubkey.c	2019-04-04 13:19:12.276822078 +0200
 | +++ openssh/auth2-pubkey.c	2019-04-04 13:19:12.276822078 +0200
 | ||||||
| @@ -72,6 +72,9 @@
 | @@ -72,6 +72,9 @@
 | ||||||
|  |   | ||||||
|  |  /* import */ | ||||||
|  extern ServerOptions options; |  extern ServerOptions options; | ||||||
|  extern u_char *session_id2; |  | ||||||
|  extern u_int session_id2_len; |  | ||||||
| +extern int inetd_flag;
 | +extern int inetd_flag;
 | ||||||
| +extern int rexeced_flag;
 | +extern int rexeced_flag;
 | ||||||
| +extern Authctxt *the_authctxt;
 | +extern Authctxt *the_authctxt;
 | ||||||
| @ -12,59 +12,59 @@ diff -up openssh/auth2-pubkey.c.refactor openssh/auth2-pubkey.c | |||||||
|  static char * |  static char * | ||||||
|  format_key(const struct sshkey *key) |  format_key(const struct sshkey *key) | ||||||
| @@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
 | @@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
 | ||||||
|   |  	if ((pid = subprocess("AuthorizedPrincipalsCommand", command, | ||||||
|  	if ((pid = subprocess("AuthorizedPrincipalsCommand", runas_pw, command, |  | ||||||
|  	    ac, av, &f, |  	    ac, av, &f, | ||||||
| -	    SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
 |  	    SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, | ||||||
| +	    SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
 | -	    runas_pw, temporarily_use_uid, restore_uid)) == 0)
 | ||||||
|  | +	    runas_pw, temporarily_use_uid, restore_uid,
 | ||||||
| +	    (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
 | +	    (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
 | ||||||
|  		goto out; |  		goto out; | ||||||
|   |   | ||||||
|  	uid_swapped = 1; |  	uid_swapped = 1; | ||||||
| @@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss
 | @@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss
 | ||||||
|   |  	if ((pid = subprocess("AuthorizedKeysCommand", command, | ||||||
|  	if ((pid = subprocess("AuthorizedKeysCommand", runas_pw, command, |  | ||||||
|  	    ac, av, &f, |  	    ac, av, &f, | ||||||
| -	    SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
 | 	    SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD, | ||||||
| +	    SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
 | -	    runas_pw, temporarily_use_uid, restore_uid)) == 0)
 | ||||||
|  | +	    runas_pw, temporarily_use_uid, restore_uid,
 | ||||||
| +	    (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
 | +	    (inetd_flag && !rexeced_flag), the_authctxt)) == 0)
 | ||||||
|  		goto out; |  		goto out; | ||||||
|   |   | ||||||
|  	uid_swapped = 1; |  	uid_swapped = 1; | ||||||
| diff -up openssh/auth.c.refactor openssh/auth.c
 | diff -up openssh/misc.c.refactor openssh/misc.c
 | ||||||
| --- openssh/auth.c.refactor	2019-04-04 13:19:12.235821686 +0200
 | --- openssh/misc.c.refactor	2019-04-04 13:19:12.235821686 +0200
 | ||||||
| +++ openssh/auth.c	2019-04-04 13:19:12.276822078 +0200
 | +++ openssh/misc.c	2019-04-04 13:19:12.276822078 +0200
 | ||||||
| @@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh *
 | @@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh *
 | ||||||
|   */ |  | ||||||
|  pid_t |  pid_t | ||||||
|  subprocess(const char *tag, struct passwd *pw, const char *command, |  subprocess(const char *tag, const char *command, | ||||||
| -    int ac, char **av, FILE **child, u_int flags)
 |      int ac, char **av, FILE **child, u_int flags, | ||||||
| +    int ac, char **av, FILE **child, u_int flags, int inetd,
 | -    struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs)
 | ||||||
| +    void *the_authctxt)
 | +    struct passwd *pw, privdrop_fn *drop_privs,
 | ||||||
|  | +    privrestore_fn *restore_privs, int inetd, void *the_authctxt)
 | ||||||
|  { |  { | ||||||
|  	FILE *f = NULL; |  	FILE *f = NULL; | ||||||
|  	struct stat st; |  	struct stat st; | ||||||
| @@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw
 | @@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw
 | ||||||
|  |  			_exit(1); | ||||||
|  		} |  		} | ||||||
|   |  | ||||||
|  #ifdef WITH_SELINUX |  #ifdef WITH_SELINUX | ||||||
| -		if (sshd_selinux_setup_env_variables() < 0) {
 | -		if (sshd_selinux_setup_env_variables() < 0) {
 | ||||||
| +		if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) {
 | +		if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) {
 | ||||||
|  			error ("failed to copy environment:  %s", |  			error ("failed to copy environment:  %s", | ||||||
|  			    strerror(errno)); |  			    strerror(errno)); | ||||||
|  			_exit(127); |  			_exit(127); | ||||||
| diff -up openssh/auth.h.refactor openssh/auth.h
 | diff -up openssh/misc.h.refactor openssh/misc.h
 | ||||||
| --- openssh/auth.h.refactor	2019-04-04 13:19:12.251821839 +0200
 | --- openssh/misc.h.refactor	2019-04-04 13:19:12.251821839 +0200
 | ||||||
| +++ openssh/auth.h	2019-04-04 13:19:12.276822078 +0200
 | +++ openssh/misc.h	2019-04-04 13:19:12.276822078 +0200
 | ||||||
| @@ -235,7 +235,7 @@ struct passwd *fakepw(void);
 | @@ -235,7 +235,7 @@ struct passwd *fakepw(void);
 | ||||||
|  #define	SSH_SUBPROCESS_STDOUT_CAPTURE  (1<<1)  /* Redirect stdout */ |  #define	SSH_SUBPROCESS_UNSAFE_PATH	(1<<3)	/* Don't check for safe cmd */ | ||||||
|  #define	SSH_SUBPROCESS_STDERR_DISCARD  (1<<2)  /* Discard stderr */ |  #define	SSH_SUBPROCESS_PRESERVE_ENV	(1<<4)	/* Keep parent environment */ | ||||||
|  pid_t	subprocess(const char *, struct passwd *, |  pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int, | ||||||
| -    const char *, int, char **, FILE **, u_int flags);
 | -    struct passwd *, privdrop_fn *, privrestore_fn *);
 | ||||||
| +    const char *, int, char **, FILE **, u_int flags, int, void *);
 | +    struct passwd *, privdrop_fn *, privrestore_fn *, int, void *);
 | ||||||
|   |  | ||||||
|  int	 sys_auth_passwd(struct ssh *, const char *); |  | ||||||
|   |   | ||||||
|  |  typedef struct arglist arglist; | ||||||
|  |  struct arglist { | ||||||
| diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h
 | diff -up openssh/openbsd-compat/port-linux.h.refactor openssh/openbsd-compat/port-linux.h
 | ||||||
| --- openssh/openbsd-compat/port-linux.h.refactor	2019-04-04 13:19:12.256821887 +0200
 | --- openssh/openbsd-compat/port-linux.h.refactor	2019-04-04 13:19:12.256821887 +0200
 | ||||||
| +++ openssh/openbsd-compat/port-linux.h	2019-04-04 13:19:12.276822078 +0200
 | +++ openssh/openbsd-compat/port-linux.h	2019-04-04 13:19:12.276822078 +0200
 | ||||||
| @ -145,7 +145,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | |||||||
|  	char *role; |  	char *role; | ||||||
| @@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
 | @@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
 | ||||||
|   |   | ||||||
|  	debug3("%s: setting execution context", __func__); |  	debug3_f("setting execution context"); | ||||||
|   |   | ||||||
| -	ssh_selinux_get_role_level(&role, &reqlvl);
 | -	ssh_selinux_get_role_level(&role, &reqlvl);
 | ||||||
| +	ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
 | +	ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
 | ||||||
| @ -203,10 +203,10 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compa | |||||||
| +		if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) {
 | +		if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) {
 | ||||||
|  			switch (security_getenforce()) { |  			switch (security_getenforce()) { | ||||||
|  			case -1: |  			case -1: | ||||||
|  				fatal("%s: security_getenforce() failed", __func__); |  				fatal_f("security_getenforce() failed"); | ||||||
| @@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw
 | @@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw
 | ||||||
|   |   | ||||||
|  	debug3("%s: setting execution context", __func__); |  	debug3_f("setting execution context"); | ||||||
|   |   | ||||||
| -	r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
 | -	r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
 | ||||||
| +	r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt);
 | +	r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt);
 | ||||||
| @ -269,3 +269,15 @@ diff -up openssh/sshd.c.refactor openssh/sshd.c | |||||||
|  #endif |  #endif | ||||||
|  #ifdef USE_PAM |  #ifdef USE_PAM | ||||||
|  	if (options.use_pam) { |  	if (options.use_pam) { | ||||||
|  | diff -up openssh/sshconnect.c.refactor openssh/sshconnect.c
 | ||||||
|  | --- openssh/sshconnect.c.refactor	2021-02-24 00:12:03.065325046 +0100
 | ||||||
|  | +++ openssh/sshconnect.c	2021-02-24 00:12:12.126449544 +0100
 | ||||||
|  | @@ -892,7 +892,7 @@ load_hostkeys_command(struct hostkeys *h
 | ||||||
|  |   | ||||||
|  |  	if ((pid = subprocess(tag, command, ac, av, &f, | ||||||
|  |  	    SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_UNSAFE_PATH| | ||||||
|  | -	    SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL)) == 0)
 | ||||||
|  | +	    SSH_SUBPROCESS_PRESERVE_ENV, NULL, NULL, NULL, 0, NULL)) == 0)
 | ||||||
|  |  		goto out; | ||||||
|  |   | ||||||
|  |  	load_hostkeys_file(hostkeys, hostfile_hostname, tag, f, 1); | ||||||
|  | |||||||
| @ -1,33 +1,15 @@ | |||||||
| diff -up openssh-7.9p1/cipher-ctr.c.fips openssh-7.9p1/cipher-ctr.c
 | diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
 | ||||||
| --- openssh-7.9p1/cipher-ctr.c.fips	2019-03-11 17:06:37.519877082 +0100
 | --- openssh-8.6p1/dh.c.fips	2021-04-16 05:55:25.000000000 +0200
 | ||||||
| +++ openssh-7.9p1/cipher-ctr.c	2019-03-11 17:06:37.620878031 +0100
 | +++ openssh-8.6p1/dh.c	2021-05-06 12:12:10.107634472 +0200
 | ||||||
| @@ -179,7 +179,8 @@ evp_aes_128_ctr(void)
 | @@ -36,6 +36,7 @@
 | ||||||
|  	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.9p1/clientloop.c.fips openssh-7.9p1/clientloop.c
 |  | ||||||
| --- openssh-7.9p1/clientloop.c.fips	2019-03-11 17:06:37.523877120 +0100
 |  | ||||||
| +++ openssh-7.9p1/clientloop.c	2019-03-11 17:06:37.620878031 +0100
 |  | ||||||
| @@ -2014,7 +2014,8 @@ key_accepted_by_hostkeyalgs(const struct
 |  | ||||||
|  { |  | ||||||
|  	const char *ktype = sshkey_ssh_name(key); |  | ||||||
|  	const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? |  | ||||||
| -	    options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG;
 |  | ||||||
| +	    options.hostkeyalgorithms : (FIPS_mode() ?
 |  | ||||||
| +	    KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG);
 |  | ||||||
|   |   | ||||||
|  	if (key == NULL || key->type == KEY_UNSPEC) |  #include <openssl/bn.h> | ||||||
|  		return 0; |  #include <openssl/dh.h> | ||||||
| diff -up openssh-7.9p1/dh.c.fips openssh-7.9p1/dh.c
 | +#include <openssl/fips.h>
 | ||||||
| --- openssh-7.9p1/dh.c.fips	2018-10-17 02:01:20.000000000 +0200
 |   | ||||||
| +++ openssh-7.9p1/dh.c	2019-03-11 17:08:11.769763057 +0100
 |  #include "dh.h" | ||||||
| @@ -152,6 +152,12 @@ choose_dh(int min, int wantbits, int max
 |  #include "pathnames.h" | ||||||
|  | @@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max
 | ||||||
|  	int best, bestcount, which, linenum; |  	int best, bestcount, which, linenum; | ||||||
|  	struct dhgroup dhg; |  	struct dhgroup dhg; | ||||||
|   |   | ||||||
| @ -37,10 +19,10 @@ diff -up openssh-7.9p1/dh.c.fips openssh-7.9p1/dh.c | |||||||
| +		return (dh_new_group_fallback(max));
 | +		return (dh_new_group_fallback(max));
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
|  	if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL) { |  	if ((f = fopen(get_moduli_filename(), "r")) == NULL) { | ||||||
|  		logit("WARNING: could not open %s (%s), using fixed modulus", |  		logit("WARNING: could not open %s (%s), using fixed modulus", | ||||||
|  		    _PATH_DH_MODULI, strerror(errno)); |  		    get_moduli_filename(), strerror(errno)); | ||||||
| @@ -489,4 +495,38 @@ dh_estimate(int bits)
 | @@ -502,4 +508,38 @@ dh_estimate(int bits)
 | ||||||
|  	return 8192; |  	return 8192; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @ -79,21 +61,29 @@ diff -up openssh-7.9p1/dh.c.fips openssh-7.9p1/dh.c | |||||||
| +}
 | +}
 | ||||||
| +
 | +
 | ||||||
|  #endif /* WITH_OPENSSL */ |  #endif /* WITH_OPENSSL */ | ||||||
| diff -up openssh-7.9p1/dh.h.fips openssh-7.9p1/dh.h
 | diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h
 | ||||||
| --- openssh-7.9p1/dh.h.fips	2018-10-17 02:01:20.000000000 +0200
 | --- openssh-8.6p1/dh.h.fips	2021-05-06 12:08:36.498926877 +0200
 | ||||||
| +++ openssh-7.9p1/dh.h	2019-03-11 17:08:18.718828381 +0100
 | +++ openssh-8.6p1/dh.h	2021-05-06 12:11:28.393298005 +0200
 | ||||||
| @@ -43,6 +43,7 @@ DH	*dh_new_group_fallback(int);
 | @@ -45,6 +45,7 @@ DH	*dh_new_group_fallback(int);
 | ||||||
|   |   | ||||||
|  int	 dh_gen_key(DH *, int); |  int	 dh_gen_key(DH *, int); | ||||||
|  int	 dh_pub_is_valid(const DH *, const BIGNUM *); |  int	 dh_pub_is_valid(const DH *, const BIGNUM *); | ||||||
| +int	 dh_is_known_group(const DH *);
 | +int	 dh_is_known_group(const DH *);
 | ||||||
|   |   | ||||||
|  u_int	 dh_estimate(int); |  u_int	 dh_estimate(int); | ||||||
|  |  void	 dh_set_moduli_file(const char *); | ||||||
|  | diff -up openssh-8.6p1/kex.c.fips openssh-8.6p1/kex.c
 | ||||||
|  | --- openssh-8.6p1/kex.c.fips	2021-05-06 12:08:36.489926807 +0200
 | ||||||
|  | +++ openssh-8.6p1/kex.c	2021-05-06 12:08:36.498926877 +0200
 | ||||||
|  | @@ -39,6 +39,7 @@
 | ||||||
|   |   | ||||||
| diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c
 |  #ifdef WITH_OPENSSL | ||||||
| --- openssh-7.9p1/kex.c.fips	2019-03-11 17:06:37.614877975 +0100
 |  #include <openssl/crypto.h> | ||||||
| +++ openssh-7.9p1/kex.c	2019-03-11 17:06:37.621878041 +0100
 | +#include <openssl/fips.h>
 | ||||||
| @@ -175,7 +196,10 @@ kex_names_valid(const char *names)
 |  #include <openssl/dh.h> | ||||||
|  |  # ifdef HAVE_EVP_KDF_CTX_NEW_ID | ||||||
|  |  # include <openssl/kdf.h> | ||||||
|  | @@ -203,7 +203,10 @@ kex_names_valid(const char *names)
 | ||||||
|  	for ((p = strsep(&cp, ",")); p && *p != '\0'; |  	for ((p = strsep(&cp, ",")); p && *p != '\0'; | ||||||
|  	    (p = strsep(&cp, ","))) { |  	    (p = strsep(&cp, ","))) { | ||||||
|  		if (kex_alg_by_name(p) == NULL) { |  		if (kex_alg_by_name(p) == NULL) { | ||||||
| @ -105,18 +95,18 @@ diff -up openssh-7.9p1/kex.c.fips openssh-7.9p1/kex.c | |||||||
|  			free(s); |  			free(s); | ||||||
|  			return 0; |  			return 0; | ||||||
|  		} |  		} | ||||||
| diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c
 | diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
 | ||||||
| --- openssh-7.9p1/kexgexc.c.fips	2018-10-17 02:01:20.000000000 +0200
 | --- openssh-8.6p1/kexgexc.c.fips	2021-04-16 05:55:25.000000000 +0200
 | ||||||
| +++ openssh-7.9p1/kexgexc.c	2019-03-11 17:06:37.621878041 +0100
 | +++ openssh-8.6p1/kexgexc.c	2021-05-06 12:08:36.498926877 +0200
 | ||||||
| @@ -28,6 +28,7 @@
 | @@ -28,6 +28,7 @@
 | ||||||
|   |   | ||||||
|  #ifdef WITH_OPENSSL |  #ifdef WITH_OPENSSL | ||||||
|   |   | ||||||
| +#include <openssl/crypto.h>
 | +#include <openssl/fips.h>
 | ||||||
|  #include <sys/types.h> |  #include <sys/types.h> | ||||||
|   |   | ||||||
|  #include <openssl/dh.h> |  #include <openssl/dh.h> | ||||||
| @@ -118,6 +119,10 @@ input_kex_dh_gex_group(int type, u_int32
 | @@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32
 | ||||||
|  		r = SSH_ERR_ALLOC_FAIL; |  		r = SSH_ERR_ALLOC_FAIL; | ||||||
|  		goto out; |  		goto out; | ||||||
|  	} |  	} | ||||||
| @ -127,39 +117,44 @@ diff -up openssh-7.9p1/kexgexc.c.fips openssh-7.9p1/kexgexc.c | |||||||
|  	p = g = NULL; /* belong to kex->dh now */ |  	p = g = NULL; /* belong to kex->dh now */ | ||||||
|   |   | ||||||
|  	/* generate and send 'e', client DH public key */ |  	/* generate and send 'e', client DH public key */ | ||||||
| diff -up openssh-7.9p1/myproposal.h.fips openssh-7.9p1/myproposal.h
 | diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
 | ||||||
| --- openssh-7.9p1/myproposal.h.fips	2018-10-17 02:01:20.000000000 +0200
 | --- openssh-8.6p1/myproposal.h.fips	2021-04-16 05:55:25.000000000 +0200
 | ||||||
| +++ openssh-7.9p1/myproposal.h	2019-03-11 17:06:37.621878041 +0100
 | +++ openssh-8.6p1/myproposal.h	2021-05-06 12:08:36.498926877 +0200
 | ||||||
| @@ -116,6 +116,16 @@
 | @@ -57,6 +57,18 @@
 | ||||||
|  	"rsa-sha2-256," \ |  	"rsa-sha2-256," \ | ||||||
|  	"ssh-rsa" |  	"ssh-rsa" | ||||||
|   |   | ||||||
| +#define	KEX_FIPS_PK_ALG	\
 | +#define	KEX_FIPS_PK_ALG	\
 | ||||||
| +	HOSTKEY_ECDSA_CERT_METHODS \
 | +	"ecdsa-sha2-nistp256-cert-v01@openssh.com," \
 | ||||||
|  | +	"ecdsa-sha2-nistp384-cert-v01@openssh.com," \
 | ||||||
|  | +	"ecdsa-sha2-nistp521-cert-v01@openssh.com," \
 | ||||||
| +	"rsa-sha2-512-cert-v01@openssh.com," \
 | +	"rsa-sha2-512-cert-v01@openssh.com," \
 | ||||||
| +	"rsa-sha2-256-cert-v01@openssh.com," \
 | +	"rsa-sha2-256-cert-v01@openssh.com," \
 | ||||||
| +	"ssh-rsa-cert-v01@openssh.com," \
 | +	"ecdsa-sha2-nistp256," \
 | ||||||
| +	HOSTKEY_ECDSA_METHODS \
 | +	"ecdsa-sha2-nistp384," \
 | ||||||
|  | +	"ecdsa-sha2-nistp521," \
 | ||||||
| +	"rsa-sha2-512," \
 | +	"rsa-sha2-512," \
 | ||||||
| +	"rsa-sha2-256," \
 | +	"rsa-sha2-256"
 | ||||||
| +	"ssh-rsa"
 |  | ||||||
| +
 | +
 | ||||||
|  /* the actual algorithms */ |  | ||||||
|   |  | ||||||
|  #define	KEX_SERVER_ENCRYPT \ |  #define	KEX_SERVER_ENCRYPT \ | ||||||
| @@ -139,6 +147,38 @@
 |  	"chacha20-poly1305@openssh.com," \ | ||||||
|  |  	"aes128-ctr,aes192-ctr,aes256-ctr," \ | ||||||
|  | @@ -78,6 +92,27 @@
 | ||||||
|   |   | ||||||
|  #define KEX_CLIENT_MAC KEX_SERVER_MAC |  #define KEX_CLIENT_MAC KEX_SERVER_MAC | ||||||
|   |   | ||||||
| +#define	KEX_FIPS_ENCRYPT \
 | +#define	KEX_FIPS_ENCRYPT \
 | ||||||
| +	"aes128-ctr,aes192-ctr,aes256-ctr," \
 | +	"aes128-ctr,aes192-ctr,aes256-ctr," \
 | ||||||
| +	"aes128-cbc,3des-cbc," \
 | +	"aes128-cbc,3des-cbc," \
 | ||||||
| +	"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" \
 | +	"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
 | ||||||
| +	AESGCM_CIPHER_MODES
 | +	"aes128-gcm@openssh.com,aes256-gcm@openssh.com"
 | ||||||
| +#ifdef HAVE_EVP_SHA256
 |  | ||||||
| +#define KEX_DEFAULT_KEX_FIPS		\
 | +#define KEX_DEFAULT_KEX_FIPS		\
 | ||||||
| +	KEX_ECDH_METHODS \
 | +	"ecdh-sha2-nistp256," \
 | ||||||
| +	KEX_SHA2_METHODS \
 | +	"ecdh-sha2-nistp384," \
 | ||||||
|  | +	"ecdh-sha2-nistp521," \
 | ||||||
|  | +	"diffie-hellman-group-exchange-sha256," \
 | ||||||
|  | +	"diffie-hellman-group16-sha512," \
 | ||||||
|  | +	"diffie-hellman-group18-sha512," \
 | ||||||
| +	"diffie-hellman-group14-sha256"
 | +	"diffie-hellman-group14-sha256"
 | ||||||
| +#define KEX_FIPS_MAC \
 | +#define KEX_FIPS_MAC \
 | ||||||
| +	"hmac-sha1," \
 | +	"hmac-sha1," \
 | ||||||
| @ -168,59 +163,47 @@ diff -up openssh-7.9p1/myproposal.h.fips openssh-7.9p1/myproposal.h | |||||||
| +	"hmac-sha1-etm@openssh.com," \
 | +	"hmac-sha1-etm@openssh.com," \
 | ||||||
| +	"hmac-sha2-256-etm@openssh.com," \
 | +	"hmac-sha2-256-etm@openssh.com," \
 | ||||||
| +	"hmac-sha2-512-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
 |  | ||||||
| +
 | +
 | ||||||
|  /* Not a KEX value, but here so all the algorithm defaults are together */ |  /* Not a KEX value, but here so all the algorithm defaults are together */ | ||||||
|  #define	SSH_ALLOWED_CA_SIGALGS	\ |  #define	SSH_ALLOWED_CA_SIGALGS	\ | ||||||
|  	"ecdsa-sha2-nistp256," \ |  	"ssh-ed25519," \ | ||||||
| diff -up openssh-7.9p1/readconf.c.fips openssh-7.9p1/readconf.c
 | diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c
 | ||||||
| --- openssh-7.9p1/readconf.c.fips	2019-03-11 17:06:37.601877853 +0100
 | --- openssh-8.6p1/readconf.c.fips	2021-05-06 12:08:36.428926336 +0200
 | ||||||
| +++ openssh-7.9p1/readconf.c	2019-03-11 17:06:37.622878050 +0100
 | +++ openssh-8.6p1/readconf.c	2021-05-06 12:08:36.499926885 +0200
 | ||||||
| @@ -2178,18 +2178,19 @@ fill_default_options(Options * options)
 | @@ -39,6 +39,7 @@
 | ||||||
|  	all_kex = kex_alg_list(','); |  #include <string.h> | ||||||
|  |  #include <stdarg.h> | ||||||
|  |  #include <unistd.h> | ||||||
|  | +#include <openssl/fips.h>
 | ||||||
|  |  #ifdef USE_SYSTEM_GLOB | ||||||
|  |  # include <glob.h> | ||||||
|  |  #else | ||||||
|  | @@ -2538,11 +2538,16 @@ fill_default_options(Options * options)
 | ||||||
|  	all_key = sshkey_alg_list(0, 0, 1, ','); |  	all_key = sshkey_alg_list(0, 0, 1, ','); | ||||||
|  	all_sig = sshkey_alg_list(0, 1, 1, ','); |  	all_sig = sshkey_alg_list(0, 1, 1, ','); | ||||||
| -#define ASSEMBLE(what, defaults, all) \
 |  	/* remove unsupported algos from default lists */ | ||||||
| +#define ASSEMBLE(what, defaults, fips_defaults, all) \
 | -	def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher);
 | ||||||
|  | -	def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac);
 | ||||||
|  | -	def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex);
 | ||||||
|  | -	def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
 | ||||||
|  | -	def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
 | ||||||
|  | +	def_cipher = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_FIPS_ENCRYPT : KEX_CLIENT_ENCRYPT), all_cipher);
 | ||||||
|  | +	def_mac = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_FIPS_MAC : KEX_CLIENT_MAC), all_mac);
 | ||||||
|  | +	def_kex = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_DEFAULT_KEX_FIPS : KEX_CLIENT_KEX), all_kex);
 | ||||||
|  | +	def_key = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key);
 | ||||||
|  | +	def_sig = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig);
 | ||||||
|  |  #define ASSEMBLE(what, defaults, all) \ | ||||||
|  	do { \ |  	do { \ | ||||||
|  		if ((r = kex_assemble_names(&options->what, \ |  		if ((r = kex_assemble_names(&options->what, \ | ||||||
| -		    defaults, all)) != 0) \
 | diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c
 | ||||||
| +		    (FIPS_mode() ? fips_defaults : defaults), \
 | --- openssh-8.6p1/sandbox-seccomp-filter.c.fips	2021-05-06 12:08:36.463926606 +0200
 | ||||||
| +		    all)) != 0) \
 | +++ openssh-8.6p1/sandbox-seccomp-filter.c	2021-05-06 12:08:36.499926885 +0200
 | ||||||
|  			fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ | @@ -160,6 +160,9 @@ static const struct sock_filter preauth_
 | ||||||
|  	} while (0) |  | ||||||
| -	ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, all_cipher);
 |  | ||||||
| -	ASSEMBLE(macs, KEX_CLIENT_MAC, all_mac);
 |  | ||||||
| -	ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, all_kex);
 |  | ||||||
| -	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
 |  | ||||||
| -	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
 |  | ||||||
| -	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
 |  | ||||||
| +	ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
 |  | ||||||
| +	ASSEMBLE(macs, KEX_CLIENT_MAC, KEX_FIPS_MAC, all_mac);
 |  | ||||||
| +	ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
 |  | ||||||
| +	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 |  | ||||||
| +	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 |  | ||||||
| +	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig);
 |  | ||||||
|  #undef ASSEMBLE |  | ||||||
|  	free(all_cipher); |  | ||||||
|  	free(all_mac); |  | ||||||
| diff -up openssh-7.9p1/sandbox-seccomp-filter.c.fips openssh-7.9p1/sandbox-seccomp-filter.c
 |  | ||||||
| --- openssh-7.9p1/sandbox-seccomp-filter.c.fips	2019-03-11 17:06:37.586877712 +0100
 |  | ||||||
| +++ openssh-7.9p1/sandbox-seccomp-filter.c	2019-03-11 17:06:37.622878050 +0100
 |  | ||||||
| @@ -137,6 +137,9 @@ static const struct sock_filter preauth_
 |  | ||||||
|  #ifdef __NR_open |  #ifdef __NR_open | ||||||
|  	SC_DENY(__NR_open, EACCES), |  	SC_DENY(__NR_open, EACCES), | ||||||
|  #endif |  #endif | ||||||
| @ -230,102 +213,74 @@ diff -up openssh-7.9p1/sandbox-seccomp-filter.c.fips openssh-7.9p1/sandbox-secco | |||||||
|  #ifdef __NR_openat |  #ifdef __NR_openat | ||||||
|  	SC_DENY(__NR_openat, EACCES), |  	SC_DENY(__NR_openat, EACCES), | ||||||
|  #endif |  #endif | ||||||
| diff -up openssh-7.9p1/servconf.c.fips openssh-7.9p1/servconf.c
 | diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c
 | ||||||
| --- openssh-7.9p1/servconf.c.fips	2019-03-11 17:06:37.568877543 +0100
 | --- openssh-8.6p1/servconf.c.fips	2021-05-06 12:08:36.455926545 +0200
 | ||||||
| +++ openssh-7.9p1/servconf.c	2019-03-11 17:06:37.622878050 +0100
 | +++ openssh-8.6p1/servconf.c	2021-05-06 12:08:36.500926893 +0200
 | ||||||
| @@ -209,18 +209,19 @@ assemble_algorithms(ServerOptions *o)
 | @@ -38,6 +38,7 @@
 | ||||||
|  	all_kex = kex_alg_list(','); |  #include <limits.h> | ||||||
|  |  #include <stdarg.h> | ||||||
|  |  #include <errno.h> | ||||||
|  | +#include <openssl/fips.h>
 | ||||||
|  |  #ifdef HAVE_UTIL_H | ||||||
|  |  #include <util.h> | ||||||
|  |  #endif | ||||||
|  | @@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o)
 | ||||||
|  	all_key = sshkey_alg_list(0, 0, 1, ','); |  	all_key = sshkey_alg_list(0, 0, 1, ','); | ||||||
|  	all_sig = sshkey_alg_list(0, 1, 1, ','); |  	all_sig = sshkey_alg_list(0, 1, 1, ','); | ||||||
| -#define ASSEMBLE(what, defaults, all) \
 |  	/* remove unsupported algos from default lists */ | ||||||
| +#define ASSEMBLE(what, defaults, fips_defaults, all) \
 | -	def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
 | ||||||
|  | -	def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
 | ||||||
|  | -	def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
 | ||||||
|  | -	def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
 | ||||||
|  | -	def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
 | ||||||
|  | +	def_cipher = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_FIPS_ENCRYPT : KEX_SERVER_ENCRYPT), all_cipher);
 | ||||||
|  | +	def_mac = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_FIPS_MAC : KEX_SERVER_MAC), all_mac);
 | ||||||
|  | +	def_kex = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_DEFAULT_KEX_FIPS : KEX_SERVER_KEX), all_kex);
 | ||||||
|  | +	def_key = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG), all_key);
 | ||||||
|  | +	def_sig = match_filter_allowlist((FIPS_mode() ?
 | ||||||
|  | +	    KEX_FIPS_PK_ALG : SSH_ALLOWED_CA_SIGALGS), all_sig);
 | ||||||
|  |  #define ASSEMBLE(what, defaults, all) \ | ||||||
|  	do { \ |  	do { \ | ||||||
| -		if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
 |  		if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ | ||||||
| +		if ((r = kex_assemble_names(&o->what, (FIPS_mode() \
 | diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c
 | ||||||
| +		    ? fips_defaults : defaults), all)) != 0) \
 | --- openssh-8.6p1/ssh.c.fips	2021-05-06 12:08:36.467926637 +0200
 | ||||||
|  			fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ | +++ openssh-8.6p1/ssh.c	2021-05-06 12:08:36.500926893 +0200
 | ||||||
|  	} while (0) | @@ -77,6 +77,7 @@
 | ||||||
| -	ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
 |  | ||||||
| -	ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
 |  | ||||||
| -	ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
 |  | ||||||
| -	ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key);
 |  | ||||||
| -	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
 |  | ||||||
| -	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
 |  | ||||||
| -	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
 |  | ||||||
| +	ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, KEX_FIPS_ENCRYPT, all_cipher);
 |  | ||||||
| +	ASSEMBLE(macs, KEX_SERVER_MAC, KEX_FIPS_MAC, all_mac);
 |  | ||||||
| +	ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, KEX_DEFAULT_KEX_FIPS, all_kex);
 |  | ||||||
| +	ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 |  | ||||||
| +	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 |  | ||||||
| +	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, KEX_FIPS_PK_ALG, all_key);
 |  | ||||||
| +	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, KEX_FIPS_PK_ALG, all_sig);
 |  | ||||||
|  #undef ASSEMBLE |  | ||||||
|  	free(all_cipher); |  | ||||||
|  	free(all_mac); |  | ||||||
| diff -up openssh-7.9p1/ssh.c.fips openssh-7.9p1/ssh.c
 |  | ||||||
| --- openssh-7.9p1/ssh.c.fips	2019-03-11 17:06:37.602877862 +0100
 |  | ||||||
| +++ openssh-7.9p1/ssh.c	2019-03-11 17:06:37.623878060 +0100
 |  | ||||||
| @@ -76,6 +76,7 @@
 |  | ||||||
|  #include <openssl/evp.h> |  #include <openssl/evp.h> | ||||||
|  #include <openssl/err.h> |  #include <openssl/err.h> | ||||||
|  #endif |  #endif | ||||||
| +#include <openssl/crypto.h>
 | +#include <openssl/fips.h>
 | ||||||
|  #include "openbsd-compat/openssl-compat.h" |  #include "openbsd-compat/openssl-compat.h" | ||||||
|  #include "openbsd-compat/sys-queue.h" |  #include "openbsd-compat/sys-queue.h" | ||||||
|   |   | ||||||
| @@ -1283,6 +1294,10 @@ main(int ac, char **av)
 | @@ -1516,6 +1517,10 @@ main(int ac, char **av)
 | ||||||
|  		dump_client_config(&options, host); |  | ||||||
|  		exit(0); |  		exit(0); | ||||||
|  	} |  	} | ||||||
| +
 |   | ||||||
| +	if (FIPS_mode()) {
 | +	if (FIPS_mode()) {
 | ||||||
| +		debug("FIPS mode initialized");
 | +		debug("FIPS mode initialized");
 | ||||||
| +	}
 | +	}
 | ||||||
|   | +
 | ||||||
|  	if (muxclient_command != 0 && options.control_path == NULL) |  	/* Expand SecurityKeyProvider if it refers to an environment variable */ | ||||||
|  		fatal("No ControlPath specified for \"-O\" command"); |  	if (options.sk_provider != NULL && *options.sk_provider == '$' && | ||||||
| diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c
 |  	    strlen(options.sk_provider) > 1) { | ||||||
| --- openssh-7.9p1/sshconnect2.c.fips	2019-03-11 17:06:37.580877655 +0100
 | diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c
 | ||||||
| +++ openssh-7.9p1/sshconnect2.c	2019-03-11 17:06:37.623878060 +0100
 | --- openssh-8.6p1/sshconnect2.c.fips	2021-05-06 12:08:36.485926777 +0200
 | ||||||
| @@ -44,6 +44,8 @@
 | +++ openssh-8.6p1/sshconnect2.c	2021-05-06 12:08:36.501926900 +0200
 | ||||||
|  | @@ -45,6 +45,8 @@
 | ||||||
|  #include <vis.h> |  #include <vis.h> | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
| +#include <openssl/crypto.h>
 | +#include <openssl/fips.h>
 | ||||||
| +
 | +
 | ||||||
|  #include "openbsd-compat/sys-queue.h" |  #include "openbsd-compat/sys-queue.h" | ||||||
|   |   | ||||||
|  #include "xmalloc.h" |  #include "xmalloc.h" | ||||||
| @@ -148,7 +150,8 @@ order_hostkeyalgs(char *host, struct soc
 | @@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | ||||||
|  	 * Otherwise, prefer the host key algorithms that match known keys |  | ||||||
|  	 * while keeping the ordering of HostkeyAlgorithms as much as possible. |  | ||||||
|  	 */ |  | ||||||
| -	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); |  | ||||||
| @@ -229,14 +232,16 @@ ssh_kex2(struct ssh *ssh, char *host, st
 |  | ||||||
|  	if (options.hostkeyalgorithms != NULL) { |  | ||||||
|  		all_key = sshkey_alg_list(0, 0, 1, ','); |  | ||||||
|  		if (kex_assemble_names(&options.hostkeyalgorithms, |  | ||||||
| -		    KEX_DEFAULT_PK_ALG, all_key) != 0)
 |  | ||||||
| +		    (FIPS_mode() ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG),
 |  | ||||||
| +		    all_key) != 0)
 |  | ||||||
|  			fatal("%s: kex_assemble_namelist", __func__); |  | ||||||
|  		free(all_key); |  | ||||||
|  		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( |  | ||||||
| @@ -201,35 +201,40 @@ ssh_kex2(char *host, struct sockaddr *ho
 |  | ||||||
|   |   | ||||||
|  #if defined(GSSAPI) && defined(WITH_OPENSSL) |  #if defined(GSSAPI) && defined(WITH_OPENSSL) | ||||||
|  	if (options.gss_keyex) { |  	if (options.gss_keyex) { | ||||||
| @ -340,24 +295,7 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c | |||||||
| -			/* Fall back to specified host if we are using proxy command
 | -			/* Fall back to specified host if we are using proxy command
 | ||||||
| -			 * and can not use DNS on that socket */
 | -			 * and can not use DNS on that socket */
 | ||||||
| -			if (strcmp(gss_host, "UNKNOWN") == 0) {
 | -			if (strcmp(gss_host, "UNKNOWN") == 0) {
 | ||||||
| -				gss_host = xstrdup(host);
 | -				free(gss_host);
 | ||||||
| -			}
 |  | ||||||
| -		} else {
 |  | ||||||
| -			gss_host = xstrdup(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 we've got GSSAPI algorithms, then we also support the
 |  | ||||||
| -			 * 'null' hostkey, as a last resort */
 |  | ||||||
| -			orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
 |  | ||||||
| -			xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
 |  | ||||||
| -			    "%s,null", orig);
 |  | ||||||
| +		if (FIPS_mode()) {
 | +		if (FIPS_mode()) {
 | ||||||
| +			logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
 | +			logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
 | ||||||
| +			options.gss_keyex = 0;
 | +			options.gss_keyex = 0;
 | ||||||
| @ -373,12 +311,28 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c | |||||||
| +				/* Fall back to specified host if we are using proxy command
 | +				/* Fall back to specified host if we are using proxy command
 | ||||||
| +				 * and can not use DNS on that socket */
 | +				 * and can not use DNS on that socket */
 | ||||||
| +				if (strcmp(gss_host, "UNKNOWN") == 0) {
 | +				if (strcmp(gss_host, "UNKNOWN") == 0) {
 | ||||||
|  | +					free(gss_host);
 | ||||||
| +					gss_host = xstrdup(host);
 | +					gss_host = xstrdup(host);
 | ||||||
| +				}
 | +				}
 | ||||||
| +			} else {
 | +			} else {
 | ||||||
| +				gss_host = xstrdup(host);
 |  				gss_host = xstrdup(host); | ||||||
| +			}
 |  			} | ||||||
| +
 | -		} else {
 | ||||||
|  | -			gss_host = xstrdup(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 we've got GSSAPI algorithms, then we also support the
 | ||||||
|  | -			 * 'null' hostkey, as a last resort */
 | ||||||
|  | -			orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
 | ||||||
|  | -			xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
 | ||||||
|  | -			    "%s,null", orig);
 | ||||||
| +			gss = ssh_gssapi_client_mechanisms(gss_host,
 | +			gss = ssh_gssapi_client_mechanisms(gss_host,
 | ||||||
| +			    options.gss_client_identity, options.gss_kex_algorithms);
 | +			    options.gss_client_identity, options.gss_kex_algorithms);
 | ||||||
| +			if (gss) {
 | +			if (gss) {
 | ||||||
| @ -395,9 +349,9 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c | |||||||
|  		} |  		} | ||||||
|  	} |  	} | ||||||
|  #endif |  #endif | ||||||
| diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c
 | diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
 | ||||||
| --- openssh-7.9p1/sshd.c.fips	2019-03-11 17:06:37.617878003 +0100
 | --- openssh-8.6p1/sshd.c.fips	2021-05-06 12:08:36.493926838 +0200
 | ||||||
| +++ openssh-7.9p1/sshd.c	2019-03-11 17:06:37.624878069 +0100
 | +++ openssh-8.6p1/sshd.c	2021-05-06 12:13:56.501492639 +0200
 | ||||||
| @@ -66,6 +66,7 @@
 | @@ -66,6 +66,7 @@
 | ||||||
|  #include <grp.h> |  #include <grp.h> | ||||||
|  #include <pwd.h> |  #include <pwd.h> | ||||||
| @ -410,11 +364,11 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c | |||||||
|  #include <openssl/dh.h> |  #include <openssl/dh.h> | ||||||
|  #include <openssl/bn.h> |  #include <openssl/bn.h> | ||||||
|  #include <openssl/rand.h> |  #include <openssl/rand.h> | ||||||
| +#include <openssl/crypto.h>
 | +#include <openssl/fips.h>
 | ||||||
|  #include "openbsd-compat/openssl-compat.h" |  #include "openbsd-compat/openssl-compat.h" | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
| @@ -1581,6 +1584,7 @@ main(int ac, char **av)
 | @@ -1619,6 +1621,7 @@ main(int ac, char **av)
 | ||||||
|  #endif |  #endif | ||||||
|  	__progname = ssh_get_progname(av[0]); |  	__progname = ssh_get_progname(av[0]); | ||||||
|   |   | ||||||
| @ -422,7 +376,21 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c | |||||||
|  	/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ |  	/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ | ||||||
|  	saved_argc = ac; |  	saved_argc = ac; | ||||||
|  	rexec_argc = ac; |  	rexec_argc = ac; | ||||||
| @@ -2036,6 +2051,10 @@ main(int ac, char **av)
 | @@ -1931,6 +1931,13 @@ main(int ac, char **av)
 | ||||||
|  |  		    &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) | ||||||
|  |  			do_log2_r(r, ll, "Unable to load host key \"%s\"", | ||||||
|  |  			    options.host_key_files[i]); | ||||||
|  | +		if (FIPS_mode() && key != NULL && (sshkey_type_plain(key->type) == KEY_ED25519_SK
 | ||||||
|  | +				||  sshkey_type_plain(key->type) == KEY_ED25519)) {
 | ||||||
|  | +		    logit_f("sshd: Ed25519 keys are not allowed in FIPS mode, skipping %s", options.host_key_files[i]);
 | ||||||
|  | +		    sshkey_free(key);
 | ||||||
|  | +		    key = NULL;
 | ||||||
|  | +		    continue;
 | ||||||
|  | +		}
 | ||||||
|  |  		if (sshkey_is_sk(key) && | ||||||
|  |  		    key->sk_flags & SSH_SK_USER_PRESENCE_REQD) { | ||||||
|  |  			debug("host key %s requires user presence, ignoring", | ||||||
|  | @@ -2110,6 +2113,10 @@ main(int ac, char **av)
 | ||||||
|  	/* Reinitialize the log (because of the fork above). */ |  	/* Reinitialize the log (because of the fork above). */ | ||||||
|  	log_init(__progname, options.log_level, options.log_facility, log_stderr); |  	log_init(__progname, options.log_level, options.log_facility, log_stderr); | ||||||
|   |   | ||||||
| @ -430,10 +398,10 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c | |||||||
| +		debug("FIPS mode initialized");
 | +		debug("FIPS mode initialized");
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
|  	/* Chdir to the root directory so that the current disk can be |  	/* | ||||||
|  	   unmounted if desired. */ |  	 * Chdir to the root directory so that the current disk can be | ||||||
|  	if (chdir("/") == -1) |  	 * unmounted if desired. | ||||||
| @@ -2412,10 +2431,14 @@ do_ssh2_kex(void)
 | @@ -2494,10 +2501,14 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||||
|  	if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) |  	if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) | ||||||
|  		orig = NULL; |  		orig = NULL; | ||||||
|   |   | ||||||
| @ -452,92 +420,122 @@ diff -up openssh-7.9p1/sshd.c.fips openssh-7.9p1/sshd.c | |||||||
|   |   | ||||||
|  	if (gss && orig) |  	if (gss && orig) | ||||||
|  		xasprintf(&newstr, "%s,%s", gss, orig); |  		xasprintf(&newstr, "%s,%s", gss, orig); | ||||||
| diff -up openssh-7.9p1/sshkey.c.fips openssh-7.9p1/sshkey.c
 | diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
 | ||||||
| --- openssh-7.9p1/sshkey.c.fips	2019-03-11 17:06:37.617878003 +0100
 | --- openssh-8.6p1/sshkey.c.fips	2021-05-06 12:08:36.493926838 +0200
 | ||||||
| +++ openssh-7.9p1/sshkey.c	2019-03-11 17:06:37.624878069 +0100
 | +++ openssh-8.6p1/sshkey.c	2021-05-06 12:08:36.502926908 +0200
 | ||||||
| @@ -34,6 +34,7 @@
 | @@ -34,6 +34,7 @@
 | ||||||
|  #include <openssl/evp.h> |  #include <openssl/evp.h> | ||||||
|  #include <openssl/err.h> |  #include <openssl/err.h> | ||||||
|  #include <openssl/pem.h> |  #include <openssl/pem.h> | ||||||
| +#include <openssl/crypto.h>
 | +#include <openssl/fips.h>
 | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
|  #include "crypto_api.h" |  #include "crypto_api.h" | ||||||
| @@ -57,6 +58,7 @@
 | @@ -57,6 +58,7 @@
 | ||||||
|  |  #define SSHKEY_INTERNAL | ||||||
|  #include "sshkey.h" |  #include "sshkey.h" | ||||||
|  #include "sshkey-xmss.h" |  | ||||||
|  #include "match.h" |  #include "match.h" | ||||||
| +#include "log.h"
 | +#include "log.h"
 | ||||||
|  |  #include "ssh-sk.h" | ||||||
|   |   | ||||||
|  #include "xmss_fast.h" |  #ifdef WITH_XMSS | ||||||
|  | @@ -285,6 +285,18 @@ sshkey_alg_list(int certs_only, int plai
 | ||||||
|  |  	for (kt = keytypes; kt->type != -1; kt++) { | ||||||
|  |  		if (kt->name == NULL || kt->type == KEY_NULL) | ||||||
|  |  			continue; | ||||||
|  | +		if (FIPS_mode()) {
 | ||||||
|  | +			switch (kt->type) {
 | ||||||
|  | +			case KEY_ED25519:
 | ||||||
|  | +			case KEY_ED25519_SK:
 | ||||||
|  | +			case KEY_ED25519_CERT:
 | ||||||
|  | +			case KEY_ED25519_SK_CERT:
 | ||||||
|  | +			     continue;
 | ||||||
|  | +			     break;
 | ||||||
|  | +			default:
 | ||||||
|  | +			     break;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  |  		if (!include_sigonly && kt->sigonly) | ||||||
|  |  			continue; | ||||||
|  |  		if ((certs_only && !kt->cert) || (plain_only && kt->cert)) | ||||||
|  | @@ -1503,6 +1503,20 @@ sshkey_read(struct sshkey *ret, char **c
 | ||||||
|  |  		return SSH_ERR_EC_CURVE_MISMATCH; | ||||||
|  |  	} | ||||||
|   |   | ||||||
| @@ -392,7 +394,8 @@ sshkey_calculate_signature(EVP_PKEY *pkey
 | +	switch (type) {
 | ||||||
|  { | +	case KEY_ED25519:
 | ||||||
|  	EVP_MD_CTX *ctx = NULL; | +	case KEY_ED25519_SK:
 | ||||||
|  	u_char *sig = NULL; | +	case KEY_ED25519_CERT:
 | ||||||
| -	int ret, slen, len;
 | +	case KEY_ED25519_SK_CERT:
 | ||||||
| +	int ret, slen;
 | +		if (FIPS_mode()) {
 | ||||||
| +	size_t len;
 | +		    sshkey_free(k);
 | ||||||
|  | +		    logit_f("Ed25519 keys are not allowed in FIPS mode");
 | ||||||
|  | +		    return SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +		}
 | ||||||
|  | +		break;
 | ||||||
|  | +	default:
 | ||||||
|  | +		break;
 | ||||||
|  | +	}
 | ||||||
|  |  	/* Fill in ret from parsed key */ | ||||||
|  |  	ret->type = type; | ||||||
|  |  	if (sshkey_is_cert(ret)) { | ||||||
|  | @@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA
 | ||||||
|  | 		goto out; | ||||||
| 
 | 
 | ||||||
|  	if (sigp == NULL || lenp == NULL) { | 	if (EVP_PKEY_keygen(ctx, &res) <= 0) { | ||||||
|  		return SSH_ERR_INVALID_ARGUMENT; |  | ||||||
| @@ -411,9 +414,10 @@ sshkey_calculate_signature(EVP_PKEY *pkey
 |  | ||||||
|  		ret = SSH_ERR_ALLOC_FAIL; |  | ||||||
|  		goto error; |  | ||||||
|  	} |  | ||||||
| -	if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 |  | ||||||
| -	    EVP_SignUpdate(ctx, data, datalen) <= 0 ||
 |  | ||||||
| -	    EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
 |  | ||||||
| +	if (EVP_DigestSignInit(ctx, NULL, ssh_digest_to_md(hash_alg),
 |  | ||||||
| +	        NULL, pkey) != 1 ||
 |  | ||||||
| +	    EVP_DigestSignUpdate(ctx, data, datalen) != 1 ||
 |  | ||||||
| +	    EVP_DigestSignFinal(ctx, sig, &len) != 1) {
 |  | ||||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; |  | ||||||
|  		goto error; |  | ||||||
|  	} |  | ||||||
| @@ -440,12 +444,13 @@ sshkey_verify_signature(EVP_PKEY *pkey
 |  | ||||||
|  	if ((ctx = EVP_MD_CTX_new()) == NULL) { |  | ||||||
|  		return SSH_ERR_ALLOC_FAIL; |  | ||||||
|  	} |  | ||||||
| -	if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 |  | ||||||
| -	    EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
 |  | ||||||
| +	if (EVP_DigestVerifyInit(ctx, NULL, ssh_digest_to_md(hash_alg),
 |  | ||||||
| +	    NULL, pkey) != 1 ||
 |  | ||||||
| +	    EVP_DigestVerifyUpdate(ctx, data, datalen) != 1) {
 |  | ||||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; |  | ||||||
|  		goto done; |  | ||||||
|  	} |  | ||||||
| -	ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
 |  | ||||||
| +	ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen);
 |  | ||||||
|  	switch (ret) { |  | ||||||
|  	case 1: |  | ||||||
|  		ret = 0; |  | ||||||
| @@ -1514,6 +1516,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())
 | +		if (FIPS_mode())
 | ||||||
| +			logit("%s: the key length might be unsupported by FIPS mode approved key generation method", __func__);
 | +			logit_f("the key length might be unsupported by FIPS mode approved key generation method");
 | ||||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; |  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  		goto out; |  		goto out; | ||||||
|  	} |  	} | ||||||
| diff -up openssh-7.9p1/ssh-keygen.c.fips openssh-7.9p1/ssh-keygen.c
 | @@ -2916,6 +2916,11 @@ sshkey_sign(struct sshkey *key,
 | ||||||
| --- openssh-7.9p1/ssh-keygen.c.fips	2019-03-11 17:06:37.590877750 +0100
 |  		break; | ||||||
| +++ openssh-7.9p1/ssh-keygen.c	2019-03-11 17:06:37.625878079 +0100
 |  	case KEY_ED25519_SK: | ||||||
| @@ -230,6 +230,12 @@ type_bits_valid(int type, const char *na
 |  	case KEY_ED25519_SK_CERT: | ||||||
|  	    OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; | +		if (FIPS_mode()) {
 | ||||||
|  	if (*bitsp > maxbits) | +		    logit_f("Ed25519 keys are not allowed in FIPS mode");
 | ||||||
|  		fatal("key bits exceeds maximum %d", maxbits); | +		    return SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +		}
 | ||||||
|  | +		/* Fallthrough */
 | ||||||
|  |  	case KEY_ECDSA_SK_CERT: | ||||||
|  |  	case KEY_ECDSA_SK: | ||||||
|  |  		r = sshsk_sign(sk_provider, key, sigp, lenp, data, | ||||||
|  | @@ -2973,6 +2978,10 @@ sshkey_verify(const struct sshkey *key,
 | ||||||
|  |  		return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat); | ||||||
|  |  	case KEY_ED25519_SK: | ||||||
|  |  	case KEY_ED25519_SK_CERT: | ||||||
|  | +		if (FIPS_mode()) {
 | ||||||
|  | +		    logit_f("Ed25519 keys are not allowed in FIPS mode");
 | ||||||
|  | +		    return SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +		}
 | ||||||
|  |  		return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen, | ||||||
|  |  		    compat, detailsp); | ||||||
|  |  #ifdef WITH_XMSS | ||||||
|  | diff -up openssh-8.6p1/ssh-keygen.c.fips openssh-8.6p1/ssh-keygen.c
 | ||||||
|  | --- openssh-8.6p1/ssh-keygen.c.fips	2021-05-06 12:08:36.467926637 +0200
 | ||||||
|  | +++ openssh-8.6p1/ssh-keygen.c	2021-05-06 12:08:36.503926916 +0200
 | ||||||
|  | @@ -20,6 +20,7 @@
 | ||||||
|  |   | ||||||
|  |  #ifdef WITH_OPENSSL | ||||||
|  |  #include <openssl/evp.h> | ||||||
|  | +#include <openssl/fips.h>
 | ||||||
|  |  #include <openssl/pem.h> | ||||||
|  |  #include "openbsd-compat/openssl-compat.h" | ||||||
|  |  #endif | ||||||
|  | @@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na
 | ||||||
|  |  #endif | ||||||
|  |  	} | ||||||
|  |  #ifdef WITH_OPENSSL | ||||||
| +	if (FIPS_mode()) {
 | +	if (FIPS_mode()) {
 | ||||||
| +		if (type == KEY_DSA)
 | +		if (type == KEY_DSA)
 | ||||||
| +			fatal("DSA keys are not allowed in FIPS mode");
 | +			fatal("DSA keys are not allowed in FIPS mode");
 | ||||||
| +		if (type == KEY_ED25519)
 | +		if (type == KEY_ED25519 || type == KEY_ED25519_SK)
 | ||||||
| +			fatal("ED25519 keys are not allowed in FIPS mode");
 | +			fatal("ED25519 keys are not allowed in FIPS mode");
 | ||||||
| +	}
 | +	}
 | ||||||
|  	switch (type) { |  	switch (type) { | ||||||
|  	case KEY_DSA: |  	case KEY_DSA: | ||||||
|  		if (*bitsp != 1024) |  		if (*bitsp != 1024) | ||||||
| @@ -1029,9 +1035,17 @@ do_gen_all_hostkeys(struct passwd *pw)
 | @@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw)
 | ||||||
|  			first = 1; |  			first = 1; | ||||||
|  			printf("%s: generating new host keys: ", __progname); |  			printf("%s: generating new host keys: ", __progname); | ||||||
|  		} |  		} | ||||||
| @ -554,16 +552,124 @@ diff -up openssh-7.9p1/ssh-keygen.c.fips openssh-7.9p1/ssh-keygen.c | |||||||
|  		fflush(stdout); |  		fflush(stdout); | ||||||
| -		type = sshkey_type_from_name(key_types[i].key_type);
 | -		type = sshkey_type_from_name(key_types[i].key_type);
 | ||||||
|  		if ((fd = mkstemp(prv_tmp)) == -1) { |  		if ((fd = mkstemp(prv_tmp)) == -1) { | ||||||
|  			error("Could not save your public key in %s: %s", |  			error("Could not save your private key in %s: %s", | ||||||
|  			    prv_tmp, strerror(errno)); |  			    prv_tmp, strerror(errno)); | ||||||
| diff -up openssh-8.0p1/sshd_config.xxx openssh-8.0p1/sshd_config
 | diff -up openssh-8.7p1/kexgen.c.fips3 openssh-8.7p1/kexgen.c
 | ||||||
| --- openssh-8.0p1/sshd_config.xxx	2023-10-30 13:01:59.150952364 +0100
 | --- openssh-8.7p1/kexgen.c.fips3	2022-07-11 16:11:21.973519913 +0200
 | ||||||
| +++ openssh-8.0p1/sshd_config	2023-10-30 13:02:56.662231354 +0100
 | +++ openssh-8.7p1/kexgen.c	2022-07-11 16:25:31.172187365 +0200
 | ||||||
| @@ -21,6 +21,7 @@
 | @@ -31,6 +31,7 @@
 | ||||||
|  |  #include <stdio.h> | ||||||
|  |  #include <string.h> | ||||||
|  |  #include <signal.h> | ||||||
|  | +#include <openssl/fips.h>
 | ||||||
|   |   | ||||||
|  HostKey /etc/ssh/ssh_host_rsa_key |  #include "sshkey.h" | ||||||
|  HostKey /etc/ssh/ssh_host_ecdsa_key |  #include "kex.h" | ||||||
| +#In FIPS mode Ed25519 keys are not supported, please comment out the next line
 | @@ -115,10 +116,20 @@ kex_gen_client(struct ssh *ssh)
 | ||||||
|  HostKey /etc/ssh/ssh_host_ed25519_key |  		break; | ||||||
|  |  #endif | ||||||
|  |  	case KEX_C25519_SHA256: | ||||||
|  | -		r = kex_c25519_keypair(kex);
 | ||||||
|  | +		if (FIPS_mode()) {
 | ||||||
|  | +		    logit_f("Key exchange type c25519 is not allowed in FIPS mode");
 | ||||||
|  | +		    r = SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +		} else {
 | ||||||
|  | +		    r = kex_c25519_keypair(kex);
 | ||||||
|  | +		}
 | ||||||
|  |  		break; | ||||||
|  |  	case KEX_KEM_SNTRUP761X25519_SHA512: | ||||||
|  | -		r = kex_kem_sntrup761x25519_keypair(kex);
 | ||||||
|  | +		if (FIPS_mode()) {
 | ||||||
|  | +		    logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
 | ||||||
|  | +		    r = SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +		} else {
 | ||||||
|  | +		    r = kex_kem_sntrup761x25519_keypair(kex);
 | ||||||
|  | +		}
 | ||||||
|  |  		break; | ||||||
|  |  	default: | ||||||
|  |  		r = SSH_ERR_INVALID_ARGUMENT; | ||||||
|  | @@ -186,11 +197,21 @@ input_kex_gen_reply(int type, u_int32_t
 | ||||||
|  |  		break; | ||||||
|  |  #endif | ||||||
|  |  	case KEX_C25519_SHA256: | ||||||
|  | -		r = kex_c25519_dec(kex, server_blob, &shared_secret);
 | ||||||
|  | +		if (FIPS_mode()) {
 | ||||||
|  | +		    logit_f("Key exchange type c25519 is not allowed in FIPS mode");
 | ||||||
|  | +		    r = SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +		} else {
 | ||||||
|  | +		    r = kex_c25519_dec(kex, server_blob, &shared_secret);
 | ||||||
|  | +		}
 | ||||||
|  |  		break; | ||||||
|  |  	case KEX_KEM_SNTRUP761X25519_SHA512: | ||||||
|  | -		r = kex_kem_sntrup761x25519_dec(kex, server_blob,
 | ||||||
|  | -		    &shared_secret);
 | ||||||
|  | +		if (FIPS_mode()) {
 | ||||||
|  | +		    logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
 | ||||||
|  | +		    r = SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +		} else {
 | ||||||
|  | +		    r = kex_kem_sntrup761x25519_dec(kex, server_blob,
 | ||||||
|  | +		        &shared_secret);
 | ||||||
|  | +		}
 | ||||||
|  |  		break; | ||||||
|  |  	default: | ||||||
|  |  		r = SSH_ERR_INVALID_ARGUMENT; | ||||||
|  | @@ -285,12 +306,22 @@ input_kex_gen_init(int type, u_int32_t s
 | ||||||
|  |  		break; | ||||||
|  |  #endif | ||||||
|  |  	case KEX_C25519_SHA256: | ||||||
|  | -		r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
 | ||||||
|  | -		    &shared_secret);
 | ||||||
|  | +		if (FIPS_mode()) {
 | ||||||
|  | +		    logit_f("Key exchange type c25519 is not allowed in FIPS mode");
 | ||||||
|  | +		    r = SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +		} else {
 | ||||||
|  | +		    r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
 | ||||||
|  | +		        &shared_secret);
 | ||||||
|  | +		}
 | ||||||
|  |  		break; | ||||||
|  |  	case KEX_KEM_SNTRUP761X25519_SHA512: | ||||||
|  | -		r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
 | ||||||
|  | -		    &server_pubkey, &shared_secret);
 | ||||||
|  | +		if (FIPS_mode()) {
 | ||||||
|  | +		    logit_f("Key exchange type sntrup761 is not allowed in FIPS mode");
 | ||||||
|  | +		    r = SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +		} else {
 | ||||||
|  | +		    r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
 | ||||||
|  | +		        &server_pubkey, &shared_secret);
 | ||||||
|  | +		}
 | ||||||
|  |  		break; | ||||||
|  |  	default: | ||||||
|  |  		r = SSH_ERR_INVALID_ARGUMENT; | ||||||
|  | diff -up openssh-8.7p1/ssh-ed25519.c.fips3 openssh-8.7p1/ssh-ed25519.c
 | ||||||
|  | --- openssh-8.7p1/ssh-ed25519.c.fips3	2022-07-11 16:53:41.428343304 +0200
 | ||||||
|  | +++ openssh-8.7p1/ssh-ed25519.c	2022-07-11 16:56:09.284663661 +0200
 | ||||||
|  | @@ -24,6 +24,7 @@
 | ||||||
|   |   | ||||||
|  # Ciphers and keying |  #include <string.h> | ||||||
|  |  #include <stdarg.h> | ||||||
|  | +#include <openssl/fips.h>
 | ||||||
|  |   | ||||||
|  |  #include "log.h" | ||||||
|  |  #include "sshbuf.h" | ||||||
|  | @@ -52,6 +53,10 @@ ssh_ed25519_sign(const struct sshkey *ke
 | ||||||
|  |  	    key->ed25519_sk == NULL || | ||||||
|  |  	    datalen >= INT_MAX - crypto_sign_ed25519_BYTES) | ||||||
|  |  		return SSH_ERR_INVALID_ARGUMENT; | ||||||
|  | +	if (FIPS_mode()) {
 | ||||||
|  | +	    logit_f("Ed25519 keys are not allowed in FIPS mode");
 | ||||||
|  | +	    return SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +	}
 | ||||||
|  |  	smlen = slen = datalen + crypto_sign_ed25519_BYTES; | ||||||
|  |  	if ((sig = malloc(slen)) == NULL) | ||||||
|  |  		return SSH_ERR_ALLOC_FAIL; | ||||||
|  | @@ -108,6 +113,10 @@ ssh_ed25519_verify(const struct sshkey *
 | ||||||
|  |  	    datalen >= INT_MAX - crypto_sign_ed25519_BYTES || | ||||||
|  |  	    signature == NULL || signaturelen == 0) | ||||||
|  |  		return SSH_ERR_INVALID_ARGUMENT; | ||||||
|  | +	if (FIPS_mode()) {
 | ||||||
|  | +	    logit_f("Ed25519 keys are not allowed in FIPS mode");
 | ||||||
|  | +	    return SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	if ((b = sshbuf_from(signature, signaturelen)) == NULL) | ||||||
|  |  		return SSH_ERR_ALLOC_FAIL; | ||||||
|  | |||||||
| @ -1,7 +1,26 @@ | |||||||
| diff --git a/auth-krb5.c b/auth-krb5.c
 | diff -up openssh-8.6p1/auth.h.ccache_name openssh-8.6p1/auth.h
 | ||||||
| index a5a81ed2..63f877f2 100644
 | --- openssh-8.6p1/auth.h.ccache_name	2021-05-06 11:15:36.345143341 +0200
 | ||||||
| --- a/auth-krb5.c
 | +++ openssh-8.6p1/auth.h	2021-05-06 11:15:36.387143654 +0200
 | ||||||
| +++ b/auth-krb5.c
 | @@ -83,6 +83,7 @@ struct Authctxt {
 | ||||||
|  |  	krb5_principal	 krb5_user; | ||||||
|  |  	char		*krb5_ticket_file; | ||||||
|  |  	char		*krb5_ccname; | ||||||
|  | +	int		 krb5_set_env;
 | ||||||
|  |  #endif | ||||||
|  |  	struct sshbuf	*loginmsg; | ||||||
|  |   | ||||||
|  | @@ -231,7 +232,7 @@ struct passwd *fakepw(void);
 | ||||||
|  |  int	 sys_auth_passwd(struct ssh *, const char *); | ||||||
|  |   | ||||||
|  |  #if defined(KRB5) && !defined(HEIMDAL) | ||||||
|  | -krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
 | ||||||
|  | +krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
 | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  #endif /* AUTH_H */ | ||||||
|  | diff -up openssh-8.6p1/auth-krb5.c.ccache_name openssh-8.6p1/auth-krb5.c
 | ||||||
|  | --- openssh-8.6p1/auth-krb5.c.ccache_name	2021-04-16 05:55:25.000000000 +0200
 | ||||||
|  | +++ openssh-8.6p1/auth-krb5.c	2021-05-06 11:28:40.195242317 +0200
 | ||||||
| @@ -51,6 +51,7 @@
 | @@ -51,6 +51,7 @@
 | ||||||
|  #include <unistd.h> |  #include <unistd.h> | ||||||
|  #include <string.h> |  #include <string.h> | ||||||
| @ -10,7 +29,7 @@ index a5a81ed2..63f877f2 100644 | |||||||
|   |   | ||||||
|  extern ServerOptions	 options; |  extern ServerOptions	 options; | ||||||
|   |   | ||||||
| @@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
 | @@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c
 | ||||||
|  #endif |  #endif | ||||||
|  	krb5_error_code problem; |  	krb5_error_code problem; | ||||||
|  	krb5_ccache ccache = NULL; |  	krb5_ccache ccache = NULL; | ||||||
| @ -19,24 +38,18 @@ index a5a81ed2..63f877f2 100644 | |||||||
|  	char *client, *platform_client; |  	char *client, *platform_client; | ||||||
|  	const char *errmsg; |  	const char *errmsg; | ||||||
|   |   | ||||||
| @@ -163,7 +164,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
 | @@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, c
 | ||||||
|  		goto out; |  		goto out; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| -	problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache);
 | -	problem = ssh_krb5_cc_gen(authctxt->krb5_ctx,
 | ||||||
|  | -	    &authctxt->krb5_fwd_ccache);
 | ||||||
| +	problem = ssh_krb5_cc_new_unique(authctxt->krb5_ctx,
 | +	problem = ssh_krb5_cc_new_unique(authctxt->krb5_ctx,
 | ||||||
| +	     &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env);
 | +	     &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env);
 | ||||||
|  	if (problem) |  	if (problem) | ||||||
|  		goto out; |  		goto out; | ||||||
|   |   | ||||||
| @@ -172,21 +174,20 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
 | @@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, c
 | ||||||
|  	if (problem) |  | ||||||
|  		goto out; |  | ||||||
|   |  | ||||||
| -	problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
 |  | ||||||
| +	problem = krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
 |  | ||||||
|  				 &creds); |  | ||||||
|  	if (problem) |  | ||||||
|  		goto out; |  		goto out; | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
| @ -57,7 +70,7 @@ index a5a81ed2..63f877f2 100644 | |||||||
|  		do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); |  		do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
| @@ -222,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
 | @@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, c
 | ||||||
|  void |  void | ||||||
|  krb5_cleanup_proc(Authctxt *authctxt) |  krb5_cleanup_proc(Authctxt *authctxt) | ||||||
|  { |  { | ||||||
| @ -113,7 +126,7 @@ index a5a81ed2..63f877f2 100644 | |||||||
|  	if (authctxt->krb5_user) { |  	if (authctxt->krb5_user) { | ||||||
|  		krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); |  		krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); | ||||||
|  		authctxt->krb5_user = NULL; |  		authctxt->krb5_user = NULL; | ||||||
| @@ -237,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt)
 | @@ -238,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt)
 | ||||||
|  	} |  	} | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @ -151,7 +164,7 @@ index a5a81ed2..63f877f2 100644 | |||||||
| +ssh_krb5_expand_template(char **result, const char *template) {
 | +ssh_krb5_expand_template(char **result, const char *template) {
 | ||||||
| +	char *p_n, *p_o, *r, *tmp_template;
 | +	char *p_n, *p_o, *r, *tmp_template;
 | ||||||
| +
 | +
 | ||||||
| +	debug3("%s: called, template = %s", __func__, template);
 | +	debug3_f("called, template = %s", template);
 | ||||||
| +	if (template == NULL)
 | +	if (template == NULL)
 | ||||||
| +		return -1;
 | +		return -1;
 | ||||||
| +
 | +
 | ||||||
| @ -179,7 +192,7 @@ index a5a81ed2..63f877f2 100644 | |||||||
| +		} else {
 | +		} else {
 | ||||||
| +			p_o = strchr(p_n, '}') + 1;
 | +			p_o = strchr(p_n, '}') + 1;
 | ||||||
| +			*p_o = '\0';
 | +			*p_o = '\0';
 | ||||||
| +			debug("%s: unsupported token %s in %s", __func__, p_n, template);
 | +			debug_f("unsupported token %s in %s", p_n, template);
 | ||||||
| +			/* unknown token, fallback to the default */
 | +			/* unknown token, fallback to the default */
 | ||||||
| +			goto cleanup;
 | +			goto cleanup;
 | ||||||
| +		}
 | +		}
 | ||||||
| @ -198,16 +211,13 @@ index a5a81ed2..63f877f2 100644 | |||||||
| +	return -1;
 | +	return -1;
 | ||||||
| +}
 | +}
 | ||||||
| +
 | +
 | ||||||
|  krb5_error_code | +krb5_error_code
 | ||||||
| -ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
 |  | ||||||
| -	int tmpfd, ret, oerrno;
 |  | ||||||
| -	char ccname[40];
 |  | ||||||
| +ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
 | +ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
 | ||||||
| +	profile_t p;
 | +	profile_t p;
 | ||||||
| +	int ret = 0;
 | +	int ret = 0;
 | ||||||
| +	char *value = NULL;
 | +	char *value = NULL;
 | ||||||
| +
 | +
 | ||||||
| +	debug3("%s: called", __func__);
 | +	debug3_f("called");
 | ||||||
| +	ret = krb5_get_profile(ctx, &p);
 | +	ret = krb5_get_profile(ctx, &p);
 | ||||||
| +	if (ret)
 | +	if (ret)
 | ||||||
| +		return ret;
 | +		return ret;
 | ||||||
| @ -218,11 +228,14 @@ index a5a81ed2..63f877f2 100644 | |||||||
| +
 | +
 | ||||||
| +	ret = ssh_krb5_expand_template(ccname, value);
 | +	ret = ssh_krb5_expand_template(ccname, value);
 | ||||||
| +
 | +
 | ||||||
| +	debug3("%s: returning with ccname = %s", __func__, *ccname);
 | +	debug3_f("returning with ccname = %s", *ccname);
 | ||||||
| +	return ret;
 | +	return ret;
 | ||||||
| +}
 | +}
 | ||||||
| +
 | +
 | ||||||
| +krb5_error_code
 |  krb5_error_code | ||||||
|  | -ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
 | ||||||
|  | -	int tmpfd, ret, oerrno;
 | ||||||
|  | -	char ccname[40];
 | ||||||
| +ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) {
 | +ssh_krb5_cc_new_unique(krb5_context ctx, krb5_ccache *ccache, int *need_environment) {
 | ||||||
| +	int tmpfd, ret, oerrno, type_len;
 | +	int tmpfd, ret, oerrno, type_len;
 | ||||||
| +	char *ccname = NULL;
 | +	char *ccname = NULL;
 | ||||||
| @ -242,7 +255,7 @@ index a5a81ed2..63f877f2 100644 | |||||||
| -		logit("mkstemp(): %.100s", strerror(oerrno));
 | -		logit("mkstemp(): %.100s", strerror(oerrno));
 | ||||||
| -		return oerrno;
 | -		return oerrno;
 | ||||||
| -	}
 | -	}
 | ||||||
| +	debug3("%s: called", __func__);
 | +	debug3_f("called");
 | ||||||
| +	if (need_environment)
 | +	if (need_environment)
 | ||||||
| +		*need_environment = 0;
 | +		*need_environment = 0;
 | ||||||
| +	ret = ssh_krb5_get_cctemplate(ctx, &ccname);
 | +	ret = ssh_krb5_get_cctemplate(ctx, &ccname);
 | ||||||
| @ -283,7 +296,7 @@ index a5a81ed2..63f877f2 100644 | |||||||
| -	close(tmpfd);
 | -	close(tmpfd);
 | ||||||
|   |   | ||||||
| -	return (krb5_cc_resolve(ctx, ccname, ccache));
 | -	return (krb5_cc_resolve(ctx, ccname, ccache));
 | ||||||
| +	debug3("%s: setting default ccname to %s", __func__, ccname);
 | +	debug3_f("setting default ccname to %s", ccname);
 | ||||||
| +	/* set the default with already expanded user IDs */
 | +	/* set the default with already expanded user IDs */
 | ||||||
| +	ret = krb5_cc_set_default_name(ctx, ccname);
 | +	ret = krb5_cc_set_default_name(ctx, ccname);
 | ||||||
| +	if (ret)
 | +	if (ret)
 | ||||||
| @ -304,13 +317,13 @@ index a5a81ed2..63f877f2 100644 | |||||||
| +	 * a primary cache for this collection, if it supports that (non-FILE)
 | +	 * a primary cache for this collection, if it supports that (non-FILE)
 | ||||||
| +	 */
 | +	 */
 | ||||||
| +	if (krb5_cc_support_switch(ctx, type)) {
 | +	if (krb5_cc_support_switch(ctx, type)) {
 | ||||||
| +		debug3("%s: calling cc_new_unique(%s)", __func__, ccname);
 | +		debug3_f("calling cc_new_unique(%s)", ccname);
 | ||||||
| +		ret = krb5_cc_new_unique(ctx, type, NULL, ccache);
 | +		ret = krb5_cc_new_unique(ctx, type, NULL, ccache);
 | ||||||
| +		free(type);
 | +		free(type);
 | ||||||
| +		if (ret)
 | +		if (ret)
 | ||||||
| +			return ret;
 | +			return ret;
 | ||||||
| +
 | +
 | ||||||
| +		debug3("%s: calling cc_switch()", __func__);
 | +		debug3_f("calling cc_switch()");
 | ||||||
| +		return krb5_cc_switch(ctx, *ccache);
 | +		return krb5_cc_switch(ctx, *ccache);
 | ||||||
| +	} else {
 | +	} else {
 | ||||||
| +		/* Otherwise, we can not create a unique ccname here (either
 | +		/* Otherwise, we can not create a unique ccname here (either
 | ||||||
| @ -318,35 +331,47 @@ index a5a81ed2..63f877f2 100644 | |||||||
| +		 * collections
 | +		 * collections
 | ||||||
| +		 */
 | +		 */
 | ||||||
| +		free(type);
 | +		free(type);
 | ||||||
| +		debug3("%s: calling cc_resolve(%s)", __func__, ccname);
 | +		debug3_f("calling cc_resolve(%s)", ccname);
 | ||||||
| +		return (krb5_cc_resolve(ctx, ccname, ccache));
 | +		return (krb5_cc_resolve(ctx, ccname, ccache));
 | ||||||
| +	}
 | +	}
 | ||||||
|  } |  } | ||||||
|  #endif /* !HEIMDAL */ |  #endif /* !HEIMDAL */ | ||||||
|  #endif /* KRB5 */ |  #endif /* KRB5 */ | ||||||
| diff --git a/auth.h b/auth.h
 | diff -up openssh-8.6p1/gss-serv.c.ccache_name openssh-8.6p1/gss-serv.c
 | ||||||
| index 29491df9..fdab5040 100644
 | --- openssh-8.6p1/gss-serv.c.ccache_name	2021-05-06 11:15:36.374143558 +0200
 | ||||||
| --- a/auth.h
 | +++ openssh-8.6p1/gss-serv.c	2021-05-06 11:15:36.387143654 +0200
 | ||||||
| +++ b/auth.h
 | @@ -413,13 +413,15 @@ ssh_gssapi_cleanup_creds(void)
 | ||||||
| @@ -82,6 +82,7 @@ struct Authctxt {
 |  } | ||||||
|  	krb5_principal	 krb5_user; |  | ||||||
|  	char		*krb5_ticket_file; |  | ||||||
|  	char		*krb5_ccname; |  | ||||||
| +	int		 krb5_set_env;
 |  | ||||||
|  #endif |  | ||||||
|  	struct sshbuf	*loginmsg; |  | ||||||
|   |   | ||||||
| @@ -243,6 +244,6 @@ int	 sys_auth_passwd(struct ssh *, const char *);
 |  /* As user */ | ||||||
|  | -void
 | ||||||
|  | +int
 | ||||||
|  |  ssh_gssapi_storecreds(void) | ||||||
|  |  { | ||||||
|  |  	if (gssapi_client.mech && gssapi_client.mech->storecreds) { | ||||||
|  | -		(*gssapi_client.mech->storecreds)(&gssapi_client);
 | ||||||
|  | +		return (*gssapi_client.mech->storecreds)(&gssapi_client);
 | ||||||
|  |  	} else | ||||||
|  |  		debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); | ||||||
|  | +
 | ||||||
|  | +	return 0;
 | ||||||
|  |  } | ||||||
|   |   | ||||||
|  #if defined(KRB5) && !defined(HEIMDAL) |  /* This allows GSSAPI methods to do things to the child's environment based | ||||||
|  #include <krb5.h> | @@ -499,9 +501,7 @@ ssh_gssapi_rekey_creds(void) {
 | ||||||
| -krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
 |  	char *envstr; | ||||||
| +krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *);
 |  | ||||||
|  #endif |  #endif | ||||||
|  #endif |   | ||||||
| diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c
 | -	if (gssapi_client.store.filename == NULL &&
 | ||||||
| --- openssh-7.9p1/gss-serv-krb5.c.ccache_name	2019-03-01 15:17:42.708611802 +0100
 | -	    gssapi_client.store.envval == NULL &&
 | ||||||
| +++ openssh-7.9p1/gss-serv-krb5.c	2019-03-01 15:17:42.713611844 +0100
 | -	    gssapi_client.store.envvar == NULL)
 | ||||||
|  | +	if (gssapi_client.store.envval == NULL)
 | ||||||
|  |  		return; | ||||||
|  |   | ||||||
|  |  	ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); | ||||||
|  | diff -up openssh-8.6p1/gss-serv-krb5.c.ccache_name openssh-8.6p1/gss-serv-krb5.c
 | ||||||
|  | --- openssh-8.6p1/gss-serv-krb5.c.ccache_name	2021-05-06 11:15:36.384143632 +0200
 | ||||||
|  | +++ openssh-8.6p1/gss-serv-krb5.c	2021-05-06 11:15:36.387143654 +0200
 | ||||||
| @@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
 | @@ -267,7 +267,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
 | ||||||
|  /* This writes out any forwarded credentials from the structure populated |  /* This writes out any forwarded credentials from the structure populated | ||||||
|   * during userauth. Called after we have setuid to the user */ |   * during userauth. Called after we have setuid to the user */ | ||||||
| @ -449,7 +474,7 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c | |||||||
|  		do_pam_putenv(client->store.envvar, client->store.envval); |  		do_pam_putenv(client->store.envvar, client->store.envval); | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
| @@ -361,7 +355,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | @@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||||
|   |   | ||||||
|  	client->store.data = krb_context; |  	client->store.data = krb_context; | ||||||
|   |   | ||||||
| @ -458,43 +483,10 @@ diff -up openssh-7.9p1/gss-serv-krb5.c.ccache_name openssh-7.9p1/gss-serv-krb5.c | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  int |  int | ||||||
| diff --git a/gss-serv.c b/gss-serv.c
 | diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c
 | ||||||
| index 6cae720e..16e55cbc 100644
 | --- openssh-8.6p1/servconf.c.ccache_name	2021-05-06 11:15:36.377143580 +0200
 | ||||||
| --- a/gss-serv.c
 | +++ openssh-8.6p1/servconf.c	2021-05-06 11:15:36.388143662 +0200
 | ||||||
| +++ b/gss-serv.c
 | @@ -136,6 +136,7 @@ initialize_server_options(ServerOptions
 | ||||||
| @@ -320,13 +320,15 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* As user */ |  | ||||||
| -void
 |  | ||||||
| +int
 |  | ||||||
|  ssh_gssapi_storecreds(void) |  | ||||||
|  { |  | ||||||
|  	if (gssapi_client.mech && gssapi_client.mech->storecreds) { |  | ||||||
| -		(*gssapi_client.mech->storecreds)(&gssapi_client);
 |  | ||||||
| +		return (*gssapi_client.mech->storecreds)(&gssapi_client);
 |  | ||||||
|  	} else |  | ||||||
|  		debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); |  | ||||||
| +
 |  | ||||||
| +	return 0;
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* This allows GSSAPI methods to do things to the childs environment based |  | ||||||
| @@ -498,9 +500,7 @@ ssh_gssapi_rekey_creds() {
 |  | ||||||
|  	char *envstr; |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| -	if (gssapi_client.store.filename == NULL &&
 |  | ||||||
| -	    gssapi_client.store.envval == NULL &&
 |  | ||||||
| -	    gssapi_client.store.envvar == NULL)
 |  | ||||||
| +	if (gssapi_client.store.envval == NULL)
 |  | ||||||
|  		return; |  | ||||||
|   |  | ||||||
|  	ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); |  | ||||||
| diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c
 |  | ||||||
| --- openssh-7.9p1/servconf.c.ccache_name	2019-03-01 15:17:42.704611768 +0100
 |  | ||||||
| +++ openssh-7.9p1/servconf.c	2019-03-01 15:17:42.713611844 +0100
 |  | ||||||
| @@ -123,6 +123,7 @@ initialize_server_options(ServerOptions
 |  | ||||||
|  	options->kerberos_or_local_passwd = -1; |  	options->kerberos_or_local_passwd = -1; | ||||||
|  	options->kerberos_ticket_cleanup = -1; |  	options->kerberos_ticket_cleanup = -1; | ||||||
|  	options->kerberos_get_afs_token = -1; |  	options->kerberos_get_afs_token = -1; | ||||||
| @ -502,7 +494,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c | |||||||
|  	options->gss_authentication=-1; |  	options->gss_authentication=-1; | ||||||
|  	options->gss_keyex = -1; |  	options->gss_keyex = -1; | ||||||
|  	options->gss_cleanup_creds = -1; |  	options->gss_cleanup_creds = -1; | ||||||
| @@ -315,6 +316,8 @@ fill_default_server_options(ServerOptions *options)
 | @@ -359,6 +360,8 @@ fill_default_server_options(ServerOption
 | ||||||
|  		options->kerberos_ticket_cleanup = 1; |  		options->kerberos_ticket_cleanup = 1; | ||||||
|  	if (options->kerberos_get_afs_token == -1) |  	if (options->kerberos_get_afs_token == -1) | ||||||
|  		options->kerberos_get_afs_token = 0; |  		options->kerberos_get_afs_token = 0; | ||||||
| @ -511,9 +503,9 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c | |||||||
|  	if (options->gss_authentication == -1) |  	if (options->gss_authentication == -1) | ||||||
|  		options->gss_authentication = 0; |  		options->gss_authentication = 0; | ||||||
|  	if (options->gss_keyex == -1) |  	if (options->gss_keyex == -1) | ||||||
| @@ -447,7 +450,8 @@ typedef enum {
 | @@ -506,7 +509,8 @@ typedef enum {
 | ||||||
|  	sPermitRootLogin, sLogFacility, sLogLevel, | 	sPort, sHostKeyFile, sLoginGraceTime, | ||||||
|  	sRhostsRSAAuthentication, sRSAAuthentication, | 	sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, | ||||||
| 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, | 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, | ||||||
| -	sKerberosGetAFSToken, sChallengeResponseAuthentication,
 | -	sKerberosGetAFSToken, sChallengeResponseAuthentication,
 | ||||||
| +	sKerberosGetAFSToken, sKerberosUniqueCCache,
 | +	sKerberosGetAFSToken, sKerberosUniqueCCache,
 | ||||||
| @ -521,7 +513,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c | |||||||
| 	sPasswordAuthentication, sKbdInteractiveAuthentication, | 	sPasswordAuthentication, sKbdInteractiveAuthentication, | ||||||
| 	sListenAddress, sAddressFamily, | 	sListenAddress, sAddressFamily, | ||||||
| 	sPrintMotd, sPrintLastLog, sIgnoreRhosts, | 	sPrintMotd, sPrintLastLog, sIgnoreRhosts, | ||||||
| @@ -526,11 +530,13 @@ static struct {
 | @@ -593,11 +597,13 @@ static struct {
 | ||||||
|  #else |  #else | ||||||
|  	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, |  	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, | ||||||
|  #endif |  #endif | ||||||
| @ -535,7 +527,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c | |||||||
|  #endif |  #endif | ||||||
|  	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, |  	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, | ||||||
|  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, |  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, | ||||||
| @@ -1437,6 +1443,10 @@ process_server_config_line(ServerOptions *options, char *line,
 | @@ -1573,6 +1579,10 @@ process_server_config_line_depth(ServerO
 | ||||||
|  		intptr = &options->kerberos_get_afs_token; |  		intptr = &options->kerberos_get_afs_token; | ||||||
|  		goto parse_flag; |  		goto parse_flag; | ||||||
|   |   | ||||||
| @ -546,7 +538,7 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c | |||||||
|  	case sGssAuthentication: |  	case sGssAuthentication: | ||||||
|  		intptr = &options->gss_authentication; |  		intptr = &options->gss_authentication; | ||||||
|  		goto parse_flag; |  		goto parse_flag; | ||||||
| @@ -2507,6 +2517,7 @@ dump_config(ServerOptions *o)
 | @@ -2891,6 +2901,7 @@ dump_config(ServerOptions *o)
 | ||||||
|  # ifdef USE_AFS |  # ifdef USE_AFS | ||||||
|  	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); |  	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); | ||||||
|  # endif |  # endif | ||||||
| @ -554,11 +546,10 @@ diff -up openssh-7.9p1/servconf.c.ccache_name openssh-7.9p1/servconf.c | |||||||
|  #endif |  #endif | ||||||
|  #ifdef GSSAPI |  #ifdef GSSAPI | ||||||
|  	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); |  	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); | ||||||
| diff --git a/servconf.h b/servconf.h
 | diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h
 | ||||||
| index db8362c6..4fa42d64 100644
 | --- openssh-8.6p1/servconf.h.ccache_name	2021-05-06 11:15:36.377143580 +0200
 | ||||||
| --- a/servconf.h
 | +++ openssh-8.6p1/servconf.h	2021-05-06 11:15:36.397143729 +0200
 | ||||||
| +++ b/servconf.h
 | @@ -140,6 +140,8 @@ typedef struct {
 | ||||||
| @@ -123,6 +123,8 @@ typedef struct {
 |  | ||||||
|  						 * file on logout. */ |  						 * file on logout. */ | ||||||
|  	int     kerberos_get_afs_token;		/* If true, try to get AFS token if |  	int     kerberos_get_afs_token;		/* If true, try to get AFS token if | ||||||
|  						 * authenticated with Kerberos. */ |  						 * authenticated with Kerberos. */ | ||||||
| @ -567,13 +558,12 @@ index db8362c6..4fa42d64 100644 | |||||||
|  	int     gss_authentication;	/* If true, permit GSSAPI authentication */ |  	int     gss_authentication;	/* If true, permit GSSAPI authentication */ | ||||||
|  	int     gss_keyex;		/* If true, permit GSSAPI key exchange */ |  	int     gss_keyex;		/* If true, permit GSSAPI key exchange */ | ||||||
|  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */ |  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */ | ||||||
| diff --git a/session.c b/session.c
 | diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c
 | ||||||
| index 85df6a27..480a5ead 100644
 | --- openssh-8.6p1/session.c.ccache_name	2021-05-06 11:15:36.384143632 +0200
 | ||||||
| --- a/session.c
 | +++ openssh-8.6p1/session.c	2021-05-06 11:15:36.397143729 +0200
 | ||||||
| +++ b/session.c
 | @@ -1038,7 +1038,8 @@ do_setup_env(struct ssh *ssh, Session *s
 | ||||||
| @@ -1033,7 +1033,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
 |  | ||||||
|  	/* Allow any GSSAPI methods that we've used to alter |  	/* Allow any GSSAPI methods that we've used to alter | ||||||
|  	 * the childs environment as they see fit |  	 * the child's environment as they see fit | ||||||
|  	 */ |  	 */ | ||||||
| -	ssh_gssapi_do_child(&env, &envsize);
 | -	ssh_gssapi_do_child(&env, &envsize);
 | ||||||
| +	if (s->authctxt->krb5_set_env)
 | +	if (s->authctxt->krb5_set_env)
 | ||||||
| @ -581,7 +571,7 @@ index 85df6a27..480a5ead 100644 | |||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
|  	/* Set basic environment. */ |  	/* Set basic environment. */ | ||||||
| @@ -1105,7 +1106,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
 | @@ -1114,7 +1115,7 @@ do_setup_env(struct ssh *ssh, Session *s
 | ||||||
|  	} |  	} | ||||||
|  #endif |  #endif | ||||||
|  #ifdef KRB5 |  #ifdef KRB5 | ||||||
| @ -590,33 +580,10 @@ index 85df6a27..480a5ead 100644 | |||||||
|  		child_set_env(&env, &envsize, "KRB5CCNAME", |  		child_set_env(&env, &envsize, "KRB5CCNAME", | ||||||
|  		    s->authctxt->krb5_ccname); |  		    s->authctxt->krb5_ccname); | ||||||
|  #endif |  #endif | ||||||
| diff --git a/ssh-gss.h b/ssh-gss.h
 | diff -up openssh-8.6p1/sshd.c.ccache_name openssh-8.6p1/sshd.c
 | ||||||
| index 6593e422..245178af 100644
 | --- openssh-8.6p1/sshd.c.ccache_name	2021-05-06 11:15:36.380143602 +0200
 | ||||||
| --- a/ssh-gss.h
 | +++ openssh-8.6p1/sshd.c	2021-05-06 11:15:36.398143736 +0200
 | ||||||
| +++ b/ssh-gss.h
 | @@ -2284,7 +2284,7 @@ main(int ac, char **av)
 | ||||||
| @@ -83,7 +82,7 @@ typedef struct ssh_gssapi_mech_struct {
 |  | ||||||
|  	int (*dochild) (ssh_gssapi_client *); |  | ||||||
|  	int (*userok) (ssh_gssapi_client *, char *); |  | ||||||
|  	int (*localname) (ssh_gssapi_client *, char **); |  | ||||||
| -	void (*storecreds) (ssh_gssapi_client *);
 |  | ||||||
| +	int (*storecreds) (ssh_gssapi_client *);
 |  | ||||||
|  	int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); |  | ||||||
|  } ssh_gssapi_mech; |  | ||||||
|   |  | ||||||
| @@ -127,7 +126,7 @@ int ssh_gssapi_userok(char *name);
 |  | ||||||
|  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); |  | ||||||
| -void ssh_gssapi_storecreds(void);
 |  | ||||||
| +int ssh_gssapi_storecreds(void);
 |  | ||||||
|  const char *ssh_gssapi_displayname(void); |  | ||||||
|   |  | ||||||
|  char *ssh_gssapi_server_mechanisms(void); |  | ||||||
| diff --git a/sshd.c b/sshd.c
 |  | ||||||
| index edbe815c..89514e8a 100644
 |  | ||||||
| --- a/sshd.c
 |  | ||||||
| +++ b/sshd.c
 |  | ||||||
| @@ -2162,7 +2162,7 @@ main(int ac, char **av)
 |  | ||||||
|  #ifdef GSSAPI |  #ifdef GSSAPI | ||||||
|  	if (options.gss_authentication) { |  	if (options.gss_authentication) { | ||||||
|  		temporarily_use_uid(authctxt->pw); |  		temporarily_use_uid(authctxt->pw); | ||||||
| @ -625,11 +592,10 @@ index edbe815c..89514e8a 100644 | |||||||
|  		restore_uid(); |  		restore_uid(); | ||||||
|  	} |  	} | ||||||
|  #endif |  #endif | ||||||
| diff --git a/sshd_config.5 b/sshd_config.5
 | diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5
 | ||||||
| index c0683d4a..2349f477 100644
 | --- openssh-8.6p1/sshd_config.5.ccache_name	2021-05-06 11:15:36.380143602 +0200
 | ||||||
| --- a/sshd_config.5
 | +++ openssh-8.6p1/sshd_config.5	2021-05-06 11:15:36.398143736 +0200
 | ||||||
| +++ b/sshd_config.5
 | @@ -939,6 +939,14 @@ Specifies whether to automatically destr
 | ||||||
| @@ -860,6 +860,14 @@ Specifies whether to automatically destroy the user's ticket cache
 |  | ||||||
|  file on logout. |  file on logout. | ||||||
|  The default is |  The default is | ||||||
|  .Cm yes . |  .Cm yes . | ||||||
| @ -644,3 +610,24 @@ index c0683d4a..2349f477 100644 | |||||||
|  .It Cm KexAlgorithms |  .It Cm KexAlgorithms | ||||||
|  Specifies the available KEX (Key Exchange) algorithms. |  Specifies the available KEX (Key Exchange) algorithms. | ||||||
|  Multiple algorithms must be comma-separated. |  Multiple algorithms must be comma-separated. | ||||||
|  | diff -up openssh-8.6p1/ssh-gss.h.ccache_name openssh-8.6p1/ssh-gss.h
 | ||||||
|  | --- openssh-8.6p1/ssh-gss.h.ccache_name	2021-05-06 11:15:36.384143632 +0200
 | ||||||
|  | +++ openssh-8.6p1/ssh-gss.h	2021-05-06 11:15:36.398143736 +0200
 | ||||||
|  | @@ -114,7 +114,7 @@ typedef struct ssh_gssapi_mech_struct {
 | ||||||
|  |  	int (*dochild) (ssh_gssapi_client *); | ||||||
|  |  	int (*userok) (ssh_gssapi_client *, char *); | ||||||
|  |  	int (*localname) (ssh_gssapi_client *, char **); | ||||||
|  | -	void (*storecreds) (ssh_gssapi_client *);
 | ||||||
|  | +	int (*storecreds) (ssh_gssapi_client *);
 | ||||||
|  |  	int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *); | ||||||
|  |  } ssh_gssapi_mech; | ||||||
|  |   | ||||||
|  | @@ -175,7 +175,7 @@ int ssh_gssapi_userok(char *name, struct
 | ||||||
|  |  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); | ||||||
|  | -void ssh_gssapi_storecreds(void);
 | ||||||
|  | +int ssh_gssapi_storecreds(void);
 | ||||||
|  |  const char *ssh_gssapi_displayname(void); | ||||||
|  |   | ||||||
|  |  char *ssh_gssapi_server_mechanisms(void); | ||||||
|  | |||||||
| @ -1,19 +1,21 @@ | |||||||
| diff -up openssh-7.7p1/ssh_config.redhat openssh-7.7p1/ssh_config
 | diff -up openssh/ssh_config.redhat openssh/ssh_config
 | ||||||
| --- openssh-7.7p1/ssh_config.redhat	2018-04-02 07:38:28.000000000 +0200
 | --- openssh/ssh_config.redhat	2020-02-11 23:28:35.000000000 +0100
 | ||||||
| +++ openssh-7.7p1/ssh_config	2018-07-03 10:44:06.522245125 +0200
 | +++ openssh/ssh_config	2020-02-13 18:13:39.180641839 +0100
 | ||||||
| @@ -44,3 +44,8 @@
 | @@ -43,3 +43,10 @@
 | ||||||
|  #   VisualHostKey no |  | ||||||
|  #   ProxyCommand ssh -q -W %h:%p gateway.example.com |  #   ProxyCommand ssh -q -W %h:%p gateway.example.com | ||||||
|  #   RekeyLimit 1G 1h |  #   RekeyLimit 1G 1h | ||||||
|  |  #   UserKnownHostsFile ~/.ssh/known_hosts.d/%k | ||||||
| +#
 | +#
 | ||||||
| +# This system is following system-wide crypto policy.
 | +# This system is following system-wide crypto policy.
 | ||||||
| +# To modify the system-wide ssh configuration, create a  *.conf  file under
 | +# To modify the crypto properties (Ciphers, MACs, ...), create a  *.conf
 | ||||||
| +#  /etc/ssh/ssh_config.d/  which will be automatically included below
 | +#  file under  /etc/ssh/ssh_config.d/  which will be automatically
 | ||||||
|  | +# included below. For more information, see manual page for
 | ||||||
|  | +#  update-crypto-policies(8)  and  ssh_config(5).
 | ||||||
| +Include /etc/ssh/ssh_config.d/*.conf
 | +Include /etc/ssh/ssh_config.d/*.conf
 | ||||||
| diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat
 | diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat
 | ||||||
| --- openssh-7.7p1/ssh_config_redhat.redhat	2018-07-03 10:44:06.522245125 +0200
 | --- openssh/ssh_config_redhat.redhat	2020-02-13 18:13:39.180641839 +0100
 | ||||||
| +++ openssh-7.7p1/ssh_config_redhat	2018-07-03 10:44:06.522245125 +0200
 | +++ openssh/ssh_config_redhat	2020-02-13 18:13:39.180641839 +0100
 | ||||||
| @@ -0,0 +1,21 @@
 | @@ -0,0 +1,15 @@
 | ||||||
| +# The options here are in the "Match final block" to be applied as the last
 | +# The options here are in the "Match final block" to be applied as the last
 | ||||||
| +# options and could be potentially overwritten by the user configuration
 | +# options and could be potentially overwritten by the user configuration
 | ||||||
| +Match final all
 | +Match final all
 | ||||||
| @ -27,19 +29,12 @@ diff -up openssh-7.7p1/ssh_config_redhat.redhat openssh-7.7p1/ssh_config_redhat | |||||||
| +# mode correctly we set this to yes.
 | +# mode correctly we set this to yes.
 | ||||||
| +	ForwardX11Trusted 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
 |  | ||||||
| +
 |  | ||||||
| +# Uncomment this if you want to use .local domain
 | +# Uncomment this if you want to use .local domain
 | ||||||
| +# Host *.local
 | +# Host *.local
 | ||||||
| +#   CheckHostIP no
 | diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0
 | ||||||
| diff -up openssh-7.7p1/sshd_config.0.redhat openssh-7.7p1/sshd_config.0
 | --- openssh/sshd_config.0.redhat	2020-02-12 14:30:04.000000000 +0100
 | ||||||
| --- openssh-7.7p1/sshd_config.0.redhat	2018-04-02 07:39:27.000000000 +0200
 | +++ openssh/sshd_config.0	2020-02-13 18:13:39.181641855 +0100
 | ||||||
| +++ openssh-7.7p1/sshd_config.0	2018-07-03 10:44:06.523245133 +0200
 | @@ -970,9 +970,9 @@ DESCRIPTION
 | ||||||
| @@ -872,9 +872,9 @@ DESCRIPTION
 |  | ||||||
|   |   | ||||||
|       SyslogFacility |       SyslogFacility | ||||||
|               Gives the facility code that is used when logging messages from |               Gives the facility code that is used when logging messages from | ||||||
| @ -52,10 +47,10 @@ diff -up openssh-7.7p1/sshd_config.0.redhat openssh-7.7p1/sshd_config.0 | |||||||
|   |   | ||||||
|       TCPKeepAlive |       TCPKeepAlive | ||||||
|               Specifies whether the system should send TCP keepalive messages |               Specifies whether the system should send TCP keepalive messages | ||||||
| diff -up openssh-7.7p1/sshd_config.5.redhat openssh-7.7p1/sshd_config.5
 | diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5
 | ||||||
| --- openssh-7.7p1/sshd_config.5.redhat	2018-04-02 07:38:28.000000000 +0200
 | --- openssh/sshd_config.5.redhat	2020-02-11 23:28:35.000000000 +0100
 | ||||||
| +++ openssh-7.7p1/sshd_config.5	2018-07-03 10:44:06.523245133 +0200
 | +++ openssh/sshd_config.5	2020-02-13 18:13:39.181641855 +0100
 | ||||||
| @@ -1461,7 +1461,7 @@ By default no subsystems are defined.
 | @@ -1614,7 +1614,7 @@ By default no subsystems are defined.
 | ||||||
|  .It Cm SyslogFacility |  .It Cm SyslogFacility | ||||||
|  Gives the facility code that is used when logging messages from |  Gives the facility code that is used when logging messages from | ||||||
|  .Xr sshd 8 . |  .Xr sshd 8 . | ||||||
| @ -64,13 +59,17 @@ diff -up openssh-7.7p1/sshd_config.5.redhat openssh-7.7p1/sshd_config.5 | |||||||
|  LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. |  LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. | ||||||
|  The default is AUTH. |  The default is AUTH. | ||||||
|  .It Cm TCPKeepAlive |  .It Cm TCPKeepAlive | ||||||
| diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config
 | diff -up openssh/sshd_config.redhat openssh/sshd_config
 | ||||||
| --- openssh-7.7p1/sshd_config.redhat	2018-04-02 07:38:28.000000000 +0200
 | --- openssh/sshd_config.redhat	2020-02-11 23:28:35.000000000 +0100
 | ||||||
| +++ openssh-7.7p1/sshd_config	2018-07-03 10:45:16.950782466 +0200
 | +++ openssh/sshd_config	2020-02-13 18:20:16.349913681 +0100
 | ||||||
| @@ -10,20 +10,31 @@
 | @@ -10,6 +10,14 @@
 | ||||||
|  # possible, but leave them commented.  Uncommented options override the |  # possible, but leave them commented.  Uncommented options override the | ||||||
|  # default value. |  # default value. | ||||||
| 
 | 
 | ||||||
|  | +# To modify the system-wide sshd configuration, create a  *.conf  file under
 | ||||||
|  | +#  /etc/ssh/sshd_config.d/  which will be automatically included below
 | ||||||
|  | +Include /etc/ssh/sshd_config.d/*.conf
 | ||||||
|  | +
 | ||||||
| +# If you want to change the port on a SELinux system, you have to tell
 | +# If you want to change the port on a SELinux system, you have to tell
 | ||||||
| +# SELinux about this change.
 | +# SELinux about this change.
 | ||||||
| +# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
 | +# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
 | ||||||
| @ -78,87 +77,29 @@ diff -up openssh-7.7p1/sshd_config.redhat openssh-7.7p1/sshd_config | |||||||
|  #Port 22 |  #Port 22 | ||||||
|  #AddressFamily any |  #AddressFamily any | ||||||
|  #ListenAddress 0.0.0.0 |  #ListenAddress 0.0.0.0 | ||||||
|  #ListenAddress :: | diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat
 | ||||||
|   | --- openssh/sshd_config_redhat.redhat	2020-02-13 18:14:02.268006439 +0100
 | ||||||
| -#HostKey /etc/ssh/ssh_host_rsa_key
 | +++ openssh/sshd_config_redhat	2020-02-13 18:19:20.765035947 +0100
 | ||||||
| -#HostKey /etc/ssh/ssh_host_ecdsa_key
 | @@ -0,0 +1,22 @@
 | ||||||
| -#HostKey /etc/ssh/ssh_host_ed25519_key
 |  | ||||||
| +HostKey /etc/ssh/ssh_host_rsa_key
 |  | ||||||
| +HostKey /etc/ssh/ssh_host_ecdsa_key
 |  | ||||||
| +HostKey /etc/ssh/ssh_host_ed25519_key
 |  | ||||||
|   |  | ||||||
|  # Ciphers and keying |  | ||||||
|  #RekeyLimit default none |  | ||||||
|   |  | ||||||
| +# This system is following system-wide crypto policy. The changes to
 | +# This system is following system-wide crypto policy. The changes to
 | ||||||
| +# crypto properties (Ciphers, MACs, ...) will not have any effect here.
 | +# crypto properties (Ciphers, MACs, ...) will not have any effect in
 | ||||||
| +# They will be overridden by command-line options passed to the server
 | +# this or following included files. To override some configuration option,
 | ||||||
| +# on command line.
 | +# write it before this block or include it before this file.
 | ||||||
| +# Please, check manual pages for update-crypto-policies(8) and sshd_config(5).
 | +# Please, see manual pages for update-crypto-policies(8) and sshd_config(5).
 | ||||||
|  | +Include /etc/crypto-policies/back-ends/opensshserver.config
 | ||||||
| +
 | +
 | ||||||
|  # Logging |  | ||||||
|  #SyslogFacility AUTH |  | ||||||
| +SyslogFacility AUTHPRIV
 | +SyslogFacility AUTHPRIV
 | ||||||
|  #LogLevel INFO | +
 | ||||||
|   |  | ||||||
|  # Authentication: |  | ||||||
| @@ -56,9 +70,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
 | +ChallengeResponseAuthentication no
 | ||||||
|   | +
 | ||||||
|  # Kerberos options |  | ||||||
|  #KerberosAuthentication no |  | ||||||
| @@ -67,8 +83,8 @@ AuthorizedKeysFile	.ssh/authorized_keys
 |  | ||||||
|  #KerberosGetAFSToken no |  | ||||||
|   |  | ||||||
|  # GSSAPI options |  | ||||||
| -#GSSAPIAuthentication no
 |  | ||||||
| -#GSSAPICleanupCredentials yes
 |  | ||||||
| +GSSAPIAuthentication yes
 | +GSSAPIAuthentication yes
 | ||||||
| +GSSAPICleanupCredentials no
 | +GSSAPICleanupCredentials no
 | ||||||
|   | +
 | ||||||
|  # Set this to 'yes' to enable PAM authentication, account processing, |  | ||||||
|  # and session processing. If this is enabled, PAM authentication will |  | ||||||
| @@ -79,16 +95,20 @@ 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
 | +UsePAM yes
 | ||||||
|   | +
 | ||||||
|  #AllowAgentForwarding yes |  | ||||||
|  #AllowTcpForwarding yes |  | ||||||
|  #GatewayPorts no |  | ||||||
| -#X11Forwarding no
 |  | ||||||
| +X11Forwarding yes
 | +X11Forwarding yes
 | ||||||
|  #X11DisplayOffset 10 |  | ||||||
|  #X11UseLocalhost yes |  | ||||||
|  #PermitTTY yes |  | ||||||
| -#PrintMotd yes
 |  | ||||||
| +
 | +
 | ||||||
| +# It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd,
 | +# It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd,
 | ||||||
| +# as it is more configurable and versatile than the built-in version.
 | +# as it is more configurable and versatile than the built-in version.
 | ||||||
| +PrintMotd no
 | +PrintMotd no
 | ||||||
| +
 | +
 | ||||||
|  #PrintLastLog yes |  | ||||||
|  #TCPKeepAlive yes |  | ||||||
|  #PermitUserEnvironment no |  | ||||||
| @@ -106,6 +126,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 |  | ||||||
|   |  | ||||||
|  | |||||||
| @ -1,26 +1,26 @@ | |||||||
| diff --git a/sshd.c b/sshd.c
 | diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c
 | ||||||
| --- a/sshd.c
 | --- openssh-8.6p1/sshd.c.log-usepam-no	2021-04-19 14:00:45.099735129 +0200
 | ||||||
| +++ b/sshd.c
 | +++ openssh-8.6p1/sshd.c	2021-04-19 14:03:21.140920974 +0200
 | ||||||
| @@ -1701,6 +1701,10 @@ main(int ac, char **av)
 | @@ -1749,6 +1749,10 @@ main(int ac, char **av)
 | ||||||
|  	parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, |  	parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, | ||||||
|  	    cfg, NULL); |  	    cfg, &includes, NULL); | ||||||
|   |   | ||||||
| +	/* 'UsePAM no' is not supported in RHEL */
 | +	/* 'UsePAM no' is not supported in RHEL */
 | ||||||
| +	if (! options.use_pam)
 | +	if (! options.use_pam)
 | ||||||
| +		logit("WARNING: 'UsePAM no' is not supported in RHEL and may cause several problems.");
 | +		logit("WARNING: 'UsePAM no' is not supported in RHEL and may cause several problems.");
 | ||||||
| +
 | +
 | ||||||
|  	/* Fill in default values for those options not explicitly set. */ |  #ifdef WITH_OPENSSL | ||||||
|  	fill_default_server_options(&options); |  	if (options.moduli_file != NULL) | ||||||
|   |  		dh_set_moduli_file(options.moduli_file); | ||||||
| diff --git a/sshd_config b/sshd_config
 | diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config
 | ||||||
| --- a/sshd_config
 | --- openssh-8.6p1/sshd_config.log-usepam-no	2021-04-19 14:00:45.098735121 +0200
 | ||||||
| +++ b/sshd_config
 | +++ openssh-8.6p1/sshd_config	2021-04-19 14:00:45.099735129 +0200
 | ||||||
| @@ -101,6 +101,8 @@ GSSAPICleanupCredentials no
 | @@ -87,6 +87,8 @@ AuthorizedKeysFile	.ssh/authorized_keys
 | ||||||
|  # If you just want the PAM account and session checks to run without |  # If you just want the PAM account and session checks to run without | ||||||
|  # PAM authentication, then enable this but set PasswordAuthentication |  # PAM authentication, then enable this but set PasswordAuthentication | ||||||
|  # and ChallengeResponseAuthentication to 'no'. |  # and KbdInteractiveAuthentication to 'no'. | ||||||
| +# WARNING: 'UsePAM no' is not supported in RHEL and may cause several
 | +# WARNING: 'UsePAM no' is not supported in RHEL and may cause several
 | ||||||
| +# problems.
 | +# problems.
 | ||||||
|  UsePAM yes |  #UsePAM no | ||||||
|   |   | ||||||
|  #AllowAgentForwarding yes |  #AllowAgentForwarding yes | ||||||
|  | |||||||
| @ -52,7 +52,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c | |||||||
|  	gss_buffer_desc mic, gssbuf; |  	gss_buffer_desc mic, gssbuf; | ||||||
|  	const char *displayname; |  	const char *displayname; | ||||||
| @@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple
 | @@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple
 | ||||||
|  		fatal("%s: sshbuf_new failed", __func__); |  		fatal_f("sshbuf_new failed"); | ||||||
|  	mic.value = p; |  	mic.value = p; | ||||||
|  	mic.length = len; |  	mic.length = len; | ||||||
| -	ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
 | -	ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
 | ||||||
| @ -63,7 +63,7 @@ diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c | |||||||
| +#endif
 | +#endif
 | ||||||
| +		micuser = authctxt->user;
 | +		micuser = authctxt->user;
 | ||||||
| +	ssh_gssapi_buildmic(b, micuser, authctxt->service,
 | +	ssh_gssapi_buildmic(b, micuser, authctxt->service,
 | ||||||
|  	    "gssapi-with-mic"); |  	    "gssapi-with-mic", ssh->kex->session_id); | ||||||
|   |   | ||||||
|  	if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) |  	if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) | ||||||
| @@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple
 | @@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple
 | ||||||
| @ -80,7 +80,7 @@ diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c | |||||||
| +++ openssh/auth2-hostbased.c	2018-08-22 11:14:56.816430924 +0200
 | +++ openssh/auth2-hostbased.c	2018-08-22 11:14:56.816430924 +0200
 | ||||||
| @@ -123,7 +123,16 @@ userauth_hostbased(struct ssh *ssh)
 | @@ -123,7 +123,16 @@ userauth_hostbased(struct ssh *ssh)
 | ||||||
|  	/* reconstruct packet */ |  	/* reconstruct packet */ | ||||||
|  	if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || |  	if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 || | ||||||
|  	    (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |  	    (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || | ||||||
| +#ifdef WITH_SELINUX
 | +#ifdef WITH_SELINUX
 | ||||||
| +	    (authctxt->role
 | +	    (authctxt->role
 | ||||||
| @ -141,7 +141,7 @@ diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c | |||||||
| +do_pam_putenv(char *name, const char *value)
 | +do_pam_putenv(char *name, const char *value)
 | ||||||
|  { |  { | ||||||
|  	int ret = 1; |  	int ret = 1; | ||||||
|  #ifdef HAVE_PAM_PUTENV |  	char *compound; | ||||||
| diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h
 | diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h
 | ||||||
| --- openssh/auth-pam.h.role-mls	2018-08-20 07:57:29.000000000 +0200
 | --- openssh/auth-pam.h.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||||
| +++ openssh/auth-pam.h	2018-08-22 11:14:56.817430932 +0200
 | +++ openssh/auth-pam.h	2018-08-22 11:14:56.817430932 +0200
 | ||||||
| @ -154,20 +154,6 @@ diff -up openssh/auth-pam.h.role-mls openssh/auth-pam.h | |||||||
|  char ** fetch_pam_environment(void); |  char ** fetch_pam_environment(void); | ||||||
|  char ** fetch_pam_child_environment(void); |  char ** fetch_pam_child_environment(void); | ||||||
|  void free_pam_environment(char **); |  void free_pam_environment(char **); | ||||||
| diff -up openssh/configure.ac.role-mls openssh/configure.ac
 |  | ||||||
| --- openssh/configure.ac.role-mls	2018-08-20 07:57:29.000000000 +0200
 |  | ||||||
| +++ openssh/configure.ac	2018-08-22 11:14:56.820430957 +0200
 |  | ||||||
| @@ -4241,10 +4241,7 @@ AC_ARG_WITH([selinux],
 |  | ||||||
|  			  LIBS="$LIBS -lselinux" |  | ||||||
|  			], |  | ||||||
|  			AC_MSG_ERROR([SELinux support requires libselinux library])) |  | ||||||
| -		SSHLIBS="$SSHLIBS $LIBSELINUX"
 |  | ||||||
| -		SSHDLIBS="$SSHDLIBS $LIBSELINUX"
 |  | ||||||
|  		AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level]) |  | ||||||
| -		LIBS="$save_LIBS"
 |  | ||||||
|  	fi ] |  | ||||||
|  ) |  | ||||||
|  AC_SUBST([SSHLIBS]) |  | ||||||
| diff -up openssh/misc.c.role-mls openssh/misc.c
 | diff -up openssh/misc.c.role-mls openssh/misc.c
 | ||||||
| --- openssh/misc.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | --- openssh/misc.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||||
| +++ openssh/misc.c	2018-08-22 11:14:56.817430932 +0200
 | +++ openssh/misc.c	2018-08-22 11:14:56.817430932 +0200
 | ||||||
| @ -193,10 +179,10 @@ diff -up openssh/misc.c.role-mls openssh/misc.c | |||||||
|  	} |  	} | ||||||
|  	return NULL; |  	return NULL; | ||||||
|  } |  } | ||||||
| diff -up openssh/monitor.c.role-mls openssh/monitor.c
 | diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c
 | ||||||
| --- openssh/monitor.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | --- openssh-8.6p1/monitor.c.role-mls	2021-04-16 05:55:25.000000000 +0200
 | ||||||
| +++ openssh/monitor.c	2018-08-22 11:19:56.006844867 +0200
 | +++ openssh-8.6p1/monitor.c	2021-05-21 14:21:56.719414087 +0200
 | ||||||
| @@ -115,6 +115,9 @@ int mm_answer_sign(int, struct sshbuf *)
 | @@ -117,6 +117,9 @@ int mm_answer_sign(struct ssh *, int, st
 | ||||||
|  int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); |  int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); | ||||||
|  int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); |  int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); | ||||||
|  int mm_answer_authserv(struct ssh *, int, struct sshbuf *); |  int mm_answer_authserv(struct ssh *, int, struct sshbuf *); | ||||||
| @ -206,7 +192,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | |||||||
|  int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); |  int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); | ||||||
|  int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); |  int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); | ||||||
|  int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); |  int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); | ||||||
| @@ -189,6 +192,9 @@ struct mon_table mon_dispatch_proto20[]
 | @@ -195,6 +198,9 @@ struct mon_table mon_dispatch_proto20[]
 | ||||||
|      {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, |      {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, | ||||||
|      {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, |      {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, | ||||||
|      {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, |      {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, | ||||||
| @ -216,7 +202,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | |||||||
|      {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, |      {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, | ||||||
|      {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, |      {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, | ||||||
|  #ifdef USE_PAM |  #ifdef USE_PAM | ||||||
| @@ -796,6 +802,9 @@ mm_answer_pwnamallow(int sock, struct ss
 | @@ -803,6 +809,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in
 | ||||||
|   |   | ||||||
|  	/* Allow service/style information on the auth context */ |  	/* Allow service/style information on the auth context */ | ||||||
|  	monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |  	monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); | ||||||
| @ -226,7 +212,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | |||||||
|  	monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |  	monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); | ||||||
|   |   | ||||||
|  #ifdef USE_PAM |  #ifdef USE_PAM | ||||||
| @@ -842,6 +851,26 @@ mm_answer_authserv(int sock, struct sshb
 | @@ -877,6 +886,26 @@ key_base_type_match(const char *method,
 | ||||||
|  	return found; |  	return found; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @ -238,8 +224,8 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | |||||||
| +	monitor_permit_authentications(1);
 | +	monitor_permit_authentications(1);
 | ||||||
| +
 | +
 | ||||||
| +	if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0)
 | +	if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0)
 | ||||||
| +		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | +		fatal_f("buffer error: %s", ssh_err(r));
 | ||||||
| +	debug3("%s: role=%s", __func__, authctxt->role);
 | +	debug3_f("role=%s", authctxt->role);
 | ||||||
| +
 | +
 | ||||||
| +	if (strlen(authctxt->role) == 0) {
 | +	if (strlen(authctxt->role) == 0) {
 | ||||||
| +		free(authctxt->role);
 | +		free(authctxt->role);
 | ||||||
| @ -253,7 +239,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | |||||||
|  int |  int | ||||||
|  mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) |  mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) | ||||||
|  { |  { | ||||||
| @@ -1218,7 +1247,7 @@ monitor_valid_userblob(u_char *data, u_i
 | @@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh,
 | ||||||
|  { |  { | ||||||
|  	struct sshbuf *b; |  	struct sshbuf *b; | ||||||
|  	const u_char *p; |  	const u_char *p; | ||||||
| @ -262,16 +248,16 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | |||||||
|  	size_t len; |  	size_t len; | ||||||
|  	u_char type; |  	u_char type; | ||||||
|  	int r, fail = 0; |  	int r, fail = 0; | ||||||
| @@ -1251,6 +1280,8 @@ monitor_valid_userblob(u_char *data, u_i
 | @@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh,
 | ||||||
|  		fail++; |  		fail++; | ||||||
|  	if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |  	if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) | ||||||
|  		fatal("%s: buffer error: %s", __func__, ssh_err(r)); |  		fatal_fr(r, "parse userstyle"); | ||||||
| +	if ((s = strchr(cp, '/')) != NULL)
 | +	if ((s = strchr(cp, '/')) != NULL)
 | ||||||
| +		*s = '\0';
 | +		*s = '\0';
 | ||||||
|  	xasprintf(&userstyle, "%s%s%s", authctxt->user, |  	xasprintf(&userstyle, "%s%s%s", authctxt->user, | ||||||
|  	    authctxt->style ? ":" : "", |  	    authctxt->style ? ":" : "", | ||||||
|  	    authctxt->style ? authctxt->style : ""); |  	    authctxt->style ? authctxt->style : ""); | ||||||
| @@ -1286,7 +1317,7 @@ monitor_valid_hostbasedblob(u_char *data
 | @@ -1317,7 +1348,7 @@ monitor_valid_hostbasedblob(const u_char
 | ||||||
|  { |  { | ||||||
|  	struct sshbuf *b; |  	struct sshbuf *b; | ||||||
|  	const u_char *p; |  	const u_char *p; | ||||||
| @ -280,10 +266,10 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c | |||||||
|  	size_t len; |  	size_t len; | ||||||
|  	int r, fail = 0; |  	int r, fail = 0; | ||||||
|  	u_char type; |  	u_char type; | ||||||
| @@ -1308,6 +1339,8 @@ monitor_valid_hostbasedblob(u_char *data
 | @@ -1338,6 +1370,8 @@ monitor_valid_hostbasedblob(const u_char
 | ||||||
|  		fail++; |  		fail++; | ||||||
|  	if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |  	if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) | ||||||
|  		fatal("%s: buffer error: %s", __func__, ssh_err(r)); |  		fatal_fr(r, "parse userstyle"); | ||||||
| +	if ((s = strchr(cp, '/')) != NULL)
 | +	if ((s = strchr(cp, '/')) != NULL)
 | ||||||
| +		*s = '\0';
 | +		*s = '\0';
 | ||||||
|  	xasprintf(&userstyle, "%s%s%s", authctxt->user, |  	xasprintf(&userstyle, "%s%s%s", authctxt->user, | ||||||
| @ -319,12 +305,12 @@ diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c | |||||||
| +	int r;
 | +	int r;
 | ||||||
| +	struct sshbuf *m;
 | +	struct sshbuf *m;
 | ||||||
| +
 | +
 | ||||||
| +	debug3("%s entering", __func__);
 | +	debug3_f("entering");
 | ||||||
| +
 | +
 | ||||||
| +	if ((m = sshbuf_new()) == NULL)
 | +	if ((m = sshbuf_new()) == NULL)
 | ||||||
| +		fatal("%s: sshbuf_new failed", __func__);
 | +		fatal_f("sshbuf_new failed");
 | ||||||
| +	if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0)
 | +	if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0)
 | ||||||
| +		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | +		fatal_f("buffer error: %s", ssh_err(r));
 | ||||||
| +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m);
 | +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m);
 | ||||||
| +
 | +
 | ||||||
| +	sshbuf_free(m);
 | +	sshbuf_free(m);
 | ||||||
| @ -338,8 +324,8 @@ diff -up openssh/monitor_wrap.h.role-mls openssh/monitor_wrap.h | |||||||
| --- openssh/monitor_wrap.h.role-mls	2018-08-22 11:14:56.818430941 +0200
 | --- openssh/monitor_wrap.h.role-mls	2018-08-22 11:14:56.818430941 +0200
 | ||||||
| +++ openssh/monitor_wrap.h	2018-08-22 11:22:10.439929513 +0200
 | +++ openssh/monitor_wrap.h	2018-08-22 11:22:10.439929513 +0200
 | ||||||
| @@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int);
 | @@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int);
 | ||||||
|  int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, |      const u_char *, size_t, const char *, const char *, | ||||||
|      const u_char *, size_t, const char *, u_int compat); |      const char *, u_int compat); | ||||||
|  void mm_inform_authserv(char *, char *); |  void mm_inform_authserv(char *, char *); | ||||||
| +#ifdef WITH_SELINUX
 | +#ifdef WITH_SELINUX
 | ||||||
| +void mm_inform_authrole(char *);
 | +void mm_inform_authrole(char *);
 | ||||||
| @ -351,7 +337,7 @@ diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Make | |||||||
| --- openssh/openbsd-compat/Makefile.in.role-mls	2018-08-20 07:57:29.000000000 +0200
 | --- openssh/openbsd-compat/Makefile.in.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||||
| +++ openssh/openbsd-compat/Makefile.in	2018-08-22 11:14:56.819430949 +0200
 | +++ openssh/openbsd-compat/Makefile.in	2018-08-22 11:14:56.819430949 +0200
 | ||||||
| @@ -92,7 +92,8 @@ PORTS=	port-aix.o \
 | @@ -92,7 +92,8 @@ PORTS=	port-aix.o \
 | ||||||
|  	port-linux.o \ |  	port-prngd.o \ | ||||||
|  	port-solaris.o \ |  	port-solaris.o \ | ||||||
|  	port-net.o \ |  	port-net.o \ | ||||||
| -	port-uw.o
 | -	port-uw.o
 | ||||||
| @ -359,7 +345,7 @@ diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Make | |||||||
| +	port-linux-sshd.o
 | +	port-linux-sshd.o
 | ||||||
|   |   | ||||||
|  .c.o: |  .c.o: | ||||||
|  	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< |  	$(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $< | ||||||
| diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/port-linux.c
 | diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/port-linux.c
 | ||||||
| --- openssh/openbsd-compat/port-linux.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | --- openssh/openbsd-compat/port-linux.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||||
| +++ openssh/openbsd-compat/port-linux.c	2018-08-22 11:14:56.819430949 +0200
 | +++ openssh/openbsd-compat/port-linux.c	2018-08-22 11:14:56.819430949 +0200
 | ||||||
| @ -371,7 +357,7 @@ diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/por | |||||||
| -void
 | -void
 | ||||||
| -ssh_selinux_setup_exec_context(char *pwname)
 | -ssh_selinux_setup_exec_context(char *pwname)
 | ||||||
| -{
 | -{
 | ||||||
| -	security_context_t user_ctx = NULL;
 | -	char *user_ctx = NULL;
 | ||||||
| -
 | -
 | ||||||
| -	if (!ssh_selinux_enabled())
 | -	if (!ssh_selinux_enabled())
 | ||||||
| -		return;
 | -		return;
 | ||||||
| @ -407,7 +393,7 @@ diff -up openssh/openbsd-compat/port-linux.c.role-mls openssh/openbsd-compat/por | |||||||
|   |   | ||||||
| -	user_ctx = ssh_selinux_getctxbyname(pwname);
 | -	user_ctx = ssh_selinux_getctxbyname(pwname);
 | ||||||
| +	if (getexeccon(&user_ctx) != 0) {
 | +	if (getexeccon(&user_ctx) != 0) {
 | ||||||
| +		error("%s: getexeccon: %s", __func__, strerror(errno));
 | +		error_f("getexeccon: %s", strerror(errno));
 | ||||||
| +		goto out;
 | +		goto out;
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
| @ -432,7 +418,7 @@ diff -up openssh/openbsd-compat/port-linux.h.role-mls openssh/openbsd-compat/por | |||||||
| diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compat/port-linux-sshd.c
 | diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compat/port-linux-sshd.c
 | ||||||
| --- openssh/openbsd-compat/port-linux-sshd.c.role-mls	2018-08-22 11:14:56.819430949 +0200
 | --- openssh/openbsd-compat/port-linux-sshd.c.role-mls	2018-08-22 11:14:56.819430949 +0200
 | ||||||
| +++ openssh/openbsd-compat/port-linux-sshd.c	2018-08-22 11:14:56.819430949 +0200
 | +++ openssh/openbsd-compat/port-linux-sshd.c	2018-08-22 11:14:56.819430949 +0200
 | ||||||
| @@ -0,0 +1,425 @@
 | @@ -0,0 +1,421 @@
 | ||||||
| +/*
 | +/*
 | ||||||
| + * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
 | + * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
 | ||||||
| + * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com>
 | + * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com>
 | ||||||
| @ -544,7 +530,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa | |||||||
| +	access_vector_t bit;
 | +	access_vector_t bit;
 | ||||||
| +	security_class_t class;
 | +	security_class_t class;
 | ||||||
| +
 | +
 | ||||||
| +	debug("%s: src:%s dst:%s", __func__, src, dst);
 | +	debug_f("src:%s dst:%s", src, dst);
 | ||||||
| +	class = string_to_security_class("context");
 | +	class = string_to_security_class("context");
 | ||||||
| +	if (!class) {
 | +	if (!class) {
 | ||||||
| +		error("string_to_security_class failed to translate security class context");
 | +		error("string_to_security_class failed to translate security class context");
 | ||||||
| @ -706,7 +692,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa | |||||||
| +			    /* we actually don't change level */
 | +			    /* we actually don't change level */
 | ||||||
| +			    reqlvl = "";
 | +			    reqlvl = "";
 | ||||||
| +
 | +
 | ||||||
| +			debug("%s: current connection level '%s'", __func__, reqlvl);
 | +			debug_f("current connection level '%s'", reqlvl);
 | ||||||
| +
 | +
 | ||||||
| +		}
 | +		}
 | ||||||
| +
 | +
 | ||||||
| @ -734,8 +720,8 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa | |||||||
| +		}
 | +		}
 | ||||||
| +	}
 | +	}
 | ||||||
| +	if (r != 0) {
 | +	if (r != 0) {
 | ||||||
| +		error("%s: Failed to get default SELinux security "
 | +		error_f("Failed to get default SELinux security "
 | ||||||
| +		    "context for %s", __func__, pwname);
 | +		    "context for %s", pwname);
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
| +#ifdef HAVE_GETSEUSERBYNAME
 | +#ifdef HAVE_GETSEUSERBYNAME
 | ||||||
| @ -760,7 +746,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa | |||||||
| +	char *use_current;
 | +	char *use_current;
 | ||||||
| +	int rv;
 | +	int rv;
 | ||||||
| +
 | +
 | ||||||
| +	debug3("%s: setting execution context", __func__);
 | +	debug3_f("setting execution context");
 | ||||||
| +
 | +
 | ||||||
| +	ssh_selinux_get_role_level(&role, &reqlvl);
 | +	ssh_selinux_get_role_level(&role, &reqlvl);
 | ||||||
| +
 | +
 | ||||||
| @ -797,32 +783,30 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa | |||||||
| +		if (sshd_selinux_setup_pam_variables()) {
 | +		if (sshd_selinux_setup_pam_variables()) {
 | ||||||
| +			switch (security_getenforce()) {
 | +			switch (security_getenforce()) {
 | ||||||
| +			case -1:
 | +			case -1:
 | ||||||
| +				fatal("%s: security_getenforce() failed", __func__);
 | +				fatal_f("security_getenforce() failed");
 | ||||||
| +			case 0:
 | +			case 0:
 | ||||||
| +				error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.",
 | +				error_f("SELinux PAM variable setup failure. Continuing in permissive mode.");
 | ||||||
| +				    __func__);
 |  | ||||||
| +			break;
 | +			break;
 | ||||||
| +			default:
 | +			default:
 | ||||||
| +				fatal("%s: SELinux PAM variable setup failure. Aborting connection.",
 | +				fatal_f("SELinux PAM variable setup failure. Aborting connection.");
 | ||||||
| +				    __func__);
 |  | ||||||
| +			}
 | +			}
 | ||||||
| +		}
 | +		}
 | ||||||
| +		return;
 | +		return;
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
| +	debug3("%s: setting execution context", __func__);
 | +	debug3_f("setting execution context");
 | ||||||
| +
 | +
 | ||||||
| +	r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
 | +	r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
 | ||||||
| +	if (r >= 0) {
 | +	if (r >= 0) {
 | ||||||
| +		r = setexeccon(user_ctx);
 | +		r = setexeccon(user_ctx);
 | ||||||
| +		if (r < 0) {
 | +		if (r < 0) {
 | ||||||
| +			error("%s: Failed to set SELinux execution context %s for %s",
 | +			error_f("Failed to set SELinux execution context %s for %s",
 | ||||||
| +			    __func__, user_ctx, pwname);
 | +			    user_ctx, pwname);
 | ||||||
| +		}
 | +		}
 | ||||||
| +#ifdef HAVE_SETKEYCREATECON
 | +#ifdef HAVE_SETKEYCREATECON
 | ||||||
| +		else if (setkeycreatecon(user_ctx) < 0) {
 | +		else if (setkeycreatecon(user_ctx) < 0) {
 | ||||||
| +			error("%s: Failed to set SELinux keyring creation context %s for %s",
 | +			error_f("Failed to set SELinux keyring creation context %s for %s",
 | ||||||
| +			    __func__, user_ctx, pwname);
 | +			    user_ctx, pwname);
 | ||||||
| +		}
 | +		}
 | ||||||
| +#endif
 | +#endif
 | ||||||
| +	}
 | +	}
 | ||||||
| @ -837,14 +821,12 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa | |||||||
| +	if (r < 0) {
 | +	if (r < 0) {
 | ||||||
| +		switch (security_getenforce()) {
 | +		switch (security_getenforce()) {
 | ||||||
| +		case -1:
 | +		case -1:
 | ||||||
| +			fatal("%s: security_getenforce() failed", __func__);
 | +			fatal_f("security_getenforce() failed");
 | ||||||
| +		case 0:
 | +		case 0:
 | ||||||
| +			error("%s: SELinux failure. Continuing in permissive mode.",
 | +			error_f("ELinux failure. Continuing in permissive mode.");
 | ||||||
| +			    __func__);
 |  | ||||||
| +			break;
 | +			break;
 | ||||||
| +		default:
 | +		default:
 | ||||||
| +			fatal("%s: SELinux failure. Aborting connection.",
 | +			fatal_f("SELinux failure. Aborting connection.");
 | ||||||
| +			    __func__);
 |  | ||||||
| +		}
 | +		}
 | ||||||
| +	}
 | +	}
 | ||||||
| +	if (user_ctx != NULL && user_ctx != default_ctx)
 | +	if (user_ctx != NULL && user_ctx != default_ctx)
 | ||||||
| @ -852,7 +834,7 @@ diff -up openssh/openbsd-compat/port-linux-sshd.c.role-mls openssh/openbsd-compa | |||||||
| +	if (default_ctx != NULL)
 | +	if (default_ctx != NULL)
 | ||||||
| +		freecon(default_ctx);
 | +		freecon(default_ctx);
 | ||||||
| +
 | +
 | ||||||
| +	debug3("%s: done", __func__);
 | +	debug3_f("done");
 | ||||||
| +}
 | +}
 | ||||||
| +
 | +
 | ||||||
| +#endif
 | +#endif
 | ||||||
|  | |||||||
| @ -1,42 +0,0 @@ | |||||||
| diff -up openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id openssh-7.9p1/contrib/ssh-copy-id
 |  | ||||||
| --- openssh-7.9p1/contrib/ssh-copy-id.ssh-copy-id	2018-10-17 02:01:20.000000000 +0200
 |  | ||||||
| +++ openssh-7.9p1/contrib/ssh-copy-id	2019-01-23 20:49:30.513393667 +0100
 |  | ||||||
| @@ -112,7 +112,8 @@ do
 |  | ||||||
|          usage |  | ||||||
|    } |  | ||||||
|   |  | ||||||
| -  OPT= OPTARG=
 |  | ||||||
| +  OPT=
 |  | ||||||
| +  OPTARG=
 |  | ||||||
|    # implement something like getopt to avoid Solaris pain |  | ||||||
|    case "$1" in |  | ||||||
|      -i?*|-o?*|-p?*) |  | ||||||
| @@ -185,8 +185,8 @@
 |  | ||||||
|    usage |  | ||||||
|  fi |  | ||||||
|   |  | ||||||
| -# drop trailing colon
 |  | ||||||
| -USER_HOST=$(printf "%s\n" "$1" | sed 's/:$//')
 |  | ||||||
| +# don't drop trailing colon because it can be a valid ipv6 address
 |  | ||||||
| +USER_HOST=$(printf "%s\n" "$1")
 |  | ||||||
|  # tack the hostname onto SSH_OPTS |  | ||||||
|  SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }'$(quote "$USER_HOST")'" |  | ||||||
|  # and populate "$@" for later use (only way to get proper quoting of options) |  | ||||||
| @@ -261,7 +262,7 @@ populate_new_ids() {
 |  | ||||||
|    fi |  | ||||||
|    if [ -z "$NEW_IDS" ] ; then |  | ||||||
|      printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 |  | ||||||
| -    printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2
 |  | ||||||
| +    printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' >&2
 |  | ||||||
|      exit 0 |  | ||||||
|    fi |  | ||||||
|    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 |  | ||||||
| @@ -296,7 +297,7 @@ case "$REMOTE_VERSION" in
 |  | ||||||
|      # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; |  | ||||||
|      #     'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh. |  | ||||||
|      [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ |  | ||||||
| -      ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
 |  | ||||||
| +      ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys || exit 1; } && 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) |  | ||||||
|      ;; |  | ||||||
| @ -1,57 +0,0 @@ | |||||||
| diff --git a/openssh-8.0p1/krl.c b/openssh-8.0p1/krl.c
 |  | ||||||
| index 8e2d5d5..e5b046d 100644
 |  | ||||||
| --- a/openssh-8.0p1/krl.c
 |  | ||||||
| +++ b/openssh-8.0p1/krl.c
 |  | ||||||
| @@ -676,6 +676,7 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
 |  | ||||||
|  			break; |  | ||||||
|  		case KRL_SECTION_CERT_SERIAL_BITMAP: |  | ||||||
|  			if (rs->lo - bitmap_start > INT_MAX) { |  | ||||||
| +				r = SSH_ERR_INVALID_FORMAT;
 |  | ||||||
|  				error("%s: insane bitmap gap", __func__); |  | ||||||
|  				goto out; |  | ||||||
|  			} |  | ||||||
| @@ -1011,6 +1012,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
 |  | ||||||
|  		goto out; |  | ||||||
|   |  | ||||||
|  	if ((krl = ssh_krl_init()) == NULL) { |  | ||||||
| +		r = SSH_ERR_ALLOC_FAIL;
 |  | ||||||
|  		error("%s: alloc failed", __func__); |  | ||||||
|  		goto out; |  | ||||||
|  	} |  | ||||||
| diff --git a/openssh-8.0p1/sshconnect2.c b/openssh-8.0p1/sshconnect2.c
 |  | ||||||
| index ce855eb..9650b24 100644
 |  | ||||||
| --- a/openssh-8.0p1/sshconnect2.c
 |  | ||||||
| +++ b/openssh-8.0p1/sshconnect2.c
 |  | ||||||
| @@ -95,7 +95,7 @@ struct sockaddr *xxx_hostaddr;
 |  | ||||||
|  static int |  | ||||||
|  verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) |  | ||||||
|  { |  | ||||||
| -	if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
 |  | ||||||
| +	if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) != 0)
 |  | ||||||
|  		fatal("Host key verification failed."); |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| @@ -767,6 +767,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
 |  | ||||||
|   |  | ||||||
|  	if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { |  | ||||||
|  		debug("%s: server sent unknown pkalg %s", __func__, pkalg); |  | ||||||
| +		r = SSH_ERR_INVALID_FORMAT;
 |  | ||||||
|  		goto done; |  | ||||||
|  	} |  | ||||||
|  	if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { |  | ||||||
| @@ -777,6 +778,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
 |  | ||||||
|  		error("input_userauth_pk_ok: type mismatch " |  | ||||||
|  		    "for decoded key (received %d, expected %d)", |  | ||||||
|  		    key->type, pktype); |  | ||||||
| +		r = SSH_ERR_INVALID_FORMAT;
 |  | ||||||
|  		goto done; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -796,6 +798,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
 |  | ||||||
|  		    SSH_FP_DEFAULT); |  | ||||||
|  		error("%s: server replied with unknown key: %s %s", __func__, |  | ||||||
|  		    sshkey_type(key), fp == NULL ? "<ERROR>" : fp); |  | ||||||
| +		r = SSH_ERR_INVALID_FORMAT;
 |  | ||||||
|  		goto done; |  | ||||||
|  	} |  | ||||||
|  	ident = format_identity(id); |  | ||||||
| @ -1,20 +0,0 @@ | |||||||
| diff --git a/sftp.c b/sftp.c
 |  | ||||||
| index b66037f1..54538ff9 100644
 |  | ||||||
| --- a/sftp.c
 |  | ||||||
| +++ b/sftp.c
 |  | ||||||
| @@ -220,9 +220,12 @@ static const struct CMD cmds[] = {
 |  | ||||||
|  static void |  | ||||||
|  killchild(int signo) |  | ||||||
|  { |  | ||||||
| -	if (sshpid > 1) {
 |  | ||||||
| -		kill(sshpid, SIGTERM);
 |  | ||||||
| -		waitpid(sshpid, NULL, 0);
 |  | ||||||
| +	pid_t pid;
 |  | ||||||
| +
 |  | ||||||
| +	pid = sshpid;
 |  | ||||||
| +	if (pid > 1) {
 |  | ||||||
| +		kill(pid, SIGTERM);
 |  | ||||||
| +		(void)waitpid(pid, NULL, 0);
 |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	_exit(1); |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| diff --git a/msg.c b/msg.c
 |  | ||||||
| index 99c25cd2..574a566e 100644
 |  | ||||||
| --- a/msg.c
 |  | ||||||
| +++ b/msg.c
 |  | ||||||
| @@ -77,7 +77,7 @@ ssh_msg_recv(int fd, struct sshbuf *m)
 |  | ||||||
|  		return (-1); |  | ||||||
|  	} |  | ||||||
|  	msg_len = get_u32(buf); |  | ||||||
| -	if (msg_len > 256 * 1024) {
 |  | ||||||
| +	if (msg_len > sshbuf_max_size(m)) {
 |  | ||||||
|  		error("ssh_msg_recv: read: bad msg_len %u", msg_len); |  | ||||||
|  		return (-1); |  | ||||||
|  	} |  | ||||||
| @ -1,33 +0,0 @@ | |||||||
| diff -up openssh-8.0p1/channels.c.channel-limits openssh-8.0p1/channels.c
 |  | ||||||
| --- openssh-8.0p1/channels.c.channel-limits	2021-03-16 12:17:58.905576511 +0100
 |  | ||||||
| +++ openssh-8.0p1/channels.c	2021-03-16 12:17:58.925576667 +0100
 |  | ||||||
| @@ -354,6 +354,7 @@ channel_new(struct ssh *ssh, char *ctype
 |  | ||||||
|  	struct ssh_channels *sc = ssh->chanctxt; |  | ||||||
|  	u_int i, found; |  | ||||||
|  	Channel *c; |  | ||||||
| +	int r;
 |  | ||||||
|   |  | ||||||
|  	/* Try to find a free slot where to put the new channel. */ |  | ||||||
|  	for (i = 0; i < sc->channels_alloc; i++) { |  | ||||||
| @@ -383,6 +384,8 @@ channel_new(struct ssh *ssh, char *ctype
 |  | ||||||
|  	    (c->output = sshbuf_new()) == NULL || |  | ||||||
|  	    (c->extended = sshbuf_new()) == NULL) |  | ||||||
|  		fatal("%s: sshbuf_new failed", __func__); |  | ||||||
| +	if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0)
 |  | ||||||
| +		fatal("%s: sshbuf_set_max_size: %s", __func__, ssh_err(r));
 |  | ||||||
|  	c->ostate = CHAN_OUTPUT_OPEN; |  | ||||||
|  	c->istate = CHAN_INPUT_OPEN; |  | ||||||
|  	channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0); |  | ||||||
| diff -up openssh-8.0p1/channels.h.channel-limits openssh-8.0p1/channels.h
 |  | ||||||
| --- openssh-8.0p1/channels.h.channel-limits	2021-03-16 12:17:58.868576223 +0100
 |  | ||||||
| +++ openssh-8.0p1/channels.h	2021-03-16 12:17:58.907576527 +0100
 |  | ||||||
| @@ -215,6 +215,9 @@ struct Channel {
 |  | ||||||
|  /* Read buffer size */ |  | ||||||
|  #define CHAN_RBUF	(16*1024) |  | ||||||
|   |  | ||||||
| +/* Maximum channel input buffer size */
 |  | ||||||
| +#define CHAN_INPUT_MAX	(16*1024*1024)
 |  | ||||||
| +
 |  | ||||||
|  /* Hard limit on number of channels */ |  | ||||||
|  #define CHANNELS_MAX_CHANNELS	(16*1024) |  | ||||||
|   |  | ||||||
| @ -1,28 +0,0 @@ | |||||||
| diff --git a/serverloop.c b/serverloop.c
 |  | ||||||
| index e16eabe2..a8c99e2e 100644
 |  | ||||||
| --- a/serverloop.c
 |  | ||||||
| +++ b/serverloop.c
 |  | ||||||
| @@ -184,7 +184,8 @@ client_alive_check(struct ssh *ssh)
 |  | ||||||
|  	int r, channel_id; |  | ||||||
|   |  | ||||||
|  	/* timeout, check to see how many we have had */ |  | ||||||
| -	if (ssh_packet_inc_alive_timeouts(ssh) >
 |  | ||||||
| +	if (options.client_alive_count_max > 0 &&
 |  | ||||||
| +	    ssh_packet_inc_alive_timeouts(ssh) >
 |  | ||||||
|  	    options.client_alive_count_max) { |  | ||||||
|  		sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); |  | ||||||
|  		logit("Timeout, client not responding from %s", remote_id); |  | ||||||
| diff --git a/sshd_config.5 b/sshd_config.5
 |  | ||||||
| index d47cb0d2..2cddbd59 100644
 |  | ||||||
| --- a/sshd_config.5
 |  | ||||||
| +++ b/sshd_config.5
 |  | ||||||
| @@ -519,6 +519,9 @@ is set to 15, and
 |  | ||||||
|  .Cm ClientAliveCountMax |  | ||||||
|  is left at the default, unresponsive SSH clients |  | ||||||
|  will be disconnected after approximately 45 seconds. |  | ||||||
| +Setting a zero
 |  | ||||||
| +.Cm ClientAliveCountMax
 |  | ||||||
| +disables connection termination.
 |  | ||||||
|  .It Cm ClientAliveInterval |  | ||||||
|  Sets a timeout interval in seconds after which if no data has been received |  | ||||||
|  from the client, |  | ||||||
| @ -1,55 +1,60 @@ | |||||||
| diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5
 | diff --color -ru a/ssh_config.5 b/ssh_config.5
 | ||||||
| --- openssh-8.0p1/ssh_config.5.crypto-policies	2020-03-24 17:32:54.821789205 +0100
 | --- a/ssh_config.5	2022-07-12 15:05:22.550013071 +0200
 | ||||||
| +++ openssh-8.0p1/ssh_config.5	2020-03-24 17:59:58.174122920 +0100
 | +++ b/ssh_config.5	2022-07-12 15:17:20.016704545 +0200
 | ||||||
| @@ -357,17 +357,17 @@ or
 | @@ -373,17 +373,13 @@
 | ||||||
|  .Qq *.c.example.com |  .Qq *.c.example.com | ||||||
|  domains. |  domains. | ||||||
|  .It Cm CASignatureAlgorithms |  .It Cm CASignatureAlgorithms | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies which algorithms are allowed for signing of certificates |  Specifies which algorithms are allowed for signing of certificates | ||||||
|  by certificate authorities (CAs). |  by certificate authorities (CAs). | ||||||
| -The default is:
 | -The default is:
 | ||||||
| -.Bd -literal -offset indent
 | -.Bd -literal -offset indent
 | ||||||
| -ecdsa-sha2-nistp256.ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | -ssh-ed25519,ecdsa-sha2-nistp256,
 | ||||||
| -ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | -ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||||
|  | -sk-ssh-ed25519@openssh.com,
 | ||||||
|  | -sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||||
|  | -rsa-sha2-512,rsa-sha2-256
 | ||||||
| -.Ed
 | -.Ed
 | ||||||
| -.Pp
 | -.Pp
 | ||||||
|  .Xr ssh 1 |  If the specified list begins with a | ||||||
|  will not accept host certificates signed using algorithms other than those |  .Sq + | ||||||
|  specified. |  character, then the specified algorithms will be appended to the default set | ||||||
| +.Pp
 | @@ -445,20 +441,25 @@
 | ||||||
|  .It Cm CertificateFile |  (the default), | ||||||
|  Specifies a file from which the user's certificate is read. |  | ||||||
|  A corresponding private key must be provided separately in order |  | ||||||
| @@ -420,16 +420,21 @@ If the option is set to
 |  | ||||||
|  .Cm no , |  | ||||||
|  the check will not be executed. |  the check will not be executed. | ||||||
|  .It Cm Ciphers |  .It Cm Ciphers | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies the ciphers allowed and their order of preference. |  Specifies the ciphers allowed and their order of preference. | ||||||
|  Multiple ciphers must be comma-separated. |  Multiple ciphers must be comma-separated. | ||||||
|  If the specified value begins with a |  If the specified list begins with a | ||||||
|  .Sq + |  .Sq + | ||||||
| -character, then the specified ciphers will be appended to the default set
 | -character, then the specified ciphers will be appended to the default set
 | ||||||
| +character, then the specified ciphers will be appended to the built-in default set
 | -instead of replacing them.
 | ||||||
|  instead of replacing them. | +character, then the specified ciphers will be appended to the built-in
 | ||||||
|  If the specified value begins with a | +openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  .Sq - |  .Sq - | ||||||
|  character, then the specified ciphers (including wildcards) will be removed |  character, then the specified ciphers (including wildcards) will be removed | ||||||
| -from the default set instead of replacing them.
 | -from the default set instead of replacing them.
 | ||||||
| +from the built-in default set instead of replacing them.
 | +from the built-in openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  |  .Sq ^ | ||||||
|  |  character, then the specified ciphers will be placed at the head of the | ||||||
|  | -default set.
 | ||||||
|  | +built-in openssh default set.
 | ||||||
|  .Pp |  .Pp | ||||||
|  The supported ciphers are: |  The supported ciphers are: | ||||||
|  .Bd -literal -offset indent |  .Bd -literal -offset indent | ||||||
| @@ -445,13 +450,6 @@ aes256-gcm@openssh.com
 | @@ -474,13 +475,6 @@
 | ||||||
|  chacha20-poly1305@openssh.com |  chacha20-poly1305@openssh.com | ||||||
|  .Ed |  .Ed | ||||||
|  .Pp |  .Pp | ||||||
| @ -63,49 +68,56 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 | |||||||
|  The list of available ciphers may also be obtained using |  The list of available ciphers may also be obtained using | ||||||
|  .Qq ssh -Q cipher . |  .Qq ssh -Q cipher . | ||||||
|  .It Cm ClearAllForwardings |  .It Cm ClearAllForwardings | ||||||
| @@ -800,6 +798,11 @@ command line will be passed untouched to
 | @@ -874,6 +868,11 @@
 | ||||||
|  The default is |  The default is | ||||||
|  .Dq no . |  .Dq no . | ||||||
|  .It Cm GSSAPIKexAlgorithms |  .It Cm GSSAPIKexAlgorithms | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  The list of key exchange algorithms that are offered for GSSAPI |  The list of key exchange algorithms that are offered for GSSAPI | ||||||
|  key exchange. Possible values are |  key exchange. Possible values are | ||||||
|  .Bd -literal -offset 3n |  .Bd -literal -offset 3n | ||||||
| @@ -812,9 +815,8 @@ gss-nistp256-sha256-,
 | @@ -886,10 +885,8 @@
 | ||||||
|  gss-curve25519-sha256- |  gss-curve25519-sha256- | ||||||
|  .Ed |  .Ed | ||||||
|  .Pp |  .Pp | ||||||
| -The default is
 | -The default is
 | ||||||
| -.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
 | -.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,
 | ||||||
|  | -gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
 | ||||||
|  This option only applies to connections using GSSAPI. |  This option only applies to connections using GSSAPI. | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  .It Cm HashKnownHosts |  .It Cm HashKnownHosts | ||||||
|  Indicates that |  Indicates that | ||||||
|  .Xr ssh 1 |  .Xr ssh 1 | ||||||
| @@ -1114,26 +1115,21 @@ it may be zero or more of:
 | @@ -1219,29 +1216,25 @@
 | ||||||
|  and |  and | ||||||
|  .Cm pam . |  .Cm pam . | ||||||
|  .It Cm KexAlgorithms |  .It Cm KexAlgorithms | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies the available KEX (Key Exchange) algorithms. |  Specifies the available KEX (Key Exchange) algorithms. | ||||||
|  Multiple algorithms must be comma-separated. |  Multiple algorithms must be comma-separated. | ||||||
|  Alternately if the specified value begins with a |  If the specified list begins with a | ||||||
|  .Sq + |  .Sq + | ||||||
| -character, then the specified methods will be appended to the default set
 | -character, then the specified methods will be appended to the default set
 | ||||||
| +character, then the specified methods will be appended to the built-in default set
 | -instead of replacing them.
 | ||||||
|  instead of replacing them. | +character, then the specified methods will be appended to the built-in
 | ||||||
|  If the specified value begins with a | +openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  .Sq - |  .Sq - | ||||||
|  character, then the specified methods (including wildcards) will be removed |  character, then the specified methods (including wildcards) will be removed | ||||||
| -from the default set instead of replacing them.
 | -from the default set instead of replacing them.
 | ||||||
|  | +from the built-in openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  |  .Sq ^ | ||||||
|  |  character, then the specified methods will be placed at the head of the | ||||||
|  | -default set.
 | ||||||
| -The default is:
 | -The default is:
 | ||||||
| -.Bd -literal -offset indent
 | -.Bd -literal -offset indent
 | ||||||
| -curve25519-sha256,curve25519-sha256@libssh.org,
 | -curve25519-sha256,curve25519-sha256@libssh.org,
 | ||||||
| @ -113,36 +125,41 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 | |||||||
| -diffie-hellman-group-exchange-sha256,
 | -diffie-hellman-group-exchange-sha256,
 | ||||||
| -diffie-hellman-group16-sha512,
 | -diffie-hellman-group16-sha512,
 | ||||||
| -diffie-hellman-group18-sha512,
 | -diffie-hellman-group18-sha512,
 | ||||||
| -diffie-hellman-group14-sha256,
 | -diffie-hellman-group14-sha256
 | ||||||
| -diffie-hellman-group14-sha1
 |  | ||||||
| -.Ed
 | -.Ed
 | ||||||
| +from the built-in default set instead of replacing them.
 | +built-in openssh default set.
 | ||||||
|  .Pp |  .Pp | ||||||
|  The list of available key exchange algorithms may also be obtained using |  The list of available key exchange algorithms may also be obtained using | ||||||
|  .Qq ssh -Q kex . |  .Qq ssh -Q kex . | ||||||
| @@ -1193,33 +1189,29 @@ The default is INFO.
 | @@ -1351,37 +1344,33 @@
 | ||||||
|  DEBUG and DEBUG1 are equivalent. |  file. | ||||||
|  DEBUG2 and DEBUG3 each specify higher levels of verbose output. |  This option is intended for debugging and no overrides are enabled by default. | ||||||
|  .It Cm MACs |  .It Cm MACs | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies the MAC (message authentication code) algorithms |  Specifies the MAC (message authentication code) algorithms | ||||||
|  in order of preference. |  in order of preference. | ||||||
|  The MAC algorithm is used for data integrity protection. |  The MAC algorithm is used for data integrity protection. | ||||||
|  Multiple algorithms must be comma-separated. |  Multiple algorithms must be comma-separated. | ||||||
|  If the specified value begins with a |  If the specified list begins with a | ||||||
|  .Sq + |  .Sq + | ||||||
| -character, then the specified algorithms will be appended to the default set
 | -character, then the specified algorithms will be appended to the default set
 | ||||||
| +character, then the specified algorithms will be appended to the built-in default set
 | -instead of replacing them.
 | ||||||
|  instead of replacing them. | +character, then the specified algorithms will be appended to the built-in
 | ||||||
|  If the specified value begins with a | +openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  .Sq - |  .Sq - | ||||||
|  character, then the specified algorithms (including wildcards) will be removed |  character, then the specified algorithms (including wildcards) will be removed | ||||||
| -from the default set instead of replacing them.
 | -from the default set instead of replacing them.
 | ||||||
| +from the built-in default set instead of replacing them.
 | +from the built-in openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  |  .Sq ^ | ||||||
|  |  character, then the specified algorithms will be placed at the head of the | ||||||
|  | -default set.
 | ||||||
|  | +built-in openssh default set.
 | ||||||
|  .Pp |  .Pp | ||||||
|  The algorithms that contain |  The algorithms that contain | ||||||
|  .Qq -etm |  .Qq -etm | ||||||
| @ -161,92 +178,110 @@ diff -up openssh-8.0p1/ssh_config.5.crypto-policies openssh-8.0p1/ssh_config.5 | |||||||
|  The list of available MAC algorithms may also be obtained using |  The list of available MAC algorithms may also be obtained using | ||||||
|  .Qq ssh -Q mac . |  .Qq ssh -Q mac . | ||||||
|  .It Cm NoHostAuthenticationForLocalhost |  .It Cm NoHostAuthenticationForLocalhost | ||||||
| @@ -1352,27 +1344,21 @@ instead of continuing to execute and pas
 | @@ -1553,37 +1542,25 @@
 | ||||||
|  The default is |  The default is | ||||||
|  .Cm no . |  .Cm no . | ||||||
|  .It Cm PubkeyAcceptedKeyTypes |  .It Cm PubkeyAcceptedAlgorithms | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies the key types that will be used for public key authentication |  Specifies the signature algorithms that will be used for public key | ||||||
|  as a comma-separated list of patterns. |  authentication as a comma-separated list of patterns. | ||||||
|  Alternately if the specified value begins with a |  If the specified list begins with a | ||||||
|  .Sq + |  .Sq + | ||||||
| -character, then the key types after it will be appended to the default
 | -character, then the algorithms after it will be appended to the default
 | ||||||
| +character, then the key types after it will be appended to the built-in default
 | -instead of replacing it.
 | ||||||
|  instead of replacing it. | +character, then the algorithms after it will be appended to the built-in
 | ||||||
|  If the specified value begins with a | +openssh default instead of replacing it.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  .Sq - |  .Sq - | ||||||
|  character, then the specified key types (including wildcards) will be removed |  character, then the specified algorithms (including wildcards) will be removed | ||||||
| -from the default set instead of replacing them.
 | -from the default set instead of replacing them.
 | ||||||
|  | +from the built-in openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  |  .Sq ^ | ||||||
|  |  character, then the specified algorithms will be placed at the head of the | ||||||
|  | -default set.
 | ||||||
| -The default for this option is:
 | -The default for this option is:
 | ||||||
| -.Bd -literal -offset 3n
 | -.Bd -literal -offset 3n
 | ||||||
|  | -ssh-ed25519-cert-v01@openssh.com,
 | ||||||
| -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||||
| -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | ||||||
| -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | ||||||
| -ssh-ed25519-cert-v01@openssh.com,
 | -sk-ssh-ed25519-cert-v01@openssh.com,
 | ||||||
| -rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
 | -sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||||
|  | -rsa-sha2-512-cert-v01@openssh.com,
 | ||||||
|  | -rsa-sha2-256-cert-v01@openssh.com,
 | ||||||
| -ssh-rsa-cert-v01@openssh.com,
 | -ssh-rsa-cert-v01@openssh.com,
 | ||||||
|  | -ssh-ed25519,
 | ||||||
| -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||||
| -ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | -sk-ssh-ed25519@openssh.com,
 | ||||||
|  | -sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||||
|  | -rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | ||||||
| -.Ed
 | -.Ed
 | ||||||
| +from the built-in default set instead of replacing them.
 | +built-in openssh default set.
 | ||||||
|  .Pp |  .Pp | ||||||
|  The list of available key types may also be obtained using |  The list of available signature algorithms may also be obtained using | ||||||
|  .Qq ssh -Q key . |  .Qq ssh -Q PubkeyAcceptedAlgorithms . | ||||||
| diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5
 | diff --color -ru a/sshd_config.5 b/sshd_config.5
 | ||||||
| --- openssh-8.0p1/sshd_config.5.crypto-policies	2020-03-24 17:32:54.802788908 +0100
 | --- a/sshd_config.5	2022-07-12 15:05:22.535012771 +0200
 | ||||||
| +++ openssh-8.0p1/sshd_config.5	2020-03-24 17:54:13.347740176 +0100
 | +++ b/sshd_config.5	2022-07-12 15:15:33.394809258 +0200
 | ||||||
| @@ -383,16 +383,16 @@ If the argument is
 | @@ -373,17 +373,13 @@
 | ||||||
|  then no banner is displayed. |  then no banner is displayed. | ||||||
|  By default, no banner is displayed. |  By default, no banner is displayed. | ||||||
|  .It Cm CASignatureAlgorithms |  .It Cm CASignatureAlgorithms | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies which algorithms are allowed for signing of certificates |  Specifies which algorithms are allowed for signing of certificates | ||||||
|  by certificate authorities (CAs). |  by certificate authorities (CAs). | ||||||
| -The default is:
 | -The default is:
 | ||||||
| -.Bd -literal -offset indent
 | -.Bd -literal -offset indent
 | ||||||
| -ecdsa-sha2-nistp256.ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | -ssh-ed25519,ecdsa-sha2-nistp256,
 | ||||||
| -ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | -ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||||
|  | -sk-ssh-ed25519@openssh.com,
 | ||||||
|  | -sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||||
|  | -rsa-sha2-512,rsa-sha2-256
 | ||||||
| -.Ed
 | -.Ed
 | ||||||
| -.Pp
 | -.Pp
 | ||||||
|  Certificates signed using other algorithms will not be accepted for |  If the specified list begins with a | ||||||
|  public key or host-based authentication. |  .Sq + | ||||||
| +.Pp
 |  character, then the specified algorithms will be appended to the default set | ||||||
|  .It Cm ChallengeResponseAuthentication | @@ -450,20 +446,25 @@
 | ||||||
|  Specifies whether challenge-response authentication is allowed (e.g. via |  | ||||||
|  PAM or through authentication styles supported in |  | ||||||
| @@ -454,16 +454,21 @@ The default is
 |  | ||||||
|  indicating not to |  indicating not to | ||||||
|  .Xr chroot 2 . |  .Xr chroot 2 . | ||||||
|  .It Cm Ciphers |  .It Cm Ciphers | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies the ciphers allowed. |  Specifies the ciphers allowed. | ||||||
|  Multiple ciphers must be comma-separated. |  Multiple ciphers must be comma-separated. | ||||||
|  If the specified value begins with a |  If the specified list begins with a | ||||||
|  .Sq + |  .Sq + | ||||||
| -character, then the specified ciphers will be appended to the default set
 | -character, then the specified ciphers will be appended to the default set
 | ||||||
| +character, then the specified ciphers will be appended to the built-in default set
 | -instead of replacing them.
 | ||||||
|  instead of replacing them. | +character, then the specified ciphers will be appended to the built-in
 | ||||||
|  If the specified value begins with a | +openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  .Sq - |  .Sq - | ||||||
|  character, then the specified ciphers (including wildcards) will be removed |  character, then the specified ciphers (including wildcards) will be removed | ||||||
| -from the default set instead of replacing them.
 | -from the default set instead of replacing them.
 | ||||||
| +from the built-in default set instead of replacing them.
 | +from the built-in openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  |  .Sq ^ | ||||||
|  |  character, then the specified ciphers will be placed at the head of the | ||||||
|  | -default set.
 | ||||||
|  | +built-in openssh default set.
 | ||||||
|  .Pp |  .Pp | ||||||
|  The supported ciphers are: |  The supported ciphers are: | ||||||
|  .Pp |  .Pp | ||||||
| @@ -490,13 +495,6 @@ aes256-gcm@openssh.com
 | @@ -490,13 +491,6 @@
 | ||||||
|  chacha20-poly1305@openssh.com |  chacha20-poly1305@openssh.com | ||||||
|  .El |  .El | ||||||
|  .Pp |  .Pp | ||||||
| @ -260,78 +295,103 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 | |||||||
|  The list of available ciphers may also be obtained using |  The list of available ciphers may also be obtained using | ||||||
|  .Qq ssh -Q cipher . |  .Qq ssh -Q cipher . | ||||||
|  .It Cm ClientAliveCountMax |  .It Cm ClientAliveCountMax | ||||||
| @@ -688,6 +686,11 @@ For this to work
 | @@ -685,21 +679,22 @@
 | ||||||
|  .Cm GSSAPIKeyExchange |  .Cm GSSAPIKeyExchange | ||||||
|  needs to be enabled in the server and also used by the client. |  needs to be enabled in the server and also used by the client. | ||||||
|  .It Cm GSSAPIKexAlgorithms |  .It Cm GSSAPIKexAlgorithms | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  The list of key exchange algorithms that are accepted by GSSAPI |  The list of key exchange algorithms that are accepted by GSSAPI | ||||||
|  key exchange. Possible values are |  key exchange. Possible values are | ||||||
|  .Bd -literal -offset 3n |  .Bd -literal -offset 3n | ||||||
| @@ -700,8 +703,6 @@ gss-nistp256-sha256-,
 | -gss-gex-sha1-,
 | ||||||
|  | -gss-group1-sha1-,
 | ||||||
|  | -gss-group14-sha1-,
 | ||||||
|  | -gss-group14-sha256-,
 | ||||||
|  | -gss-group16-sha512-,
 | ||||||
|  | -gss-nistp256-sha256-,
 | ||||||
|  | +gss-gex-sha1-
 | ||||||
|  | +gss-group1-sha1-
 | ||||||
|  | +gss-group14-sha1-
 | ||||||
|  | +gss-group14-sha256-
 | ||||||
|  | +gss-group16-sha512-
 | ||||||
|  | +gss-nistp256-sha256-
 | ||||||
|  gss-curve25519-sha256- |  gss-curve25519-sha256- | ||||||
|  .Ed |  .Ed | ||||||
|  .Pp | -.Pp
 | ||||||
| -The default is
 | -The default is
 | ||||||
| -.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
 | -.Dq gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,
 | ||||||
|  | -gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1- .
 | ||||||
|  This option only applies to connections using GSSAPI. |  This option only applies to connections using GSSAPI. | ||||||
|  .It Cm HostbasedAcceptedKeyTypes |  .It Cm HostbasedAcceptedAlgorithms | ||||||
|  Specifies the key types that will be accepted for hostbased authentication |  Specifies the signature algorithms that will be accepted for hostbased | ||||||
| @@ -791,19 +791,13 @@ is specified, the location of the socket
 | @@ -799,26 +794,13 @@
 | ||||||
|  .Ev SSH_AUTH_SOCK |  .Ev SSH_AUTH_SOCK | ||||||
|  environment variable. |  environment variable. | ||||||
|  .It Cm HostKeyAlgorithms |  .It Cm HostKeyAlgorithms | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies the host key algorithms |  Specifies the host key signature algorithms | ||||||
|  that the server offers. |  that the server offers. | ||||||
| -The default for this option is:
 | -The default for this option is:
 | ||||||
| -.Bd -literal -offset 3n
 | -.Bd -literal -offset 3n
 | ||||||
|  | -ssh-ed25519-cert-v01@openssh.com,
 | ||||||
| -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||||
| -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | ||||||
| -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | ||||||
| -ssh-ed25519-cert-v01@openssh.com,
 | -sk-ssh-ed25519-cert-v01@openssh.com,
 | ||||||
| -rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
 | -sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||||
|  | -rsa-sha2-512-cert-v01@openssh.com,
 | ||||||
|  | -rsa-sha2-256-cert-v01@openssh.com,
 | ||||||
| -ssh-rsa-cert-v01@openssh.com,
 | -ssh-rsa-cert-v01@openssh.com,
 | ||||||
|  | -ssh-ed25519,
 | ||||||
| -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||||
| -ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | -sk-ssh-ed25519@openssh.com,
 | ||||||
|  | -sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||||
|  | -rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | ||||||
| -.Ed
 | -.Ed
 | ||||||
|  .Pp | -.Pp
 | ||||||
|  The list of available key types may also be obtained using |  The list of available signature algorithms may also be obtained using | ||||||
|  .Qq ssh -Q key . |  .Qq ssh -Q HostKeyAlgorithms . | ||||||
| @@ -922,16 +916,21 @@ Specifies whether to look at .k5login fi
 |  .It Cm IgnoreRhosts | ||||||
|  | @@ -965,20 +947,25 @@
 | ||||||
|  The default is |  The default is | ||||||
|  .Cm yes . |  .Cm yes . | ||||||
|  .It Cm KexAlgorithms |  .It Cm KexAlgorithms | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies the available KEX (Key Exchange) algorithms. |  Specifies the available KEX (Key Exchange) algorithms. | ||||||
|  Multiple algorithms must be comma-separated. |  Multiple algorithms must be comma-separated. | ||||||
|  Alternately if the specified value begins with a |  Alternately if the specified list begins with a | ||||||
|  .Sq + |  .Sq + | ||||||
| -character, then the specified methods will be appended to the default set
 | -character, then the specified methods will be appended to the default set
 | ||||||
| +character, then the specified methods will be appended to the built-in default set
 | -instead of replacing them.
 | ||||||
|  instead of replacing them. | +character, then the specified methods will be appended to the built-in
 | ||||||
|  If the specified value begins with a | +openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  .Sq - |  .Sq - | ||||||
|  character, then the specified methods (including wildcards) will be removed |  character, then the specified methods (including wildcards) will be removed | ||||||
| -from the default set instead of replacing them.
 | -from the default set instead of replacing them.
 | ||||||
| +from the built-in default set instead of replacing them.
 | +from the built-in openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  |  .Sq ^ | ||||||
|  |  character, then the specified methods will be placed at the head of the | ||||||
|  | -default set.
 | ||||||
|  | +built-in openssh default set.
 | ||||||
|  The supported algorithms are: |  The supported algorithms are: | ||||||
|  .Pp |  .Pp | ||||||
|  .Bl -item -compact -offset indent |  .Bl -item -compact -offset indent | ||||||
| @@ -961,15 +960,6 @@ ecdh-sha2-nistp384
 | @@ -1010,15 +997,6 @@
 | ||||||
|  ecdh-sha2-nistp521 |  sntrup761x25519-sha512@openssh.com | ||||||
|  .El |  .El | ||||||
|  .Pp |  .Pp | ||||||
| -The default is:
 | -The default is:
 | ||||||
| @ -340,38 +400,44 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 | |||||||
| -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
 | -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
 | ||||||
| -diffie-hellman-group-exchange-sha256,
 | -diffie-hellman-group-exchange-sha256,
 | ||||||
| -diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,
 | -diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,
 | ||||||
| -diffie-hellman-group14-sha256,diffie-hellman-group14-sha1
 | -diffie-hellman-group14-sha256
 | ||||||
| -.Ed
 | -.Ed
 | ||||||
| -.Pp
 | -.Pp
 | ||||||
|  The list of available key exchange algorithms may also be obtained using |  The list of available key exchange algorithms may also be obtained using | ||||||
|  .Qq ssh -Q kex . |  .Qq ssh -Q KexAlgorithms . | ||||||
|  .It Cm ListenAddress |  .It Cm ListenAddress | ||||||
| @@ -1038,17 +1028,22 @@ DEBUG and DEBUG1 are equivalent.
 | @@ -1104,21 +1082,26 @@
 | ||||||
|  DEBUG2 and DEBUG3 each specify higher levels of debugging output. |  file. | ||||||
|  Logging with a DEBUG level violates the privacy of users and is not recommended. |  This option is intended for debugging and no overrides are enabled by default. | ||||||
|  .It Cm MACs |  .It Cm MACs | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies the available MAC (message authentication code) algorithms. |  Specifies the available MAC (message authentication code) algorithms. | ||||||
|  The MAC algorithm is used for data integrity protection. |  The MAC algorithm is used for data integrity protection. | ||||||
|  Multiple algorithms must be comma-separated. |  Multiple algorithms must be comma-separated. | ||||||
|  If the specified value begins with a |  If the specified list begins with a | ||||||
|  .Sq + |  .Sq + | ||||||
| -character, then the specified algorithms will be appended to the default set
 | -character, then the specified algorithms will be appended to the default set
 | ||||||
| +character, then the specified algorithms will be appended to the built-in default set
 | -instead of replacing them.
 | ||||||
|  instead of replacing them. | +character, then the specified algorithms will be appended to the built-in
 | ||||||
|  If the specified value begins with a | +openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  .Sq - |  .Sq - | ||||||
|  character, then the specified algorithms (including wildcards) will be removed |  character, then the specified algorithms (including wildcards) will be removed | ||||||
| -from the default set instead of replacing them.
 | -from the default set instead of replacing them.
 | ||||||
| +from the built-in default set instead of replacing them.
 | +from the built-in openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  |  .Sq ^ | ||||||
|  |  character, then the specified algorithms will be placed at the head of the | ||||||
|  | -default set.
 | ||||||
|  | +built-in openssh default set.
 | ||||||
|  .Pp |  .Pp | ||||||
|  The algorithms that contain |  The algorithms that contain | ||||||
|  .Qq -etm |  .Qq -etm | ||||||
| @@ -1091,15 +1086,6 @@ umac-64-etm@openssh.com
 | @@ -1161,15 +1144,6 @@
 | ||||||
|  umac-128-etm@openssh.com |  umac-128-etm@openssh.com | ||||||
|  .El |  .El | ||||||
|  .Pp |  .Pp | ||||||
| @ -387,38 +453,50 @@ diff -up openssh-8.0p1/sshd_config.5.crypto-policies openssh-8.0p1/sshd_config.5 | |||||||
|  The list of available MAC algorithms may also be obtained using |  The list of available MAC algorithms may also be obtained using | ||||||
|  .Qq ssh -Q mac . |  .Qq ssh -Q mac . | ||||||
|  .It Cm Match |  .It Cm Match | ||||||
| @@ -1446,27 +1432,21 @@ or equivalent.)
 | @@ -1548,37 +1522,25 @@
 | ||||||
|  The default is |  The default is | ||||||
|  .Cm yes . |  .Cm yes . | ||||||
|  .It Cm PubkeyAcceptedKeyTypes |  .It Cm PubkeyAcceptedAlgorithms | ||||||
| +The default is handled system-wide by
 | +The default is handled system-wide by
 | ||||||
| +.Xr crypto-policies 7 .
 | +.Xr crypto-policies 7 .
 | ||||||
| +To see the current defaults and how to modify them, see manual page
 | +Information about defaults, how to modify the defaults and how to customize existing policies with sub-policies are present in manual page
 | ||||||
| +.Xr update-crypto-policies 8 .
 | +.Xr update-crypto-policies 8 .
 | ||||||
| +.Pp
 | +.Pp
 | ||||||
|  Specifies the key types that will be accepted for public key authentication |  Specifies the signature algorithms that will be accepted for public key | ||||||
|  as a list of comma-separated patterns. |  authentication as a list of comma-separated patterns. | ||||||
|  Alternately if the specified value begins with a |  Alternately if the specified list begins with a | ||||||
|  .Sq + |  .Sq + | ||||||
| -character, then the specified key types will be appended to the default set
 | -character, then the specified algorithms will be appended to the default set
 | ||||||
| +character, then the specified key types will be appended to the built-in default set
 | -instead of replacing them.
 | ||||||
|  instead of replacing them. | +character, then the specified algorithms will be appended to the built-in
 | ||||||
|  If the specified value begins with a | +openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  .Sq - |  .Sq - | ||||||
|  character, then the specified key types (including wildcards) will be removed |  character, then the specified algorithms (including wildcards) will be removed | ||||||
| -from the default set instead of replacing them.
 | -from the default set instead of replacing them.
 | ||||||
|  | +from the built-in openssh default set instead of replacing them.
 | ||||||
|  |  If the specified list begins with a | ||||||
|  |  .Sq ^ | ||||||
|  |  character, then the specified algorithms will be placed at the head of the | ||||||
|  | -default set.
 | ||||||
| -The default for this option is:
 | -The default for this option is:
 | ||||||
| -.Bd -literal -offset 3n
 | -.Bd -literal -offset 3n
 | ||||||
|  | -ssh-ed25519-cert-v01@openssh.com,
 | ||||||
| -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||||
| -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | ||||||
| -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | ||||||
| -ssh-ed25519-cert-v01@openssh.com,
 | -sk-ssh-ed25519-cert-v01@openssh.com,
 | ||||||
| -rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,
 | -sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||||
|  | -rsa-sha2-512-cert-v01@openssh.com,
 | ||||||
|  | -rsa-sha2-256-cert-v01@openssh.com,
 | ||||||
| -ssh-rsa-cert-v01@openssh.com,
 | -ssh-rsa-cert-v01@openssh.com,
 | ||||||
|  | -ssh-ed25519,
 | ||||||
| -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||||
| -ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | -sk-ssh-ed25519@openssh.com,
 | ||||||
|  | -sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||||
|  | -rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | ||||||
| -.Ed
 | -.Ed
 | ||||||
| +from the built-in default set instead of replacing them.
 | +built-in openssh default set.
 | ||||||
|  .Pp |  .Pp | ||||||
|  The list of available key types may also be obtained using |  The list of available signature algorithms may also be obtained using | ||||||
|  .Qq ssh -Q key . |  .Qq ssh -Q PubkeyAcceptedAlgorithms . | ||||||
|  | |||||||
| @ -1,25 +0,0 @@ | |||||||
| diff --color -ru a/sshd.8 b/sshd.8
 |  | ||||||
| --- a/sshd.8	2022-05-31 13:39:10.231843926 +0200
 |  | ||||||
| +++ b/sshd.8	2022-05-31 14:34:01.460815420 +0200
 |  | ||||||
| @@ -78,6 +78,7 @@
 |  | ||||||
|  .Xr sshd_config 5 ) ; |  | ||||||
|  command-line options override values specified in the |  | ||||||
|  configuration file. |  | ||||||
| +This mechanism is used by systemd to apply system-wide crypto-policies to ssh server.
 |  | ||||||
|  .Nm |  | ||||||
|  rereads its configuration file when it receives a hangup signal, |  | ||||||
|  .Dv SIGHUP , |  | ||||||
| @@ -207,6 +208,13 @@
 |  | ||||||
|  rules may be applied by specifying the connection parameters using one or more |  | ||||||
|  .Fl C |  | ||||||
|  options. |  | ||||||
| +The configuration does not contain the system-wide crypto-policy configuration.
 |  | ||||||
| +To show the most accurate runtime configuration, use:
 |  | ||||||
| +.Bd -literal -offset 3n
 |  | ||||||
| +source /etc/crypto-policies/back-ends/opensshserver.config
 |  | ||||||
| +source /etc/sysconfig/sshd
 |  | ||||||
| +sshd -T $OPTIONS $CRYPTO_POLICY
 |  | ||||||
| +.Ed
 |  | ||||||
|  .It Fl t |  | ||||||
|  Test mode. |  | ||||||
|  Only check the validity of the configuration file and sanity of the keys. |  | ||||||
| @ -1,127 +0,0 @@ | |||||||
| diff -up openssh-8.0p1/hostfile.c.cve-2020-14145 openssh-8.0p1/hostfile.c
 |  | ||||||
| --- openssh-8.0p1/hostfile.c.cve-2020-14145	2019-04-18 00:52:57.000000000 +0200
 |  | ||||||
| +++ openssh-8.0p1/hostfile.c	2021-05-17 16:53:38.694577251 +0200
 |  | ||||||
| @@ -409,6 +409,18 @@ lookup_key_in_hostkeys_by_type(struct ho
 |  | ||||||
|  	    found) == HOST_FOUND); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +int
 |  | ||||||
| +lookup_marker_in_hostkeys(struct hostkeys *hostkeys, int want_marker)
 |  | ||||||
| +{
 |  | ||||||
| +	u_int i;
 |  | ||||||
| +
 |  | ||||||
| +	for (i = 0; i < hostkeys->num_entries; i++) {
 |  | ||||||
| +		if (hostkeys->entries[i].marker == (HostkeyMarker)want_marker)
 |  | ||||||
| +			return 1;
 |  | ||||||
| +	}
 |  | ||||||
| +	return 0;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  static int |  | ||||||
|  write_host_entry(FILE *f, const char *host, const char *ip, |  | ||||||
|      const struct sshkey *key, int store_hash) |  | ||||||
| diff -up openssh-8.0p1/hostfile.h.cve-2020-14145 openssh-8.0p1/hostfile.h
 |  | ||||||
| --- openssh-8.0p1/hostfile.h.cve-2020-14145	2019-04-18 00:52:57.000000000 +0200
 |  | ||||||
| +++ openssh-8.0p1/hostfile.h	2021-05-17 16:53:38.694577251 +0200
 |  | ||||||
| @@ -39,6 +39,7 @@ HostStatus check_key_in_hostkeys(struct
 |  | ||||||
|      const struct hostkey_entry **); |  | ||||||
|  int	 lookup_key_in_hostkeys_by_type(struct hostkeys *, int, |  | ||||||
|      const struct hostkey_entry **); |  | ||||||
| +int	 lookup_marker_in_hostkeys(struct hostkeys *, int);
 |  | ||||||
|   |  | ||||||
|  int	 hostfile_read_key(char **, u_int *, struct sshkey *); |  | ||||||
|  int	 add_host_to_hostfile(const char *, const char *, |  | ||||||
| diff -up openssh-8.0p1/sshconnect2.c.cve-2020-14145 openssh-8.0p1/sshconnect2.c
 |  | ||||||
| --- openssh-8.0p1/sshconnect2.c.cve-2020-14145	2021-05-17 16:53:38.610576561 +0200
 |  | ||||||
| +++ openssh-8.0p1/sshconnect2.c	2021-05-17 16:54:58.169230103 +0200
 |  | ||||||
| @@ -98,12 +98,25 @@ verify_host_key_callback(struct sshkey *
 |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +/* Returns the first item from a comma-separated algorithm list */
 |  | ||||||
| +static char *
 |  | ||||||
| +first_alg(const char *algs)
 |  | ||||||
| +{
 |  | ||||||
| +	char *ret, *cp;
 |  | ||||||
| +
 |  | ||||||
| +	ret = xstrdup(algs);
 |  | ||||||
| +	if ((cp = strchr(ret, ',')) != NULL)
 |  | ||||||
| +		*cp = '\0';
 |  | ||||||
| +	return ret;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  static char * |  | ||||||
|  order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) |  | ||||||
|  { |  | ||||||
| -	char *oavail, *avail, *first, *last, *alg, *hostname, *ret;
 |  | ||||||
| +	char *oavail = NULL, *avail = NULL, *first = NULL, *last = NULL;
 |  | ||||||
| +	char *alg = NULL, *hostname = NULL, *ret = NULL, *best = NULL;
 |  | ||||||
|  	size_t maxlen; |  | ||||||
| -	struct hostkeys *hostkeys;
 |  | ||||||
| +	struct hostkeys *hostkeys = NULL;
 |  | ||||||
|  	int ktype; |  | ||||||
|  	u_int i; |  | ||||||
|   |  | ||||||
| @@ -115,6 +128,26 @@ order_hostkeyalgs(char *host, struct soc
 |  | ||||||
|  	for (i = 0; i < options.num_system_hostfiles; i++) |  | ||||||
|  		load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); |  | ||||||
|   |  | ||||||
| +	/*
 |  | ||||||
| +	 * If a plain public key exists that matches the type of the best
 |  | ||||||
| +	 * preference HostkeyAlgorithms, then use the whole list as is.
 |  | ||||||
| +	 * Note that we ignore whether the best preference algorithm is a
 |  | ||||||
| +	 * certificate type, as sshconnect.c will downgrade certs to
 |  | ||||||
| +	 * plain keys if necessary.
 |  | ||||||
| +	 */
 |  | ||||||
| +	best = first_alg(options.hostkeyalgorithms);
 |  | ||||||
| +	if (lookup_key_in_hostkeys_by_type(hostkeys,
 |  | ||||||
| +	    sshkey_type_plain(sshkey_type_from_name(best)), NULL)) {
 |  | ||||||
| +		debug3("%s: have matching best-preference key type %s, "
 |  | ||||||
| +		    "using HostkeyAlgorithms verbatim", __func__, best);
 |  | ||||||
| +		ret = xstrdup(options.hostkeyalgorithms);
 |  | ||||||
| +		goto out;
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +	/*
 |  | ||||||
| +	 * Otherwise, prefer the host key algorithms that match known keys
 |  | ||||||
| +	 * while keeping the ordering of HostkeyAlgorithms as much as possible.
 |  | ||||||
| +	 */
 |  | ||||||
|  	oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); |  | ||||||
|  	maxlen = strlen(avail) + 1; |  | ||||||
|  	first = xmalloc(maxlen); |  | ||||||
| @@ -131,11 +164,23 @@ order_hostkeyalgs(char *host, struct soc
 |  | ||||||
|  	while ((alg = strsep(&avail, ",")) && *alg != '\0') { |  | ||||||
|  		if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) |  | ||||||
|  			fatal("%s: unknown alg %s", __func__, alg); |  | ||||||
| +		/*
 |  | ||||||
| +		 * If we have a @cert-authority marker in known_hosts then
 |  | ||||||
| +		 * prefer all certificate algorithms.
 |  | ||||||
| +		 */
 |  | ||||||
| +		if (sshkey_type_is_cert(ktype) &&
 |  | ||||||
| +		    lookup_marker_in_hostkeys(hostkeys, MRK_CA)) {
 |  | ||||||
| +			ALG_APPEND(first, alg);
 |  | ||||||
| +			continue;
 |  | ||||||
| +		}
 |  | ||||||
| +		/* If the key appears in known_hosts then prefer it */
 |  | ||||||
|  		if (lookup_key_in_hostkeys_by_type(hostkeys, |  | ||||||
| -		    sshkey_type_plain(ktype), NULL))
 |  | ||||||
| +		    sshkey_type_plain(ktype), NULL)) {
 |  | ||||||
|  			ALG_APPEND(first, alg); |  | ||||||
| -		else
 |  | ||||||
| -			ALG_APPEND(last, alg);
 |  | ||||||
| +			continue;
 |  | ||||||
| +		}
 |  | ||||||
| +		/* Otherwise, put it last */
 |  | ||||||
| +		ALG_APPEND(last, alg);
 |  | ||||||
|  	} |  | ||||||
|  #undef ALG_APPEND |  | ||||||
|  	xasprintf(&ret, "%s%s%s", first, |  | ||||||
| @@ -143,6 +188,8 @@ order_hostkeyalgs(char *host, struct soc
 |  | ||||||
|  	if (*first != '\0') |  | ||||||
|  		debug3("%s: prefer hostkeyalgs: %s", __func__, first); |  | ||||||
|   |  | ||||||
| + out:
 |  | ||||||
| +	free(best);
 |  | ||||||
|  	free(first); |  | ||||||
|  	free(last); |  | ||||||
|  	free(hostname); |  | ||||||
| @ -1,302 +0,0 @@ | |||||||
| 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)
 |  | ||||||
|  	} |  | ||||||
|  #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,6 +20,7 @@ OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o di
 |  | ||||||
|  	port-solaris.o \ |  | ||||||
|  	port-net.o \ |  | ||||||
|  	port-uw.o \ |  | ||||||
| +	port-linux-prng.o \
 |  | ||||||
|  	port-linux-sshd.o |  | ||||||
|   |  | ||||||
|  .c.o: |  | ||||||
| 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,78 @@
 |  | ||||||
| +/*
 |  | ||||||
| + * Copyright (c) 2011 - 2020 Red Hat, Inc.
 |  | ||||||
| + *
 |  | ||||||
| + * Authors:
 |  | ||||||
| + *  Jan F. Chadima <jchadima@redhat.com>
 |  | ||||||
| + *  Jakub Jelen <jjelen@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 <string.h>
 |  | ||||||
| +#include <openssl/rand.h>
 |  | ||||||
| +#include <sys/random.h>
 |  | ||||||
| +
 |  | ||||||
| +#include "log.h"
 |  | ||||||
| +
 |  | ||||||
| +void
 |  | ||||||
| +linux_seed(void)
 |  | ||||||
| +{
 |  | ||||||
| +	char *env = NULL;
 |  | ||||||
| +	size_t randlen = 14, left;
 |  | ||||||
| +	unsigned int flags = 0;
 |  | ||||||
| +	unsigned char buf[256], *p;
 |  | ||||||
| +
 |  | ||||||
| +	env = getenv("SSH_USE_STRONG_RNG");
 |  | ||||||
| +	if (env && strcmp(env, "0") != 0) {
 |  | ||||||
| +		size_t ienv = atoi(env);
 |  | ||||||
| +
 |  | ||||||
| +		/* Max on buffer length */
 |  | ||||||
| +		if (ienv > sizeof(buf))
 |  | ||||||
| +			ienv = sizeof(buf);
 |  | ||||||
| +		/* Minimum is always 14 B */
 |  | ||||||
| +		if (ienv > randlen)
 |  | ||||||
| +			randlen = ienv;
 |  | ||||||
| +		flags = GRND_RANDOM;
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +	errno = 0;
 |  | ||||||
| +	left = randlen;
 |  | ||||||
| +	p = buf;
 |  | ||||||
| +	do {
 |  | ||||||
| +		ssize_t len = getrandom(p, left, flags);
 |  | ||||||
| +		if (len == -1) {
 |  | ||||||
| +			if (errno != EINTR) {
 |  | ||||||
| +				if (flags) {
 |  | ||||||
| +					/* With the variable present, this is fatal error */
 |  | ||||||
| +					fatal("Failed to seed from getrandom: %s", strerror(errno));
 |  | ||||||
| +				} else {
 |  | ||||||
| +					/* Otherwise we log the issue drop out from here */
 |  | ||||||
| +					debug("Failed to seed from getrandom: %s", strerror(errno));
 |  | ||||||
| +					return;
 |  | ||||||
| +				}
 |  | ||||||
| +			}
 |  | ||||||
| +		} else if (len > 0) {
 |  | ||||||
| +			left -= len;
 |  | ||||||
| +			p += len;
 |  | ||||||
| +		}
 |  | ||||||
| +	} while (left > 0);
 |  | ||||||
| +
 |  | ||||||
| +	RAND_seed(buf, randlen);
 |  | ||||||
| +}
 |  | ||||||
| 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,22 @@ 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 getrandom(1)
 |  | ||||||
| +without any specific flags.
 |  | ||||||
| +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 getrandom(1)
 |  | ||||||
| +with GRND_RANDOM flag specified.
 |  | ||||||
| +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,26 @@ 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 getrandom(1)
 |  | ||||||
| +without any specific flags.
 |  | ||||||
| +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 getrandom(1)
 |  | ||||||
| +with GRND_RANDOM flag specified.
 |  | ||||||
| +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,26 @@ 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 getrandom(1)
 |  | ||||||
| +without any specific flags.
 |  | ||||||
| +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 getrandom(1)
 |  | ||||||
| +with GRND_RANDOM flag specified.
 |  | ||||||
| +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,26 @@ 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 getrandom(1)
 |  | ||||||
| +without any specific flags.
 |  | ||||||
| +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 getrandom(1)
 |  | ||||||
| +with GRND_RANDOM flag specified.
 |  | ||||||
| +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,25 @@ For more information, see the
 |  | ||||||
|  .Cm PermitUserEnvironment |  | ||||||
|  option in |  | ||||||
|  .Xr sshd_config 5 . |  | ||||||
| +.Bl -tag -width "SSH_ORIGINAL_COMMAND"
 |  | ||||||
| +.Pp
 |  | ||||||
| +.It Ev SSH_USE_STRONG_RNG
 |  | ||||||
| +The reseeding of the OpenSSL random generator is usually done from
 |  | ||||||
| +.Cm getrandom(1)
 |  | ||||||
| +without any specific flags.
 |  | ||||||
| +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 getrandom(1)
 |  | ||||||
| +with GRND_RANDOM flag specified.
 |  | ||||||
| +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,26 @@ 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 Ev SSH_USE_STRONG_RNG
 |  | ||||||
| +The reseeding of the OpenSSL random generator is usually done from
 |  | ||||||
| +.Cm getrandom(1)
 |  | ||||||
| +without any specific flags.
 |  | ||||||
| +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 getrandom(1)
 |  | ||||||
| +with GRND_RANDOM flag specified.
 |  | ||||||
| +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 |  | ||||||
| 
 |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,27 +0,0 @@ | |||||||
| diff --git a/sftp.c b/sftp.c
 |  | ||||||
| index 04881c83..03c7a5c7 100644
 |  | ||||||
| --- a/sftp.c
 |  | ||||||
| +++ b/sftp.c
 |  | ||||||
| @@ -2527,12 +2527,17 @@ main(int argc, char **argv)
 |  | ||||||
|  				port = tmp; |  | ||||||
|  			break; |  | ||||||
|  		default: |  | ||||||
| +			/* Try with user, host and path. */
 |  | ||||||
|  			if (parse_user_host_path(*argv, &user, &host, |  | ||||||
| -			    &file1) == -1) {
 |  | ||||||
| -				/* Treat as a plain hostname. */
 |  | ||||||
| -				host = xstrdup(*argv);
 |  | ||||||
| -				host = cleanhostname(host);
 |  | ||||||
| -			}
 |  | ||||||
| +			    &file1) == 0)
 |  | ||||||
| +				break;
 |  | ||||||
| +			/* Try with user and host. */
 |  | ||||||
| +			if (parse_user_host_port(*argv, &user, &host, NULL)
 |  | ||||||
| +			    == 0)
 |  | ||||||
| +				break;
 |  | ||||||
| +			/* Treat as a plain hostname. */
 |  | ||||||
| +			host = xstrdup(*argv);
 |  | ||||||
| +			host = cleanhostname(host);
 |  | ||||||
|  			break; |  | ||||||
|  		} |  | ||||||
|  		file2 = *(argv + 1); |  | ||||||
| @ -1,107 +0,0 @@ | |||||||
| From 4a41d245d6b13bd3882c8dc058dbd2e2b39a9f67 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "djm@openbsd.org" <djm@openbsd.org> |  | ||||||
| Date: Fri, 24 Jan 2020 00:27:04 +0000 |  | ||||||
| Subject: [PATCH] upstream: when signing a certificate with an RSA key, default |  | ||||||
|  to |  | ||||||
| 
 |  | ||||||
| a safe signature algorithm (rsa-sha-512) if not is explicitly specified by |  | ||||||
| the user; ok markus@ |  | ||||||
| 
 |  | ||||||
| OpenBSD-Commit-ID: e05f638f0be6c0266e1d3d799716b461011e83a9 |  | ||||||
| ---
 |  | ||||||
|  ssh-keygen.c | 14 +++++++++----- |  | ||||||
|  1 file changed, 9 insertions(+), 5 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/ssh-keygen.c b/ssh-keygen.c
 |  | ||||||
| index 564c3c481..f2192edb9 100644
 |  | ||||||
| --- a/ssh-keygen.c
 |  | ||||||
| +++ b/ssh-keygen.c
 |  | ||||||
| @@ -1788,10 +1788,14 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
 |  | ||||||
|  	} |  | ||||||
|  	free(tmp); |  | ||||||
|   |  | ||||||
| -	if (key_type_name != NULL &&
 |  | ||||||
| -	    sshkey_type_from_name(key_type_name) != ca->type)  {
 |  | ||||||
| -		fatal("CA key type %s doesn't match specified %s",
 |  | ||||||
| -		    sshkey_ssh_name(ca), key_type_name);
 |  | ||||||
| +	if (key_type_name != NULL) {
 |  | ||||||
| +		if (sshkey_type_from_name(key_type_name) != ca->type) {
 |  | ||||||
| +			fatal("CA key type %s doesn't match specified %s",
 |  | ||||||
| +			    sshkey_ssh_name(ca), key_type_name);
 |  | ||||||
| +		}
 |  | ||||||
| +	} else if (ca->type == KEY_RSA) {
 |  | ||||||
| +		/* Default to a good signature algorithm */
 |  | ||||||
| +		key_type_name = "rsa-sha2-512";
 |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	for (i = 0; i < argc; i++) { |  | ||||||
| 
 |  | ||||||
| From 476e3551b2952ef73acc43d995e832539bf9bc4d Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "djm@openbsd.org" <djm@openbsd.org> |  | ||||||
| Date: Mon, 20 May 2019 00:20:35 +0000 |  | ||||||
| Subject: [PATCH] upstream: When signing certificates with an RSA key, default |  | ||||||
|  to |  | ||||||
| 
 |  | ||||||
| using the rsa-sha2-512 signature algorithm. Certificates signed by RSA keys |  | ||||||
| will therefore be incompatible with OpenSSH < 7.2 unless the default is |  | ||||||
| overridden. |  | ||||||
| 
 |  | ||||||
| Document the ability of the ssh-keygen -t flag to override the |  | ||||||
| signature algorithm when signing certificates, and the new default. |  | ||||||
| 
 |  | ||||||
| ok deraadt@ |  | ||||||
| 
 |  | ||||||
| OpenBSD-Commit-ID: 400c9c15013978204c2cb80f294b03ae4cfc8b95 |  | ||||||
| ---
 |  | ||||||
|  ssh-keygen.1 | 13 +++++++++++-- |  | ||||||
|  sshkey.c     |  9 ++++++++- |  | ||||||
|  2 files changed, 19 insertions(+), 3 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/ssh-keygen.1 b/ssh-keygen.1
 |  | ||||||
| index f29774249..673bf6e2f 100644
 |  | ||||||
| --- a/ssh-keygen.1
 |  | ||||||
| +++ b/ssh-keygen.1
 |  | ||||||
| @@ -35,7 +35,7 @@
 |  | ||||||
|  .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |  | ||||||
|  .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | ||||||
|  .\" |  | ||||||
| -.Dd $Mdocdate: March 5 2019 $
 |  | ||||||
| +.Dd $Mdocdate: May 20 2019 $
 |  | ||||||
|  .Dt SSH-KEYGEN 1 |  | ||||||
|  .Os |  | ||||||
|  .Sh NAME |  | ||||||
| @@ -577,6 +577,15 @@ The possible values are
 |  | ||||||
|  .Dq ed25519 , |  | ||||||
|  or |  | ||||||
|  .Dq rsa . |  | ||||||
| +.Pp
 |  | ||||||
| +This flag may also be used to specify the desired signature type when
 |  | ||||||
| +signing certificates using a RSA CA key.
 |  | ||||||
| +The available RSA signature variants are
 |  | ||||||
| +.Dq ssh-rsa
 |  | ||||||
| +(SHA1 signatures, not recommended),
 |  | ||||||
| +.Dq rsa-sha2-256
 |  | ||||||
| +.Dq rsa-sha2-512
 |  | ||||||
| +(the default).
 |  | ||||||
|  .It Fl U |  | ||||||
|  When used in combination with |  | ||||||
|  .Fl s , |  | ||||||
| diff --git a/sshkey.c b/sshkey.c
 |  | ||||||
| index 9849cb237..379a579cf 100644
 |  | ||||||
| --- a/sshkey.c
 |  | ||||||
| +++ b/sshkey.c
 |  | ||||||
| @@ -2528,6 +2528,13 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
 |  | ||||||
|  	    strcmp(alg, k->cert->signature_type) != 0) |  | ||||||
|  		return SSH_ERR_INVALID_ARGUMENT; |  | ||||||
|   |  | ||||||
| +	/*
 |  | ||||||
| +	 * If no signing algorithm or signature_type was specified and we're
 |  | ||||||
| +	 * using a RSA key, then default to a good signature algorithm.
 |  | ||||||
| +	 */
 |  | ||||||
| +	if (alg == NULL && ca->type == KEY_RSA)
 |  | ||||||
| +		alg = "rsa-sha2-512";
 |  | ||||||
| +
 |  | ||||||
|  	if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0) |  | ||||||
|  		return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; |  | ||||||
|   |  | ||||||
| 
 |  | ||||||
| @ -1,33 +0,0 @@ | |||||||
| From 7250879c72d28275a53f2f220e49646c3e42ef18 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "djm@openbsd.org" <djm@openbsd.org> |  | ||||||
| Date: Fri, 12 Jul 2019 04:08:39 +0000 |  | ||||||
| Subject: [PATCH] upstream: include SHA2-variant RSA key algorithms in KEX |  | ||||||
|  proposal; |  | ||||||
| 
 |  | ||||||
| allows ssh-keyscan to harvest keys from servers that disable olde SHA1 |  | ||||||
| ssh-rsa. bz#3029 from Jakub Jelen |  | ||||||
| 
 |  | ||||||
| OpenBSD-Commit-ID: 9f95ebf76a150c2f727ca4780fb2599d50bbab7a |  | ||||||
| ---
 |  | ||||||
|  ssh-keyscan.c | 9 +++++++-- |  | ||||||
|  1 file changed, 7 insertions(+), 2 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/ssh-keyscan.c b/ssh-keyscan.c
 |  | ||||||
| index d95ba1b37..d383b57b9 100644
 |  | ||||||
| --- a/ssh-keyscan.c
 |  | ||||||
| +++ b/ssh-keyscan.c
 |  | ||||||
| @@ -233,7 +233,12 @@ keygrab_ssh2(con *c)
 |  | ||||||
|  		break; |  | ||||||
|  	case KT_RSA: |  | ||||||
|  		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? |  | ||||||
| -		    "ssh-rsa-cert-v01@openssh.com" : "ssh-rsa";
 |  | ||||||
| +		    "rsa-sha2-512-cert-v01@openssh.com,"
 |  | ||||||
| +		    "rsa-sha2-256-cert-v01@openssh.com,"
 |  | ||||||
| +		    "ssh-rsa-cert-v01@openssh.com" :
 |  | ||||||
| +		    "rsa-sha2-512,"
 |  | ||||||
| +		    "rsa-sha2-256,"
 |  | ||||||
| +		    "ssh-rsa";
 |  | ||||||
|  		break; |  | ||||||
|  	case KT_ED25519: |  | ||||||
|  		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? |  | ||||||
| 
 |  | ||||||
| @ -96,7 +96,7 @@ index b6f041f4..1fbce2bb 100644 | |||||||
| +		goto out;
 | +		goto out;
 | ||||||
| +	}
 | +	}
 | ||||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
 | +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
 | ||||||
| +	    kex->session_id, kex->session_id_len);
 | +	    sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id));
 | ||||||
| +	if (r != 1) {
 | +	if (r != 1) {
 | ||||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
| +		goto out;
 | +		goto out;
 | ||||||
|  | |||||||
| @ -1,324 +0,0 @@ | |||||||
| From eb0d8e708a1f958aecd2d6e2ff2450af488d4c2a Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "djm@openbsd.org" <djm@openbsd.org> |  | ||||||
| Date: Mon, 15 Jul 2019 13:16:29 +0000 |  | ||||||
| Subject: [PATCH] upstream: support PKCS8 as an optional format for storage of |  | ||||||
| 
 |  | ||||||
| private keys, enabled via "ssh-keygen -m PKCS8" on operations that save |  | ||||||
| private keys to disk. |  | ||||||
| 
 |  | ||||||
| The OpenSSH native key format remains the default, but PKCS8 is a |  | ||||||
| superior format to PEM if interoperability with non-OpenSSH software |  | ||||||
| is required, as it may use a less terrible KDF (IIRC PEM uses a single |  | ||||||
| round of MD5 as a KDF). |  | ||||||
| 
 |  | ||||||
| adapted from patch by Jakub Jelen via bz3013; ok markus |  | ||||||
| 
 |  | ||||||
| OpenBSD-Commit-ID: 027824e3bc0b1c243dc5188504526d73a55accb1 |  | ||||||
| ---
 |  | ||||||
|  authfile.c   |  6 ++-- |  | ||||||
|  ssh-keygen.1 |  9 +++--- |  | ||||||
|  ssh-keygen.c | 25 +++++++++-------- |  | ||||||
|  sshkey.c     | 78 +++++++++++++++++++++++++++++++++++++--------------- |  | ||||||
|  sshkey.h     | 11 ++++++-- |  | ||||||
|  5 files changed, 87 insertions(+), 42 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/authfile.c b/authfile.c
 |  | ||||||
| index 2166c1689..851c1a8a1 100644
 |  | ||||||
| --- a/authfile.c
 |  | ||||||
| +++ b/authfile.c
 |  | ||||||
| @@ -74,7 +74,7 @@ sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
 |  | ||||||
|  int |  | ||||||
|  sshkey_save_private(struct sshkey *key, const char *filename, |  | ||||||
|      const char *passphrase, const char *comment, |  | ||||||
| -    int force_new_format, const char *new_format_cipher, int new_format_rounds)
 |  | ||||||
| +    int format, const char *openssh_format_cipher, int openssh_format_rounds)
 |  | ||||||
|  { |  | ||||||
|  	struct sshbuf *keyblob = NULL; |  | ||||||
|  	int r; |  | ||||||
| @@ -82,7 +82,7 @@ sshkey_save_private(struct sshkey *key, const char *filename,
 |  | ||||||
|  	if ((keyblob = sshbuf_new()) == NULL) |  | ||||||
|  		return SSH_ERR_ALLOC_FAIL; |  | ||||||
|  	if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment, |  | ||||||
| -	    force_new_format, new_format_cipher, new_format_rounds)) != 0)
 |  | ||||||
| +	    format, openssh_format_cipher, openssh_format_rounds)) != 0)
 |  | ||||||
|  		goto out; |  | ||||||
|  	if ((r = sshkey_save_private_blob(keyblob, filename)) != 0) |  | ||||||
|  		goto out; |  | ||||||
| diff --git a/ssh-keygen.1 b/ssh-keygen.1
 |  | ||||||
| index f42127c60..8184a1797 100644
 |  | ||||||
| --- a/ssh-keygen.1
 |  | ||||||
| +++ b/ssh-keygen.1
 |  | ||||||
| @@ -419,11 +419,12 @@ The supported key formats are:
 |  | ||||||
|  .Dq RFC4716 |  | ||||||
|  (RFC 4716/SSH2 public or private key), |  | ||||||
|  .Dq PKCS8 |  | ||||||
| -(PEM PKCS8 public key)
 |  | ||||||
| +(PKCS8 public or private key)
 |  | ||||||
|  or |  | ||||||
|  .Dq PEM |  | ||||||
|  (PEM public key). |  | ||||||
| -The default conversion format is
 |  | ||||||
| +By default OpenSSH will write newly-generated private keys in its own
 |  | ||||||
| +format, but when converting public keys for export the default format is
 |  | ||||||
|  .Dq RFC4716 . |  | ||||||
|  Setting a format of |  | ||||||
|  .Dq PEM |  | ||||||
| diff --git a/ssh-keygen.c b/ssh-keygen.c
 |  | ||||||
| index b019a02ff..5dcad1f61 100644
 |  | ||||||
| --- a/ssh-keygen.c
 |  | ||||||
| +++ b/ssh-keygen.c
 |  | ||||||
| @@ -147,11 +147,11 @@ static char *key_type_name = NULL;
 |  | ||||||
|  /* Load key from this PKCS#11 provider */ |  | ||||||
|  static char *pkcs11provider = NULL; |  | ||||||
|   |  | ||||||
| -/* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */
 |  | ||||||
| -static int use_new_format = 1;
 |  | ||||||
| +/* Format for writing private keys */
 |  | ||||||
| +static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
 |  | ||||||
|   |  | ||||||
|  /* Cipher for new-format private keys */ |  | ||||||
| -static char *new_format_cipher = NULL;
 |  | ||||||
| +static char *openssh_format_cipher = NULL;
 |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
|   * Number of KDF rounds to derive new format keys / |  | ||||||
| @@ -1048,7 +1048,8 @@ do_gen_all_hostkeys(struct passwd *pw)
 |  | ||||||
|  		snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, |  | ||||||
|  		    hostname); |  | ||||||
|  		if ((r = sshkey_save_private(private, prv_tmp, "", |  | ||||||
| -		    comment, use_new_format, new_format_cipher, rounds)) != 0) {
 |  | ||||||
| +		    comment, private_key_format, openssh_format_cipher,
 |  | ||||||
| +		    rounds)) != 0) {
 |  | ||||||
|  			error("Saving key \"%s\" failed: %s", |  | ||||||
|  			    prv_tmp, ssh_err(r)); |  | ||||||
|  			goto failnext; |  | ||||||
| @@ -1391,7 +1392,7 @@ do_change_passphrase(struct passwd *pw)
 |  | ||||||
|   |  | ||||||
|  	/* Save the file using the new passphrase. */ |  | ||||||
|  	if ((r = sshkey_save_private(private, identity_file, passphrase1, |  | ||||||
| -	    comment, use_new_format, new_format_cipher, rounds)) != 0) {
 |  | ||||||
| +	    comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
 |  | ||||||
|  		error("Saving key \"%s\" failed: %s.", |  | ||||||
|  		    identity_file, ssh_err(r)); |  | ||||||
|  		explicit_bzero(passphrase1, strlen(passphrase1)); |  | ||||||
| @@ -1480,7 +1481,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
 |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if (private->type != KEY_ED25519 && private->type != KEY_XMSS && |  | ||||||
| -	    !use_new_format) {
 |  | ||||||
| +	    private_key_format != SSHKEY_PRIVATE_OPENSSH) {
 |  | ||||||
|  		error("Comments are only supported for keys stored in " |  | ||||||
|  		    "the new format (-o)."); |  | ||||||
|  		explicit_bzero(passphrase, strlen(passphrase)); |  | ||||||
| @@ -1514,7 +1515,8 @@ do_change_comment(struct passwd *pw, const char *identity_comment)
 |  | ||||||
|   |  | ||||||
|  	/* Save the file using the new passphrase. */ |  | ||||||
|  	if ((r = sshkey_save_private(private, identity_file, passphrase, |  | ||||||
| -	    new_comment, use_new_format, new_format_cipher, rounds)) != 0) {
 |  | ||||||
| +	    new_comment, private_key_format, openssh_format_cipher,
 |  | ||||||
| +	    rounds)) != 0) {
 |  | ||||||
|  		error("Saving key \"%s\" failed: %s", |  | ||||||
|  		    identity_file, ssh_err(r)); |  | ||||||
|  		explicit_bzero(passphrase, strlen(passphrase)); |  | ||||||
| @@ -2525,11 +2527,12 @@ main(int argc, char **argv)
 |  | ||||||
|  			} |  | ||||||
|  			if (strcasecmp(optarg, "PKCS8") == 0) { |  | ||||||
|  				convert_format = FMT_PKCS8; |  | ||||||
| +				private_key_format = SSHKEY_PRIVATE_PKCS8;
 |  | ||||||
|  				break; |  | ||||||
|  			} |  | ||||||
|  			if (strcasecmp(optarg, "PEM") == 0) { |  | ||||||
|  				convert_format = FMT_PEM; |  | ||||||
| -				use_new_format = 0;
 |  | ||||||
| +				private_key_format = SSHKEY_PRIVATE_PEM;
 |  | ||||||
|  				break; |  | ||||||
|  			} |  | ||||||
|  			fatal("Unsupported conversion format \"%s\"", optarg); |  | ||||||
| @@ -2567,7 +2570,7 @@ main(int argc, char **argv)
 |  | ||||||
|  			add_cert_option(optarg); |  | ||||||
|  			break; |  | ||||||
|  		case 'Z': |  | ||||||
| -			new_format_cipher = optarg;
 |  | ||||||
| +			openssh_format_cipher = optarg;
 |  | ||||||
|  			break; |  | ||||||
|  		case 'C': |  | ||||||
|  			identity_comment = optarg; |  | ||||||
| @@ -2912,7 +2915,7 @@ main(int argc, char **argv)
 |  | ||||||
|   |  | ||||||
|  	/* Save the key with the given passphrase and comment. */ |  | ||||||
|  	if ((r = sshkey_save_private(private, identity_file, passphrase1, |  | ||||||
| -	    comment, use_new_format, new_format_cipher, rounds)) != 0) {
 |  | ||||||
| +	    comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
 |  | ||||||
|  		error("Saving key \"%s\" failed: %s", |  | ||||||
|  		    identity_file, ssh_err(r)); |  | ||||||
|  		explicit_bzero(passphrase1, strlen(passphrase1)); |  | ||||||
| diff --git a/sshkey.c b/sshkey.c
 |  | ||||||
| index 6b5ff0485..a0cea9257 100644
 |  | ||||||
| --- a/sshkey.c
 |  | ||||||
| +++ b/sshkey.c
 |  | ||||||
| @@ -3975,10 +3975,10 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
 |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  #ifdef WITH_OPENSSL |  | ||||||
| -/* convert SSH v2 key in OpenSSL PEM format */
 |  | ||||||
| +/* convert SSH v2 key to PEM or PKCS#8 format */
 |  | ||||||
|  static int |  | ||||||
| -sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
 |  | ||||||
| -    const char *_passphrase, const char *comment)
 |  | ||||||
| +sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *blob,
 |  | ||||||
| +    int format, const char *_passphrase, const char *comment)
 |  | ||||||
|  { |  | ||||||
|  	int success, r; |  | ||||||
|  	int blen, len = strlen(_passphrase); |  | ||||||
| @@ -3988,26 +3988,46 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
 |  | ||||||
|  	const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; |  | ||||||
|  	char *bptr; |  | ||||||
|  	BIO *bio = NULL; |  | ||||||
| +	EVP_PKEY *pkey = NULL;
 |  | ||||||
|   |  | ||||||
|  	if (len > 0 && len <= 4) |  | ||||||
|  		return SSH_ERR_PASSPHRASE_TOO_SHORT; |  | ||||||
| -	if ((bio = BIO_new(BIO_s_mem())) == NULL)
 |  | ||||||
| -		return SSH_ERR_ALLOC_FAIL;
 |  | ||||||
| + 	if ((bio = BIO_new(BIO_s_mem())) == NULL) {
 |  | ||||||
| +		r = SSH_ERR_ALLOC_FAIL;
 |  | ||||||
| +		goto out;
 |  | ||||||
| + 	}
 |  | ||||||
| +
 |  | ||||||
| +	if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) {
 |  | ||||||
| +		r = SSH_ERR_ALLOC_FAIL;
 |  | ||||||
| +		goto out;
 |  | ||||||
| + 	}
 |  | ||||||
|   |  | ||||||
|  	switch (key->type) { |  | ||||||
|  	case KEY_DSA: |  | ||||||
| -		success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
 |  | ||||||
| -		    cipher, passphrase, len, NULL, NULL);
 |  | ||||||
| +		if (format == SSHKEY_PRIVATE_PEM) {
 |  | ||||||
| +			success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
 |  | ||||||
| +			    cipher, passphrase, len, NULL, NULL);
 |  | ||||||
| +		} else {
 |  | ||||||
| +			success = EVP_PKEY_set1_DSA(pkey, key->dsa);
 |  | ||||||
| +		}
 |  | ||||||
|  		break; |  | ||||||
|  #ifdef OPENSSL_HAS_ECC |  | ||||||
|  	case KEY_ECDSA: |  | ||||||
| -		success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
 |  | ||||||
| -		    cipher, passphrase, len, NULL, NULL);
 |  | ||||||
| +		if (format == SSHKEY_PRIVATE_PEM) {
 |  | ||||||
| +			success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
 |  | ||||||
| +			    cipher, passphrase, len, NULL, NULL);
 |  | ||||||
| +		} else {
 |  | ||||||
| +			success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa);
 |  | ||||||
| +		}
 |  | ||||||
|  		break; |  | ||||||
|  #endif |  | ||||||
|  	case KEY_RSA: |  | ||||||
| -		success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
 |  | ||||||
| -		    cipher, passphrase, len, NULL, NULL);
 |  | ||||||
| +		if (format == SSHKEY_PRIVATE_PEM) {
 |  | ||||||
| +			success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
 |  | ||||||
| +			    cipher, passphrase, len, NULL, NULL);
 |  | ||||||
| +		} else {
 |  | ||||||
| +			success = EVP_PKEY_set1_RSA(pkey, key->rsa);
 |  | ||||||
| +		}
 |  | ||||||
|  		break; |  | ||||||
|  	default: |  | ||||||
|  		success = 0; |  | ||||||
| @@ -4023,6 +4040,13 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
 |  | ||||||
|  		r = SSH_ERR_LIBCRYPTO_ERROR; |  | ||||||
|  		goto out; |  | ||||||
|  	} |  | ||||||
| +	if (format == SSHKEY_PRIVATE_PKCS8) {
 |  | ||||||
| +		if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher,
 |  | ||||||
| +		    passphrase, len, NULL, NULL)) == 0) {
 |  | ||||||
| +			r = SSH_ERR_LIBCRYPTO_ERROR;
 |  | ||||||
| +			goto out;
 |  | ||||||
| +		}
 |  | ||||||
| +	}
 |  | ||||||
|  	if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) { |  | ||||||
|  		r = SSH_ERR_INTERNAL_ERROR; |  | ||||||
|  		goto out; |  | ||||||
| @@ -4035,6 +4059,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
 |  | ||||||
|  		goto out; |  | ||||||
|  	r = 0; |  | ||||||
|   out: |  | ||||||
| +	EVP_PKEY_free(pkey);
 |  | ||||||
|  	BIO_free(bio); |  | ||||||
|  	return r; |  | ||||||
|  } |  | ||||||
| @@ -4046,29 +4071,38 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *buf,
 |  | ||||||
|  int |  | ||||||
|  sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, |  | ||||||
|      const char *passphrase, const char *comment, |  | ||||||
| -    int force_new_format, const char *new_format_cipher, int new_format_rounds)
 |  | ||||||
| +    int format, const char *openssh_format_cipher, int openssh_format_rounds)
 |  | ||||||
|  { |  | ||||||
|  	switch (key->type) { |  | ||||||
|  #ifdef WITH_OPENSSL |  | ||||||
|  	case KEY_DSA: |  | ||||||
|  	case KEY_ECDSA: |  | ||||||
|  	case KEY_RSA: |  | ||||||
| -		if (force_new_format) {
 |  | ||||||
| -			return sshkey_private_to_blob2(key, blob, passphrase,
 |  | ||||||
| -			    comment, new_format_cipher, new_format_rounds);
 |  | ||||||
| -		}
 |  | ||||||
| -		return sshkey_private_pem_to_blob(key, blob,
 |  | ||||||
| -		    passphrase, comment);
 |  | ||||||
| +		break; /* see below */
 |  | ||||||
|  #endif /* WITH_OPENSSL */ |  | ||||||
|  	case KEY_ED25519: |  | ||||||
|  #ifdef WITH_XMSS |  | ||||||
|  	case KEY_XMSS: |  | ||||||
|  #endif /* WITH_XMSS */ |  | ||||||
|  		return sshkey_private_to_blob2(key, blob, passphrase, |  | ||||||
| -		    comment, new_format_cipher, new_format_rounds);
 |  | ||||||
| +		    comment, openssh_format_cipher, openssh_format_rounds);
 |  | ||||||
|  	default: |  | ||||||
|  		return SSH_ERR_KEY_TYPE_UNKNOWN; |  | ||||||
|  	} |  | ||||||
| +
 |  | ||||||
| +#ifdef WITH_OPENSSL
 |  | ||||||
| +	switch (format) {
 |  | ||||||
| +	case SSHKEY_PRIVATE_OPENSSH:
 |  | ||||||
| +		return sshkey_private_to_blob2(key, blob, passphrase,
 |  | ||||||
| +		    comment, openssh_format_cipher, openssh_format_rounds);
 |  | ||||||
| +	case SSHKEY_PRIVATE_PEM:
 |  | ||||||
| +	case SSHKEY_PRIVATE_PKCS8:
 |  | ||||||
| +		return sshkey_private_to_blob_pem_pkcs8(key, blob,
 |  | ||||||
| +		    format, passphrase, comment);
 |  | ||||||
| +	default:
 |  | ||||||
| +		return SSH_ERR_INVALID_ARGUMENT;
 |  | ||||||
| +	}
 |  | ||||||
| +#endif /* WITH_OPENSSL */
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|   |  | ||||||
| diff --git a/sshkey.h b/sshkey.h
 |  | ||||||
| index 41d159a1b..d30a69cc9 100644
 |  | ||||||
| --- a/sshkey.h
 |  | ||||||
| +++ b/sshkey.h
 |  | ||||||
| @@ -88,6 +88,13 @@ enum sshkey_serialize_rep {
 |  | ||||||
|  	SSHKEY_SERIALIZE_INFO = 254, |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +/* Private key disk formats */
 |  | ||||||
| +enum sshkey_private_format {
 |  | ||||||
| +	SSHKEY_PRIVATE_OPENSSH = 0,
 |  | ||||||
| +	SSHKEY_PRIVATE_PEM = 1,
 |  | ||||||
| +	SSHKEY_PRIVATE_PKCS8 = 2,
 |  | ||||||
| +};
 |  | ||||||
| +
 |  | ||||||
|  /* key is stored in external hardware */ |  | ||||||
|  #define SSHKEY_FLAG_EXT		0x0001 |  | ||||||
|   |  | ||||||
| @@ -221,7 +228,7 @@ int	sshkey_private_deserialize(struct sshbuf *buf,  struct sshkey **keyp);
 |  | ||||||
|  /* private key file format parsing and serialisation */ |  | ||||||
|  int	sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, |  | ||||||
|      const char *passphrase, const char *comment, |  | ||||||
| -    int force_new_format, const char *new_format_cipher, int new_format_rounds);
 |  | ||||||
| +    int format, const char *openssh_format_cipher, int openssh_format_rounds);
 |  | ||||||
|  int	sshkey_parse_private_fileblob(struct sshbuf *buffer, |  | ||||||
|      const char *passphrase, struct sshkey **keyp, char **commentp); |  | ||||||
|  int	sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, |  | ||||||
| 
 |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,33 +0,0 @@ | |||||||
| From de1f3564cd85915b3002859873a37cb8d31ac9ce Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "dtucker@openbsd.org" <dtucker@openbsd.org> |  | ||||||
| Date: Tue, 18 Feb 2020 08:49:49 +0000 |  | ||||||
| Subject: [PATCH] upstream: Detect and prevent simple configuration loops when |  | ||||||
|  using |  | ||||||
| 
 |  | ||||||
| ProxyJump. bz#3057, ok djm@ |  | ||||||
| 
 |  | ||||||
| OpenBSD-Commit-ID: 077d21c564c886c98309d871ed6f8ef267b9f037 |  | ||||||
| ---
 |  | ||||||
|  ssh.c | 10 +++++++++- |  | ||||||
|  1 file changed, 9 insertions(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/ssh.c b/ssh.c
 |  | ||||||
| index 15aee569e..a983a108b 100644
 |  | ||||||
| --- a/ssh.c
 |  | ||||||
| +++ b/ssh.c
 |  | ||||||
| @@ -1208,6 +1208,14 @@ main(int ac, char **av)
 |  | ||||||
|  	if (options.jump_host != NULL) { |  | ||||||
|  		char port_s[8]; |  | ||||||
|  		const char *sshbin = argv0; |  | ||||||
| +		int port = options.port, jumpport = options.jump_port;
 |  | ||||||
| +
 |  | ||||||
| +		if (port <= 0)
 |  | ||||||
| +			port = default_ssh_port();
 |  | ||||||
| +		if (jumpport <= 0)
 |  | ||||||
| +			jumpport = default_ssh_port();
 |  | ||||||
| +		if (strcmp(options.jump_host, host) == 0 && port == jumpport)
 |  | ||||||
| +			fatal("jumphost loop via %s", options.jump_host);
 |  | ||||||
|   |  | ||||||
|  		/* |  | ||||||
|  		 * Try to use SSH indicated by argv[0], but fall back to |  | ||||||
| 
 |  | ||||||
| @ -1,44 +0,0 @@ | |||||||
| commit 5481d0b4036b33b92c372ee36258ed11bff57d5d |  | ||||||
| Author: Jakub Jelen <jjelen@redhat.com> |  | ||||||
| Date:   Thu Feb 27 10:07:33 2020 +0100 |  | ||||||
| 
 |  | ||||||
|     Mark the RDomain configuration option unsupported on non-openbsd builds |  | ||||||
| 
 |  | ||||||
| diff --git a/servconf.c b/servconf.c
 |  | ||||||
| index db80e943..153d2525 100644
 |  | ||||||
| --- a/servconf.c
 |  | ||||||
| +++ b/servconf.c
 |  | ||||||
| @@ -698,7 +698,11 @@ static struct {
 |  | ||||||
|  	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, |  | ||||||
|  	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL }, |  | ||||||
|  	{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, |  | ||||||
| +#if defined(__OpenBSD__)
 |  | ||||||
|  	{ "rdomain", sRDomain, SSHCFG_ALL }, |  | ||||||
| +#else
 |  | ||||||
| +	{ "rdomain", sUnsupported, SSHCFG_ALL },
 |  | ||||||
| +#endif
 |  | ||||||
|  	{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, |  | ||||||
|  	{ NULL, sBadOption, 0 } |  | ||||||
|  }; |  | ||||||
| @@ -2841,7 +2845,9 @@ dump_config(ServerOptions *o)
 |  | ||||||
|  	    o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); |  | ||||||
|  	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? |  | ||||||
|  	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG); |  | ||||||
| +#if defined(__OpenBSD__)
 |  | ||||||
|  	dump_cfg_string(sRDomain, o->routing_domain); |  | ||||||
| +#endif
 |  | ||||||
|   |  | ||||||
|  	/* string arguments requiring a lookup */ |  | ||||||
|  	dump_cfg_string(sLogLevel, log_level_name(o->log_level)); |  | ||||||
| diff --git a/sshd_config.5 b/sshd_config.5
 |  | ||||||
| index 5dca8981..766e9b90 100644
 |  | ||||||
| --- a/sshd_config.5
 |  | ||||||
| +++ b/sshd_config.5
 |  | ||||||
| @@ -1542,6 +1542,7 @@ will be bound to this
 |  | ||||||
|  If the routing domain is set to |  | ||||||
|  .Cm \&%D , |  | ||||||
|  then the domain in which the incoming connection was received will be applied. |  | ||||||
| +This feature is available on OpenBSD only.
 |  | ||||||
|  .It Cm SetEnv |  | ||||||
|  Specifies one or more environment variables to set in child sessions started |  | ||||||
|  by |  | ||||||
| @ -1,311 +0,0 @@ | |||||||
| diff -up openssh-8.0p1/channels.c.restore-nonblock openssh-8.0p1/channels.c
 |  | ||||||
| --- openssh-8.0p1/channels.c.restore-nonblock	2021-06-21 10:44:26.380559612 +0200
 |  | ||||||
| +++ openssh-8.0p1/channels.c	2021-06-21 10:48:47.754579151 +0200
 |  | ||||||
| @@ -333,7 +333,27 @@ channel_register_fds(struct ssh *ssh, Ch
 |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
|  	/* enable nonblocking mode */ |  | ||||||
| -	if (nonblock) {
 |  | ||||||
| +	c->restore_block = 0;
 |  | ||||||
| +	if (nonblock == CHANNEL_NONBLOCK_STDIO) {
 |  | ||||||
| +		/*
 |  | ||||||
| +		 * Special handling for stdio file descriptors: do not set
 |  | ||||||
| +		 * non-blocking mode if they are TTYs. Otherwise prepare to
 |  | ||||||
| +		 * restore their blocking state on exit to avoid interfering
 |  | ||||||
| +		 * with other programs that follow.
 |  | ||||||
| +		 */
 |  | ||||||
| +		if (rfd != -1 && !isatty(rfd) && fcntl(rfd, F_GETFL) == 0) {
 |  | ||||||
| +			c->restore_block |= CHANNEL_RESTORE_RFD;
 |  | ||||||
| +			set_nonblock(rfd);
 |  | ||||||
| +		}
 |  | ||||||
| +		if (wfd != -1 && !isatty(wfd) && fcntl(wfd, F_GETFL) == 0) {
 |  | ||||||
| +			c->restore_block |= CHANNEL_RESTORE_WFD;
 |  | ||||||
| +			set_nonblock(wfd);
 |  | ||||||
| +		}
 |  | ||||||
| +		if (efd != -1 && !isatty(efd) && fcntl(efd, F_GETFL) == 0) {
 |  | ||||||
| +			c->restore_block |= CHANNEL_RESTORE_EFD;
 |  | ||||||
| +			set_nonblock(efd);
 |  | ||||||
| +		}
 |  | ||||||
| +	} else if (nonblock) {
 |  | ||||||
|  		if (rfd != -1) |  | ||||||
|  			set_nonblock(rfd); |  | ||||||
|  		if (wfd != -1) |  | ||||||
| @@ -422,17 +442,23 @@ channel_find_maxfd(struct ssh_channels *
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  int |  | ||||||
| -channel_close_fd(struct ssh *ssh, int *fdp)
 |  | ||||||
| +channel_close_fd(struct ssh *ssh, Channel *c, int *fdp)
 |  | ||||||
|  { |  | ||||||
|  	struct ssh_channels *sc = ssh->chanctxt; |  | ||||||
| -	int ret = 0, fd = *fdp;
 |  | ||||||
| +	int ret, fd = *fdp;
 |  | ||||||
|   |  | ||||||
| -	if (fd != -1) {
 |  | ||||||
| -		ret = close(fd);
 |  | ||||||
| -		*fdp = -1;
 |  | ||||||
| -		if (fd == sc->channel_max_fd)
 |  | ||||||
| -			channel_find_maxfd(sc);
 |  | ||||||
| -	}
 |  | ||||||
| +	if (fd == -1)
 |  | ||||||
| +		return 0;
 |  | ||||||
| +
 |  | ||||||
| +	if ((*fdp == c->rfd && (c->restore_block & CHANNEL_RESTORE_RFD) != 0) ||
 |  | ||||||
| +	   (*fdp == c->wfd && (c->restore_block & CHANNEL_RESTORE_WFD) != 0) ||
 |  | ||||||
| +	   (*fdp == c->efd && (c->restore_block & CHANNEL_RESTORE_EFD) != 0))
 |  | ||||||
| +		(void)fcntl(*fdp, F_SETFL, 0);	/* restore blocking */
 |  | ||||||
| +
 |  | ||||||
| +	ret = close(fd);
 |  | ||||||
| +	*fdp = -1;
 |  | ||||||
| +	if (fd == sc->channel_max_fd)
 |  | ||||||
| +		channel_find_maxfd(sc);
 |  | ||||||
|  	return ret; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -442,13 +468,13 @@ channel_close_fds(struct ssh *ssh, Chann
 |  | ||||||
|  { |  | ||||||
|  	int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; |  | ||||||
|   |  | ||||||
| -	channel_close_fd(ssh, &c->sock);
 |  | ||||||
| +	channel_close_fd(ssh, c, &c->sock);
 |  | ||||||
|  	if (rfd != sock) |  | ||||||
| -		channel_close_fd(ssh, &c->rfd);
 |  | ||||||
| +		channel_close_fd(ssh, c, &c->rfd);
 |  | ||||||
|  	if (wfd != sock && wfd != rfd) |  | ||||||
| -		channel_close_fd(ssh, &c->wfd);
 |  | ||||||
| +		channel_close_fd(ssh, c, &c->wfd);
 |  | ||||||
|  	if (efd != sock && efd != rfd && efd != wfd) |  | ||||||
| -		channel_close_fd(ssh, &c->efd);
 |  | ||||||
| +		channel_close_fd(ssh, c, &c->efd);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static void |  | ||||||
| @@ -681,7 +707,7 @@ channel_stop_listening(struct ssh *ssh)
 |  | ||||||
|  			case SSH_CHANNEL_X11_LISTENER: |  | ||||||
|  			case SSH_CHANNEL_UNIX_LISTENER: |  | ||||||
|  			case SSH_CHANNEL_RUNIX_LISTENER: |  | ||||||
| -				channel_close_fd(ssh, &c->sock);
 |  | ||||||
| +				channel_close_fd(ssh, c, &c->sock);
 |  | ||||||
|  				channel_free(ssh, c); |  | ||||||
|  				break; |  | ||||||
|  			} |  | ||||||
| @@ -1487,7 +1513,8 @@ channel_decode_socks5(Channel *c, struct
 |  | ||||||
|   |  | ||||||
|  Channel * |  | ||||||
|  channel_connect_stdio_fwd(struct ssh *ssh, |  | ||||||
| -    const char *host_to_connect, u_short port_to_connect, int in, int out)
 |  | ||||||
| +    const char *host_to_connect, u_short port_to_connect,
 |  | ||||||
| +    int in, int out, int nonblock)
 |  | ||||||
|  { |  | ||||||
|  	Channel *c; |  | ||||||
|   |  | ||||||
| @@ -1495,7 +1522,7 @@ channel_connect_stdio_fwd(struct ssh *ss
 |  | ||||||
|   |  | ||||||
|  	c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out, |  | ||||||
|  	    -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, |  | ||||||
| -	    0, "stdio-forward", /*nonblock*/0);
 |  | ||||||
| +	    0, "stdio-forward", nonblock);
 |  | ||||||
|   |  | ||||||
|  	c->path = xstrdup(host_to_connect); |  | ||||||
|  	c->host_port = port_to_connect; |  | ||||||
| @@ -1650,7 +1677,7 @@ channel_post_x11_listener(struct ssh *ss
 |  | ||||||
|  	if (c->single_connection) { |  | ||||||
|  		oerrno = errno; |  | ||||||
|  		debug2("single_connection: closing X11 listener."); |  | ||||||
| -		channel_close_fd(ssh, &c->sock);
 |  | ||||||
| +		channel_close_fd(ssh, c, &c->sock);
 |  | ||||||
|  		chan_mark_dead(ssh, c); |  | ||||||
|  		errno = oerrno; |  | ||||||
|  	} |  | ||||||
| @@ -2087,7 +2114,7 @@ channel_handle_efd_write(struct ssh *ssh
 |  | ||||||
|  		return 1; |  | ||||||
|  	if (len <= 0) { |  | ||||||
|  		debug2("channel %d: closing write-efd %d", c->self, c->efd); |  | ||||||
| -		channel_close_fd(ssh, &c->efd);
 |  | ||||||
| +		channel_close_fd(ssh, c, &c->efd);
 |  | ||||||
|  	} else { |  | ||||||
|  		if ((r = sshbuf_consume(c->extended, len)) != 0) { |  | ||||||
|  			fatal("%s: channel %d: consume: %s", |  | ||||||
| @@ -2119,7 +2146,7 @@ channel_handle_efd_read(struct ssh *ssh,
 |  | ||||||
|  	if (len <= 0) { |  | ||||||
|  		debug2("channel %d: closing read-efd %d", |  | ||||||
|  		    c->self, c->efd); |  | ||||||
| -		channel_close_fd(ssh, &c->efd);
 |  | ||||||
| +		channel_close_fd(ssh, c, &c->efd);
 |  | ||||||
|  	} else { |  | ||||||
|  		if (c->extended_usage == CHAN_EXTENDED_IGNORE) { |  | ||||||
|  			debug3("channel %d: discard efd", |  | ||||||
| diff -up openssh-8.0p1/channels.h.restore-nonblock openssh-8.0p1/channels.h
 |  | ||||||
| --- openssh-8.0p1/channels.h.restore-nonblock	2021-06-21 10:44:26.380559612 +0200
 |  | ||||||
| +++ openssh-8.0p1/channels.h	2021-06-21 10:44:26.387559665 +0200
 |  | ||||||
| @@ -63,6 +63,16 @@
 |  | ||||||
|   |  | ||||||
|  #define CHANNEL_CANCEL_PORT_STATIC	-1 |  | ||||||
|   |  | ||||||
| +/* nonblocking flags for channel_new */
 |  | ||||||
| +#define CHANNEL_NONBLOCK_LEAVE	0 /* don't modify non-blocking state */
 |  | ||||||
| +#define CHANNEL_NONBLOCK_SET	1 /* set non-blocking state */
 |  | ||||||
| +#define CHANNEL_NONBLOCK_STDIO	2 /* set non-blocking and restore on close */
 |  | ||||||
| +
 |  | ||||||
| +/* c->restore_block mask flags */
 |  | ||||||
| +#define CHANNEL_RESTORE_RFD	0x01
 |  | ||||||
| +#define CHANNEL_RESTORE_WFD	0x02
 |  | ||||||
| +#define CHANNEL_RESTORE_EFD	0x04
 |  | ||||||
| +
 |  | ||||||
|  /* TCP forwarding */ |  | ||||||
|  #define FORWARD_DENY		0 |  | ||||||
|  #define FORWARD_REMOTE		(1) |  | ||||||
| @@ -131,6 +141,7 @@ struct Channel {
 |  | ||||||
|  				 * to a matching pre-select handler. |  | ||||||
|  				 * this way post-select handlers are not |  | ||||||
|  				 * accidentally called if a FD gets reused */ |  | ||||||
| +	int	restore_block;	/* fd mask to restore blocking status */
 |  | ||||||
|  	struct sshbuf *input;	/* data read from socket, to be sent over |  | ||||||
|  				 * encrypted connection */ |  | ||||||
|  	struct sshbuf *output;	/* data received over encrypted connection for |  | ||||||
| @@ -258,7 +269,7 @@ void	 channel_register_filter(struct ssh
 |  | ||||||
|  void	 channel_register_status_confirm(struct ssh *, int, |  | ||||||
|  	    channel_confirm_cb *, channel_confirm_abandon_cb *, void *); |  | ||||||
|  void	 channel_cancel_cleanup(struct ssh *, int); |  | ||||||
| -int	 channel_close_fd(struct ssh *, int *);
 |  | ||||||
| +int	 channel_close_fd(struct ssh *, Channel *, int *);
 |  | ||||||
|  void	 channel_send_window_changes(struct ssh *); |  | ||||||
|   |  | ||||||
|  /* mux proxy support */ |  | ||||||
| @@ -305,7 +316,7 @@ Channel	*channel_connect_to_port(struct
 |  | ||||||
|  	    char *, char *, int *, const char **); |  | ||||||
|  Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *); |  | ||||||
|  Channel	*channel_connect_stdio_fwd(struct ssh *, const char*, |  | ||||||
| -	    u_short, int, int);
 |  | ||||||
| +	    u_short, int, int, int);
 |  | ||||||
|  Channel	*channel_connect_by_listen_address(struct ssh *, const char *, |  | ||||||
|  	    u_short, char *, char *); |  | ||||||
|  Channel	*channel_connect_by_listen_path(struct ssh *, const char *, |  | ||||||
| diff -up openssh-8.0p1/clientloop.c.restore-nonblock openssh-8.0p1/clientloop.c
 |  | ||||||
| --- openssh-8.0p1/clientloop.c.restore-nonblock	2021-06-21 10:44:26.290558923 +0200
 |  | ||||||
| +++ openssh-8.0p1/clientloop.c	2021-06-21 10:44:26.387559665 +0200
 |  | ||||||
| @@ -1436,14 +1436,6 @@ client_loop(struct ssh *ssh, int have_pt
 |  | ||||||
|  	if (have_pty) |  | ||||||
|  		leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |  | ||||||
|   |  | ||||||
| -	/* restore blocking io */
 |  | ||||||
| -	if (!isatty(fileno(stdin)))
 |  | ||||||
| -		unset_nonblock(fileno(stdin));
 |  | ||||||
| -	if (!isatty(fileno(stdout)))
 |  | ||||||
| -		unset_nonblock(fileno(stdout));
 |  | ||||||
| -	if (!isatty(fileno(stderr)))
 |  | ||||||
| -		unset_nonblock(fileno(stderr));
 |  | ||||||
| -
 |  | ||||||
|  	/* |  | ||||||
|  	 * If there was no shell or command requested, there will be no remote |  | ||||||
|  	 * exit status to be returned.  In that case, clear error code if the |  | ||||||
| diff -up openssh-8.0p1/mux.c.restore-nonblock openssh-8.0p1/mux.c
 |  | ||||||
| --- openssh-8.0p1/mux.c.restore-nonblock	2019-04-18 00:52:57.000000000 +0200
 |  | ||||||
| +++ openssh-8.0p1/mux.c	2021-06-21 10:50:51.007537336 +0200
 |  | ||||||
| @@ -454,14 +454,6 @@ mux_master_process_new_session(struct ss
 |  | ||||||
|  	if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) |  | ||||||
|  		error("%s: tcgetattr: %s", __func__, strerror(errno)); |  | ||||||
|   |  | ||||||
| -	/* enable nonblocking unless tty */
 |  | ||||||
| -	if (!isatty(new_fd[0]))
 |  | ||||||
| -		set_nonblock(new_fd[0]);
 |  | ||||||
| -	if (!isatty(new_fd[1]))
 |  | ||||||
| -		set_nonblock(new_fd[1]);
 |  | ||||||
| -	if (!isatty(new_fd[2]))
 |  | ||||||
| -		set_nonblock(new_fd[2]);
 |  | ||||||
| -
 |  | ||||||
|  	window = CHAN_SES_WINDOW_DEFAULT; |  | ||||||
|  	packetmax = CHAN_SES_PACKET_DEFAULT; |  | ||||||
|  	if (cctx->want_tty) { |  | ||||||
| @@ -471,7 +463,7 @@ mux_master_process_new_session(struct ss
 |  | ||||||
|   |  | ||||||
|  	nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING, |  | ||||||
|  	    new_fd[0], new_fd[1], new_fd[2], window, packetmax, |  | ||||||
| -	    CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
 |  | ||||||
| +	    CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO);
 |  | ||||||
|   |  | ||||||
|  	nc->ctl_chan = c->self;		/* link session -> control channel */ |  | ||||||
|  	c->remote_id = nc->self; 	/* link control -> session channel */ |  | ||||||
| @@ -1033,13 +1025,8 @@ mux_master_process_stdio_fwd(struct ssh
 |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| -	/* enable nonblocking unless tty */
 |  | ||||||
| -	if (!isatty(new_fd[0]))
 |  | ||||||
| -		set_nonblock(new_fd[0]);
 |  | ||||||
| -	if (!isatty(new_fd[1]))
 |  | ||||||
| -		set_nonblock(new_fd[1]);
 |  | ||||||
| -
 |  | ||||||
| -	nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]);
 |  | ||||||
| +	nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1],
 |  | ||||||
| +	    CHANNEL_NONBLOCK_STDIO);
 |  | ||||||
|  	free(chost); |  | ||||||
|   |  | ||||||
|  	nc->ctl_chan = c->self;		/* link session -> control channel */ |  | ||||||
| diff -up openssh-8.0p1/nchan.c.restore-nonblock openssh-8.0p1/nchan.c
 |  | ||||||
| --- openssh-8.0p1/nchan.c.restore-nonblock	2021-06-21 10:44:26.388559673 +0200
 |  | ||||||
| +++ openssh-8.0p1/nchan.c	2021-06-21 10:52:42.685405537 +0200
 |  | ||||||
| @@ -387,7 +387,7 @@ chan_shutdown_write(struct ssh *ssh, Cha
 |  | ||||||
|  			    strerror(errno)); |  | ||||||
|  		} |  | ||||||
|  	} else { |  | ||||||
| -		if (channel_close_fd(ssh, &c->wfd) < 0) {
 |  | ||||||
| +		if (channel_close_fd(ssh, c, &c->wfd) < 0) {
 |  | ||||||
|  			logit("channel %d: %s: close() failed for " |  | ||||||
|  			    "fd %d [i%d o%d]: %.100s", |  | ||||||
|  			    c->self, __func__, c->wfd, c->istate, c->ostate, |  | ||||||
| @@ -417,7 +417,7 @@ chan_shutdown_read(struct ssh *ssh, Chan
 |  | ||||||
|   			    strerror(errno)); |  | ||||||
|  		} |  | ||||||
|  	} else { |  | ||||||
| -		if (channel_close_fd(ssh, &c->rfd) < 0) {
 |  | ||||||
| +		if (channel_close_fd(ssh, c, &c->rfd) < 0) {
 |  | ||||||
|  			logit("channel %d: %s: close() failed for " |  | ||||||
|  			    "fd %d [i%d o%d]: %.100s", |  | ||||||
|  			    c->self, __func__, c->rfd, c->istate, c->ostate, |  | ||||||
| @@ -437,7 +437,7 @@ chan_shutdown_extended_read(struct ssh *
 |  | ||||||
|  	debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])", |  | ||||||
|  	    c->self, __func__, c->istate, c->ostate, c->sock, c->rfd, c->efd, |  | ||||||
|  	    channel_format_extended_usage(c)); |  | ||||||
| -	if (channel_close_fd(ssh, &c->efd) < 0) {
 |  | ||||||
| +	if (channel_close_fd(ssh, c, &c->efd) < 0) {
 |  | ||||||
|  		logit("channel %d: %s: close() failed for " |  | ||||||
|  		    "extended fd %d [i%d o%d]: %.100s", |  | ||||||
|  		    c->self, __func__, c->efd, c->istate, c->ostate, |  | ||||||
| diff -up openssh-8.0p1/ssh.c.restore-nonblock openssh-8.0p1/ssh.c
 |  | ||||||
| --- openssh-8.0p1/ssh.c.restore-nonblock	2021-06-21 10:44:26.389559681 +0200
 |  | ||||||
| +++ openssh-8.0p1/ssh.c	2021-06-21 10:54:47.651377045 +0200
 |  | ||||||
| @@ -1709,7 +1709,8 @@ ssh_init_stdio_forwarding(struct ssh *ss
 |  | ||||||
|  	    (out = dup(STDOUT_FILENO)) < 0) |  | ||||||
|  		fatal("channel_connect_stdio_fwd: dup() in/out failed"); |  | ||||||
|  	if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host, |  | ||||||
| -	    options.stdio_forward_port, in, out)) == NULL)
 |  | ||||||
| +	    options.stdio_forward_port, in, out,
 |  | ||||||
| +	    CHANNEL_NONBLOCK_STDIO)) == NULL)
 |  | ||||||
|  		fatal("%s: channel_connect_stdio_fwd failed", __func__); |  | ||||||
|  	channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0); |  | ||||||
|  	channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL); |  | ||||||
| @@ -1862,14 +1863,6 @@ ssh_session2_open(struct ssh *ssh)
 |  | ||||||
|  	if (in < 0 || out < 0 || err < 0) |  | ||||||
|  		fatal("dup() in/out/err failed"); |  | ||||||
|   |  | ||||||
| -	/* enable nonblocking unless tty */
 |  | ||||||
| -	if (!isatty(in))
 |  | ||||||
| -		set_nonblock(in);
 |  | ||||||
| -	if (!isatty(out))
 |  | ||||||
| -		set_nonblock(out);
 |  | ||||||
| -	if (!isatty(err))
 |  | ||||||
| -		set_nonblock(err);
 |  | ||||||
| -
 |  | ||||||
|  	window = CHAN_SES_WINDOW_DEFAULT; |  | ||||||
|  	packetmax = CHAN_SES_PACKET_DEFAULT; |  | ||||||
|  	if (tty_flag) { |  | ||||||
| @@ -1879,7 +1872,7 @@ ssh_session2_open(struct ssh *ssh)
 |  | ||||||
|  	c = channel_new(ssh, |  | ||||||
|  	    "session", SSH_CHANNEL_OPENING, in, out, err, |  | ||||||
|  	    window, packetmax, CHAN_EXTENDED_WRITE, |  | ||||||
| -	    "client-session", /*nonblock*/0);
 |  | ||||||
| +	    "client-session", CHANNEL_NONBLOCK_STDIO);
 |  | ||||||
|   |  | ||||||
|  	debug3("%s: channel_new: %d", __func__, c->self); |  | ||||||
|   |  | ||||||
| @ -1,61 +0,0 @@ | |||||||
| diff --git a/regress/scp-ssh-wrapper.sh b/regress/scp-ssh-wrapper.sh
 |  | ||||||
| index 59f1ff63..dd48a482 100644
 |  | ||||||
| --- a/regress/scp-ssh-wrapper.sh
 |  | ||||||
| +++ b/regress/scp-ssh-wrapper.sh
 |  | ||||||
| @@ -51,6 +51,18 @@ badserver_4)
 |  | ||||||
|  	echo "C755 2 file" |  | ||||||
|  	echo "X" |  | ||||||
|  	;; |  | ||||||
| +badserver_5)
 |  | ||||||
| +	echo "D0555 0 "
 |  | ||||||
| +	echo "X"
 |  | ||||||
| +	;;
 |  | ||||||
| +badserver_6)
 |  | ||||||
| +	echo "D0555 0 ."
 |  | ||||||
| +	echo "X"
 |  | ||||||
| +	;;
 |  | ||||||
| +badserver_7)
 |  | ||||||
| +	echo "C0755 2 extrafile"
 |  | ||||||
| +	echo "X"
 |  | ||||||
| +	;;
 |  | ||||||
|  *) |  | ||||||
|  	set -- $arg |  | ||||||
|  	shift |  | ||||||
| diff --git a/regress/scp.sh b/regress/scp.sh
 |  | ||||||
| index 57cc7706..104c89e1 100644
 |  | ||||||
| --- a/regress/scp.sh
 |  | ||||||
| +++ b/regress/scp.sh
 |  | ||||||
| @@ -25,6 +25,7 @@ export SCP # used in scp-ssh-wrapper.scp
 |  | ||||||
|  scpclean() { |  | ||||||
|  	rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} |  | ||||||
|  	mkdir ${DIR} ${DIR2} |  | ||||||
| +	chmod 755 ${DIR} ${DIR2}
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  verbose "$tid: simple copy local file to local file" |  | ||||||
| @@ -101,7 +102,7 @@ if [ ! -z "$SUDO" ]; then
 |  | ||||||
|  	$SUDO rm ${DIR2}/copy |  | ||||||
|  fi |  | ||||||
|   |  | ||||||
| -for i in 0 1 2 3 4; do
 |  | ||||||
| +for i in 0 1 2 3 4 5 6 7; do
 |  | ||||||
|  	verbose "$tid: disallow bad server #$i" |  | ||||||
|  	SCPTESTMODE=badserver_$i |  | ||||||
|  	export DIR SCPTESTMODE |  | ||||||
| @@ -113,6 +114,15 @@ for i in 0 1 2 3 4; do
 |  | ||||||
|  	scpclean |  | ||||||
|  	$SCP -r $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null |  | ||||||
|  	[ -d ${DIR}/dotpathdir ] && fail "allows dir creation outside of subdir" |  | ||||||
| +
 |  | ||||||
| +	scpclean
 |  | ||||||
| +	$SCP -pr $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
 |  | ||||||
| +	[ ! -w ${DIR2} ] && fail "allows target root attribute change"
 |  | ||||||
| +
 |  | ||||||
| +	scpclean
 |  | ||||||
| +	$SCP $scpopts somehost:${DATA} ${DIR2} >/dev/null 2>/dev/null
 |  | ||||||
| +	[ -e ${DIR2}/extrafile ] && fail "allows extranous object creation"
 |  | ||||||
| +	rm -f ${DIR2}/extrafile
 |  | ||||||
|  done |  | ||||||
|   |  | ||||||
|  verbose "$tid: detect non-directory target" |  | ||||||
| 
 |  | ||||||
| @ -1,273 +0,0 @@ | |||||||
| diff --color -ruN a/Makefile.in b/Makefile.in
 |  | ||||||
| --- a/Makefile.in	2022-06-23 11:31:10.168186838 +0200
 |  | ||||||
| +++ b/Makefile.in	2022-06-23 11:32:19.146513347 +0200
 |  | ||||||
| @@ -125,7 +125,7 @@
 |  | ||||||
|  	monitor.o monitor_wrap.o auth-krb5.o \ |  | ||||||
|  	auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ |  | ||||||
|  	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ |  | ||||||
| -	sftp-server.o sftp-common.o \
 |  | ||||||
| +	sftp-server.o sftp-common.o sftp-realpath.o \
 |  | ||||||
|  	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ |  | ||||||
|  	sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ |  | ||||||
|  	sandbox-solaris.o uidswap.o |  | ||||||
| @@ -217,8 +217,8 @@
 |  | ||||||
|  ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o |  | ||||||
|  	$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(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)
 |  | ||||||
| +sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-realpath.o sftp-server.o sftp-server-main.o
 |  | ||||||
| +	$(LD) -o $@ sftp-server.o sftp-common.o sftp-realpath.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 |  | ||||||
|   |  | ||||||
|  sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o |  | ||||||
|  	$(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT) |  | ||||||
| diff --color -ruN a/sftp-realpath.c b/sftp-realpath.c
 |  | ||||||
| --- a/sftp-realpath.c	1970-01-01 01:00:00.000000000 +0100
 |  | ||||||
| +++ b/sftp-realpath.c	2022-06-23 11:35:33.193244873 +0200
 |  | ||||||
| @@ -0,0 +1,225 @@
 |  | ||||||
| +/*	$OpenBSD: sftp-realpath.c,v 1.2 2021/09/02 21:03:54 deraadt Exp $ */
 |  | ||||||
| +/*
 |  | ||||||
| + * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
 |  | ||||||
| + *
 |  | ||||||
| + * Redistribution and use in source and binary forms, with or without
 |  | ||||||
| + * modification, are permitted provided that the following conditions
 |  | ||||||
| + * are met:
 |  | ||||||
| + * 1. Redistributions of source code must retain the above copyright
 |  | ||||||
| + *    notice, this list of conditions and the following disclaimer.
 |  | ||||||
| + * 2. Redistributions in binary form must reproduce the above copyright
 |  | ||||||
| + *    notice, this list of conditions and the following disclaimer in the
 |  | ||||||
| + *    documentation and/or other materials provided with the distribution.
 |  | ||||||
| + * 3. The names of the authors may not be used to endorse or promote
 |  | ||||||
| + *    products derived from this software without specific prior written
 |  | ||||||
| + *    permission.
 |  | ||||||
| + *
 |  | ||||||
| + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
 |  | ||||||
| + */
 |  | ||||||
| +
 |  | ||||||
| +#include "includes.h"
 |  | ||||||
| +
 |  | ||||||
| +#include <sys/types.h>
 |  | ||||||
| +#include <sys/stat.h>
 |  | ||||||
| +
 |  | ||||||
| +#include <errno.h>
 |  | ||||||
| +#include <stdlib.h>
 |  | ||||||
| +#include <stddef.h>
 |  | ||||||
| +#include <string.h>
 |  | ||||||
| +#include <unistd.h>
 |  | ||||||
| +#include <limits.h>
 |  | ||||||
| +
 |  | ||||||
| +#ifndef SYMLOOP_MAX
 |  | ||||||
| +# define SYMLOOP_MAX 32
 |  | ||||||
| +#endif
 |  | ||||||
| +
 |  | ||||||
| +/* XXX rewrite sftp-server to use POSIX realpath and remove this hack */
 |  | ||||||
| +
 |  | ||||||
| +char *sftp_realpath(const char *path, char *resolved);
 |  | ||||||
| +
 |  | ||||||
| +/*
 |  | ||||||
| + * char *realpath(const char *path, char resolved[PATH_MAX]);
 |  | ||||||
| + *
 |  | ||||||
| + * Find the real name of path, by removing all ".", ".." and symlink
 |  | ||||||
| + * components.  Returns (resolved) on success, or (NULL) on failure,
 |  | ||||||
| + * in which case the path which caused trouble is left in (resolved).
 |  | ||||||
| + */
 |  | ||||||
| +char *
 |  | ||||||
| +sftp_realpath(const char *path, char *resolved)
 |  | ||||||
| +{
 |  | ||||||
| +	struct stat sb;
 |  | ||||||
| +	char *p, *q, *s;
 |  | ||||||
| +	size_t left_len, resolved_len;
 |  | ||||||
| +	unsigned symlinks;
 |  | ||||||
| +	int serrno, slen, mem_allocated;
 |  | ||||||
| +	char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
 |  | ||||||
| +
 |  | ||||||
| +	if (path[0] == '\0') {
 |  | ||||||
| +		errno = ENOENT;
 |  | ||||||
| +		return (NULL);
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +	serrno = errno;
 |  | ||||||
| +
 |  | ||||||
| +	if (resolved == NULL) {
 |  | ||||||
| +		resolved = malloc(PATH_MAX);
 |  | ||||||
| +		if (resolved == NULL)
 |  | ||||||
| +			return (NULL);
 |  | ||||||
| +		mem_allocated = 1;
 |  | ||||||
| +	} else
 |  | ||||||
| +		mem_allocated = 0;
 |  | ||||||
| +
 |  | ||||||
| +	symlinks = 0;
 |  | ||||||
| +	if (path[0] == '/') {
 |  | ||||||
| +		resolved[0] = '/';
 |  | ||||||
| +		resolved[1] = '\0';
 |  | ||||||
| +		if (path[1] == '\0')
 |  | ||||||
| +			return (resolved);
 |  | ||||||
| +		resolved_len = 1;
 |  | ||||||
| +		left_len = strlcpy(left, path + 1, sizeof(left));
 |  | ||||||
| +	} else {
 |  | ||||||
| +		if (getcwd(resolved, PATH_MAX) == NULL) {
 |  | ||||||
| +			if (mem_allocated)
 |  | ||||||
| +				free(resolved);
 |  | ||||||
| +			else
 |  | ||||||
| +				strlcpy(resolved, ".", PATH_MAX);
 |  | ||||||
| +			return (NULL);
 |  | ||||||
| +		}
 |  | ||||||
| +		resolved_len = strlen(resolved);
 |  | ||||||
| +		left_len = strlcpy(left, path, sizeof(left));
 |  | ||||||
| +	}
 |  | ||||||
| +	if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
 |  | ||||||
| +		errno = ENAMETOOLONG;
 |  | ||||||
| +		goto err;
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +	/*
 |  | ||||||
| +	 * Iterate over path components in `left'.
 |  | ||||||
| +	 */
 |  | ||||||
| +	while (left_len != 0) {
 |  | ||||||
| +		/*
 |  | ||||||
| +		 * Extract the next path component and adjust `left'
 |  | ||||||
| +		 * and its length.
 |  | ||||||
| +		 */
 |  | ||||||
| +		p = strchr(left, '/');
 |  | ||||||
| +		s = p ? p : left + left_len;
 |  | ||||||
| +		if (s - left >= (ptrdiff_t)sizeof(next_token)) {
 |  | ||||||
| +			errno = ENAMETOOLONG;
 |  | ||||||
| +			goto err;
 |  | ||||||
| +		}
 |  | ||||||
| +		memcpy(next_token, left, s - left);
 |  | ||||||
| +		next_token[s - left] = '\0';
 |  | ||||||
| +		left_len -= s - left;
 |  | ||||||
| +		if (p != NULL)
 |  | ||||||
| +			memmove(left, s + 1, left_len + 1);
 |  | ||||||
| +		if (resolved[resolved_len - 1] != '/') {
 |  | ||||||
| +			if (resolved_len + 1 >= PATH_MAX) {
 |  | ||||||
| +				errno = ENAMETOOLONG;
 |  | ||||||
| +				goto err;
 |  | ||||||
| +			}
 |  | ||||||
| +			resolved[resolved_len++] = '/';
 |  | ||||||
| +			resolved[resolved_len] = '\0';
 |  | ||||||
| +		}
 |  | ||||||
| +		if (next_token[0] == '\0')
 |  | ||||||
| +			continue;
 |  | ||||||
| +		else if (strcmp(next_token, ".") == 0)
 |  | ||||||
| +			continue;
 |  | ||||||
| +		else if (strcmp(next_token, "..") == 0) {
 |  | ||||||
| +			/*
 |  | ||||||
| +			 * Strip the last path component except when we have
 |  | ||||||
| +			 * single "/"
 |  | ||||||
| +			 */
 |  | ||||||
| +			if (resolved_len > 1) {
 |  | ||||||
| +				resolved[resolved_len - 1] = '\0';
 |  | ||||||
| +				q = strrchr(resolved, '/') + 1;
 |  | ||||||
| +				*q = '\0';
 |  | ||||||
| +				resolved_len = q - resolved;
 |  | ||||||
| +			}
 |  | ||||||
| +			continue;
 |  | ||||||
| +		}
 |  | ||||||
| +
 |  | ||||||
| +		/*
 |  | ||||||
| +		 * Append the next path component and lstat() it. If
 |  | ||||||
| +		 * lstat() fails we still can return successfully if
 |  | ||||||
| +		 * there are no more path components left.
 |  | ||||||
| +		 */
 |  | ||||||
| +		resolved_len = strlcat(resolved, next_token, PATH_MAX);
 |  | ||||||
| +		if (resolved_len >= PATH_MAX) {
 |  | ||||||
| +			errno = ENAMETOOLONG;
 |  | ||||||
| +			goto err;
 |  | ||||||
| +		}
 |  | ||||||
| +		if (lstat(resolved, &sb) != 0) {
 |  | ||||||
| +			if (errno == ENOENT && p == NULL) {
 |  | ||||||
| +				errno = serrno;
 |  | ||||||
| +				return (resolved);
 |  | ||||||
| +			}
 |  | ||||||
| +			goto err;
 |  | ||||||
| +		}
 |  | ||||||
| +		if (S_ISLNK(sb.st_mode)) {
 |  | ||||||
| +			if (symlinks++ > SYMLOOP_MAX) {
 |  | ||||||
| +				errno = ELOOP;
 |  | ||||||
| +				goto err;
 |  | ||||||
| +			}
 |  | ||||||
| +			slen = readlink(resolved, symlink, sizeof(symlink) - 1);
 |  | ||||||
| +			if (slen < 0)
 |  | ||||||
| +				goto err;
 |  | ||||||
| +			symlink[slen] = '\0';
 |  | ||||||
| +			if (symlink[0] == '/') {
 |  | ||||||
| +				resolved[1] = 0;
 |  | ||||||
| +				resolved_len = 1;
 |  | ||||||
| +			} else if (resolved_len > 1) {
 |  | ||||||
| +				/* Strip the last path component. */
 |  | ||||||
| +				resolved[resolved_len - 1] = '\0';
 |  | ||||||
| +				q = strrchr(resolved, '/') + 1;
 |  | ||||||
| +				*q = '\0';
 |  | ||||||
| +				resolved_len = q - resolved;
 |  | ||||||
| +			}
 |  | ||||||
| +
 |  | ||||||
| +			/*
 |  | ||||||
| +			 * If there are any path components left, then
 |  | ||||||
| +			 * append them to symlink. The result is placed
 |  | ||||||
| +			 * in `left'.
 |  | ||||||
| +			 */
 |  | ||||||
| +			if (p != NULL) {
 |  | ||||||
| +				if (symlink[slen - 1] != '/') {
 |  | ||||||
| +					if (slen + 1 >=
 |  | ||||||
| +					    (ptrdiff_t)sizeof(symlink)) {
 |  | ||||||
| +						errno = ENAMETOOLONG;
 |  | ||||||
| +						goto err;
 |  | ||||||
| +					}
 |  | ||||||
| +					symlink[slen] = '/';
 |  | ||||||
| +					symlink[slen + 1] = 0;
 |  | ||||||
| +				}
 |  | ||||||
| +				left_len = strlcat(symlink, left, sizeof(symlink));
 |  | ||||||
| +				if (left_len >= sizeof(symlink)) {
 |  | ||||||
| +					errno = ENAMETOOLONG;
 |  | ||||||
| +					goto err;
 |  | ||||||
| +				}
 |  | ||||||
| +			}
 |  | ||||||
| +			left_len = strlcpy(left, symlink, sizeof(left));
 |  | ||||||
| +		}
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
| +	/*
 |  | ||||||
| +	 * Remove trailing slash except when the resolved pathname
 |  | ||||||
| +	 * is a single "/".
 |  | ||||||
| +	 */
 |  | ||||||
| +	if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
 |  | ||||||
| +		resolved[resolved_len - 1] = '\0';
 |  | ||||||
| +	return (resolved);
 |  | ||||||
| +
 |  | ||||||
| +err:
 |  | ||||||
| +	if (mem_allocated)
 |  | ||||||
| +		free(resolved);
 |  | ||||||
| +	return (NULL);
 |  | ||||||
| +}
 |  | ||||||
| diff --color -ruN a/sftp-server.c b/sftp-server.c
 |  | ||||||
| --- a/sftp-server.c	2022-06-23 11:31:10.147186434 +0200
 |  | ||||||
| +++ b/sftp-server.c	2022-06-23 11:32:19.147513366 +0200
 |  | ||||||
| @@ -51,6 +51,8 @@
 |  | ||||||
|  #include "sftp.h" |  | ||||||
|  #include "sftp-common.h" |  | ||||||
|   |  | ||||||
| +char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
 |  | ||||||
| +
 |  | ||||||
|  /* Our verbosity */ |  | ||||||
|  static LogLevel log_level = SYSLOG_LEVEL_ERROR; |  | ||||||
|   |  | ||||||
| @@ -1185,7 +1187,7 @@
 |  | ||||||
|  	} |  | ||||||
|  	debug3("request %u: realpath", id); |  | ||||||
|  	verbose("realpath \"%s\"", path); |  | ||||||
| -	if (realpath(path, resolvedname) == NULL) {
 |  | ||||||
| +	if (sftp_realpath(path, resolvedname) == NULL) {
 |  | ||||||
|  		send_status(id, errno_to_portable(errno)); |  | ||||||
|  	} else { |  | ||||||
|  		Stat s; |  | ||||||
| @ -1,16 +0,0 @@ | |||||||
| diff -up openssh-8.0p1/sftp.c.original openssh-8.0p1/sftp.c
 |  | ||||||
| --- openssh-8.0p1/sftp.c.original	2020-12-22 17:05:02.105698989 +0900
 |  | ||||||
| +++ openssh-8.0p1/sftp.c	2020-12-22 17:05:42.922035780 +0900
 |  | ||||||
| @@ -937,7 +937,11 @@ sglob_comp(const void *aa, const void *b
 |  | ||||||
|  		return (rmul * strcmp(ap, bp)); |  | ||||||
|  	else if (sort_flag & LS_TIME_SORT) { |  | ||||||
|  #if defined(HAVE_STRUCT_STAT_ST_MTIM) |  | ||||||
| -		return (rmul * timespeccmp(&as->st_mtim, &bs->st_mtim, <));
 |  | ||||||
| +		if (timespeccmp(&as->st_mtim, &bs->st_mtim, <)){
 |  | ||||||
| +			return rmul;
 |  | ||||||
| +		} else {
 |  | ||||||
| +			return -rmul;
 |  | ||||||
| +		}
 |  | ||||||
|  #elif defined(HAVE_STRUCT_STAT_ST_MTIME) |  | ||||||
|  		return (rmul * NCMP(as->st_mtime, bs->st_mtime)); |  | ||||||
|  #else |  | ||||||
| @ -1,97 +0,0 @@ | |||||||
| diff --git a/servconf.c b/servconf.c
 |  | ||||||
| index ffac5d2c..340045b2 100644
 |  | ||||||
| --- a/servconf.c
 |  | ||||||
| +++ b/servconf.c
 |  | ||||||
| @@ -1042,7 +1042,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
 |  | ||||||
|  			return -1; |  | ||||||
|  		} |  | ||||||
|  		if (strcasecmp(attrib, "user") == 0) { |  | ||||||
| -			if (ci == NULL) {
 |  | ||||||
| +			if (ci == NULL || (ci->test && ci->user == NULL)) {
 |  | ||||||
|  				result = 0; |  | ||||||
|  				continue; |  | ||||||
|  			} |  | ||||||
| @@ -1054,7 +1054,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
 |  | ||||||
|  				debug("user %.100s matched 'User %.100s' at " |  | ||||||
|  				    "line %d", ci->user, arg, line); |  | ||||||
|  		} else if (strcasecmp(attrib, "group") == 0) { |  | ||||||
| -			if (ci == NULL) {
 |  | ||||||
| +			if (ci == NULL || (ci->test && ci->user == NULL)) {
 |  | ||||||
|  				result = 0; |  | ||||||
|  				continue; |  | ||||||
|  			} |  | ||||||
| @@ -1067,7 +1067,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
 |  | ||||||
|  				result = 0; |  | ||||||
|  			} |  | ||||||
|  		} else if (strcasecmp(attrib, "host") == 0) { |  | ||||||
| -			if (ci == NULL) {
 |  | ||||||
| +			if (ci == NULL || (ci->test && ci->host == NULL)) {
 |  | ||||||
|  				result = 0; |  | ||||||
|  				continue; |  | ||||||
|  			} |  | ||||||
| @@ -1079,7 +1079,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
 |  | ||||||
|  				debug("connection from %.100s matched 'Host " |  | ||||||
|  				    "%.100s' at line %d", ci->host, arg, line); |  | ||||||
|  		} else if (strcasecmp(attrib, "address") == 0) { |  | ||||||
| -			if (ci == NULL) {
 |  | ||||||
| +			if (ci == NULL || (ci->test && ci->address == NULL)) {
 |  | ||||||
|  				result = 0; |  | ||||||
|  				continue; |  | ||||||
|  			} |  | ||||||
| @@ -1098,7 +1098,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
 |  | ||||||
|  				return -1; |  | ||||||
|  			} |  | ||||||
|  		} else if (strcasecmp(attrib, "localaddress") == 0){ |  | ||||||
| -			if (ci == NULL) {
 |  | ||||||
| +			if (ci == NULL || (ci->test && ci->laddress == NULL)) {
 |  | ||||||
|  				result = 0; |  | ||||||
|  				continue; |  | ||||||
|  			} |  | ||||||
| @@ -1124,7 +1124,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
 |  | ||||||
|  				    arg); |  | ||||||
|  				return -1; |  | ||||||
|  			} |  | ||||||
| -			if (ci == NULL) {
 |  | ||||||
| +			if (ci == NULL || (ci->test && ci->lport == -1)) {
 |  | ||||||
|  				result = 0; |  | ||||||
|  				continue; |  | ||||||
|  			} |  | ||||||
| @@ -1138,10 +1138,12 @@ match_cfg_line(char **condition, int line, struct connection_info *ci)
 |  | ||||||
|  			else |  | ||||||
|  				result = 0; |  | ||||||
|  		} else if (strcasecmp(attrib, "rdomain") == 0) { |  | ||||||
| -			if (ci == NULL || ci->rdomain == NULL) {
 |  | ||||||
| +			if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
 |  | ||||||
|  				result = 0; |  | ||||||
|  				continue; |  | ||||||
|  			} |  | ||||||
| +			if (ci->rdomain == NULL)
 |  | ||||||
| +				match_test_missing_fatal("RDomain", "rdomain");
 |  | ||||||
|  			if (match_pattern_list(ci->rdomain, arg, 0) != 1) |  | ||||||
|  				result = 0; |  | ||||||
|  			else |  | ||||||
| diff --git a/servconf.h b/servconf.h
 |  | ||||||
| index 54e0a8d8..5483da05 100644
 |  | ||||||
| --- a/servconf.h
 |  | ||||||
| +++ b/servconf.h
 |  | ||||||
| @@ -221,6 +221,8 @@ struct connection_info {
 |  | ||||||
|  	const char *laddress;	/* local address */ |  | ||||||
|  	int lport;		/* local port */ |  | ||||||
|  	const char *rdomain;	/* routing domain if available */ |  | ||||||
| +	int test;		/* test mode, allow some attributes to be
 |  | ||||||
| +				 * unspecified */
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|   |  | ||||||
| diff --git a/sshd.c b/sshd.c
 |  | ||||||
| index cbd3bce9..1fcde502 100644
 |  | ||||||
| --- a/sshd.c
 |  | ||||||
| +++ b/sshd.c
 |  | ||||||
| @@ -1843,6 +1843,7 @@ main(int ac, char **av)
 |  | ||||||
|  		 */ |  | ||||||
|  		if (connection_info == NULL) |  | ||||||
|  			connection_info = get_connection_info(ssh, 0, 0); |  | ||||||
| +		connection_info->test = 1;
 |  | ||||||
|  		parse_server_match_config(&options, connection_info); |  | ||||||
|  		dump_config(&options); |  | ||||||
|  	} |  | ||||||
| @ -1,805 +0,0 @@ | |||||||
| diff -up openssh-8.0p1/auth.c.sshdinclude openssh-8.0p1/auth.c
 |  | ||||||
| --- openssh-8.0p1/auth.c.sshdinclude	2021-10-20 15:18:49.740331098 +0200
 |  | ||||||
| +++ openssh-8.0p1/auth.c	2021-10-20 15:19:41.324781344 +0200
 |  | ||||||
| @@ -80,6 +80,7 @@
 |  | ||||||
|   |  | ||||||
|  /* import */ |  | ||||||
|  extern ServerOptions options; |  | ||||||
| +extern struct include_list includes;
 |  | ||||||
|  extern int use_privsep; |  | ||||||
|  extern struct sshbuf *loginmsg; |  | ||||||
|  extern struct passwd *privsep_pw; |  | ||||||
| @@ -573,7 +574,7 @@ getpwnamallow(struct ssh *ssh, const cha
 |  | ||||||
|   |  | ||||||
|  	ci = get_connection_info(ssh, 1, options.use_dns); |  | ||||||
|  	ci->user = user; |  | ||||||
| -	parse_server_match_config(&options, ci);
 |  | ||||||
| +	parse_server_match_config(&options, &includes, ci);
 |  | ||||||
|  	log_change_level(options.log_level); |  | ||||||
|  	process_permitopen(ssh, &options); |  | ||||||
|   |  | ||||||
| diff -up openssh-8.0p1/readconf.c.sshdinclude openssh-8.0p1/readconf.c
 |  | ||||||
| --- openssh-8.0p1/readconf.c.sshdinclude	2021-10-20 15:21:43.541848103 +0200
 |  | ||||||
| +++ openssh-8.0p1/readconf.c	2021-10-20 15:22:06.302046768 +0200
 |  | ||||||
| @@ -711,7 +711,7 @@ match_cfg_line(Options *options, char **
 |  | ||||||
|  static void |  | ||||||
|  rm_env(Options *options, const char *arg, const char *filename, int linenum) |  | ||||||
|  { |  | ||||||
| -	int i, j;
 |  | ||||||
| +	int i, j, onum_send_env = options->num_send_env;
 |  | ||||||
|  	char *cp; |  | ||||||
|   |  | ||||||
|  	/* Remove an environment variable */ |  | ||||||
| @@ -734,6 +734,11 @@ rm_env(Options *options, const char *arg
 |  | ||||||
|  		options->num_send_env--; |  | ||||||
|  		/* NB. don't increment i */ |  | ||||||
|  	} |  | ||||||
| +	if (onum_send_env != options->num_send_env) {
 |  | ||||||
| +		options->send_env = xrecallocarray(options->send_env,
 |  | ||||||
| +		    onum_send_env, options->num_send_env,
 |  | ||||||
| +		    sizeof(*options->send_env));
 |  | ||||||
| +	}
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
| diff -up openssh-8.0p1/regress/Makefile.sshdinclude openssh-8.0p1/regress/Makefile
 |  | ||||||
| --- openssh-8.0p1/regress/Makefile.sshdinclude	2021-10-20 15:18:49.742331115 +0200
 |  | ||||||
| +++ openssh-8.0p1/regress/Makefile	2021-10-20 15:19:41.324781344 +0200
 |  | ||||||
| @@ -82,6 +82,7 @@ LTESTS= 	connect \
 |  | ||||||
|  		principals-command \ |  | ||||||
|  		cert-file \ |  | ||||||
|  		cfginclude \ |  | ||||||
| +		servcfginclude \
 |  | ||||||
|  		allow-deny-users \ |  | ||||||
|  		authinfo |  | ||||||
|   |  | ||||||
| @@ -118,7 +119,7 @@ CLEANFILES=	*.core actual agent-key.* au
 |  | ||||||
|  		sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ |  | ||||||
|  		ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ |  | ||||||
|  		ssh_proxy_envpass sshd.log sshd_config sshd_config_minimal \ |  | ||||||
| -		sshd_config.orig sshd_proxy sshd_proxy.* sshd_proxy_bak \
 |  | ||||||
| +		sshd_config.* sshd_proxy sshd_proxy.* sshd_proxy_bak \
 |  | ||||||
|  		sshd_proxy_orig t10.out t10.out.pub t12.out t12.out.pub \ |  | ||||||
|  		t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \ |  | ||||||
|  		t8.out t8.out.pub t9.out t9.out.pub testdata \ |  | ||||||
| diff -up openssh-8.0p1/regress/servcfginclude.sh.sshdinclude openssh-8.0p1/regress/servcfginclude.sh
 |  | ||||||
| --- openssh-8.0p1/regress/servcfginclude.sh.sshdinclude	2021-10-20 15:18:49.744331132 +0200
 |  | ||||||
| +++ openssh-8.0p1/regress/servcfginclude.sh	2021-10-20 15:22:06.303046777 +0200
 |  | ||||||
| @@ -0,0 +1,188 @@
 |  | ||||||
| +#	Placed in the Public Domain.
 |  | ||||||
| +
 |  | ||||||
| +tid="server config include"
 |  | ||||||
| +
 |  | ||||||
| +cat > $OBJ/sshd_config.i << _EOF
 |  | ||||||
| +HostKey $OBJ/host.ssh-ed25519
 |  | ||||||
| +Match host a
 |  | ||||||
| +	Banner /aa
 |  | ||||||
| +
 |  | ||||||
| +Match host b
 |  | ||||||
| +	Banner /bb
 |  | ||||||
| +	Include $OBJ/sshd_config.i.*
 |  | ||||||
| +
 |  | ||||||
| +Match host c
 |  | ||||||
| +	Include $OBJ/sshd_config.i.*
 |  | ||||||
| +	Banner /cc
 |  | ||||||
| +
 |  | ||||||
| +Match host m
 |  | ||||||
| +	Include $OBJ/sshd_config.i.*
 |  | ||||||
| +
 |  | ||||||
| +Match Host d
 |  | ||||||
| +	Banner /dd
 |  | ||||||
| +
 |  | ||||||
| +Match Host e
 |  | ||||||
| +	Banner /ee
 |  | ||||||
| +	Include $OBJ/sshd_config.i.*
 |  | ||||||
| +
 |  | ||||||
| +Match Host f
 |  | ||||||
| +	Include $OBJ/sshd_config.i.*
 |  | ||||||
| +	Banner /ff
 |  | ||||||
| +
 |  | ||||||
| +Match Host n
 |  | ||||||
| +	Include $OBJ/sshd_config.i.*
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +cat > $OBJ/sshd_config.i.0 << _EOF
 |  | ||||||
| +Match host xxxxxx
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +cat > $OBJ/sshd_config.i.1 << _EOF
 |  | ||||||
| +Match host a
 |  | ||||||
| +	Banner /aaa
 |  | ||||||
| +
 |  | ||||||
| +Match host b
 |  | ||||||
| +	Banner /bbb
 |  | ||||||
| +
 |  | ||||||
| +Match host c
 |  | ||||||
| +	Banner /ccc
 |  | ||||||
| +
 |  | ||||||
| +Match Host d
 |  | ||||||
| +	Banner /ddd
 |  | ||||||
| +
 |  | ||||||
| +Match Host e
 |  | ||||||
| +	Banner /eee
 |  | ||||||
| +
 |  | ||||||
| +Match Host f
 |  | ||||||
| +	Banner /fff
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +cat > $OBJ/sshd_config.i.2 << _EOF
 |  | ||||||
| +Match host a
 |  | ||||||
| +	Banner /aaaa
 |  | ||||||
| +
 |  | ||||||
| +Match host b
 |  | ||||||
| +	Banner /bbbb
 |  | ||||||
| +
 |  | ||||||
| +Match host c
 |  | ||||||
| +	Banner /cccc
 |  | ||||||
| +
 |  | ||||||
| +Match Host d
 |  | ||||||
| +	Banner /dddd
 |  | ||||||
| +
 |  | ||||||
| +Match Host e
 |  | ||||||
| +	Banner /eeee
 |  | ||||||
| +
 |  | ||||||
| +Match Host f
 |  | ||||||
| +	Banner /ffff
 |  | ||||||
| +
 |  | ||||||
| +Match all
 |  | ||||||
| +	Banner /xxxx
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +trial() {
 |  | ||||||
| +	_host="$1"
 |  | ||||||
| +	_exp="$2"
 |  | ||||||
| +	_desc="$3"
 |  | ||||||
| +	test -z "$_desc" && _desc="test match"
 |  | ||||||
| +	trace "$_desc host=$_host expect=$_exp"
 |  | ||||||
| +	${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i -T \
 |  | ||||||
| +	    -C "host=$_host,user=test,addr=127.0.0.1" > $OBJ/sshd_config.out ||
 |  | ||||||
| +		fatal "ssh config parse failed: $_desc host=$_host expect=$_exp"
 |  | ||||||
| +	_got=`grep -i '^banner ' $OBJ/sshd_config.out | awk '{print $2}'`
 |  | ||||||
| +	if test "x$_exp" != "x$_got" ; then
 |  | ||||||
| +		fail "$desc_ host $_host include fail: expected $_exp got $_got"
 |  | ||||||
| +	fi
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +trial a /aa
 |  | ||||||
| +trial b /bb
 |  | ||||||
| +trial c /ccc
 |  | ||||||
| +trial d /dd
 |  | ||||||
| +trial e /ee
 |  | ||||||
| +trial f /fff
 |  | ||||||
| +trial m /xxxx
 |  | ||||||
| +trial n /xxxx
 |  | ||||||
| +trial x none
 |  | ||||||
| +
 |  | ||||||
| +# Prepare an included config with an error.
 |  | ||||||
| +
 |  | ||||||
| +cat > $OBJ/sshd_config.i.3 << _EOF
 |  | ||||||
| +Banner xxxx
 |  | ||||||
| +	Junk
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +trace "disallow invalid config host=a"
 |  | ||||||
| +${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i \
 |  | ||||||
| +    -C "host=a,user=test,addr=127.0.0.1" 2>/dev/null && \
 |  | ||||||
| +	fail "sshd include allowed invalid config"
 |  | ||||||
| +
 |  | ||||||
| +trace "disallow invalid config host=x"
 |  | ||||||
| +${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i \
 |  | ||||||
| +    -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \
 |  | ||||||
| +	fail "sshd include allowed invalid config"
 |  | ||||||
| +
 |  | ||||||
| +rm -f $OBJ/sshd_config.i.*
 |  | ||||||
| +
 |  | ||||||
| +# Ensure that a missing include is not fatal.
 |  | ||||||
| +cat > $OBJ/sshd_config.i << _EOF
 |  | ||||||
| +HostKey $OBJ/host.ssh-ed25519
 |  | ||||||
| +Include $OBJ/sshd_config.i.*
 |  | ||||||
| +Banner /aa
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +trial a /aa "missing include non-fatal"
 |  | ||||||
| +
 |  | ||||||
| +# Ensure that Match/Host in an included config does not affect parent.
 |  | ||||||
| +cat > $OBJ/sshd_config.i.x << _EOF
 |  | ||||||
| +Match host x
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +trial a /aa "included file does not affect match state"
 |  | ||||||
| +
 |  | ||||||
| +# Ensure the empty include directive is not accepted
 |  | ||||||
| +cat > $OBJ/sshd_config.i.x << _EOF
 |  | ||||||
| +Include
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +trace "disallow invalid with no argument"
 |  | ||||||
| +${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i.x -T \
 |  | ||||||
| +    -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \
 |  | ||||||
| +	fail "sshd allowed Include with no argument"
 |  | ||||||
| +
 |  | ||||||
| +# Ensure the Include before any Match block works as expected (bug #3122)
 |  | ||||||
| +cat > $OBJ/sshd_config.i << _EOF
 |  | ||||||
| +Banner /xx
 |  | ||||||
| +HostKey $OBJ/host.ssh-ed25519
 |  | ||||||
| +Include $OBJ/sshd_config.i.2
 |  | ||||||
| +Match host a
 |  | ||||||
| +	Banner /aaaa
 |  | ||||||
| +_EOF
 |  | ||||||
| +cat > $OBJ/sshd_config.i.2 << _EOF
 |  | ||||||
| +Match host a
 |  | ||||||
| +	Banner /aa
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +trace "Include before match blocks"
 |  | ||||||
| +trial a /aa "included file before match blocks is properly evaluated"
 |  | ||||||
| +
 |  | ||||||
| +# Port in included file is correctly interpretted (bug #3169)
 |  | ||||||
| +cat > $OBJ/sshd_config.i << _EOF
 |  | ||||||
| +Include $OBJ/sshd_config.i.2
 |  | ||||||
| +Port 7722
 |  | ||||||
| +_EOF
 |  | ||||||
| +cat > $OBJ/sshd_config.i.2 << _EOF
 |  | ||||||
| +HostKey $OBJ/host.ssh-ed25519
 |  | ||||||
| +_EOF
 |  | ||||||
| +
 |  | ||||||
| +trace "Port after included files"
 |  | ||||||
| +${SUDO} ${REAL_SSHD} -f $OBJ/sshd_config.i -T \
 |  | ||||||
| +    -C "host=x,user=test,addr=127.0.0.1" > $OBJ/sshd_config.out || \
 |  | ||||||
| +	fail "failed to parse Port after included files"
 |  | ||||||
| +_port=`grep -i '^port ' $OBJ/sshd_config.out | awk '{print $2}'`
 |  | ||||||
| +if test "x7722" != "x$_port" ; then
 |  | ||||||
| +	fail "The Port in included file was intertepretted wrongly. Expected 7722, got $_port"
 |  | ||||||
| +fi
 |  | ||||||
| +
 |  | ||||||
| +# cleanup
 |  | ||||||
| +rm -f $OBJ/sshd_config.i $OBJ/sshd_config.i.* $OBJ/sshd_config.out
 |  | ||||||
| diff -up openssh-8.0p1/regress/test-exec.sh.sshdinclude openssh-8.0p1/regress/test-exec.sh
 |  | ||||||
| --- openssh-8.0p1/regress/test-exec.sh.sshdinclude	2021-10-20 15:18:49.746331150 +0200
 |  | ||||||
| +++ openssh-8.0p1/regress/test-exec.sh	2021-10-20 15:19:41.324781344 +0200
 |  | ||||||
| @@ -220,6 +220,7 @@ echo "exec ${SSH} -E${TEST_SSH_LOGFILE}
 |  | ||||||
|   |  | ||||||
|  chmod a+rx $OBJ/ssh-log-wrapper.sh |  | ||||||
|  REAL_SSH="$SSH" |  | ||||||
| +REAL_SSHD="$SSHD"
 |  | ||||||
|  SSH="$SSHLOGWRAP" |  | ||||||
|   |  | ||||||
|  # Some test data.  We make a copy because some tests will overwrite it. |  | ||||||
| diff -up openssh-8.0p1/servconf.c.sshdinclude openssh-8.0p1/servconf.c
 |  | ||||||
| --- openssh-8.0p1/servconf.c.sshdinclude	2021-10-20 15:18:49.748331167 +0200
 |  | ||||||
| +++ openssh-8.0p1/servconf.c	2021-10-20 15:22:06.303046777 +0200
 |  | ||||||
| @@ -40,6 +40,11 @@
 |  | ||||||
|  #ifdef HAVE_UTIL_H |  | ||||||
|  #include <util.h> |  | ||||||
|  #endif |  | ||||||
| +#ifdef USE_SYSTEM_GLOB
 |  | ||||||
| +# include <glob.h>
 |  | ||||||
| +#else
 |  | ||||||
| +# include "openbsd-compat/glob.h"
 |  | ||||||
| +#endif
 |  | ||||||
|   |  | ||||||
|  #include "openbsd-compat/sys-queue.h" |  | ||||||
|  #include "xmalloc.h" |  | ||||||
| @@ -70,6 +75,9 @@ static void add_listen_addr(ServerOption
 |  | ||||||
|      const char *, int); |  | ||||||
|  static void add_one_listen_addr(ServerOptions *, const char *, |  | ||||||
|      const char *, int); |  | ||||||
| +static void parse_server_config_depth(ServerOptions *options,
 |  | ||||||
| +    const char *filename, struct sshbuf *conf, struct include_list *includes,
 |  | ||||||
| +    struct connection_info *connectinfo, int flags, int *activep, int depth);
 |  | ||||||
|   |  | ||||||
|  /* Use of privilege separation or not */ |  | ||||||
|  extern int use_privsep; |  | ||||||
| @@ -528,7 +536,7 @@ typedef enum {
 |  | ||||||
|  	sAcceptEnv, sSetEnv, sPermitTunnel, |  | ||||||
|  	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, |  | ||||||
|  	sUsePrivilegeSeparation, sAllowAgentForwarding, |  | ||||||
| -	sHostCertificate,
 |  | ||||||
| +	sHostCertificate, sInclude,
 |  | ||||||
|  	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |  | ||||||
|  	sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, |  | ||||||
|  	sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum, |  | ||||||
| @@ -540,9 +548,11 @@ typedef enum {
 |  | ||||||
|  	sDeprecated, sIgnore, sUnsupported |  | ||||||
|  } ServerOpCodes; |  | ||||||
|   |  | ||||||
| -#define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
 |  | ||||||
| -#define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
 |  | ||||||
| -#define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
 |  | ||||||
| +#define SSHCFG_GLOBAL		0x01	/* allowed in main section of config */
 |  | ||||||
| +#define SSHCFG_MATCH		0x02	/* allowed inside a Match section */
 |  | ||||||
| +#define SSHCFG_ALL		(SSHCFG_GLOBAL|SSHCFG_MATCH)
 |  | ||||||
| +#define SSHCFG_NEVERMATCH	0x04  /* Match never matches; internal only */
 |  | ||||||
| +#define SSHCFG_MATCH_ONLY	0x08  /* Match only in conditional blocks; internal only */
 |  | ||||||
|   |  | ||||||
|  /* Textual representation of the tokens. */ |  | ||||||
|  static struct { |  | ||||||
| @@ -687,6 +697,7 @@ static struct {
 |  | ||||||
|  	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, |  | ||||||
|  	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, |  | ||||||
|  	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, |  | ||||||
| +	{ "include", sInclude, SSHCFG_ALL },
 |  | ||||||
|  	{ "ipqos", sIPQoS, SSHCFG_ALL }, |  | ||||||
|  	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, |  | ||||||
|  	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, |  | ||||||
| @@ -1259,13 +1270,14 @@ static const struct multistate multistat
 |  | ||||||
|  	{ NULL, -1 } |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| -int
 |  | ||||||
| -process_server_config_line(ServerOptions *options, char *line,
 |  | ||||||
| +static int
 |  | ||||||
| +process_server_config_line_depth(ServerOptions *options, char *line,
 |  | ||||||
|      const char *filename, int linenum, int *activep, |  | ||||||
| -    struct connection_info *connectinfo)
 |  | ||||||
| +    struct connection_info *connectinfo, int *inc_flags, int depth,
 |  | ||||||
| +    struct include_list *includes)
 |  | ||||||
|  { |  | ||||||
|  	char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p; |  | ||||||
| -	int cmdline = 0, *intptr, value, value2, n, port;
 |  | ||||||
| +	int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
 |  | ||||||
|  	SyslogFacility *log_facility_ptr; |  | ||||||
|  	LogLevel *log_level_ptr; |  | ||||||
|  	ServerOpCodes opcode; |  | ||||||
| @@ -1274,6 +1286,8 @@ process_server_config_line(ServerOptions
 |  | ||||||
|  	long long val64; |  | ||||||
|  	const struct multistate *multistate_ptr; |  | ||||||
|  	const char *errstr; |  | ||||||
| +	struct include_item *item;
 |  | ||||||
| +	glob_t gbuf;
 |  | ||||||
|   |  | ||||||
|  	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */ |  | ||||||
|  	if ((len = strlen(line)) == 0) |  | ||||||
| @@ -1300,7 +1314,7 @@ process_server_config_line(ServerOptions
 |  | ||||||
|  		cmdline = 1; |  | ||||||
|  		activep = &cmdline; |  | ||||||
|  	} |  | ||||||
| -	if (*activep && opcode != sMatch)
 |  | ||||||
| +	if (*activep && opcode != sMatch && opcode != sInclude)
 |  | ||||||
|  		debug3("%s:%d setting %s %s", filename, linenum, arg, cp); |  | ||||||
|  	if (*activep == 0 && !(flags & SSHCFG_MATCH)) { |  | ||||||
|  		if (connectinfo == NULL) { |  | ||||||
| @@ -1980,15 +1994,112 @@ process_server_config_line(ServerOptions
 |  | ||||||
|  			*intptr = value; |  | ||||||
|  		break; |  | ||||||
|   |  | ||||||
| +	case sInclude:
 |  | ||||||
| +		if (cmdline) {
 |  | ||||||
| +			fatal("Include directive not supported as a "
 |  | ||||||
| +			    "command-line option");
 |  | ||||||
| +		}
 |  | ||||||
| +		value = 0;
 |  | ||||||
| +		while ((arg2 = strdelim(&cp)) != NULL && *arg2 != '\0') {
 |  | ||||||
| +			value++;
 |  | ||||||
| +			found = 0;
 |  | ||||||
| +			if (*arg2 != '/' && *arg2 != '~') {
 |  | ||||||
| +				xasprintf(&arg, "%s/%s", SSHDIR, arg2);
 |  | ||||||
| +			} else
 |  | ||||||
| +				arg = xstrdup(arg2);
 |  | ||||||
| +
 |  | ||||||
| +			/*
 |  | ||||||
| +			 * Don't let included files clobber the containing
 |  | ||||||
| +			 * file's Match state.
 |  | ||||||
| +			 */
 |  | ||||||
| +			oactive = *activep;
 |  | ||||||
| +
 |  | ||||||
| +			/* consult cache of include files */
 |  | ||||||
| +			TAILQ_FOREACH(item, includes, entry) {
 |  | ||||||
| +				if (strcmp(item->selector, arg) != 0)
 |  | ||||||
| +					continue;
 |  | ||||||
| +				if (item->filename != NULL) {
 |  | ||||||
| +					parse_server_config_depth(options,
 |  | ||||||
| +					    item->filename, item->contents,
 |  | ||||||
| +					    includes, connectinfo,
 |  | ||||||
| +					    (*inc_flags & SSHCFG_MATCH_ONLY
 |  | ||||||
| +					        ? SSHCFG_MATCH_ONLY : (oactive
 |  | ||||||
| +					            ? 0 : SSHCFG_NEVERMATCH)),
 |  | ||||||
| +					    activep, depth + 1);
 |  | ||||||
| +				}
 |  | ||||||
| +				found = 1;
 |  | ||||||
| +				*activep = oactive;
 |  | ||||||
| +			}
 |  | ||||||
| +			if (found != 0) {
 |  | ||||||
| +				free(arg);
 |  | ||||||
| +				continue;
 |  | ||||||
| +			}
 |  | ||||||
| +
 |  | ||||||
| +			/* requested glob was not in cache */
 |  | ||||||
| +			debug2("%s line %d: new include %s",
 |  | ||||||
| +			    filename, linenum, arg);
 |  | ||||||
| +			if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
 |  | ||||||
| +				if (r != GLOB_NOMATCH) {
 |  | ||||||
| +					fatal("%s line %d: include \"%s\" "
 |  | ||||||
| +					    "glob failed", filename,
 |  | ||||||
| +					    linenum, arg);
 |  | ||||||
| +				}
 |  | ||||||
| +				/*
 |  | ||||||
| +				 * If no entry matched then record a
 |  | ||||||
| +				 * placeholder to skip later glob calls.
 |  | ||||||
| +				 */
 |  | ||||||
| +				debug2("%s line %d: no match for %s",
 |  | ||||||
| +				    filename, linenum, arg);
 |  | ||||||
| +				item = xcalloc(1, sizeof(*item));
 |  | ||||||
| +				item->selector = strdup(arg);
 |  | ||||||
| +				TAILQ_INSERT_TAIL(includes,
 |  | ||||||
| +				    item, entry);
 |  | ||||||
| +			}
 |  | ||||||
| +			if (gbuf.gl_pathc > INT_MAX)
 |  | ||||||
| +				fatal("%s: too many glob results", __func__);
 |  | ||||||
| +			for (n = 0; n < (int)gbuf.gl_pathc; n++) {
 |  | ||||||
| +				debug2("%s line %d: including %s",
 |  | ||||||
| +				    filename, linenum, gbuf.gl_pathv[n]);
 |  | ||||||
| +				item = xcalloc(1, sizeof(*item));
 |  | ||||||
| +				item->selector = strdup(arg);
 |  | ||||||
| +				item->filename = strdup(gbuf.gl_pathv[n]);
 |  | ||||||
| +				if ((item->contents = sshbuf_new()) == NULL) {
 |  | ||||||
| +					fatal("%s: sshbuf_new failed",
 |  | ||||||
| +					    __func__);
 |  | ||||||
| +				}
 |  | ||||||
| +				load_server_config(item->filename,
 |  | ||||||
| +				    item->contents);
 |  | ||||||
| +				parse_server_config_depth(options,
 |  | ||||||
| +				    item->filename, item->contents,
 |  | ||||||
| +				    includes, connectinfo,
 |  | ||||||
| +				    (*inc_flags & SSHCFG_MATCH_ONLY
 |  | ||||||
| +				        ? SSHCFG_MATCH_ONLY : (oactive
 |  | ||||||
| +				            ? 0 : SSHCFG_NEVERMATCH)),
 |  | ||||||
| +				    activep, depth + 1);
 |  | ||||||
| +				*activep = oactive;
 |  | ||||||
| +				TAILQ_INSERT_TAIL(includes, item, entry);
 |  | ||||||
| +			}
 |  | ||||||
| +			globfree(&gbuf);
 |  | ||||||
| +			free(arg);
 |  | ||||||
| +		}
 |  | ||||||
| +		if (value == 0) {
 |  | ||||||
| +			fatal("%s line %d: Include missing filename argument",
 |  | ||||||
| +			    filename, linenum);
 |  | ||||||
| +		}
 |  | ||||||
| +		break;
 |  | ||||||
| +
 |  | ||||||
|  	case sMatch: |  | ||||||
|  		if (cmdline) |  | ||||||
|  			fatal("Match directive not supported as a command-line " |  | ||||||
|  			   "option"); |  | ||||||
| -		value = match_cfg_line(&cp, linenum, connectinfo);
 |  | ||||||
| +		value = match_cfg_line(&cp, linenum,
 |  | ||||||
| +		    (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo));
 |  | ||||||
|  		if (value < 0) |  | ||||||
|  			fatal("%s line %d: Bad Match condition", filename, |  | ||||||
|  			    linenum); |  | ||||||
| -		*activep = value;
 |  | ||||||
| +		*activep = (*inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
 |  | ||||||
| +		/* The MATCH_ONLY is applicable only until the first match block */
 |  | ||||||
| +		*inc_flags &= ~SSHCFG_MATCH_ONLY;
 |  | ||||||
|  		break; |  | ||||||
|   |  | ||||||
|  	case sKerberosUseKuserok: |  | ||||||
| @@ -2275,6 +2386,18 @@ process_server_config_line(ServerOptions
 |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +int
 |  | ||||||
| +process_server_config_line(ServerOptions *options, char *line,
 |  | ||||||
| +    const char *filename, int linenum, int *activep,
 |  | ||||||
| +    struct connection_info *connectinfo, struct include_list *includes)
 |  | ||||||
| +{
 |  | ||||||
| +	int inc_flags = 0;
 |  | ||||||
| +
 |  | ||||||
| +	return process_server_config_line_depth(options, line, filename,
 |  | ||||||
| +	    linenum, activep, connectinfo, &inc_flags, 0, includes);
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +
 |  | ||||||
|  /* Reads the server configuration file. */ |  | ||||||
|   |  | ||||||
|  void |  | ||||||
| @@ -2313,12 +2436,13 @@ load_server_config(const char *filename,
 |  | ||||||
|   |  | ||||||
|  void |  | ||||||
|  parse_server_match_config(ServerOptions *options, |  | ||||||
| -   struct connection_info *connectinfo)
 |  | ||||||
| +   struct include_list *includes, struct connection_info *connectinfo)
 |  | ||||||
|  { |  | ||||||
|  	ServerOptions mo; |  | ||||||
|   |  | ||||||
|  	initialize_server_options(&mo); |  | ||||||
| -	parse_server_config(&mo, "reprocess config", cfg, connectinfo);
 |  | ||||||
| +	parse_server_config(&mo, "reprocess config", cfg, includes,
 |  | ||||||
| +	    connectinfo);
 |  | ||||||
|  	copy_set_server_options(options, &mo, 0); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -2464,28 +2588,44 @@ copy_set_server_options(ServerOptions *d
 |  | ||||||
|  #undef M_CP_STROPT |  | ||||||
|  #undef M_CP_STRARRAYOPT |  | ||||||
|   |  | ||||||
| -void
 |  | ||||||
| -parse_server_config(ServerOptions *options, const char *filename,
 |  | ||||||
| -    struct sshbuf *conf, struct connection_info *connectinfo)
 |  | ||||||
| +#define SERVCONF_MAX_DEPTH	16
 |  | ||||||
| +static void
 |  | ||||||
| +parse_server_config_depth(ServerOptions *options, const char *filename,
 |  | ||||||
| +    struct sshbuf *conf, struct include_list *includes,
 |  | ||||||
| +    struct connection_info *connectinfo, int flags, int *activep, int depth)
 |  | ||||||
|  { |  | ||||||
| -	int active, linenum, bad_options = 0;
 |  | ||||||
| +	int linenum, bad_options = 0;
 |  | ||||||
|  	char *cp, *obuf, *cbuf; |  | ||||||
|   |  | ||||||
| -	debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf));
 |  | ||||||
| +	if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
 |  | ||||||
| +		fatal("Too many recursive configuration includes");
 |  | ||||||
| +
 |  | ||||||
| +	debug2("%s: config %s len %zu%s", __func__, filename, sshbuf_len(conf),
 |  | ||||||
| +	    (flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
 |  | ||||||
|   |  | ||||||
|  	if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) |  | ||||||
|  		fatal("%s: sshbuf_dup_string failed", __func__); |  | ||||||
| -	active = connectinfo ? 0 : 1;
 |  | ||||||
|  	linenum = 1; |  | ||||||
|  	while ((cp = strsep(&cbuf, "\n")) != NULL) { |  | ||||||
| -		if (process_server_config_line(options, cp, filename,
 |  | ||||||
| -		    linenum++, &active, connectinfo) != 0)
 |  | ||||||
| +		if (process_server_config_line_depth(options, cp,
 |  | ||||||
| +		    filename, linenum++, activep, connectinfo, &flags,
 |  | ||||||
| +		    depth, includes) != 0)
 |  | ||||||
|  			bad_options++; |  | ||||||
|  	} |  | ||||||
|  	free(obuf); |  | ||||||
|  	if (bad_options > 0) |  | ||||||
|  		fatal("%s: terminating, %d bad configuration options", |  | ||||||
|  		    filename, bad_options); |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
| +void
 |  | ||||||
| +parse_server_config(ServerOptions *options, const char *filename,
 |  | ||||||
| +    struct sshbuf *conf, struct include_list *includes,
 |  | ||||||
| +    struct connection_info *connectinfo)
 |  | ||||||
| +{
 |  | ||||||
| +	int active = connectinfo ? 0 : 1;
 |  | ||||||
| +	parse_server_config_depth(options, filename, conf, includes,
 |  | ||||||
| +	    connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
 |  | ||||||
|  	process_queued_listen_addrs(options); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| diff -up openssh-8.0p1/servconf.h.sshdinclude openssh-8.0p1/servconf.h
 |  | ||||||
| --- openssh-8.0p1/servconf.h.sshdinclude	2021-10-20 15:18:49.750331185 +0200
 |  | ||||||
| +++ openssh-8.0p1/servconf.h	2021-10-20 15:19:41.325781353 +0200
 |  | ||||||
| @@ -16,6 +16,8 @@
 |  | ||||||
|  #ifndef SERVCONF_H |  | ||||||
|  #define SERVCONF_H |  | ||||||
|   |  | ||||||
| +#include <sys/queue.h>
 |  | ||||||
| +
 |  | ||||||
|  #define MAX_PORTS		256	/* Max # ports. */ |  | ||||||
|   |  | ||||||
|  #define MAX_SUBSYSTEMS		256	/* Max # subsystems. */ |  | ||||||
| @@ -234,6 +236,15 @@ struct connection_info {
 |  | ||||||
|  				 * unspecified */ |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +/* List of included files for re-exec from the parsed configuration */
 |  | ||||||
| +struct include_item {
 |  | ||||||
| +	char *selector;
 |  | ||||||
| +	char *filename;
 |  | ||||||
| +	struct sshbuf *contents;
 |  | ||||||
| +	TAILQ_ENTRY(include_item) entry;
 |  | ||||||
| +};
 |  | ||||||
| +TAILQ_HEAD(include_list, include_item);
 |  | ||||||
| +
 |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
|   * These are string config options that must be copied between the |  | ||||||
| @@ -273,12 +284,13 @@ struct connection_info *get_connection_i
 |  | ||||||
|  void	 initialize_server_options(ServerOptions *); |  | ||||||
|  void	 fill_default_server_options(ServerOptions *); |  | ||||||
|  int	 process_server_config_line(ServerOptions *, char *, const char *, int, |  | ||||||
| -	     int *, struct connection_info *);
 |  | ||||||
| +	     int *, struct connection_info *, struct include_list *includes);
 |  | ||||||
|  void	 process_permitopen(struct ssh *ssh, ServerOptions *options); |  | ||||||
|  void	 load_server_config(const char *, struct sshbuf *); |  | ||||||
|  void	 parse_server_config(ServerOptions *, const char *, struct sshbuf *, |  | ||||||
| -	     struct connection_info *);
 |  | ||||||
| -void	 parse_server_match_config(ServerOptions *, struct connection_info *);
 |  | ||||||
| +	     struct include_list *includes, struct connection_info *);
 |  | ||||||
| +void	 parse_server_match_config(ServerOptions *,
 |  | ||||||
| +	     struct include_list *includes, struct connection_info *);
 |  | ||||||
|  int	 parse_server_match_testspec(struct connection_info *, char *); |  | ||||||
|  int	 server_match_spec_complete(struct connection_info *); |  | ||||||
|  void	 copy_set_server_options(ServerOptions *, ServerOptions *, int); |  | ||||||
| diff -up openssh-8.0p1/sshd_config.5.sshdinclude openssh-8.0p1/sshd_config.5
 |  | ||||||
| --- openssh-8.0p1/sshd_config.5.sshdinclude	2021-10-20 15:18:49.754331220 +0200
 |  | ||||||
| +++ openssh-8.0p1/sshd_config.5	2021-10-20 15:19:41.325781353 +0200
 |  | ||||||
| @@ -825,7 +825,20 @@ during
 |  | ||||||
|  and use only the system-wide known hosts file |  | ||||||
|  .Pa /etc/ssh/known_hosts . |  | ||||||
|  The default is |  | ||||||
| -.Cm no .
 |  | ||||||
| +.Dq no .
 |  | ||||||
| +.It Cm Include
 |  | ||||||
| +Include the specified configuration file(s).
 |  | ||||||
| +Multiple path names may be specified and each pathname may contain
 |  | ||||||
| +.Xr glob 7
 |  | ||||||
| +wildcards.
 |  | ||||||
| +Files without absolute paths are assumed to be in
 |  | ||||||
| +.Pa /etc/ssh .
 |  | ||||||
| +A
 |  | ||||||
| +.Cm Include
 |  | ||||||
| +directive may appear inside a
 |  | ||||||
| +.Cm Match
 |  | ||||||
| +block
 |  | ||||||
| +to perform conditional inclusion.
 |  | ||||||
|  .It Cm IPQoS |  | ||||||
|  Specifies the IPv4 type-of-service or DSCP class for the connection. |  | ||||||
|  Accepted values are |  | ||||||
| diff -up openssh-8.0p1/sshd.c.sshdinclude openssh-8.0p1/sshd.c
 |  | ||||||
| --- openssh-8.0p1/sshd.c.sshdinclude	2021-10-20 15:18:49.752331202 +0200
 |  | ||||||
| +++ openssh-8.0p1/sshd.c	2021-10-20 15:19:41.325781353 +0200
 |  | ||||||
| @@ -257,6 +257,9 @@ struct sshauthopt *auth_opts = NULL;
 |  | ||||||
|  /* sshd_config buffer */ |  | ||||||
|  struct sshbuf *cfg; |  | ||||||
|   |  | ||||||
| +/* Included files from the configuration file */
 |  | ||||||
| +struct include_list includes = TAILQ_HEAD_INITIALIZER(includes);
 |  | ||||||
| +
 |  | ||||||
|  /* message to be displayed after login */ |  | ||||||
|  struct sshbuf *loginmsg; |  | ||||||
|   |  | ||||||
| @@ -927,30 +930,45 @@ usage(void)
 |  | ||||||
|  static void |  | ||||||
|  send_rexec_state(int fd, struct sshbuf *conf) |  | ||||||
|  { |  | ||||||
| -	struct sshbuf *m;
 |  | ||||||
| +	struct sshbuf *m = NULL, *inc = NULL;
 |  | ||||||
| +	struct include_item *item = NULL;
 |  | ||||||
|  	int r; |  | ||||||
|   |  | ||||||
|  	debug3("%s: entering fd = %d config len %zu", __func__, fd, |  | ||||||
|  	    sshbuf_len(conf)); |  | ||||||
|   |  | ||||||
| +	if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
 |  | ||||||
| +		fatal("%s: sshbuf_new failed", __func__);
 |  | ||||||
| +
 |  | ||||||
| +	/* pack includes into a string */
 |  | ||||||
| +	TAILQ_FOREACH(item, &includes, entry) {
 |  | ||||||
| +		if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 ||
 |  | ||||||
| +		    (r = sshbuf_put_cstring(inc, item->filename)) != 0 ||
 |  | ||||||
| +		    (r = sshbuf_put_stringb(inc, item->contents)) != 0)
 |  | ||||||
| +			fatal("%s: buffer error: %s", __func__, ssh_err(r));
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
|  	/* |  | ||||||
|  	 * Protocol from reexec master to child: |  | ||||||
|  	 *	string	configuration |  | ||||||
| -	 *	string rngseed		(only if OpenSSL is not self-seeded)
 |  | ||||||
| +	 *	string	included_files[] {
 |  | ||||||
| +	 *		string	selector
 |  | ||||||
| +	 *		string	filename
 |  | ||||||
| +	 *		string	contents
 |  | ||||||
| +	 *	}
 |  | ||||||
| +	 *	string	rng_seed (if required)
 |  | ||||||
|  	 */ |  | ||||||
| -	if ((m = sshbuf_new()) == NULL)
 |  | ||||||
| -		fatal("%s: sshbuf_new failed", __func__);
 |  | ||||||
| -	if ((r = sshbuf_put_stringb(m, conf)) != 0)
 |  | ||||||
| +	if ((r = sshbuf_put_stringb(m, conf)) != 0 ||
 |  | ||||||
| +	    (r = sshbuf_put_stringb(m, inc)) != 0)
 |  | ||||||
|  		fatal("%s: buffer error: %s", __func__, ssh_err(r)); |  | ||||||
| -
 |  | ||||||
|  #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) |  | ||||||
|  	rexec_send_rng_seed(m); |  | ||||||
|  #endif |  | ||||||
| -
 |  | ||||||
|  	if (ssh_msg_send(fd, 0, m) == -1) |  | ||||||
|  		fatal("%s: ssh_msg_send failed", __func__); |  | ||||||
|   |  | ||||||
|  	sshbuf_free(m); |  | ||||||
| +	sshbuf_free(inc);
 |  | ||||||
|   |  | ||||||
|  	debug3("%s: done", __func__); |  | ||||||
|  } |  | ||||||
| @@ -958,14 +976,15 @@ send_rexec_state(int fd, struct sshbuf *
 |  | ||||||
|  static void |  | ||||||
|  recv_rexec_state(int fd, struct sshbuf *conf) |  | ||||||
|  { |  | ||||||
| -	struct sshbuf *m;
 |  | ||||||
| +	struct sshbuf *m, *inc;
 |  | ||||||
|  	u_char *cp, ver; |  | ||||||
|  	size_t len; |  | ||||||
|  	int r; |  | ||||||
| +	struct include_item *item;
 |  | ||||||
|   |  | ||||||
|  	debug3("%s: entering fd = %d", __func__, fd); |  | ||||||
|   |  | ||||||
| -	if ((m = sshbuf_new()) == NULL)
 |  | ||||||
| +	if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
 |  | ||||||
|  		fatal("%s: sshbuf_new failed", __func__); |  | ||||||
|  	if (ssh_msg_recv(fd, m) == -1) |  | ||||||
|  		fatal("%s: ssh_msg_recv failed", __func__); |  | ||||||
| @@ -973,14 +992,28 @@ recv_rexec_state(int fd, struct sshbuf *
 |  | ||||||
|  		fatal("%s: buffer error: %s", __func__, ssh_err(r)); |  | ||||||
|  	if (ver != 0) |  | ||||||
|  		fatal("%s: rexec version mismatch", __func__); |  | ||||||
| -	if ((r = sshbuf_get_string(m, &cp, &len)) != 0)
 |  | ||||||
| -		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 |  | ||||||
| -	if (conf != NULL && (r = sshbuf_put(conf, cp, len)))
 |  | ||||||
| +	if ((r = sshbuf_get_string(m, &cp, &len)) != 0 ||
 |  | ||||||
| +	    (r = sshbuf_get_stringb(m, inc)) != 0)
 |  | ||||||
|  		fatal("%s: buffer error: %s", __func__, ssh_err(r)); |  | ||||||
| +
 |  | ||||||
|  #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) |  | ||||||
|  	rexec_recv_rng_seed(m); |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +	if (conf != NULL && (r = sshbuf_put(conf, cp, len)))
 |  | ||||||
| +		fatal("%s: buffer error: %s", __func__, ssh_err(r));
 |  | ||||||
| +
 |  | ||||||
| +	while (sshbuf_len(inc) != 0) {
 |  | ||||||
| +		item = xcalloc(1, sizeof(*item));
 |  | ||||||
| +		if ((item->contents = sshbuf_new()) == NULL)
 |  | ||||||
| +			fatal("%s: sshbuf_new failed", __func__);
 |  | ||||||
| +		if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 ||
 |  | ||||||
| +		    (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 ||
 |  | ||||||
| +		    (r = sshbuf_get_stringb(inc, item->contents)) != 0)
 |  | ||||||
| +			fatal("%s: buffer error: %s", __func__, ssh_err(r));
 |  | ||||||
| +		TAILQ_INSERT_TAIL(&includes, item, entry);
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
|  	free(cp); |  | ||||||
|  	sshbuf_free(m); |  | ||||||
|   |  | ||||||
| @@ -1661,7 +1694,7 @@ main(int ac, char **av)
 |  | ||||||
|  		case 'o': |  | ||||||
|  			line = xstrdup(optarg); |  | ||||||
|  			if (process_server_config_line(&options, line, |  | ||||||
| -			    "command-line", 0, NULL, NULL) != 0)
 |  | ||||||
| +			    "command-line", 0, NULL, NULL, &includes) != 0)
 |  | ||||||
|  				exit(1); |  | ||||||
|  			free(line); |  | ||||||
|  			break; |  | ||||||
| @@ -1692,7 +1725,7 @@ main(int ac, char **av)
 |  | ||||||
|  	    SYSLOG_LEVEL_INFO : options.log_level, |  | ||||||
|  	    options.log_facility == SYSLOG_FACILITY_NOT_SET ? |  | ||||||
|  	    SYSLOG_FACILITY_AUTH : options.log_facility, |  | ||||||
| -	    log_stderr || !inetd_flag);
 |  | ||||||
| +	    log_stderr || !inetd_flag || debug_flag);
 |  | ||||||
|   |  | ||||||
|  	/* |  | ||||||
|  	 * Unset KRB5CCNAME, otherwise the user's session may inherit it from |  | ||||||
| @@ -1725,12 +1758,11 @@ main(int ac, char **av)
 |  | ||||||
|  			 */ |  | ||||||
|  			(void)atomicio(vwrite, startup_pipe, "\0", 1); |  | ||||||
|  		} |  | ||||||
| -	}
 |  | ||||||
| -	else if (strcasecmp(config_file_name, "none") != 0)
 |  | ||||||
| +	} else if (strcasecmp(config_file_name, "none") != 0)
 |  | ||||||
|  		load_server_config(config_file_name, cfg); |  | ||||||
|   |  | ||||||
|  	parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, |  | ||||||
| -	    cfg, NULL);
 |  | ||||||
| +	    cfg, &includes, NULL);
 |  | ||||||
|   |  | ||||||
|  	/* 'UsePAM no' is not supported in RHEL */ |  | ||||||
|  	if (! options.use_pam) |  | ||||||
| @@ -1946,7 +1978,7 @@ main(int ac, char **av)
 |  | ||||||
|  		if (connection_info == NULL) |  | ||||||
|  			connection_info = get_connection_info(ssh, 0, 0); |  | ||||||
|  		connection_info->test = 1; |  | ||||||
| -		parse_server_match_config(&options, connection_info);
 |  | ||||||
| +		parse_server_match_config(&options, &includes, connection_info);
 |  | ||||||
|  		dump_config(&options); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| diff -up openssh-8.0p1/sshbuf-getput-basic.c.stringb openssh-8.0p1/sshbuf-getput-basic.c
 |  | ||||||
| --- openssh-8.0p1/sshbuf-getput-basic.c.stringb	2022-12-21 12:18:43.274799163 +0100
 |  | ||||||
| +++ openssh-8.0p1/sshbuf-getput-basic.c	2022-12-21 12:19:19.758081516 +0100
 |  | ||||||
| @@ -371,6 +371,9 @@ sshbuf_put_cstring(struct sshbuf *buf, c
 |  | ||||||
|  int |  | ||||||
|  sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v) |  | ||||||
|  { |  | ||||||
| +	if (v == NULL)
 |  | ||||||
| +		return sshbuf_put_string(buf, NULL, 0);
 |  | ||||||
| +
 |  | ||||||
|  	return sshbuf_put_string(buf, sshbuf_ptr(v), sshbuf_len(v)); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @ -1,38 +0,0 @@ | |||||||
| From d33ff14309e33aa79fdf95e1bc4facafa80b90a9 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Stepan Broz <sbroz@redhat.com> |  | ||||||
| Date: Tue, 25 Jun 2024 17:38:22 +0200 |  | ||||||
| Subject: [PATCH] upstream: ignore SIGPIPE earlier in main(), specifically |  | ||||||
|  before |  | ||||||
| 
 |  | ||||||
| muxclient() which performs operations that could cause one; Reported by Noam |  | ||||||
| Lewis via bz3454, ok dtucker@ |  | ||||||
| 
 |  | ||||||
| OpenBSD-Commit-ID: 63d8e13276869eebac6d7a05d5a96307f9026e47 |  | ||||||
| ---
 |  | ||||||
|  ssh.c | 3 ++- |  | ||||||
|  1 file changed, 2 insertions(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/ssh.c b/ssh.c
 |  | ||||||
| index 786e26d..e037c66 100644
 |  | ||||||
| --- a/ssh.c
 |  | ||||||
| +++ b/ssh.c
 |  | ||||||
| @@ -1115,6 +1115,8 @@ main(int ac, char **av)
 |  | ||||||
|  		} |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
 |  | ||||||
| +
 |  | ||||||
|  	/* |  | ||||||
|  	 * Initialize "log" output.  Since we are the client all output |  | ||||||
|  	 * goes to stderr unless otherwise specified by -y or -E. |  | ||||||
| @@ -1545,7 +1547,6 @@ main(int ac, char **av)
 |  | ||||||
|  	    options.num_system_hostfiles); |  | ||||||
|  	tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles); |  | ||||||
|   |  | ||||||
| -	signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
 |  | ||||||
|  	signal(SIGCHLD, main_sigchld_handler); |  | ||||||
|   |  | ||||||
|  	/* Log into the remote system.  Never returns if the login fails. */ |  | ||||||
| -- 
 |  | ||||||
| 2.45.2 |  | ||||||
| 
 |  | ||||||
| @ -1,14 +0,0 @@ | |||||||
| -----BEGIN PGP SIGNATURE----- |  | ||||||
| 
 |  | ||||||
| iQHDBAABCgAdFiEEWcIRjtIG2SfmZ+vj0+X1a22SDTAFAly3ro8ACgkQ0+X1a22S |  | ||||||
| DTCAiAx/W9XHoDs5NijyNIP43W2nFYuf6HG1duoLjdJ8rnsC3e90gx8h5RpUUh24 |  | ||||||
| JDACoUFnbJsNgiQBaYpO7bOnf3Vw5Oui1gPeKnQ76KQsXDwD/N/0wLUf55+XdNJ6 |  | ||||||
| tcgm6/x1W4b8bWje5bcS3qhxv6t/hSL/OxusA8zoNmnTD5XMg6QtJ0Rp9ZHPriCJ |  | ||||||
| C4eCPdHfmyHCr1IATMX9+n5CO5JUPexaDjQug7k/Z1XA/UlwVfRRs1JMpviBodC+ |  | ||||||
| ZUOuk9tH11RKSBcUeR3Ef4iaR3FchryyyBZUZdYBkmDrnHrYpUK5ifdHT+ZXdzPl |  | ||||||
| laX03Kz094LqrP6L3lafk6b1PKOVjKwx1vM5fhnv+pfx4dmao9BwZMuIq6Fa5uMX |  | ||||||
| w2oHGhlIDmeT66Yny5d0APn2wCewyYUGPanSZY/HolHAPs+doOBgI361kMAR9J3e |  | ||||||
| Ii3VKhIdE8i4K3fC19uDkf7xL8UVvRVXjgM7i+GNndh1ou/vDYxmEAsW9IR/D3XC |  | ||||||
| HM/jMdq+UewAiRG46aI5rsi/A8J8/A== |  | ||||||
| =YtoH |  | ||||||
| -----END PGP SIGNATURE----- |  | ||||||
							
								
								
									
										40
									
								
								SOURCES/openssh-8.2p1-visibility.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								SOURCES/openssh-8.2p1-visibility.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | diff --git a/regress/misc/sk-dummy/sk-dummy.c b/regress/misc/sk-dummy/sk-dummy.c
 | ||||||
|  | index dca158de..afdcb1d2 100644
 | ||||||
|  | --- a/regress/misc/sk-dummy/sk-dummy.c
 | ||||||
|  | +++ b/regress/misc/sk-dummy/sk-dummy.c
 | ||||||
|  | @@ -71,7 +71,7 @@ skdebug(const char *func, const char *fmt, ...)
 | ||||||
|  |  #endif | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -uint32_t
 | ||||||
|  | +uint32_t __attribute__((visibility("default")))
 | ||||||
|  |  sk_api_version(void) | ||||||
|  |  { | ||||||
|  |  	return SSH_SK_VERSION_MAJOR; | ||||||
|  | @@ -220,7 +220,7 @@ check_options(struct sk_option **options)
 | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -int
 | ||||||
|  | +int __attribute__((visibility("default")))
 | ||||||
|  |  sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, | ||||||
|  |      const char *application, uint8_t flags, const char *pin, | ||||||
|  |      struct sk_option **options, struct sk_enroll_response **enroll_response) | ||||||
|  | @@ -467,7 +467,7 @@ sig_ed25519(const uint8_t *message, size_t message_len,
 | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -int
 | ||||||
|  | +int __attribute__((visibility("default")))
 | ||||||
|  |  sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, | ||||||
|  |      const char *application, const uint8_t *key_handle, size_t key_handle_len, | ||||||
|  |      uint8_t flags, const char *pin, struct sk_option **options, | ||||||
|  | @@ -518,7 +518,7 @@ sk_sign(uint32_t alg, const uint8_t *message, size_t message_len,
 | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -int
 | ||||||
|  | +int __attribute__((visibility("default")))
 | ||||||
|  |  sk_load_resident_keys(const char *pin, struct sk_option **options, | ||||||
|  |      struct sk_resident_key ***rks, size_t *nrks) | ||||||
|  |  { | ||||||
| @ -6,9 +6,9 @@ diff --git a/channels.c b/channels.c | |||||||
|  				sock_set_v6only(sock); |  				sock_set_v6only(sock); | ||||||
|  			if (x11_use_localhost) |  			if (x11_use_localhost) | ||||||
|  				set_reuseaddr(sock); |  				set_reuseaddr(sock); | ||||||
|  			if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { |  			if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { | ||||||
|  				debug2("%s: bind port %d: %.100s", __func__, |  				debug2_f("bind port %d: %.100s", port, | ||||||
|  				    port, strerror(errno)); |  				    strerror(errno)); | ||||||
|  				close(sock); |  				close(sock); | ||||||
| +
 | +
 | ||||||
| +				/* do not remove successfully opened
 | +				/* do not remove successfully opened
 | ||||||
							
								
								
									
										38
									
								
								SOURCES/openssh-8.7p1-CVE-2023-25136.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								SOURCES/openssh-8.7p1-CVE-2023-25136.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | diff --git a/compat.c b/compat.c
 | ||||||
|  | index 46dfe3a9c2e..478a9403eea 100644
 | ||||||
|  | --- a/compat.c
 | ||||||
|  | +++ b/compat.c
 | ||||||
|  | @@ -190,26 +190,26 @@ compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop)
 | ||||||
|  |  char * | ||||||
|  |  compat_kex_proposal(struct ssh *ssh, char *p) | ||||||
|  |  { | ||||||
|  | -	char *cp = NULL;
 | ||||||
|  | +	char *cp = NULL, *cp2 = NULL;
 | ||||||
|  |   | ||||||
|  |  	if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) | ||||||
|  |  		return xstrdup(p); | ||||||
|  |  	debug2_f("original KEX proposal: %s", p); | ||||||
|  |  	if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) | ||||||
|  | -		if ((p = match_filter_denylist(p,
 | ||||||
|  | +		if ((cp = match_filter_denylist(p,
 | ||||||
|  |  		    "curve25519-sha256@libssh.org")) == NULL) | ||||||
|  |  			fatal("match_filter_denylist failed"); | ||||||
|  |  	if ((ssh->compat & SSH_OLD_DHGEX) != 0) { | ||||||
|  | -		cp = p;
 | ||||||
|  | -		if ((p = match_filter_denylist(p,
 | ||||||
|  | +		if ((cp2 = match_filter_denylist(cp ? cp : p,
 | ||||||
|  |  		    "diffie-hellman-group-exchange-sha256," | ||||||
|  |  		    "diffie-hellman-group-exchange-sha1")) == NULL) | ||||||
|  |  			fatal("match_filter_denylist failed"); | ||||||
|  |  		free(cp); | ||||||
|  | +		cp = cp2;
 | ||||||
|  |  	} | ||||||
|  | -	debug2_f("compat KEX proposal: %s", p);
 | ||||||
|  | -	if (*p == '\0')
 | ||||||
|  | +	if (cp == NULL || *cp == '\0')
 | ||||||
|  |  		fatal("No supported key exchange algorithms found"); | ||||||
|  | -	return p;
 | ||||||
|  | +	debug2_f("compat KEX proposal: %s", cp);
 | ||||||
|  | +	return cp;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
							
								
								
									
										323
									
								
								SOURCES/openssh-8.7p1-UTC-time-parse.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								SOURCES/openssh-8.7p1-UTC-time-parse.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,323 @@ | |||||||
|  | diff --git a/misc.c b/misc.c
 | ||||||
|  | index a8e87430..f2135803 100644
 | ||||||
|  | --- a/misc.c
 | ||||||
|  | +++ b/misc.c
 | ||||||
|  | @@ -2399,15 +2399,26 @@ parse_absolute_time(const char *s, uint64_t *tp)
 | ||||||
|  |  	struct tm tm; | ||||||
|  |  	time_t tt; | ||||||
|  |  	char buf[32], *fmt; | ||||||
|  | +	const char *cp;
 | ||||||
|  | +	size_t l;
 | ||||||
|  | +	int is_utc = 0;
 | ||||||
|  |   | ||||||
|  |  	*tp = 0; | ||||||
|  |   | ||||||
|  | +	l = strlen(s);
 | ||||||
|  | +	if (l > 1 && strcasecmp(s + l - 1, "Z") == 0) {
 | ||||||
|  | +		is_utc = 1;
 | ||||||
|  | +		l--;
 | ||||||
|  | +	} else if (l > 3 && strcasecmp(s + l - 3, "UTC") == 0) {
 | ||||||
|  | +		is_utc = 1;
 | ||||||
|  | +		l -= 3;
 | ||||||
|  | +	}
 | ||||||
|  |  	/* | ||||||
|  |  	 * POSIX strptime says "The application shall ensure that there | ||||||
|  |  	 * is white-space or other non-alphanumeric characters between | ||||||
|  |  	 * any two conversion specifications" so arrange things this way. | ||||||
|  |  	 */ | ||||||
|  | -	switch (strlen(s)) {
 | ||||||
|  | +	switch (l) {
 | ||||||
|  |  	case 8: /* YYYYMMDD */ | ||||||
|  |  		fmt = "%Y-%m-%d"; | ||||||
|  |  		snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6); | ||||||
|  | @@ -2427,10 +2438,15 @@ parse_absolute_time(const char *s, uint64_t *tp)
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	memset(&tm, 0, sizeof(tm)); | ||||||
|  | -	if (strptime(buf, fmt, &tm) == NULL)
 | ||||||
|  | -		return SSH_ERR_INVALID_FORMAT;
 | ||||||
|  | -	if ((tt = mktime(&tm)) < 0)
 | ||||||
|  | +	if ((cp = strptime(buf, fmt, &tm)) == NULL || *cp != '\0')
 | ||||||
|  |  		return SSH_ERR_INVALID_FORMAT; | ||||||
|  | +	if (is_utc) {
 | ||||||
|  | +		if ((tt = timegm(&tm)) < 0)
 | ||||||
|  | +			return SSH_ERR_INVALID_FORMAT;
 | ||||||
|  | +	} else {
 | ||||||
|  | +		if ((tt = mktime(&tm)) < 0)
 | ||||||
|  | +			return SSH_ERR_INVALID_FORMAT;
 | ||||||
|  | +	}
 | ||||||
|  |  	/* success */ | ||||||
|  |  	*tp = (uint64_t)tt; | ||||||
|  |  	return 0; | ||||||
|  | diff --git a/regress/unittests/misc/test_convtime.c b/regress/unittests/misc/test_convtime.c
 | ||||||
|  | index ef6fd77d..4794dbd9 100644
 | ||||||
|  | --- a/regress/unittests/misc/test_convtime.c
 | ||||||
|  | +++ b/regress/unittests/misc/test_convtime.c
 | ||||||
|  | @@ -20,6 +20,7 @@
 | ||||||
|  |   | ||||||
|  |  #include "log.h" | ||||||
|  |  #include "misc.h" | ||||||
|  | +#include "ssherr.h"
 | ||||||
|  |   | ||||||
|  |  void test_convtime(void); | ||||||
|  |   | ||||||
|  | @@ -27,6 +28,7 @@ void
 | ||||||
|  |  test_convtime(void) | ||||||
|  |  { | ||||||
|  |  	char buf[1024]; | ||||||
|  | +	uint64_t t;
 | ||||||
|  |   | ||||||
|  |  	TEST_START("misc_convtime"); | ||||||
|  |  	ASSERT_INT_EQ(convtime("0"), 0); | ||||||
|  | @@ -56,4 +58,64 @@ test_convtime(void)
 | ||||||
|  |  	ASSERT_INT_EQ(convtime("3550w5d3h14m8s"), -1); | ||||||
|  |  #endif | ||||||
|  |  	TEST_DONE(); | ||||||
|  | +
 | ||||||
|  | +	/* XXX timezones/DST make verification of this tricky */
 | ||||||
|  | +	/* XXX maybe setenv TZ and tzset() to make it unambiguous? */
 | ||||||
|  | +	TEST_START("misc_parse_absolute_time");
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101", &t), 0);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("200001011223", &t), 0);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101122345", &t), 0);
 | ||||||
|  | +
 | ||||||
|  | +	/* forced UTC TZ */
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101Z", &t), 0);
 | ||||||
|  | +	ASSERT_U64_EQ(t, 946684800);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("200001011223Z", &t), 0);
 | ||||||
|  | +	ASSERT_U64_EQ(t, 946729380);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101122345Z", &t), 0);
 | ||||||
|  | +	ASSERT_U64_EQ(t, 946729425);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101UTC", &t), 0);
 | ||||||
|  | +	ASSERT_U64_EQ(t, 946684800);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("200001011223UTC", &t), 0);
 | ||||||
|  | +	ASSERT_U64_EQ(t, 946729380);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101122345UTC", &t), 0);
 | ||||||
|  | +	ASSERT_U64_EQ(t, 946729425);
 | ||||||
|  | +
 | ||||||
|  | +	/* Bad month */
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20001301", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000001", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	/* Incomplete */
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("2", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("2000", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("200001", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("2000010", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("200001010", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	/* Bad day, hour, minute, second */
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000199", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("200001019900", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("200001010099", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101000099", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	/* Invalid TZ specifier */
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101ZZ", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101PDT", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101U", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +	ASSERT_INT_EQ(parse_absolute_time("20000101UTCUTC", &t),
 | ||||||
|  | +	    SSH_ERR_INVALID_FORMAT);
 | ||||||
|  | +
 | ||||||
|  | +	TEST_DONE();
 | ||||||
|  |  } | ||||||
|  | diff --git a/ssh-keygen.1 b/ssh-keygen.1
 | ||||||
|  | index 5f429813..6aeab1cb 100644
 | ||||||
|  | --- a/ssh-keygen.1
 | ||||||
|  | +++ b/ssh-keygen.1
 | ||||||
|  | @@ -511,8 +511,11 @@ Print the full public key to standard output after signature verification.
 | ||||||
|  |  .It Cm verify-time Ns = Ns Ar timestamp | ||||||
|  |  Specifies a time to use when validating signatures instead of the current | ||||||
|  |  time. | ||||||
|  | -The time may be specified as a date in YYYYMMDD format or a time
 | ||||||
|  | -in YYYYMMDDHHMM[SS] format.
 | ||||||
|  | +The time may be specified as a date or time in the YYYYMMDD[Z] or
 | ||||||
|  | +in YYYYMMDDHHMM[SS][Z] formats.
 | ||||||
|  | +Dates and times will be interpreted in the current system time zone unless
 | ||||||
|  | +suffixed with a Z character, which causes them to be interpreted in the
 | ||||||
|  | +UTC time zone.
 | ||||||
|  |  .El | ||||||
|  |  .Pp | ||||||
|  |  The | ||||||
|  | @@ -603,31 +606,67 @@ A validity interval may consist of a single time, indicating that the
 | ||||||
|  |  certificate is valid beginning now and expiring at that time, or may consist | ||||||
|  |  of two times separated by a colon to indicate an explicit time interval. | ||||||
|  |  .Pp | ||||||
|  | -The start time may be specified as the string
 | ||||||
|  | +The start time may be specified as:
 | ||||||
|  | +.Bl -bullet -compact
 | ||||||
|  | +.It
 | ||||||
|  | +The string
 | ||||||
|  |  .Dq always | ||||||
|  | -to indicate the certificate has no specified start time,
 | ||||||
|  | -a date in YYYYMMDD format, a time in YYYYMMDDHHMM[SS] format,
 | ||||||
|  | -a relative time (to the current time) consisting of a minus sign followed by
 | ||||||
|  | -an interval in the format described in the
 | ||||||
|  | +to indicate the certificate has no specified start time.
 | ||||||
|  | +.It
 | ||||||
|  | +A date or time in the system time zone formatted as YYYYMMDD or
 | ||||||
|  | +YYYYMMDDHHMM[SS].
 | ||||||
|  | +.It
 | ||||||
|  | +A date or time in the UTC time zone as YYYYMMDDZ or YYYYMMDDHHMM[SS]Z.
 | ||||||
|  | +.It
 | ||||||
|  | +A relative time before the current system time consisting of a minus sign
 | ||||||
|  | +followed by an interval in the format described in the
 | ||||||
|  |  TIME FORMATS section of | ||||||
|  |  .Xr sshd_config 5 . | ||||||
|  | +.It
 | ||||||
|  | +A raw seconds since epoch (Jan 1 1970 00:00:00 UTC) as a hexadecimal
 | ||||||
|  | +number beginning with
 | ||||||
|  | +.Dq 0x .
 | ||||||
|  | +.El
 | ||||||
|  |  .Pp | ||||||
|  | -The end time may be specified as a YYYYMMDD date, a YYYYMMDDHHMM[SS] time,
 | ||||||
|  | -a relative time starting with a plus character or the string
 | ||||||
|  | +The end time may be specified similarly to the start time:
 | ||||||
|  | +.Bl -bullet -compact
 | ||||||
|  | +.It
 | ||||||
|  | +The string
 | ||||||
|  |  .Dq forever | ||||||
|  | -to indicate that the certificate has no expiry date.
 | ||||||
|  | +to indicate the certificate has no specified end time.
 | ||||||
|  | +.It
 | ||||||
|  | +A date or time in the system time zone formatted as YYYYMMDD or
 | ||||||
|  | +YYYYMMDDHHMM[SS].
 | ||||||
|  | +.It
 | ||||||
|  | +A date or time in the UTC time zone as YYYYMMDDZ or YYYYMMDDHHMM[SS]Z.
 | ||||||
|  | +.It
 | ||||||
|  | +A relative time after the current system time consisting of a plus sign
 | ||||||
|  | +followed by an interval in the format described in the
 | ||||||
|  | +TIME FORMATS section of
 | ||||||
|  | +.Xr sshd_config 5 .
 | ||||||
|  | +.It
 | ||||||
|  | +A raw seconds since epoch (Jan 1 1970 00:00:00 UTC) as a hexadecimal
 | ||||||
|  | +number beginning with
 | ||||||
|  | +.Dq 0x .
 | ||||||
|  | +.El
 | ||||||
|  |  .Pp | ||||||
|  |  For example: | ||||||
|  | -.Dq +52w1d
 | ||||||
|  | -(valid from now to 52 weeks and one day from now),
 | ||||||
|  | -.Dq -4w:+4w
 | ||||||
|  | -(valid from four weeks ago to four weeks from now),
 | ||||||
|  | -.Dq 20100101123000:20110101123000
 | ||||||
|  | -(valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011),
 | ||||||
|  | -.Dq -1d:20110101
 | ||||||
|  | -(valid from yesterday to midnight, January 1st, 2011),
 | ||||||
|  | -.Dq -1m:forever
 | ||||||
|  | -(valid from one minute ago and never expiring).
 | ||||||
|  | +.Bl -tag -width Ds
 | ||||||
|  | +.It +52w1d
 | ||||||
|  | +Valid from now to 52 weeks and one day from now.
 | ||||||
|  | +.It -4w:+4w
 | ||||||
|  | +Valid from four weeks ago to four weeks from now.
 | ||||||
|  | +.It 20100101123000:20110101123000
 | ||||||
|  | +Valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011.
 | ||||||
|  | +.It 20100101123000Z:20110101123000Z
 | ||||||
|  | +Similar, but interpreted in the UTC time zone rather than the system time zone.
 | ||||||
|  | +.It -1d:20110101
 | ||||||
|  | +Valid from yesterday to midnight, January 1st, 2011.
 | ||||||
|  | +.It 0x1:0x2000000000
 | ||||||
|  | +Valid from roughly early 1970 to May 2033.
 | ||||||
|  | +.It -1m:forever
 | ||||||
|  | +Valid from one minute ago and never expiring.
 | ||||||
|  | +.El
 | ||||||
|  |  .It Fl v | ||||||
|  |  Verbose mode. | ||||||
|  |  Causes | ||||||
|  | @@ -1206,7 +1245,10 @@ signature object and presented on the verification command-line must
 | ||||||
|  |  match the specified list before the key will be considered acceptable. | ||||||
|  |  .It Cm valid-after Ns = Ns "timestamp" | ||||||
|  |  Indicates that the key is valid for use at or after the specified timestamp, | ||||||
|  | -which may be a date in YYYYMMDD format or a time in YYYYMMDDHHMM[SS] format.
 | ||||||
|  | +which may be a date or time in the YYYYMMDD[Z] or YYYYMMDDHHMM[SS][Z] formats.
 | ||||||
|  | +Dates and times will be interpreted in the current system time zone unless
 | ||||||
|  | +suffixed with a Z character, which causes them to be interpreted in the UTC
 | ||||||
|  | +time zone.
 | ||||||
|  |  .It Cm valid-before Ns = Ns "timestamp" | ||||||
|  |  Indicates that the key is valid for use at or before the specified timestamp. | ||||||
|  |  .El | ||||||
|  | diff --git a/ssh-keygen.c b/ssh-keygen.c
 | ||||||
|  | index 20b321cc..9b2beda0 100644
 | ||||||
|  | --- a/ssh-keygen.c
 | ||||||
|  | +++ b/ssh-keygen.c
 | ||||||
|  | @@ -1916,6 +1916,21 @@ parse_relative_time(const char *s, time_t now)
 | ||||||
|  |  	return now + (u_int64_t)(secs * mul); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static void
 | ||||||
|  | +parse_hex_u64(const char *s, uint64_t *up)
 | ||||||
|  | +{
 | ||||||
|  | +	char *ep;
 | ||||||
|  | +	unsigned long long ull;
 | ||||||
|  | +
 | ||||||
|  | +	errno = 0;
 | ||||||
|  | +	ull = strtoull(s, &ep, 16);
 | ||||||
|  | +	if (*s == '\0' || *ep != '\0')
 | ||||||
|  | +		fatal("Invalid certificate time: not a number");
 | ||||||
|  | +	if (errno == ERANGE && ull == ULONG_MAX)
 | ||||||
|  | +		fatal_fr(SSH_ERR_SYSTEM_ERROR, "Invalid certificate time");
 | ||||||
|  | +	*up = (uint64_t)ull;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static void | ||||||
|  |  parse_cert_times(char *timespec) | ||||||
|  |  { | ||||||
|  | @@ -1938,8 +1953,8 @@ parse_cert_times(char *timespec)
 | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  |  	 * from:to, where | ||||||
|  | -	 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "always"
 | ||||||
|  | -	 *   to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "forever"
 | ||||||
|  | +	 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "always"
 | ||||||
|  | +	 *   to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "forever"
 | ||||||
|  |  	 */ | ||||||
|  |  	from = xstrdup(timespec); | ||||||
|  |  	to = strchr(from, ':'); | ||||||
|  | @@ -1951,6 +1966,8 @@ parse_cert_times(char *timespec)
 | ||||||
|  |  		cert_valid_from = parse_relative_time(from, now); | ||||||
|  |  	else if (strcmp(from, "always") == 0) | ||||||
|  |  		cert_valid_from = 0; | ||||||
|  | +	else if (strncmp(from, "0x", 2) == 0)
 | ||||||
|  | +		parse_hex_u64(from, &cert_valid_from);
 | ||||||
|  |  	else if (parse_absolute_time(from, &cert_valid_from) != 0) | ||||||
|  |  		fatal("Invalid from time \"%s\"", from); | ||||||
|  |   | ||||||
|  | @@ -1958,6 +1975,8 @@ parse_cert_times(char *timespec)
 | ||||||
|  |  		cert_valid_to = parse_relative_time(to, now); | ||||||
|  |  	else if (strcmp(to, "forever") == 0) | ||||||
|  |  		cert_valid_to = ~(u_int64_t)0; | ||||||
|  | +	else if (strncmp(to, "0x", 2) == 0)
 | ||||||
|  | +		parse_hex_u64(to, &cert_valid_to);
 | ||||||
|  |  	else if (parse_absolute_time(to, &cert_valid_to) != 0) | ||||||
|  |  		fatal("Invalid to time \"%s\"", to); | ||||||
|  |   | ||||||
|  | diff --git a/sshd.8 b/sshd.8
 | ||||||
|  | index 2b50514e..8ccc5bc0 100644
 | ||||||
|  | --- a/sshd.8
 | ||||||
|  | +++ b/sshd.8
 | ||||||
|  | @@ -533,8 +533,9 @@ controlled via the
 | ||||||
|  |  option. | ||||||
|  |  .It Cm expiry-time="timespec" | ||||||
|  |  Specifies a time after which the key will not be accepted. | ||||||
|  | -The time may be specified as a YYYYMMDD date or a YYYYMMDDHHMM[SS] time
 | ||||||
|  | -in the system time-zone.
 | ||||||
|  | +The time may be specified as a YYYYMMDD[Z] date or a YYYYMMDDHHMM[SS][Z] time.
 | ||||||
|  | +Dates and times will be interpreted in the system time zone unless suffixed
 | ||||||
|  | +by a Z character, in which case they will be interpreted in the UTC time zone.
 | ||||||
|  |  .It Cm from="pattern-list" | ||||||
|  |  Specifies that in addition to public key authentication, either the canonical | ||||||
|  |  name of the remote host or its IP address must be present in the | ||||||
							
								
								
									
										292
									
								
								SOURCES/openssh-8.7p1-evp-fips-compl-dh.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								SOURCES/openssh-8.7p1-evp-fips-compl-dh.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,292 @@ | |||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/dh.c openssh-8.7p1-patched/dh.c
 | ||||||
|  | --- openssh-8.7p1/dh.c	2023-05-25 09:01:23.295627077 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/dh.c	2023-05-25 09:00:56.519332820 +0200
 | ||||||
|  | @@ -37,6 +37,9 @@
 | ||||||
|  |  #include <openssl/bn.h> | ||||||
|  |  #include <openssl/dh.h> | ||||||
|  |  #include <openssl/fips.h> | ||||||
|  | +#include <openssl/evp.h>
 | ||||||
|  | +#include <openssl/core_names.h>
 | ||||||
|  | +#include <openssl/param_build.h>
 | ||||||
|  |   | ||||||
|  |  #include "dh.h" | ||||||
|  |  #include "pathnames.h" | ||||||
|  | @@ -290,10 +293,15 @@
 | ||||||
|  |  int | ||||||
|  |  dh_gen_key(DH *dh, int need) | ||||||
|  |  { | ||||||
|  | -	int pbits;
 | ||||||
|  | -	const BIGNUM *dh_p, *pub_key;
 | ||||||
|  | +	const BIGNUM *dh_p, *dh_g;
 | ||||||
|  | +	BIGNUM *pub_key = NULL, *priv_key = NULL;
 | ||||||
|  | +	EVP_PKEY *pkey = NULL;
 | ||||||
|  | +  	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  | +  	OSSL_PARAM_BLD *param_bld = NULL;
 | ||||||
|  | +  	OSSL_PARAM *params = NULL;
 | ||||||
|  | +	int pbits, r = 0;
 | ||||||
|  |   | ||||||
|  | -	DH_get0_pqg(dh, &dh_p, NULL, NULL);
 | ||||||
|  | +	DH_get0_pqg(dh, &dh_p, NULL, &dh_g);
 | ||||||
|  |   | ||||||
|  |  	if (need < 0 || dh_p == NULL || | ||||||
|  |  	    (pbits = BN_num_bits(dh_p)) <= 0 || | ||||||
|  | @@ -301,19 +309,85 @@
 | ||||||
|  |  		return SSH_ERR_INVALID_ARGUMENT; | ||||||
|  |  	if (need < 256) | ||||||
|  |  		need = 256; | ||||||
|  | +
 | ||||||
|  | +	if ((param_bld = OSSL_PARAM_BLD_new()) == NULL ||
 | ||||||
|  | +	    (ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL) {
 | ||||||
|  | +		OSSL_PARAM_BLD_free(param_bld);
 | ||||||
|  | +		return SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (OSSL_PARAM_BLD_push_BN(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_FFC_P, dh_p) != 1 ||
 | ||||||
|  | +	    OSSL_PARAM_BLD_push_BN(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_FFC_G, dh_g) != 1) {
 | ||||||
|  | +		error_f("Could not set p,q,g parameters");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  |  	/* | ||||||
|  |  	 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), | ||||||
|  |  	 * so double requested need here. | ||||||
|  |  	 */ | ||||||
|  | -	if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
 | ||||||
|  | -		return SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | -
 | ||||||
|  | -	if (DH_generate_key(dh) == 0)
 | ||||||
|  | -		return SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | -	DH_get0_key(dh, &pub_key, NULL);
 | ||||||
|  | -	if (!dh_pub_is_valid(dh, pub_key))
 | ||||||
|  | -		return SSH_ERR_INVALID_FORMAT;
 | ||||||
|  | -	return 0;
 | ||||||
|  | +	if (OSSL_PARAM_BLD_push_int(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_DH_PRIV_LEN,
 | ||||||
|  | +		MINIMUM(need * 2, pbits - 1)) != 1 ||
 | ||||||
|  | +	    (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (EVP_PKEY_fromdata_init(ctx) != 1) {
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (EVP_PKEY_fromdata(ctx, &pkey,
 | ||||||
|  | +	        EVP_PKEY_KEY_PARAMETERS, params) != 1) {
 | ||||||
|  | +		error_f("Failed key generation");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* reuse context for key generation */
 | ||||||
|  | +	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +	ctx = NULL;
 | ||||||
|  | +
 | ||||||
|  | +	if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
 | ||||||
|  | +	    EVP_PKEY_keygen_init(ctx) != 1) {
 | ||||||
|  | +		error_f("Could not create or init context");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (EVP_PKEY_generate(ctx, &pkey) != 1) {
 | ||||||
|  | +		error_f("Could not generate keys");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (EVP_PKEY_public_check(ctx) != 1) {
 | ||||||
|  | +		error_f("The public key is incorrect");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
 | ||||||
|  | +	    &pub_key) != 1 ||
 | ||||||
|  | +	    EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
 | ||||||
|  | +	    &priv_key) != 1 ||
 | ||||||
|  | +	    DH_set0_key(dh, pub_key, priv_key) != 1) {
 | ||||||
|  | +		error_f("Could not set pub/priv keys to DH struct");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* transferred */
 | ||||||
|  | +	pub_key = NULL;
 | ||||||
|  | +	priv_key = NULL;
 | ||||||
|  | +out:
 | ||||||
|  | +	OSSL_PARAM_free(params);
 | ||||||
|  | +	OSSL_PARAM_BLD_free(param_bld);
 | ||||||
|  | +	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +	EVP_PKEY_free(pkey);
 | ||||||
|  | +	BN_clear_free(pub_key);
 | ||||||
|  | +	BN_clear_free(priv_key);
 | ||||||
|  | +	return r;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  DH * | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/kex.c openssh-8.7p1-patched/kex.c
 | ||||||
|  | --- openssh-8.7p1/kex.c	2023-05-25 09:01:23.299627122 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/kex.c	2023-05-25 09:00:56.519332820 +0200
 | ||||||
|  | @@ -1603,3 +1603,47 @@
 | ||||||
|  |  	return r; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +#ifdef WITH_OPENSSL
 | ||||||
|  | +/* 
 | ||||||
|  | + * Creates an EVP_PKEY from the given parameters and keys.
 | ||||||
|  | + * The private key can be omitted.
 | ||||||
|  | + */
 | ||||||
|  | +int
 | ||||||
|  | +kex_create_evp_dh(EVP_PKEY **pkey, const BIGNUM *p, const BIGNUM *q,
 | ||||||
|  | +    const BIGNUM *g, const BIGNUM *pub, const BIGNUM *priv)
 | ||||||
|  | +{
 | ||||||
|  | +	OSSL_PARAM_BLD *param_bld = NULL;
 | ||||||
|  | +	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  | +	int r = 0;
 | ||||||
|  | +
 | ||||||
|  | +	/* create EVP_PKEY-DH key */
 | ||||||
|  | +	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) == NULL ||
 | ||||||
|  | +	    (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
 | ||||||
|  | +		error_f("EVP_PKEY_CTX or PARAM_BLD init failed");
 | ||||||
|  | +		r = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1 ||
 | ||||||
|  | +	    OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1 ||
 | ||||||
|  | +	    OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1 ||
 | ||||||
|  | +	    OSSL_PARAM_BLD_push_BN(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_PUB_KEY, pub) != 1) {
 | ||||||
|  | +		error_f("Failed pushing params to OSSL_PARAM_BLD");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (priv != NULL &&
 | ||||||
|  | +	    OSSL_PARAM_BLD_push_BN(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
 | ||||||
|  | +		error_f("Failed pushing private key to OSSL_PARAM_BLD");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL)
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +out:
 | ||||||
|  | +	OSSL_PARAM_BLD_free(param_bld);
 | ||||||
|  | +	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +	return r;
 | ||||||
|  | +}
 | ||||||
|  | +#endif /* WITH_OPENSSL */
 | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/kexdh.c openssh-8.7p1-patched/kexdh.c
 | ||||||
|  | --- openssh-8.7p1/kexdh.c	2023-05-25 09:01:23.237626425 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/kexdh.c	2023-05-25 09:03:21.817957988 +0200
 | ||||||
|  | @@ -35,6 +35,10 @@
 | ||||||
|  |   | ||||||
|  |  #include "openbsd-compat/openssl-compat.h" | ||||||
|  |  #include <openssl/dh.h> | ||||||
|  | +#include <openssl/err.h>
 | ||||||
|  | +#include <openssl/evp.h>
 | ||||||
|  | +#include <openssl/core_names.h>
 | ||||||
|  | +#include <openssl/param_build.h>
 | ||||||
|  |   | ||||||
|  |  #include "sshkey.h" | ||||||
|  |  #include "kex.h" | ||||||
|  | @@ -83,9 +87,12 @@
 | ||||||
|  |  kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) | ||||||
|  |  { | ||||||
|  |  	BIGNUM *shared_secret = NULL; | ||||||
|  | +	const BIGNUM *pub, *priv, *p, *q, *g;
 | ||||||
|  | +	EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
 | ||||||
|  | +	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  |  	u_char *kbuf = NULL; | ||||||
|  |  	size_t klen = 0; | ||||||
|  | -	int kout, r;
 | ||||||
|  | +	int kout, r = 0;
 | ||||||
|  |   | ||||||
|  |  #ifdef DEBUG_KEXDH | ||||||
|  |  	fprintf(stderr, "dh_pub= "); | ||||||
|  | @@ -100,24 +107,59 @@
 | ||||||
|  |  		r = SSH_ERR_MESSAGE_INCOMPLETE; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	klen = DH_size(kex->dh);
 | ||||||
|  | +
 | ||||||
|  | +	DH_get0_key(kex->dh, &pub, &priv);
 | ||||||
|  | +	DH_get0_pqg(kex->dh, &p, &q, &g);
 | ||||||
|  | +	/* import key */
 | ||||||
|  | +	r = kex_create_evp_dh(&pkey, p, q, g, pub, priv);
 | ||||||
|  | +	if (r != 0) {
 | ||||||
|  | +		error_f("Could not create EVP_PKEY for dh");
 | ||||||
|  | +		ERR_print_errors_fp(stderr);
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	/* import peer key 
 | ||||||
|  | +	 * the parameters should be the same as with pkey
 | ||||||
|  | +	 */
 | ||||||
|  | +	r = kex_create_evp_dh(&dh_pkey, p, q, g, dh_pub, NULL);
 | ||||||
|  | +	if (r != 0) {
 | ||||||
|  | +		error_f("Could not import peer key for dh");
 | ||||||
|  | +		ERR_print_errors_fp(stderr);
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL) {
 | ||||||
|  | +		error_f("Could not init EVP_PKEY_CTX for dh");
 | ||||||
|  | +		r = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (EVP_PKEY_derive_init(ctx) != 1 ||
 | ||||||
|  | +	    EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
 | ||||||
|  | +	    EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
 | ||||||
|  | +		error_f("Could not get key size");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  |  	if ((kbuf = malloc(klen)) == NULL || | ||||||
|  |  	    (shared_secret = BN_new()) == NULL) { | ||||||
|  |  		r = SSH_ERR_ALLOC_FAIL; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	if ((kout = DH_compute_key(kbuf, dh_pub, kex->dh)) < 0 ||
 | ||||||
|  | -	    BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
 | ||||||
|  | +	if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1 ||
 | ||||||
|  | +	    BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
 | ||||||
|  | +		error_f("Could not derive key");
 | ||||||
|  |  		r = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  |  #ifdef DEBUG_KEXDH | ||||||
|  | -	dump_digest("shared secret", kbuf, kout);
 | ||||||
|  | +	dump_digest("shared secret", kbuf, klen);
 | ||||||
|  |  #endif | ||||||
|  |  	r = sshbuf_put_bignum2(out, shared_secret); | ||||||
|  |   out: | ||||||
|  |  	freezero(kbuf, klen); | ||||||
|  |  	BN_clear_free(shared_secret); | ||||||
|  | +	EVP_PKEY_free(pkey);
 | ||||||
|  | +	EVP_PKEY_free(dh_pkey);
 | ||||||
|  | +	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  |  	return r; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/kex.h openssh-8.7p1-patched/kex.h
 | ||||||
|  | --- openssh-8.7p1/kex.h	2023-05-25 09:01:23.299627122 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/kex.h	2023-05-25 09:00:56.519332820 +0200
 | ||||||
|  | @@ -33,6 +33,9 @@
 | ||||||
|  |  # include <openssl/bn.h> | ||||||
|  |  # include <openssl/dh.h> | ||||||
|  |  # include <openssl/ecdsa.h> | ||||||
|  | +# include <openssl/evp.h>
 | ||||||
|  | +# include <openssl/core_names.h>
 | ||||||
|  | +# include <openssl/param_build.h>
 | ||||||
|  |  # ifdef OPENSSL_HAS_ECC | ||||||
|  |  #  include <openssl/ec.h> | ||||||
|  |  # else /* OPENSSL_HAS_ECC */ | ||||||
|  | @@ -278,6 +281,8 @@
 | ||||||
|  |      const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) | ||||||
|  |  	__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) | ||||||
|  |  	__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); | ||||||
|  | +int	kex_create_evp_dh(EVP_PKEY **, const BIGNUM *, const BIGNUM *,
 | ||||||
|  | +    const BIGNUM *, const BIGNUM *, const BIGNUM *);
 | ||||||
|  |   | ||||||
|  |  #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) | ||||||
|  |  void	dump_digest(const char *, const u_char *, int); | ||||||
							
								
								
									
										207
									
								
								SOURCES/openssh-8.7p1-evp-fips-compl-ecdh.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								SOURCES/openssh-8.7p1-evp-fips-compl-ecdh.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,207 @@ | |||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../openssh-8.7p1/kexecdh.c ./kexecdh.c
 | ||||||
|  | --- ../openssh-8.7p1/kexecdh.c	2021-08-20 06:03:49.000000000 +0200
 | ||||||
|  | +++ ./kexecdh.c	2023-04-13 14:30:14.882449593 +0200
 | ||||||
|  | @@ -35,17 +35,57 @@
 | ||||||
|  |  #include <signal.h> | ||||||
|  |   | ||||||
|  |  #include <openssl/ecdh.h> | ||||||
|  | +#include <openssl/evp.h>
 | ||||||
|  | +#include <openssl/core_names.h>
 | ||||||
|  | +#include <openssl/param_build.h>
 | ||||||
|  | +#include <openssl/err.h>
 | ||||||
|  |   | ||||||
|  |  #include "sshkey.h" | ||||||
|  |  #include "kex.h" | ||||||
|  |  #include "sshbuf.h" | ||||||
|  |  #include "digest.h" | ||||||
|  |  #include "ssherr.h" | ||||||
|  | +#include "log.h"
 | ||||||
|  |   | ||||||
|  |  static int | ||||||
|  |  kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key, | ||||||
|  |      const EC_GROUP *, struct sshbuf **); | ||||||
|  |   | ||||||
|  | +static EC_KEY *
 | ||||||
|  | +generate_ec_keys(int ec_nid)
 | ||||||
|  | +{
 | ||||||
|  | +	EC_KEY *client_key = NULL;
 | ||||||
|  | +	EVP_PKEY *pkey = NULL;
 | ||||||
|  | +	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  | +	OSSL_PARAM_BLD *param_bld = NULL;
 | ||||||
|  | +	OSSL_PARAM *params = NULL;
 | ||||||
|  | +	const char *group_name;
 | ||||||
|  | +
 | ||||||
|  | +	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL ||
 | ||||||
|  | +	    (param_bld = OSSL_PARAM_BLD_new()) == NULL)
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	if ((group_name = OSSL_EC_curve_nid2name(ec_nid)) == NULL ||
 | ||||||
|  | +	    OSSL_PARAM_BLD_push_utf8_string(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
 | ||||||
|  | +	    (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
 | ||||||
|  | +		error_f("Could not create OSSL_PARAM");
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (EVP_PKEY_keygen_init(ctx) != 1 ||
 | ||||||
|  | +	    EVP_PKEY_CTX_set_params(ctx, params) != 1 ||
 | ||||||
|  | +	    EVP_PKEY_generate(ctx, &pkey) != 1 ||
 | ||||||
|  | +	    (client_key = EVP_PKEY_get1_EC_KEY(pkey)) == NULL) {
 | ||||||
|  | +		error_f("Could not generate ec keys");
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +out:
 | ||||||
|  | +	EVP_PKEY_free(pkey);
 | ||||||
|  | +	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +	OSSL_PARAM_BLD_free(param_bld);
 | ||||||
|  | +	OSSL_PARAM_free(params);
 | ||||||
|  | +	return client_key;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  int | ||||||
|  |  kex_ecdh_keypair(struct kex *kex) | ||||||
|  |  { | ||||||
|  | @@ -55,11 +95,7 @@
 | ||||||
|  |  	struct sshbuf *buf = NULL; | ||||||
|  |  	int r; | ||||||
|  |   | ||||||
|  | -	if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
 | ||||||
|  | -		r = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | -		goto out;
 | ||||||
|  | -	}
 | ||||||
|  | -	if (EC_KEY_generate_key(client_key) != 1) {
 | ||||||
|  | +	if ((client_key = generate_ec_keys(kex->ec_nid)) == NULL) {
 | ||||||
|  |  		r = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | @@ -101,11 +137,7 @@
 | ||||||
|  |  	*server_blobp = NULL; | ||||||
|  |  	*shared_secretp = NULL; | ||||||
|  |   | ||||||
|  | -	if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
 | ||||||
|  | -		r = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | -		goto out;
 | ||||||
|  | -	}
 | ||||||
|  | -	if (EC_KEY_generate_key(server_key) != 1) {
 | ||||||
|  | +	if ((server_key = generate_ec_keys(kex->ec_nid)) == NULL) {
 | ||||||
|  |  		r = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | @@ -140,11 +172,21 @@
 | ||||||
|  |  { | ||||||
|  |  	struct sshbuf *buf = NULL; | ||||||
|  |  	BIGNUM *shared_secret = NULL; | ||||||
|  | -	EC_POINT *dh_pub = NULL;
 | ||||||
|  | -	u_char *kbuf = NULL;
 | ||||||
|  | -	size_t klen = 0;
 | ||||||
|  | +	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  | +	EVP_PKEY *pkey = NULL, *dh_pkey = NULL;
 | ||||||
|  | +	OSSL_PARAM_BLD *param_bld = NULL;
 | ||||||
|  | +	OSSL_PARAM *params = NULL;
 | ||||||
|  | +	u_char *kbuf = NULL, *pub = NULL;
 | ||||||
|  | +	size_t klen = 0, publen;
 | ||||||
|  | +	const char *group_name;
 | ||||||
|  |  	int r; | ||||||
|  |   | ||||||
|  | +	/* import EC_KEY to EVP_PKEY */
 | ||||||
|  | +	if ((r = ssh_create_evp_ec(key, kex->ec_nid, &pkey)) != 0) {
 | ||||||
|  | +		error_f("Could not create EVP_PKEY");
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	*shared_secretp = NULL; | ||||||
|  |   | ||||||
|  |  	if ((buf = sshbuf_new()) == NULL) { | ||||||
|  | @@ -153,45 +195,82 @@
 | ||||||
|  |  	} | ||||||
|  |  	if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0) | ||||||
|  |  		goto out; | ||||||
|  | -	if ((dh_pub = EC_POINT_new(group)) == NULL) {
 | ||||||
|  | +
 | ||||||
|  | +	/* the public key is in the buffer in octet string UNCOMPRESSED
 | ||||||
|  | +	 * format. See sshbuf_put_ec */
 | ||||||
|  | +	if ((r = sshbuf_get_string(buf, &pub, &publen)) != 0)
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	sshbuf_reset(buf);
 | ||||||
|  | +	if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
 | ||||||
|  | +	    (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
 | ||||||
|  |  		r = SSH_ERR_ALLOC_FAIL; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	if ((r = sshbuf_get_ec(buf, dh_pub, group)) != 0) {
 | ||||||
|  | +	if ((group_name = OSSL_EC_curve_nid2name(kex->ec_nid)) == NULL) {
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (OSSL_PARAM_BLD_push_octet_string(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_PUB_KEY, pub, publen) != 1 ||
 | ||||||
|  | +	    OSSL_PARAM_BLD_push_utf8_string(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0) != 1 ||
 | ||||||
|  | +	    (params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
 | ||||||
|  | +		error_f("Failed to set params for dh_pkey");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	if (EVP_PKEY_fromdata_init(ctx) != 1 ||
 | ||||||
|  | +	    EVP_PKEY_fromdata(ctx, &dh_pkey,
 | ||||||
|  | +	        EVP_PKEY_PUBLIC_KEY, params) != 1 ||
 | ||||||
|  | +	    EVP_PKEY_public_check(ctx) != 1) {
 | ||||||
|  | +		error_f("Peer public key import failed");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	sshbuf_reset(buf);
 | ||||||
|  |   | ||||||
|  |  #ifdef DEBUG_KEXECDH | ||||||
|  |  	fputs("public key:\n", stderr); | ||||||
|  | -	sshkey_dump_ec_point(group, dh_pub);
 | ||||||
|  | +	EVP_PKEY_print_public_fp(stderr, dh_pkey, 0, NULL);
 | ||||||
|  |  #endif | ||||||
|  | -	if (sshkey_ec_validate_public(group, dh_pub) != 0) {
 | ||||||
|  | -		r = SSH_ERR_MESSAGE_INCOMPLETE;
 | ||||||
|  | +	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +	ctx = NULL;
 | ||||||
|  | +	if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL ||
 | ||||||
|  | +	    EVP_PKEY_derive_init(ctx) != 1 ||
 | ||||||
|  | +	    EVP_PKEY_derive_set_peer(ctx, dh_pkey) != 1 ||
 | ||||||
|  | +	    EVP_PKEY_derive(ctx, NULL, &klen) != 1) {
 | ||||||
|  | +		error_f("Failed to get derive information");
 | ||||||
|  | +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	klen = (EC_GROUP_get_degree(group) + 7) / 8;
 | ||||||
|  | -	if ((kbuf = malloc(klen)) == NULL ||
 | ||||||
|  | -	    (shared_secret = BN_new()) == NULL) {
 | ||||||
|  | +	if ((kbuf = malloc(klen)) == NULL) {
 | ||||||
|  |  		r = SSH_ERR_ALLOC_FAIL; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen ||
 | ||||||
|  | -	    BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
 | ||||||
|  | +	if (EVP_PKEY_derive(ctx, kbuf, &klen) != 1) {
 | ||||||
|  |  		r = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  |  #ifdef DEBUG_KEXECDH | ||||||
|  |  	dump_digest("shared secret", kbuf, klen); | ||||||
|  |  #endif | ||||||
|  | +	if ((shared_secret = BN_new()) == NULL ||
 | ||||||
|  | +	    (BN_bin2bn(kbuf, klen, shared_secret) == NULL)) {
 | ||||||
|  | +		r = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  |  	if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0) | ||||||
|  |  		goto out; | ||||||
|  |  	*shared_secretp = buf; | ||||||
|  |  	buf = NULL; | ||||||
|  |   out: | ||||||
|  | -	EC_POINT_clear_free(dh_pub);
 | ||||||
|  | +	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +	EVP_PKEY_free(pkey);
 | ||||||
|  | +	EVP_PKEY_free(dh_pkey);
 | ||||||
|  | +	OSSL_PARAM_BLD_free(param_bld);
 | ||||||
|  | +	OSSL_PARAM_free(params);
 | ||||||
|  |  	BN_clear_free(shared_secret); | ||||||
|  |  	freezero(kbuf, klen); | ||||||
|  | +	freezero(pub, publen);
 | ||||||
|  |  	sshbuf_free(buf); | ||||||
|  |  	return r; | ||||||
|  |  } | ||||||
							
								
								
									
										468
									
								
								SOURCES/openssh-8.7p1-evp-fips-compl-sign.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										468
									
								
								SOURCES/openssh-8.7p1-evp-fips-compl-sign.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,468 @@ | |||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-dss.c ./ssh-dss.c
 | ||||||
|  | --- ../../openssh-8.7p1/ssh-dss.c	2023-03-08 15:35:14.669943335 +0100
 | ||||||
|  | +++ ./ssh-dss.c	2023-03-08 15:34:33.508578129 +0100
 | ||||||
|  | @@ -32,6 +32,8 @@
 | ||||||
|  |  #include <openssl/bn.h> | ||||||
|  |  #include <openssl/dsa.h> | ||||||
|  |  #include <openssl/evp.h> | ||||||
|  | +#include <openssl/core_names.h>
 | ||||||
|  | +#include <openssl/param_build.h>
 | ||||||
|  |   | ||||||
|  |  #include <stdarg.h> | ||||||
|  |  #include <string.h> | ||||||
|  | @@ -72,9 +74,8 @@
 | ||||||
|  |  	    sshkey_type_plain(key->type) != KEY_DSA) | ||||||
|  |  		return SSH_ERR_INVALID_ARGUMENT; | ||||||
|  |   | ||||||
|  | -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||||
|  | -	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1)
 | ||||||
|  | -		return SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +  	if ((ret = ssh_create_evp_dss(key, &pkey)) != 0)
 | ||||||
|  | +    		return ret;
 | ||||||
|  |  	ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len, | ||||||
|  |  	    data, datalen); | ||||||
|  |  	EVP_PKEY_free(pkey); | ||||||
|  | @@ -201,11 +202,8 @@
 | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||||
|  | -	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) {
 | ||||||
|  | -		ret = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +  	if ((ret = ssh_create_evp_dss(key, &pkey)) != 0)
 | ||||||
|  |  		goto out; | ||||||
|  | -	}
 | ||||||
|  |  	ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen, | ||||||
|  |  	    sigb, slen); | ||||||
|  |  	EVP_PKEY_free(pkey); | ||||||
|  | @@ -221,4 +219,63 @@
 | ||||||
|  |  		freezero(sigblob, len); | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +ssh_create_evp_dss(const struct sshkey *k, EVP_PKEY **pkey)
 | ||||||
|  | +{
 | ||||||
|  | +  	OSSL_PARAM_BLD *param_bld = NULL;
 | ||||||
|  | +  	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  | +  	const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL;
 | ||||||
|  | +  	int ret = 0;
 | ||||||
|  | +
 | ||||||
|  | +  	if (k == NULL)
 | ||||||
|  | +  		return SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +  	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL ||
 | ||||||
|  | +  	    (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
 | ||||||
|  | +  		ret = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +  	  	goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +
 | ||||||
|  | +  	DSA_get0_pqg(k->dsa, &p, &q, &g);
 | ||||||
|  | +  	DSA_get0_key(k->dsa, &pub, &priv);
 | ||||||
|  | +
 | ||||||
|  | +  	if (p != NULL &&
 | ||||||
|  | +  	    OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p) != 1) {
 | ||||||
|  | +  		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +  		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (q != NULL &&
 | ||||||
|  | +  	    OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q) != 1) {
 | ||||||
|  | +  		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +  		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (g != NULL &&
 | ||||||
|  | +  	    OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) {
 | ||||||
|  | +  		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +  		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (pub != NULL &&
 | ||||||
|  | +  	    OSSL_PARAM_BLD_push_BN(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_PUB_KEY,
 | ||||||
|  | +	        pub) != 1) {
 | ||||||
|  | +  		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +  		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (priv != NULL &&
 | ||||||
|  | +  	    OSSL_PARAM_BLD_push_BN(param_bld,
 | ||||||
|  | +	        OSSL_PKEY_PARAM_PRIV_KEY,
 | ||||||
|  | +	        priv) != 1) {
 | ||||||
|  | +  		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +  		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) {
 | ||||||
|  | +  		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +  		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +
 | ||||||
|  | +out:
 | ||||||
|  | +  	OSSL_PARAM_BLD_free(param_bld);
 | ||||||
|  | +  	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +  	return ret;
 | ||||||
|  | +}
 | ||||||
|  |  #endif /* WITH_OPENSSL */ | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-ecdsa.c ./ssh-ecdsa.c
 | ||||||
|  | --- ../../openssh-8.7p1/ssh-ecdsa.c	2023-03-08 15:35:14.669943335 +0100
 | ||||||
|  | +++ ./ssh-ecdsa.c	2023-03-08 15:40:52.628201267 +0100
 | ||||||
|  | @@ -34,6 +34,8 @@
 | ||||||
|  |  #include <openssl/ec.h> | ||||||
|  |  #include <openssl/ecdsa.h> | ||||||
|  |  #include <openssl/evp.h> | ||||||
|  | +#include <openssl/core_names.h>
 | ||||||
|  | +#include <openssl/param_build.h>
 | ||||||
|  |   | ||||||
|  |  #include <string.h> | ||||||
|  |   | ||||||
|  | @@ -72,9 +74,8 @@
 | ||||||
|  |  	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) | ||||||
|  |  		return SSH_ERR_INTERNAL_ERROR; | ||||||
|  |   | ||||||
|  | -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||||
|  | -	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
 | ||||||
|  | -		return SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +  	if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0)
 | ||||||
|  | +		return ret;
 | ||||||
|  |  	ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, | ||||||
|  |  	    datalen); | ||||||
|  |  	EVP_PKEY_free(pkey); | ||||||
|  | @@ -193,11 +194,8 @@
 | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||||
|  | -	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) {
 | ||||||
|  | -		ret =  SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +  	if (ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey) != 0)
 | ||||||
|  |  		goto out; | ||||||
|  | -	}
 | ||||||
|  |  	ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len); | ||||||
|  |  	EVP_PKEY_free(pkey); | ||||||
|  |   | ||||||
|  | @@ -212,4 +210,76 @@
 | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +int
 | ||||||
|  | +ssh_create_evp_ec(EC_KEY *k, int ecdsa_nid, EVP_PKEY **pkey)
 | ||||||
|  | +{
 | ||||||
|  | +	OSSL_PARAM_BLD *param_bld = NULL;
 | ||||||
|  | +	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  | +  	BN_CTX *bn_ctx = NULL;
 | ||||||
|  | +  	uint8_t *pub_ser = NULL; 
 | ||||||
|  | +  	const char *group_name;
 | ||||||
|  | +  	const EC_POINT *pub = NULL;
 | ||||||
|  | +  	const BIGNUM *priv = NULL;
 | ||||||
|  | +  	int ret = 0;
 | ||||||
|  | +
 | ||||||
|  | +	if (k == NULL)
 | ||||||
|  | +    		return SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +  	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL ||
 | ||||||
|  | +      	    (param_bld = OSSL_PARAM_BLD_new()) == NULL ||
 | ||||||
|  | +      	    (bn_ctx = BN_CTX_new()) == NULL) {
 | ||||||
|  | +    		ret = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +    		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +
 | ||||||
|  | +	if ((group_name = OSSL_EC_curve_nid2name(ecdsa_nid)) == NULL ||
 | ||||||
|  | +     	    OSSL_PARAM_BLD_push_utf8_string(param_bld,
 | ||||||
|  | +                OSSL_PKEY_PARAM_GROUP_NAME,
 | ||||||
|  | +                group_name,
 | ||||||
|  | +                strlen(group_name)) != 1) {
 | ||||||
|  | +    		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +    		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +  	if ((pub = EC_KEY_get0_public_key(k)) != NULL) {
 | ||||||
|  | +    		const EC_GROUP *group;
 | ||||||
|  | +    		size_t len;
 | ||||||
|  | +
 | ||||||
|  | +		group = EC_KEY_get0_group(k);
 | ||||||
|  | +		len = EC_POINT_point2oct(group, pub,
 | ||||||
|  | +		    POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
 | ||||||
|  | +		if ((pub_ser = malloc(len)) == NULL) {
 | ||||||
|  | +			ret = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +			goto out;
 | ||||||
|  | +		}
 | ||||||
|  | +		EC_POINT_point2oct(group,
 | ||||||
|  | +		    pub,
 | ||||||
|  | +		    POINT_CONVERSION_UNCOMPRESSED,
 | ||||||
|  | +		    pub_ser,
 | ||||||
|  | +		    len,
 | ||||||
|  | +		    bn_ctx);
 | ||||||
|  | +		if (OSSL_PARAM_BLD_push_octet_string(param_bld,
 | ||||||
|  | +		    OSSL_PKEY_PARAM_PUB_KEY,
 | ||||||
|  | +		    pub_ser,
 | ||||||
|  | +		    len) != 1) {
 | ||||||
|  | +			ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +			goto out;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +  	if ((priv = EC_KEY_get0_private_key(k)) != NULL &&
 | ||||||
|  | +	    OSSL_PARAM_BLD_push_BN(param_bld,
 | ||||||
|  | +               OSSL_PKEY_PARAM_PRIV_KEY, priv) != 1) {
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) {
 | ||||||
|  | +    		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +    		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +
 | ||||||
|  | +out:
 | ||||||
|  | +  	OSSL_PARAM_BLD_free(param_bld);
 | ||||||
|  | +  	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +  	BN_CTX_free(bn_ctx);
 | ||||||
|  | +  	free(pub_ser);
 | ||||||
|  | +  	return ret;
 | ||||||
|  | +}
 | ||||||
|  |  #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/sshkey.c ./sshkey.c
 | ||||||
|  | --- ../../openssh-8.7p1/sshkey.c	2023-03-08 15:35:14.702943628 +0100
 | ||||||
|  | +++ ./sshkey.c	2023-03-08 15:39:03.354082015 +0100
 | ||||||
|  | @@ -35,6 +35,8 @@
 | ||||||
|  |  #include <openssl/err.h> | ||||||
|  |  #include <openssl/pem.h> | ||||||
|  |  #include <openssl/fips.h> | ||||||
|  | +#include <openssl/core_names.h>
 | ||||||
|  | +#include <openssl/param_build.h>
 | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  #include "crypto_api.h" | ||||||
|  | @@ -492,13 +494,14 @@
 | ||||||
|  |  { | ||||||
|  |  	EVP_MD_CTX *ctx = NULL; | ||||||
|  |  	u_char *sig = NULL; | ||||||
|  | -	int ret, slen, len;
 | ||||||
|  | +	int ret, slen;
 | ||||||
|  | +	size_t len;
 | ||||||
|  |   | ||||||
|  |  	if (sigp == NULL || lenp == NULL) { | ||||||
|  |  		return SSH_ERR_INVALID_ARGUMENT; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	slen = EVP_PKEY_size(pkey);
 | ||||||
|  | +	slen = EVP_PKEY_get_size(pkey);
 | ||||||
|  |  	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) | ||||||
|  |  		return SSH_ERR_INVALID_ARGUMENT; | ||||||
|  |   | ||||||
|  | @@ -511,9 +514,10 @@
 | ||||||
|  |  		ret = SSH_ERR_ALLOC_FAIL; | ||||||
|  |  		goto error; | ||||||
|  |  	} | ||||||
|  | -	if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 | ||||||
|  | -	    EVP_SignUpdate(ctx, data, datalen) <= 0 ||
 | ||||||
|  | -	    EVP_SignFinal(ctx, sig, &len, pkey) <= 0) {
 | ||||||
|  | +	if (EVP_DigestSignInit(ctx, NULL, ssh_digest_to_md(hash_alg),
 | ||||||
|  | +	        NULL, pkey) != 1 ||
 | ||||||
|  | +	    EVP_DigestSignUpdate(ctx, data, datalen) != 1 ||
 | ||||||
|  | +	    EVP_DigestSignFinal(ctx, sig, &len) != 1) {
 | ||||||
|  |  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  |  		goto error; | ||||||
|  |  	} | ||||||
|  | @@ -540,12 +544,13 @@
 | ||||||
|  |  	if ((ctx = EVP_MD_CTX_new()) == NULL) { | ||||||
|  |  		return SSH_ERR_ALLOC_FAIL; | ||||||
|  |  	} | ||||||
|  | -	if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 ||
 | ||||||
|  | -	    EVP_VerifyUpdate(ctx, data, datalen) <= 0) {
 | ||||||
|  | +	if (EVP_DigestVerifyInit(ctx, NULL, ssh_digest_to_md(hash_alg),
 | ||||||
|  | +	    NULL, pkey) != 1 ||
 | ||||||
|  | +	    EVP_DigestVerifyUpdate(ctx, data, datalen) != 1) {
 | ||||||
|  |  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  |  		goto done; | ||||||
|  |  	} | ||||||
|  | -	ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
 | ||||||
|  | +	ret = EVP_DigestVerifyFinal(ctx, sigbuf, siglen);
 | ||||||
|  |  	switch (ret) { | ||||||
|  |  	case 1: | ||||||
|  |  		ret = 0; | ||||||
|  | @@ -5038,3 +5043,27 @@
 | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |  #endif /* WITH_XMSS */ | ||||||
|  | +
 | ||||||
|  | +#ifdef WITH_OPENSSL
 | ||||||
|  | +EVP_PKEY *
 | ||||||
|  | +sshkey_create_evp(OSSL_PARAM_BLD *param_bld, EVP_PKEY_CTX *ctx)
 | ||||||
|  | +{
 | ||||||
|  | +  	EVP_PKEY *ret = NULL;
 | ||||||
|  | +  	OSSL_PARAM *params = NULL;
 | ||||||
|  | +  	if (param_bld == NULL || ctx == NULL) {
 | ||||||
|  | +  		debug2_f("param_bld or ctx is NULL");
 | ||||||
|  | +  		return NULL;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if ((params = OSSL_PARAM_BLD_to_param(param_bld)) == NULL) {
 | ||||||
|  | +  		debug2_f("Could not build param list");
 | ||||||
|  | +  		return NULL;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (EVP_PKEY_fromdata_init(ctx) != 1 ||
 | ||||||
|  | +  	    EVP_PKEY_fromdata(ctx, &ret, EVP_PKEY_KEYPAIR, params) != 1) {
 | ||||||
|  | +  		debug2_f("EVP_PKEY_fromdata failed");
 | ||||||
|  | +  		OSSL_PARAM_free(params);
 | ||||||
|  | +  		return NULL;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	return ret;
 | ||||||
|  | +}
 | ||||||
|  | +#endif /* WITH_OPENSSL */
 | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/sshkey.h ./sshkey.h
 | ||||||
|  | --- ../../openssh-8.7p1/sshkey.h	2023-03-08 15:35:14.702943628 +0100
 | ||||||
|  | +++ ./sshkey.h	2023-03-08 15:34:33.509578138 +0100
 | ||||||
|  | @@ -31,6 +31,9 @@
 | ||||||
|  |  #ifdef WITH_OPENSSL | ||||||
|  |  #include <openssl/rsa.h> | ||||||
|  |  #include <openssl/dsa.h> | ||||||
|  | +#include <openssl/evp.h>
 | ||||||
|  | +#include <openssl/param_build.h>
 | ||||||
|  | +#include <openssl/core_names.h>
 | ||||||
|  |  # ifdef OPENSSL_HAS_ECC | ||||||
|  |  #  include <openssl/ec.h> | ||||||
|  |  #  include <openssl/ecdsa.h> | ||||||
|  | @@ -293,6 +295,13 @@
 | ||||||
|  |   | ||||||
|  |  void	 sshkey_sig_details_free(struct sshkey_sig_details *); | ||||||
|  |   | ||||||
|  | +#ifdef WITH_OPENSSL
 | ||||||
|  | +EVP_PKEY  *sshkey_create_evp(OSSL_PARAM_BLD *, EVP_PKEY_CTX *);
 | ||||||
|  | +int   ssh_create_evp_dss(const struct sshkey *, EVP_PKEY **);
 | ||||||
|  | +int   ssh_create_evp_rsa(const struct sshkey *, EVP_PKEY **);
 | ||||||
|  | +int   ssh_create_evp_ec(EC_KEY *, int, EVP_PKEY **);
 | ||||||
|  | +#endif /* WITH_OPENSSL */
 | ||||||
|  | +
 | ||||||
|  |  #ifdef SSHKEY_INTERNAL | ||||||
|  |  int ssh_rsa_sign(const struct sshkey *key, | ||||||
|  |      u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac ../../openssh-8.7p1/ssh-rsa.c ./ssh-rsa.c
 | ||||||
|  | --- ../../openssh-8.7p1/ssh-rsa.c	2023-03-08 15:35:14.669943335 +0100
 | ||||||
|  | +++ ./ssh-rsa.c	2023-03-08 15:34:33.509578138 +0100
 | ||||||
|  | @@ -23,6 +23,8 @@
 | ||||||
|  |   | ||||||
|  |  #include <openssl/evp.h> | ||||||
|  |  #include <openssl/err.h> | ||||||
|  | +#include <openssl/core_names.h>
 | ||||||
|  | +#include <openssl/param_build.h>
 | ||||||
|  |   | ||||||
|  |  #include <stdarg.h> | ||||||
|  |  #include <string.h> | ||||||
|  | @@ -172,9 +174,8 @@
 | ||||||
|  |  	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) | ||||||
|  |  		return SSH_ERR_KEY_LENGTH; | ||||||
|  |   | ||||||
|  | -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||||
|  | -	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
 | ||||||
|  | -		return SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +  	if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)
 | ||||||
|  | +		return ret;
 | ||||||
|  |  	ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, | ||||||
|  |  	    datalen); | ||||||
|  |  	EVP_PKEY_free(pkey); | ||||||
|  | @@ -285,11 +286,8 @@
 | ||||||
|  |  		len = modlen; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||||
|  | -	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) {
 | ||||||
|  | -		ret = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +  	if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)
 | ||||||
|  |  		goto out; | ||||||
|  | -	}
 | ||||||
|  |  	ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey); | ||||||
|  |  	EVP_PKEY_free(pkey); | ||||||
|  |   | ||||||
|  | @@ -306,11 +304,9 @@
 | ||||||
|  |      u_char *sigbuf, size_t siglen, EVP_PKEY *pkey) | ||||||
|  |  { | ||||||
|  |  	size_t rsasize = 0; | ||||||
|  | -	const RSA *rsa;
 | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | -	rsa = EVP_PKEY_get0_RSA(pkey);
 | ||||||
|  | -	rsasize = RSA_size(rsa);
 | ||||||
|  | +	rsasize = EVP_PKEY_get_size(pkey);
 | ||||||
|  |  	if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || | ||||||
|  |  	    siglen == 0 || siglen > rsasize) { | ||||||
|  |  		ret = SSH_ERR_INVALID_ARGUMENT; | ||||||
|  | @@ -323,4 +319,87 @@
 | ||||||
|  |  done: | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +ssh_create_evp_rsa(const struct sshkey *k, EVP_PKEY **pkey)
 | ||||||
|  | +{
 | ||||||
|  | +  	OSSL_PARAM_BLD *param_bld = NULL;
 | ||||||
|  | +  	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  | +  	int ret = 0;
 | ||||||
|  | +  	const BIGNUM *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL;
 | ||||||
|  | +  	const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
 | ||||||
|  | +
 | ||||||
|  | +  	if (k == NULL)
 | ||||||
|  | +  	  	return SSH_ERR_INVALID_ARGUMENT;
 | ||||||
|  | +  	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL ||
 | ||||||
|  | +  	    (param_bld = OSSL_PARAM_BLD_new()) == NULL) {
 | ||||||
|  | +  	  	ret = SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +  	  	goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +
 | ||||||
|  | +  	RSA_get0_key(k->rsa, &n, &e, &d);
 | ||||||
|  | +  	RSA_get0_factors(k->rsa, &p, &q);
 | ||||||
|  | +  	RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp);
 | ||||||
|  | +
 | ||||||
|  | +  	if (n != NULL &&
 | ||||||
|  | +  	    OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, n) != 1) {
 | ||||||
|  | +  	  	ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +  		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (e != NULL &&
 | ||||||
|  | +  	    OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, e) != 1) {
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (d != NULL &&
 | ||||||
|  | +  	    OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_D, d) != 1) {
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +
 | ||||||
|  | +  	if ((*pkey = sshkey_create_evp(param_bld, ctx)) == NULL) {
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +
 | ||||||
|  | +  	/* setting this to param_build makes the creation process fail */
 | ||||||
|  | +  	if (p != NULL &&
 | ||||||
|  | +  	    EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, p) != 1) {
 | ||||||
|  | +		debug2_f("failed to add 'p' param");
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (q != NULL &&
 | ||||||
|  | +  	    EVP_PKEY_set_bn_param(*pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, q) != 1) {
 | ||||||
|  | +		debug2_f("failed to add 'q' param");
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (dmp1 != NULL &&
 | ||||||
|  | +  	    EVP_PKEY_set_bn_param(*pkey,
 | ||||||
|  | +  	        OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) != 1) {
 | ||||||
|  | +		debug2_f("failed to add 'dmp1' param");
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (dmq1 != NULL &&
 | ||||||
|  | +  	    EVP_PKEY_set_bn_param(*pkey,
 | ||||||
|  | +  	        OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) != 1) {
 | ||||||
|  | +		debug2_f("failed to add 'dmq1' param");
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +  	if (iqmp != NULL &&
 | ||||||
|  | +  	    EVP_PKEY_set_bn_param(*pkey,
 | ||||||
|  | +  	        OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) != 1) {
 | ||||||
|  | +		debug2_f("failed to add 'iqmp' param");
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +  	}
 | ||||||
|  | +
 | ||||||
|  | +out:
 | ||||||
|  | +  	OSSL_PARAM_BLD_free(param_bld);
 | ||||||
|  | +  	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +  	return ret;
 | ||||||
|  | +}
 | ||||||
|  |  #endif /* WITH_OPENSSL */ | ||||||
							
								
								
									
										131
									
								
								SOURCES/openssh-8.7p1-evp-pkcs11.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								SOURCES/openssh-8.7p1-evp-pkcs11.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | |||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/ssh-ecdsa.c openssh-8.7p1-patched/ssh-ecdsa.c
 | ||||||
|  | --- openssh-8.7p1/ssh-ecdsa.c	2023-05-24 09:39:45.002631174 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/ssh-ecdsa.c	2023-05-24 09:09:34.400853951 +0200
 | ||||||
|  | @@ -74,8 +74,18 @@
 | ||||||
|  |  	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) | ||||||
|  |  		return SSH_ERR_INTERNAL_ERROR; | ||||||
|  |   | ||||||
|  | -  	if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0)
 | ||||||
|  | -		return ret;
 | ||||||
|  | +#ifdef ENABLE_PKCS11
 | ||||||
|  | +	if (is_ecdsa_pkcs11(key->ecdsa)) {
 | ||||||
|  | +		if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||||
|  | +		    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
 | ||||||
|  | +			return SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +	} else {
 | ||||||
|  | +#endif
 | ||||||
|  | +		if ((ret = ssh_create_evp_ec(key->ecdsa, key->ecdsa_nid, &pkey)) != 0)
 | ||||||
|  | +			return ret;
 | ||||||
|  | +#ifdef ENABLE_PKCS11
 | ||||||
|  | +	}
 | ||||||
|  | +#endif
 | ||||||
|  |  	ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data, | ||||||
|  |  	    datalen); | ||||||
|  |  	EVP_PKEY_free(pkey); | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/ssh-pkcs11.c openssh-8.7p1-patched/ssh-pkcs11.c
 | ||||||
|  | --- openssh-8.7p1/ssh-pkcs11.c	2023-05-24 09:39:44.950630607 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/ssh-pkcs11.c	2023-05-24 09:33:59.153866357 +0200
 | ||||||
|  | @@ -775,8 +775,24 @@
 | ||||||
|  |   | ||||||
|  |  	return (0); | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +is_ecdsa_pkcs11(EC_KEY *ecdsa)
 | ||||||
|  | +{
 | ||||||
|  | +	if (EC_KEY_get_ex_data(ecdsa, ec_key_idx) != NULL)
 | ||||||
|  | +		return 1;
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  |  #endif /* HAVE_EC_KEY_METHOD_NEW */ | ||||||
|  |   | ||||||
|  | +int
 | ||||||
|  | +is_rsa_pkcs11(RSA *rsa)
 | ||||||
|  | +{
 | ||||||
|  | +	if (RSA_get_ex_data(rsa, rsa_idx) != NULL)
 | ||||||
|  | +		return 1;
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  /* remove trailing spaces */ | ||||||
|  |  static void | ||||||
|  |  rmspace(u_char *buf, size_t len) | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/ssh-pkcs11-client.c openssh-8.7p1-patched/ssh-pkcs11-client.c
 | ||||||
|  | --- openssh-8.7p1/ssh-pkcs11-client.c	2023-05-24 09:39:44.950630607 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/ssh-pkcs11-client.c	2023-05-24 09:31:16.139092673 +0200
 | ||||||
|  | @@ -225,8 +225,36 @@
 | ||||||
|  |  static RSA_METHOD	*helper_rsa; | ||||||
|  |  #ifdef HAVE_EC_KEY_METHOD_NEW | ||||||
|  |  static EC_KEY_METHOD	*helper_ecdsa; | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +is_ecdsa_pkcs11(EC_KEY *ecdsa)
 | ||||||
|  | +{
 | ||||||
|  | +	const EC_KEY_METHOD *meth;
 | ||||||
|  | +	ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgstlen,
 | ||||||
|  | +		const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey) = NULL;
 | ||||||
|  | +
 | ||||||
|  | +	meth = EC_KEY_get_method(ecdsa);
 | ||||||
|  | +	EC_KEY_METHOD_get_sign(meth, NULL, NULL, &sign_sig);
 | ||||||
|  | +	if (sign_sig == ecdsa_do_sign)
 | ||||||
|  | +		return 1;
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  |  #endif /* HAVE_EC_KEY_METHOD_NEW */ | ||||||
|  |   | ||||||
|  | +int
 | ||||||
|  | +is_rsa_pkcs11(RSA *rsa)
 | ||||||
|  | +{
 | ||||||
|  | +	const RSA_METHOD *meth;
 | ||||||
|  | +	int (*priv_enc)(int flen, const unsigned char *from,
 | ||||||
|  | +        	unsigned char *to, RSA *rsa, int padding) = NULL;
 | ||||||
|  | +
 | ||||||
|  | +	meth = RSA_get_method(rsa);
 | ||||||
|  | +	priv_enc = RSA_meth_get_priv_enc(meth);
 | ||||||
|  | +	if (priv_enc == rsa_encrypt)
 | ||||||
|  | +		return 1;
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  /* redirect private key crypto operations to the ssh-pkcs11-helper */ | ||||||
|  |  static void | ||||||
|  |  wrap_key(struct sshkey *k) | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/ssh-pkcs11.h openssh-8.7p1-patched/ssh-pkcs11.h
 | ||||||
|  | --- openssh-8.7p1/ssh-pkcs11.h	2023-05-24 09:39:44.950630607 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/ssh-pkcs11.h	2023-05-24 09:36:49.055714975 +0200
 | ||||||
|  | @@ -39,6 +39,11 @@
 | ||||||
|  |  	    u_int32_t *); | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +#ifdef HAVE_EC_KEY_METHOD_NEW
 | ||||||
|  | +int is_ecdsa_pkcs11(EC_KEY *ecdsa);
 | ||||||
|  | +#endif
 | ||||||
|  | +int is_rsa_pkcs11(RSA *rsa);
 | ||||||
|  | +
 | ||||||
|  |  #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) | ||||||
|  |  #undef ENABLE_PKCS11 | ||||||
|  |  #endif | ||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/ssh-rsa.c openssh-8.7p1-patched/ssh-rsa.c
 | ||||||
|  | --- openssh-8.7p1/ssh-rsa.c	2023-05-24 09:39:45.003631184 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/ssh-rsa.c	2023-05-24 09:31:37.019319860 +0200
 | ||||||
|  | @@ -174,8 +174,18 @@
 | ||||||
|  |  	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) | ||||||
|  |  		return SSH_ERR_KEY_LENGTH; | ||||||
|  |   | ||||||
|  | -  	if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)
 | ||||||
|  | -		return ret;
 | ||||||
|  | +#ifdef ENABLE_PKCS11
 | ||||||
|  | +	if (is_rsa_pkcs11(key->rsa)) {
 | ||||||
|  | +		if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||||
|  | +		    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
 | ||||||
|  | +			return SSH_ERR_ALLOC_FAIL;
 | ||||||
|  | +	} else {
 | ||||||
|  | +#endif
 | ||||||
|  | +		if ((ret = ssh_create_evp_rsa(key, &pkey)) != 0)
 | ||||||
|  | +			return ret;
 | ||||||
|  | +#ifdef ENABLE_PKCS11
 | ||||||
|  | +	}
 | ||||||
|  | +#endif
 | ||||||
|  |  	ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data, | ||||||
|  |  	    datalen); | ||||||
|  |  	EVP_PKEY_free(pkey); | ||||||
							
								
								
									
										110
									
								
								SOURCES/openssh-8.7p1-evpgenkey.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								SOURCES/openssh-8.7p1-evpgenkey.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | |||||||
|  | diff -up openssh-8.7p1/sshkey.c.evpgenrsa openssh-8.7p1/sshkey.c
 | ||||||
|  | --- openssh-8.7p1/sshkey.c.evpgenrsa	2022-06-30 15:14:58.200518353 +0200
 | ||||||
|  | +++ openssh-8.7p1/sshkey.c	2022-06-30 15:24:31.499641196 +0200
 | ||||||
|  | @@ -1657,7 +1657,8 @@ sshkey_cert_type(const struct sshkey *k)
 | ||||||
|  |  static int | ||||||
|  |  rsa_generate_private_key(u_int bits, RSA **rsap) | ||||||
|  |  { | ||||||
|  | -	RSA *private = NULL;
 | ||||||
|  | +	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  | +	EVP_PKEY *res = NULL;
 | ||||||
|  |  	BIGNUM *f4 = NULL; | ||||||
|  |  	int ret = SSH_ERR_INTERNAL_ERROR; | ||||||
|  |   | ||||||
|  | @@ -1667,20 +1668,42 @@ rsa_generate_private_key(u_int bits, RSA
 | ||||||
|  |  	    bits > SSHBUF_MAX_BIGNUM * 8) | ||||||
|  |  		return SSH_ERR_KEY_LENGTH; | ||||||
|  |  	*rsap = NULL; | ||||||
|  | -	if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
 | ||||||
|  | +
 | ||||||
|  | +	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)) == NULL
 | ||||||
|  | +		|| (f4 = BN_new()) == NULL || !BN_set_word(f4, RSA_F4)) {
 | ||||||
|  |  		ret = SSH_ERR_ALLOC_FAIL; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	if (!BN_set_word(f4, RSA_F4) ||
 | ||||||
|  | -	    !RSA_generate_key_ex(private, bits, f4, NULL)) {
 | ||||||
|  | +
 | ||||||
|  | +	if (EVP_PKEY_keygen_init(ctx) <= 0) {
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) {
 | ||||||
|  | +		ret = SSH_ERR_KEY_LENGTH;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, f4) <= 0)
 | ||||||
|  | +		goto out;
 | ||||||
|  | +
 | ||||||
|  | +	if (EVP_PKEY_keygen(ctx, &res) <= 0) {
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
 | ||||||
|  | +	*rsap = EVP_PKEY_get1_RSA(res);
 | ||||||
|  | +	if (*rsap) {
 | ||||||
|  | +		ret = 0;
 | ||||||
|  | +	} else {
 | ||||||
|  |  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	*rsap = private;
 | ||||||
|  | -	private = NULL;
 | ||||||
|  | -	ret = 0;
 | ||||||
|  |   out: | ||||||
|  | -	RSA_free(private);
 | ||||||
|  | +	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +	EVP_PKEY_free(res);
 | ||||||
|  |  	BN_free(f4); | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  | @@ -1820,7 +1820,8 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k)
 | ||||||
|  |  static int | ||||||
|  |  ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap) | ||||||
|  |  { | ||||||
|  | -	EC_KEY *private;
 | ||||||
|  | +	EVP_PKEY_CTX *ctx = NULL;
 | ||||||
|  | +	EVP_PKEY *res = NULL;
 | ||||||
|  |  	int ret = SSH_ERR_INTERNAL_ERROR; | ||||||
|  |   | ||||||
|  |  	if (nid == NULL || ecdsap == NULL) | ||||||
|  | @@ -1828,20 +1829,29 @@ ecdsa_generate_private_key(u_int bits, i
 | ||||||
|  |  	if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) | ||||||
|  |  		return SSH_ERR_KEY_LENGTH; | ||||||
|  |  	*ecdsap = NULL; | ||||||
|  | -	if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
 | ||||||
|  | +
 | ||||||
|  | +	if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) {
 | ||||||
|  |  		ret = SSH_ERR_ALLOC_FAIL; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	if (EC_KEY_generate_key(private) != 1) {
 | ||||||
|  | +
 | ||||||
|  | +	if (EVP_PKEY_keygen_init(ctx) <= 0 || EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(*nid)) <= 0
 | ||||||
|  | +	   || EVP_PKEY_keygen(ctx, &res) <= 0) {
 | ||||||
|  | +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  | +		goto out;
 | ||||||
|  | +	}
 | ||||||
|  | +	/* This function is deprecated in OpenSSL 3.0 but OpenSSH doesn't worry about it*/
 | ||||||
|  | +	*ecdsap = EVP_PKEY_get1_EC_KEY(res);
 | ||||||
|  | +	if (*ecdsap) {
 | ||||||
|  | +		EC_KEY_set_asn1_flag(*ecdsap, OPENSSL_EC_NAMED_CURVE);
 | ||||||
|  | +		ret = 0;
 | ||||||
|  | +	} else {
 | ||||||
|  |  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
 | ||||||
|  | -	*ecdsap = private;
 | ||||||
|  | -	private = NULL;
 | ||||||
|  | -	ret = 0;
 | ||||||
|  |   out: | ||||||
|  | -	EC_KEY_free(private);
 | ||||||
|  | +	EVP_PKEY_CTX_free(ctx);
 | ||||||
|  | +	EVP_PKEY_free(res);
 | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |  # endif /* OPENSSL_HAS_ECC */ | ||||||
							
								
								
									
										13
									
								
								SOURCES/openssh-8.7p1-find-principals-fix.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								SOURCES/openssh-8.7p1-find-principals-fix.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | diff -up openssh-8.7p1/ssh-keygen.c.find-princ openssh-8.7p1/ssh-keygen.c
 | ||||||
|  | --- openssh-8.7p1/ssh-keygen.c.find-princ	2021-11-29 15:27:03.032070863 +0100
 | ||||||
|  | +++ openssh-8.7p1/ssh-keygen.c	2021-11-29 15:27:34.736342968 +0100
 | ||||||
|  | @@ -2700,7 +2700,8 @@ sig_process_opts(char * const *opts, siz
 | ||||||
|  |  	time_t now; | ||||||
|  |   | ||||||
|  |  	*verify_timep = 0; | ||||||
|  | -	*print_pubkey = 0;
 | ||||||
|  | +	if (print_pubkey)
 | ||||||
|  | +		*print_pubkey = 0;
 | ||||||
|  |  	for (i = 0; i < nopts; i++) { | ||||||
|  |  		if (strncasecmp(opts[i], "verify-time=", 12) == 0) { | ||||||
|  |  			if (parse_absolute_time(opts[i] + 12, | ||||||
							
								
								
									
										20
									
								
								SOURCES/openssh-8.7p1-gssapi-auth.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								SOURCES/openssh-8.7p1-gssapi-auth.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | diff --color -rup a/monitor.c b/monitor.c
 | ||||||
|  | --- a/monitor.c	2022-07-11 15:11:28.146863144 +0200
 | ||||||
|  | +++ b/monitor.c	2022-07-11 15:15:35.726655877 +0200
 | ||||||
|  | @@ -376,8 +376,15 @@ monitor_child_preauth(struct ssh *ssh, s
 | ||||||
|  |  		if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { | ||||||
|  |  			auth_log(ssh, authenticated, partial, | ||||||
|  |  			    auth_method, auth_submethod); | ||||||
|  | -			if (!partial && !authenticated)
 | ||||||
|  | +			if (!partial && !authenticated) {
 | ||||||
|  | +#ifdef GSSAPI
 | ||||||
|  | +				/* If gssapi-with-mic failed, MONITOR_REQ_GSSCHECKMIC is disabled.
 | ||||||
|  | +				 * We have to reenable it to try again for gssapi-keyex */
 | ||||||
|  | +				if (strcmp(auth_method, "gssapi-with-mic") == 0 && options.gss_keyex)
 | ||||||
|  | +					monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
 | ||||||
|  | +#endif
 | ||||||
|  |  				authctxt->failures++; | ||||||
|  | +			}
 | ||||||
|  |  			if (authenticated || partial) { | ||||||
|  |  				auth2_update_session_info(authctxt, | ||||||
|  |  				    auth_method, auth_submethod); | ||||||
							
								
								
									
										151
									
								
								SOURCES/openssh-8.7p1-host-based-auth.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								SOURCES/openssh-8.7p1-host-based-auth.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,151 @@ | |||||||
|  | diff --color -rup a/sshconnect2.c b/sshconnect2.c
 | ||||||
|  | --- a/sshconnect2.c	2022-07-11 17:00:02.618575727 +0200
 | ||||||
|  | +++ b/sshconnect2.c	2022-07-11 17:03:05.096085690 +0200
 | ||||||
|  | @@ -2288,9 +2288,9 @@ userauth_hostbased(struct ssh *ssh)
 | ||||||
|  |  			if (authctxt->sensitive->keys[i] == NULL || | ||||||
|  |  			    authctxt->sensitive->keys[i]->type == KEY_UNSPEC) | ||||||
|  |  				continue; | ||||||
|  | -			if (match_pattern_list(
 | ||||||
|  | +			if (!sshkey_match_keyname_to_sigalgs(
 | ||||||
|  |  			    sshkey_ssh_name(authctxt->sensitive->keys[i]), | ||||||
|  | -			    authctxt->active_ktype, 0) != 1)
 | ||||||
|  | +			    authctxt->active_ktype))
 | ||||||
|  |  				continue; | ||||||
|  |  			/* we take and free the key */ | ||||||
|  |  			private = authctxt->sensitive->keys[i]; | ||||||
|  | @@ -2316,7 +2316,8 @@ userauth_hostbased(struct ssh *ssh)
 | ||||||
|  |  		error_f("sshkey_fingerprint failed"); | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  | -	debug_f("trying hostkey %s %s", sshkey_ssh_name(private), fp);
 | ||||||
|  | +	debug_f("trying hostkey %s %s using sigalg %s",
 | ||||||
|  | +		sshkey_ssh_name(private), fp, authctxt->active_ktype);
 | ||||||
|  |   | ||||||
|  |  	/* figure out a name for the client host */ | ||||||
|  |  	lname = get_local_name(ssh_packet_get_connection_in(ssh)); | ||||||
|  | diff --color -rup a/sshkey.c b/sshkey.c
 | ||||||
|  | --- a/sshkey.c	2022-07-11 17:00:02.609575554 +0200
 | ||||||
|  | +++ b/sshkey.c	2022-07-11 17:12:30.905976443 +0200
 | ||||||
|  | @@ -252,6 +252,29 @@ sshkey_ecdsa_nid_from_name(const char *n
 | ||||||
|  |  	return -1; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +int
 | ||||||
|  | +sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs)
 | ||||||
|  | +{
 | ||||||
|  | +	int ktype;
 | ||||||
|  | +
 | ||||||
|  | +	if (sigalgs == NULL || *sigalgs == '\0' ||
 | ||||||
|  | +	    (ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC)
 | ||||||
|  | +		return 0;
 | ||||||
|  | +	else if (ktype == KEY_RSA) {
 | ||||||
|  | +		return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 ||
 | ||||||
|  | +		    match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 ||
 | ||||||
|  | +		    match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1;
 | ||||||
|  | +	} else if (ktype == KEY_RSA_CERT) {
 | ||||||
|  | +		return match_pattern_list("ssh-rsa-cert-v01@openssh.com",
 | ||||||
|  | +		    sigalgs, 0) == 1 ||
 | ||||||
|  | +		    match_pattern_list("rsa-sha2-256-cert-v01@openssh.com",
 | ||||||
|  | +		    sigalgs, 0) == 1 ||
 | ||||||
|  | +		    match_pattern_list("rsa-sha2-512-cert-v01@openssh.com",
 | ||||||
|  | +		    sigalgs, 0) == 1;
 | ||||||
|  | +	} else
 | ||||||
|  | +		return match_pattern_list(keyname, sigalgs, 0) == 1;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  char * | ||||||
|  |  sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) | ||||||
|  |  { | ||||||
|  | diff --color -rup a/sshkey.h b/sshkey.h
 | ||||||
|  | --- a/sshkey.h	2022-07-11 17:00:02.603575438 +0200
 | ||||||
|  | +++ b/sshkey.h	2022-07-11 17:13:01.052556879 +0200
 | ||||||
|  | @@ -194,6 +194,10 @@ int	 sshkey_is_cert(const struct sshkey
 | ||||||
|  |  int	 sshkey_is_sk(const struct sshkey *); | ||||||
|  |  int	 sshkey_type_is_cert(int); | ||||||
|  |  int	 sshkey_type_plain(int); | ||||||
|  | +
 | ||||||
|  | +/* Returns non-zero if key name match sigalgs pattern list. (handles RSA) */
 | ||||||
|  | +int	 sshkey_match_keyname_to_sigalgs(const char *, const char *);
 | ||||||
|  | +
 | ||||||
|  |  int	 sshkey_to_certified(struct sshkey *); | ||||||
|  |  int	 sshkey_drop_cert(struct sshkey *); | ||||||
|  |  int	 sshkey_cert_copy(const struct sshkey *, struct sshkey *); | ||||||
|  | diff --color -rup a/ssh-keysign.c b/ssh-keysign.c
 | ||||||
|  | --- a/ssh-keysign.c	2021-08-20 06:03:49.000000000 +0200
 | ||||||
|  | +++ b/ssh-keysign.c	2022-07-11 17:00:23.306973667 +0200
 | ||||||
|  | @@ -62,7 +62,7 @@
 | ||||||
|  |  extern char *__progname; | ||||||
|  |   | ||||||
|  |  static int | ||||||
|  | -valid_request(struct passwd *pw, char *host, struct sshkey **ret,
 | ||||||
|  | +valid_request(struct passwd *pw, char *host, struct sshkey **ret, char **pkalgp,
 | ||||||
|  |      u_char *data, size_t datalen) | ||||||
|  |  { | ||||||
|  |  	struct sshbuf *b; | ||||||
|  | @@ -75,6 +75,8 @@ valid_request(struct passwd *pw, char *h
 | ||||||
|  |   | ||||||
|  |  	if (ret != NULL) | ||||||
|  |  		*ret = NULL; | ||||||
|  | +	if (pkalgp != NULL)
 | ||||||
|  | +		*pkalgp = NULL;
 | ||||||
|  |  	fail = 0; | ||||||
|  |   | ||||||
|  |  	if ((b = sshbuf_from(data, datalen)) == NULL) | ||||||
|  | @@ -122,8 +124,6 @@ valid_request(struct passwd *pw, char *h
 | ||||||
|  |  		fail++; | ||||||
|  |  	} else if (key->type != pktype) | ||||||
|  |  		fail++; | ||||||
|  | -	free(pkalg);
 | ||||||
|  | -	free(pkblob);
 | ||||||
|  |   | ||||||
|  |  	/* client host name, handle trailing dot */ | ||||||
|  |  	if ((r = sshbuf_get_cstring(b, &p, &len)) != 0) | ||||||
|  | @@ -154,8 +154,19 @@ valid_request(struct passwd *pw, char *h
 | ||||||
|  |   | ||||||
|  |  	if (fail) | ||||||
|  |  		sshkey_free(key); | ||||||
|  | -	else if (ret != NULL)
 | ||||||
|  | -		*ret = key;
 | ||||||
|  | +	else {
 | ||||||
|  | +		if (ret != NULL) {
 | ||||||
|  | +			*ret = key;
 | ||||||
|  | +			key = NULL;
 | ||||||
|  | +		}
 | ||||||
|  | +		if (pkalgp != NULL) {
 | ||||||
|  | +			*pkalgp = pkalg;
 | ||||||
|  | +			pkalg = NULL;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +	sshkey_free(key);
 | ||||||
|  | +	free(pkalg);
 | ||||||
|  | +	free(pkblob);
 | ||||||
|  |   | ||||||
|  |  	return (fail ? -1 : 0); | ||||||
|  |  } | ||||||
|  | @@ -170,7 +181,7 @@ main(int argc, char **argv)
 | ||||||
|  |  	struct passwd *pw; | ||||||
|  |  	int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd; | ||||||
|  |  	u_char *signature, *data, rver; | ||||||
|  | -	char *host, *fp;
 | ||||||
|  | +	char *host, *fp, *pkalg;
 | ||||||
|  |  	size_t slen, dlen; | ||||||
|  |   | ||||||
|  |  	if (pledge("stdio rpath getpw dns id", NULL) != 0) | ||||||
|  | @@ -258,7 +269,7 @@ main(int argc, char **argv)
 | ||||||
|  |   | ||||||
|  |  	if ((r = sshbuf_get_string(b, &data, &dlen)) != 0) | ||||||
|  |  		fatal_r(r, "%s: buffer error", __progname); | ||||||
|  | -	if (valid_request(pw, host, &key, data, dlen) < 0)
 | ||||||
|  | +	if (valid_request(pw, host, &key, &pkalg, data, dlen) < 0)
 | ||||||
|  |  		fatal("%s: not a valid request", __progname); | ||||||
|  |  	free(host); | ||||||
|  |   | ||||||
|  | @@ -279,7 +290,7 @@ main(int argc, char **argv)
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, | ||||||
|  | -	    NULL, NULL, NULL, 0)) != 0)
 | ||||||
|  | +	    pkalg, NULL, NULL, 0)) != 0)
 | ||||||
|  |  		fatal_r(r, "%s: sshkey_sign failed", __progname); | ||||||
|  |  	free(data); | ||||||
|  |   | ||||||
							
								
								
									
										12
									
								
								SOURCES/openssh-8.7p1-ibmca.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								SOURCES/openssh-8.7p1-ibmca.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | --- openssh-8.7p1/openbsd-compat/bsd-closefrom.c.orig	2022-04-12 15:47:03.815044607 +0200
 | ||||||
|  | +++ openssh-8.7p1/openbsd-compat/bsd-closefrom.c	2022-04-12 15:48:12.464963511 +0200
 | ||||||
|  | @@ -16,7 +16,7 @@
 | ||||||
|  |   | ||||||
|  |  #include "includes.h" | ||||||
|  |   | ||||||
|  | -#ifndef HAVE_CLOSEFROM
 | ||||||
|  | +#if (!defined HAVE_CLOSEFROM) || (defined __s390__)
 | ||||||
|  |   | ||||||
|  |  #include <sys/types.h> | ||||||
|  |  #include <sys/param.h> | ||||||
|  | 
 | ||||||
							
								
								
									
										31
									
								
								SOURCES/openssh-8.7p1-man-hostkeyalgos.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								SOURCES/openssh-8.7p1-man-hostkeyalgos.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | diff --color -ru -x regress -x autom4te.cache -x '*.o' -x '*.lo' -x Makefile -x config.status -x configure~ -x configure.ac openssh-8.7p1/ssh_config.5 openssh-8.7p1-patched/ssh_config.5
 | ||||||
|  | --- openssh-8.7p1/ssh_config.5	2023-06-02 09:14:40.279373577 +0200
 | ||||||
|  | +++ openssh-8.7p1-patched/ssh_config.5	2023-05-30 16:01:04.533848172 +0200
 | ||||||
|  | @@ -989,6 +989,17 @@
 | ||||||
|  |  .Pp | ||||||
|  |  The list of available signature algorithms may also be obtained using | ||||||
|  |  .Qq ssh -Q HostKeyAlgorithms . | ||||||
|  | +.Pp
 | ||||||
|  | +The proposed
 | ||||||
|  | +.Cm HostKeyAlgorithms
 | ||||||
|  | +during KEX are limited to the set of algorithms that is defined in
 | ||||||
|  | +.Cm PubkeyAcceptedAlgorithms
 | ||||||
|  | +and therefore they are indirectly affected by system-wide
 | ||||||
|  | +.Xr crypto_policies 7 .
 | ||||||
|  | +.Xr crypto_policies 7 can not handle the list of host key algorithms directly as doing so
 | ||||||
|  | +would break the order given by the
 | ||||||
|  | +.Pa known_hosts
 | ||||||
|  | +file.
 | ||||||
|  |  .It Cm HostKeyAlias | ||||||
|  |  Specifies an alias that should be used instead of the | ||||||
|  |  real host name when looking up or saving the host key | ||||||
|  | @@ -1564,6 +1575,9 @@
 | ||||||
|  |  .Pp | ||||||
|  |  The list of available signature algorithms may also be obtained using | ||||||
|  |  .Qq ssh -Q PubkeyAcceptedAlgorithms . | ||||||
|  | +.Pp
 | ||||||
|  | +This option affects also
 | ||||||
|  | +.Cm HostKeyAlgorithms
 | ||||||
|  |  .It Cm PubkeyAuthentication | ||||||
|  |  Specifies whether to try public key authentication. | ||||||
|  |  The argument to this keyword must be | ||||||
							
								
								
									
										156
									
								
								SOURCES/openssh-8.7p1-mem-leak.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								SOURCES/openssh-8.7p1-mem-leak.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | |||||||
|  | diff --color -rup a/compat.c b/compat.c
 | ||||||
|  | --- a/compat.c	2021-08-20 06:03:49.000000000 +0200
 | ||||||
|  | +++ b/compat.c	2022-07-14 17:39:23.770268440 +0200
 | ||||||
|  | @@ -157,11 +157,12 @@ compat_banner(struct ssh *ssh, const cha
 | ||||||
|  |  	debug_f("no match: %s", version); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* Always returns pointer to allocated memory, caller must free. */
 | ||||||
|  |  char * | ||||||
|  |  compat_cipher_proposal(struct ssh *ssh, char *cipher_prop) | ||||||
|  |  { | ||||||
|  |  	if (!(ssh->compat & SSH_BUG_BIGENDIANAES)) | ||||||
|  | -		return cipher_prop;
 | ||||||
|  | +		return xstrdup(cipher_prop);
 | ||||||
|  |  	debug2_f("original cipher proposal: %s", cipher_prop); | ||||||
|  |  	if ((cipher_prop = match_filter_denylist(cipher_prop, "aes*")) == NULL) | ||||||
|  |  		fatal("match_filter_denylist failed"); | ||||||
|  | @@ -171,11 +172,12 @@ compat_cipher_proposal(struct ssh *ssh,
 | ||||||
|  |  	return cipher_prop; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* Always returns pointer to allocated memory, caller must free. */
 | ||||||
|  |  char * | ||||||
|  |  compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) | ||||||
|  |  { | ||||||
|  |  	if (!(ssh->compat & SSH_BUG_RSASIGMD5)) | ||||||
|  | -		return pkalg_prop;
 | ||||||
|  | +		return xstrdup(pkalg_prop);
 | ||||||
|  |  	debug2_f("original public key proposal: %s", pkalg_prop); | ||||||
|  |  	if ((pkalg_prop = match_filter_denylist(pkalg_prop, "ssh-rsa")) == NULL) | ||||||
|  |  		fatal("match_filter_denylist failed"); | ||||||
|  | @@ -185,21 +187,26 @@ compat_pkalg_proposal(struct ssh *ssh, c
 | ||||||
|  |  	return pkalg_prop; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* Always returns pointer to allocated memory, caller must free. */
 | ||||||
|  |  char * | ||||||
|  |  compat_kex_proposal(struct ssh *ssh, char *p) | ||||||
|  |  { | ||||||
|  | +	char *cp = NULL;
 | ||||||
|  | +
 | ||||||
|  |  	if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) | ||||||
|  | -		return p;
 | ||||||
|  | +		return xstrdup(p);
 | ||||||
|  |  	debug2_f("original KEX proposal: %s", p); | ||||||
|  |  	if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) | ||||||
|  |  		if ((p = match_filter_denylist(p, | ||||||
|  |  		    "curve25519-sha256@libssh.org")) == NULL) | ||||||
|  |  			fatal("match_filter_denylist failed"); | ||||||
|  |  	if ((ssh->compat & SSH_OLD_DHGEX) != 0) { | ||||||
|  | +		cp = p;
 | ||||||
|  |  		if ((p = match_filter_denylist(p, | ||||||
|  |  		    "diffie-hellman-group-exchange-sha256," | ||||||
|  |  		    "diffie-hellman-group-exchange-sha1")) == NULL) | ||||||
|  |  			fatal("match_filter_denylist failed"); | ||||||
|  | +		free(cp);
 | ||||||
|  |  	} | ||||||
|  |  	debug2_f("compat KEX proposal: %s", p); | ||||||
|  |  	if (*p == '\0') | ||||||
|  | diff --color -rup a/sshconnect2.c b/sshconnect2.c
 | ||||||
|  | --- a/sshconnect2.c	2022-07-14 17:38:43.241496549 +0200
 | ||||||
|  | +++ b/sshconnect2.c	2022-07-14 17:39:23.772268479 +0200
 | ||||||
|  | @@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | ||||||
|  |  { | ||||||
|  |  	char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; | ||||||
|  |  	char *s, *all_key; | ||||||
|  | +	char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL;
 | ||||||
|  |  	int r, use_known_hosts_order = 0; | ||||||
|  |   | ||||||
|  |  #if defined(GSSAPI) && defined(WITH_OPENSSL) | ||||||
|  | @@ -252,10 +253,9 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | ||||||
|  |   | ||||||
|  |  	if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) | ||||||
|  |  		fatal_f("kex_names_cat"); | ||||||
|  | -	myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, s);
 | ||||||
|  | +	myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, s);
 | ||||||
|  |  	myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||||||
|  | -	    compat_cipher_proposal(ssh, options.ciphers);
 | ||||||
|  | -	myproposal[PROPOSAL_ENC_ALGS_STOC] =
 | ||||||
|  | +	    myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc =
 | ||||||
|  |  	    compat_cipher_proposal(ssh, options.ciphers); | ||||||
|  |  	myproposal[PROPOSAL_COMP_ALGS_CTOS] = | ||||||
|  |  	    myproposal[PROPOSAL_COMP_ALGS_STOC] = | ||||||
|  | @@ -264,12 +264,12 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | ||||||
|  |  	    myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; | ||||||
|  |  	if (use_known_hosts_order) { | ||||||
|  |  		/* Query known_hosts and prefer algorithms that appear there */ | ||||||
|  | -		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
 | ||||||
|  | +		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
 | ||||||
|  |  		    compat_pkalg_proposal(ssh, | ||||||
|  |  		    order_hostkeyalgs(host, hostaddr, port, cinfo)); | ||||||
|  |  	} else { | ||||||
|  |  		/* Use specified HostkeyAlgorithms exactly */ | ||||||
|  | -		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
 | ||||||
|  | +		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
 | ||||||
|  |  		    compat_pkalg_proposal(ssh, options.hostkeyalgorithms); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -383,6 +383,10 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | ||||||
|  |  	    (r = ssh_packet_write_wait(ssh)) != 0) | ||||||
|  |  		fatal_fr(r, "send packet"); | ||||||
|  |  #endif | ||||||
|  | +	/* Free only parts of proposal that were dynamically allocated here. */
 | ||||||
|  | +	free(prop_kex);
 | ||||||
|  | +	free(prop_enc);
 | ||||||
|  | +	free(prop_hostkey);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  | diff --color -rup a/sshd.c b/sshd.c
 | ||||||
|  | --- a/sshd.c	2022-07-14 17:38:43.242496568 +0200
 | ||||||
|  | +++ b/sshd.c	2022-07-14 17:42:07.616388978 +0200
 | ||||||
|  | @@ -2493,14 +2493,15 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||||
|  |  { | ||||||
|  |  	char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; | ||||||
|  |  	struct kex *kex; | ||||||
|  | +	char *hostkey_types = NULL;
 | ||||||
|  | +	char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL;
 | ||||||
|  |  	int r; | ||||||
|  |   | ||||||
|  | -	myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh,
 | ||||||
|  | +	myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh,
 | ||||||
|  |  	    options.kex_algorithms); | ||||||
|  | -	myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh,
 | ||||||
|  | -	    options.ciphers);
 | ||||||
|  | -	myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(ssh,
 | ||||||
|  | -	    options.ciphers);
 | ||||||
|  | +	myproposal[PROPOSAL_ENC_ALGS_CTOS] =
 | ||||||
|  | +	    myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc =
 | ||||||
|  | +	    compat_cipher_proposal(ssh, options.ciphers);
 | ||||||
|  |  	myproposal[PROPOSAL_MAC_ALGS_CTOS] = | ||||||
|  |  	    myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; | ||||||
|  |   | ||||||
|  | @@ -2513,8 +2514,10 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||||
|  |  		ssh_packet_set_rekey_limits(ssh, options.rekey_limit, | ||||||
|  |  		    options.rekey_interval); | ||||||
|  |   | ||||||
|  | -	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
 | ||||||
|  | -	    ssh, list_hostkey_types());
 | ||||||
|  | +	hostkey_types = list_hostkey_types();
 | ||||||
|  | +	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
 | ||||||
|  | +	    compat_pkalg_proposal(ssh, hostkey_types);
 | ||||||
|  | +	free(hostkey_types);
 | ||||||
|  |   | ||||||
|  |  #if defined(GSSAPI) && defined(WITH_OPENSSL) | ||||||
|  |  	{ | ||||||
|  | @@ -2606,6 +2609,9 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||||
|  |  	    (r = ssh_packet_write_wait(ssh)) != 0) | ||||||
|  |  		fatal_fr(r, "send test"); | ||||||
|  |  #endif | ||||||
|  | +	free(prop_kex);
 | ||||||
|  | +	free(prop_enc);
 | ||||||
|  | +	free(prop_hostkey);
 | ||||||
|  |  	debug("KEX done"); | ||||||
|  |  } | ||||||
|  |   | ||||||
| @ -1,7 +1,109 @@ | |||||||
|  | diff --color -ru a/clientloop.c b/clientloop.c
 | ||||||
|  | --- a/clientloop.c	2022-06-29 16:35:06.677597259 +0200
 | ||||||
|  | +++ b/clientloop.c	2022-06-29 16:40:29.737926205 +0200
 | ||||||
|  | @@ -116,6 +116,9 @@
 | ||||||
|  |  #include "ssh-gss.h" | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +/* Permitted RSA signature algorithms for UpdateHostkeys proofs */
 | ||||||
|  | +#define HOSTKEY_PROOF_RSA_ALGS	"rsa-sha2-512,rsa-sha2-256"
 | ||||||
|  | +
 | ||||||
|  |  /* import options */ | ||||||
|  |  extern Options options; | ||||||
|  |   | ||||||
|  | @@ -2110,8 +2113,10 @@
 | ||||||
|  |  	struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; | ||||||
|  |  	size_t i, ndone; | ||||||
|  |  	struct sshbuf *signdata; | ||||||
|  | -	int r, kexsigtype, use_kexsigtype;
 | ||||||
|  | +	int r, plaintype;
 | ||||||
|  |  	const u_char *sig; | ||||||
|  | +	const char *rsa_kexalg = NULL;
 | ||||||
|  | +	char *alg = NULL;
 | ||||||
|  |  	size_t siglen; | ||||||
|  |   | ||||||
|  |  	if (ctx->nnew == 0) | ||||||
|  | @@ -2122,9 +2127,9 @@
 | ||||||
|  |  		hostkeys_update_ctx_free(ctx); | ||||||
|  |  		return; | ||||||
|  |  	} | ||||||
|  | -	kexsigtype = sshkey_type_plain(
 | ||||||
|  | -	    sshkey_type_from_name(ssh->kex->hostkey_alg));
 | ||||||
|  | -
 | ||||||
|  | +	if (sshkey_type_plain(sshkey_type_from_name(
 | ||||||
|  | +	    ssh->kex->hostkey_alg)) == KEY_RSA)
 | ||||||
|  | +		rsa_kexalg = ssh->kex->hostkey_alg;
 | ||||||
|  |  	if ((signdata = sshbuf_new()) == NULL) | ||||||
|  |  		fatal_f("sshbuf_new failed"); | ||||||
|  |  	/* | ||||||
|  | @@ -2135,6 +2140,7 @@
 | ||||||
|  |  	for (ndone = i = 0; i < ctx->nkeys; i++) { | ||||||
|  |  		if (ctx->keys_match[i]) | ||||||
|  |  			continue; | ||||||
|  | +		plaintype = sshkey_type_plain(ctx->keys[i]->type);
 | ||||||
|  |  		/* Prepare data to be signed: session ID, unique string, key */ | ||||||
|  |  		sshbuf_reset(signdata); | ||||||
|  |  		if ( (r = sshbuf_put_cstring(signdata, | ||||||
|  | @@ -2148,19 +2154,33 @@
 | ||||||
|  |  			error_fr(r, "parse sig"); | ||||||
|  |  			goto out; | ||||||
|  |  		} | ||||||
|  | +		if ((r = sshkey_get_sigtype(sig, siglen, &alg)) != 0) {
 | ||||||
|  | +			error_fr(r, "server gave unintelligible signature "
 | ||||||
|  | +				"for %s key %zu", sshkey_type(ctx->keys[i]), i);
 | ||||||
|  | +			goto out;
 | ||||||
|  | +		}
 | ||||||
|  |  		/* | ||||||
|  | -		 * For RSA keys, prefer to use the signature type negotiated
 | ||||||
|  | -		 * during KEX to the default (SHA1).
 | ||||||
|  | +		 * Special case for RSA keys: if a RSA hostkey was negotiated,
 | ||||||
|  | +		 * then use its signature type for verification of RSA hostkey
 | ||||||
|  | +		 * proofs. Otherwise, accept only RSA-SHA256/512 signatures.
 | ||||||
|  |  		 */ | ||||||
|  | -		use_kexsigtype = kexsigtype == KEY_RSA &&
 | ||||||
|  | -		    sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA;
 | ||||||
|  | -		debug3_f("verify %s key %zu using %s sigalg",
 | ||||||
|  | -		    sshkey_type(ctx->keys[i]), i,
 | ||||||
|  | -		    use_kexsigtype ? ssh->kex->hostkey_alg : "default");
 | ||||||
|  | +		if (plaintype == KEY_RSA && rsa_kexalg == NULL &&
 | ||||||
|  | +		    match_pattern_list(alg, HOSTKEY_PROOF_RSA_ALGS, 0) != 1) {
 | ||||||
|  | +			debug_f("server used untrusted RSA signature algorithm "
 | ||||||
|  | +				"%s for key %zu, disregarding", alg, i);
 | ||||||
|  | +			free(alg);
 | ||||||
|  | +			/* zap the key from the list */
 | ||||||
|  | +			sshkey_free(ctx->keys[i]);
 | ||||||
|  | +			ctx->keys[i] = NULL;
 | ||||||
|  | +			ndone++;
 | ||||||
|  | +			continue;
 | ||||||
|  | +		}
 | ||||||
|  | +		debug3_f("verify %s key %zu using sigalg %s",
 | ||||||
|  | +			sshkey_type(ctx->keys[i]), i, alg);
 | ||||||
|  | +		free(alg);
 | ||||||
|  |  		if ((r = sshkey_verify(ctx->keys[i], sig, siglen, | ||||||
|  |  		    sshbuf_ptr(signdata), sshbuf_len(signdata), | ||||||
|  | -		    use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0,
 | ||||||
|  | -		    NULL)) != 0) {
 | ||||||
|  | +		    plaintype == KEY_RSA ? rsa_kexalg : NULL, 0, NULL)) != 0) {
 | ||||||
|  |  			error_fr(r, "server gave bad signature for %s key %zu", | ||||||
|  |  			    sshkey_type(ctx->keys[i]), i); | ||||||
|  |  			goto out; | ||||||
|  | diff --git a/hostfile.c b/hostfile.c
 | ||||||
|  | index a035b381..bd49e3ac 100644
 | ||||||
|  | --- a/hostfile.c
 | ||||||
|  | +++ b/hostfile.c
 | ||||||
|  | @@ -642,7 +642,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip,
 | ||||||
|  |  	/* Re-add the requested keys */ | ||||||
|  |  	want = HKF_MATCH_HOST | (ip == NULL ? 0 : HKF_MATCH_IP); | ||||||
|  |  	for (i = 0; i < nkeys; i++) { | ||||||
|  | -		if ((want & ctx.match_keys[i]) == want)
 | ||||||
|  | +		if (keys[i] == NULL || (want & ctx.match_keys[i]) == want)
 | ||||||
|  |  			continue; | ||||||
|  |  		if ((fp = sshkey_fingerprint(keys[i], hash_alg, | ||||||
|  |  		    SSH_FP_DEFAULT)) == NULL) { | ||||||
| diff --color -ru a/kex.c b/kex.c
 | diff --color -ru a/kex.c b/kex.c
 | ||||||
| --- a/kex.c	2022-06-23 10:25:29.529922670 +0200
 | --- a/kex.c	2022-06-29 16:35:06.775599179 +0200
 | ||||||
| +++ b/kex.c	2022-06-23 10:26:12.911762100 +0200
 | +++ b/kex.c	2022-06-29 16:42:00.839710940 +0200
 | ||||||
| @@ -906,6 +906,18 @@
 | @@ -959,6 +959,18 @@
 | ||||||
|  	return (1); |  	return (1); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @ -20,7 +122,7 @@ diff --color -ru a/kex.c b/kex.c | |||||||
|  static int |  static int | ||||||
|  kex_choose_conf(struct ssh *ssh) |  kex_choose_conf(struct ssh *ssh) | ||||||
|  { |  { | ||||||
| @@ -941,6 +953,16 @@
 | @@ -994,6 +1006,16 @@
 | ||||||
|  		free(ext); |  		free(ext); | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @ -38,9 +140,9 @@ diff --color -ru a/kex.c b/kex.c | |||||||
|  	if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], |  	if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], | ||||||
|  	    sprop[PROPOSAL_KEX_ALGS])) != 0) { |  	    sprop[PROPOSAL_KEX_ALGS])) != 0) { | ||||||
| diff --color -ru a/kex.h b/kex.h
 | diff --color -ru a/kex.h b/kex.h
 | ||||||
| --- a/kex.h	2022-06-23 10:25:29.511922322 +0200
 | --- a/kex.h	2022-06-29 16:35:06.766599003 +0200
 | ||||||
| +++ b/kex.h	2022-06-23 10:26:12.902761926 +0200
 | +++ b/kex.h	2022-06-29 16:42:24.199168567 +0200
 | ||||||
| @@ -117,6 +117,8 @@
 | @@ -116,6 +116,8 @@
 | ||||||
|   |   | ||||||
|  #define KEX_INIT_SENT	0x0001 |  #define KEX_INIT_SENT	0x0001 | ||||||
|  #define KEX_INITIAL	0x0002 |  #define KEX_INITIAL	0x0002 | ||||||
| @ -50,9 +152,9 @@ diff --color -ru a/kex.h b/kex.h | |||||||
|  struct sshenc { |  struct sshenc { | ||||||
|  	char	*name; |  	char	*name; | ||||||
| diff --color -ru a/serverloop.c b/serverloop.c
 | diff --color -ru a/serverloop.c b/serverloop.c
 | ||||||
| --- a/serverloop.c	2022-06-23 10:25:29.537922825 +0200
 | --- a/serverloop.c	2021-08-20 06:03:49.000000000 +0200
 | ||||||
| +++ b/serverloop.c	2022-06-23 10:26:12.918762235 +0200
 | +++ b/serverloop.c	2022-06-29 16:45:05.902336428 +0200
 | ||||||
| @@ -736,16 +736,17 @@
 | @@ -684,16 +684,18 @@
 | ||||||
|  	struct sshbuf *resp = NULL; |  	struct sshbuf *resp = NULL; | ||||||
|  	struct sshbuf *sigbuf = NULL; |  	struct sshbuf *sigbuf = NULL; | ||||||
|  	struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; |  	struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; | ||||||
| @ -64,8 +166,8 @@ diff --color -ru a/serverloop.c b/serverloop.c | |||||||
|  	size_t blen, slen; |  	size_t blen, slen; | ||||||
|   |   | ||||||
|  	if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) |  	if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) | ||||||
|  		fatal("%s: sshbuf_new", __func__); |  		fatal_f("sshbuf_new"); | ||||||
| -
 |   | ||||||
| -	kexsigtype = sshkey_type_plain(
 | -	kexsigtype = sshkey_type_plain(
 | ||||||
| -	    sshkey_type_from_name(ssh->kex->hostkey_alg));
 | -	    sshkey_type_from_name(ssh->kex->hostkey_alg));
 | ||||||
| +	if (sshkey_type_plain(sshkey_type_from_name(
 | +	if (sshkey_type_plain(sshkey_type_from_name(
 | ||||||
| @ -74,7 +176,7 @@ diff --color -ru a/serverloop.c b/serverloop.c | |||||||
|  	while (ssh_packet_remaining(ssh) > 0) { |  	while (ssh_packet_remaining(ssh) > 0) { | ||||||
|  		sshkey_free(key); |  		sshkey_free(key); | ||||||
|  		key = NULL; |  		key = NULL; | ||||||
| @@ -780,16 +781,24 @@
 | @@ -726,16 +728,24 @@
 | ||||||
|  		 * For RSA keys, prefer to use the signature type negotiated |  		 * For RSA keys, prefer to use the signature type negotiated | ||||||
|  		 * during KEX to the default (SHA1). |  		 * during KEX to the default (SHA1). | ||||||
|  		 */ |  		 */ | ||||||
| @ -89,78 +191,17 @@ diff --color -ru a/serverloop.c b/serverloop.c | |||||||
| +			else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
 | +			else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
 | ||||||
| +				sigalg = "rsa-sha2-256";
 | +				sigalg = "rsa-sha2-256";
 | ||||||
| +		}
 | +		}
 | ||||||
| +		debug3("%s: sign %s key (index %d) using sigalg %s", __func__,
 | +		debug3_f("sign %s key (index %d) using sigalg %s",
 | ||||||
| +		sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
 | +		sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
 | ||||||
|  		if ((r = sshbuf_put_cstring(sigbuf, |  		if ((r = sshbuf_put_cstring(sigbuf, | ||||||
|  		    "hostkeys-prove-00@openssh.com")) != 0 || |  		    "hostkeys-prove-00@openssh.com")) != 0 || | ||||||
|  		    (r = sshbuf_put_string(sigbuf, |  		    (r = sshbuf_put_stringb(sigbuf, | ||||||
|  		    ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || |  		    ssh->kex->session_id)) != 0 || | ||||||
|  		    (r = sshkey_puts(key, sigbuf)) != 0 || |  		    (r = sshkey_puts(key, sigbuf)) != 0 || | ||||||
|  		    (r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen, |  		    (r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen, | ||||||
| -		    sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
 | -		    sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
 | ||||||
| -		    use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
 | -		    use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
 | ||||||
| +		    sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 ||
 | +		    sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 ||
 | ||||||
|  		    (r = sshbuf_put_string(resp, sig, slen)) != 0) { |  		    (r = sshbuf_put_string(resp, sig, slen)) != 0) { | ||||||
|  			error("%s: couldn't prepare signature: %s", |  			error_fr(r, "assemble signature"); | ||||||
|  			    __func__, ssh_err(r)); |  | ||||||
| diff --color -ru a/sshkey.c b/sshkey.c
 |  | ||||||
| --- a/sshkey.c	2022-06-23 10:25:29.532922728 +0200
 |  | ||||||
| +++ b/sshkey.c	2022-06-23 10:26:12.914762158 +0200
 |  | ||||||
| @@ -82,7 +82,6 @@
 |  | ||||||
|      struct sshbuf *buf, enum sshkey_serialize_rep); |  | ||||||
|  static int sshkey_from_blob_internal(struct sshbuf *buf, |  | ||||||
|      struct sshkey **keyp, int allow_cert); |  | ||||||
| -static int get_sigtype(const u_char *sig, size_t siglen, char **sigtypep);
 |  | ||||||
|   |  | ||||||
|  /* Supported key types */ |  | ||||||
|  struct keytype { |  | ||||||
| @@ -2092,7 +2091,8 @@
 |  | ||||||
|  	if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, |  | ||||||
|  	    sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0) |  | ||||||
|  			goto out; |  			goto out; | ||||||
| -	if ((ret = get_sigtype(sig, slen, &key->cert->signature_type)) != 0)
 |  | ||||||
| +	if ((ret = sshkey_get_sigtype(sig, slen,
 |  | ||||||
| +	    &key->cert->signature_type)) != 0)
 |  | ||||||
|  		goto out; |  | ||||||
|   |  | ||||||
|  	/* Success */ |  | ||||||
| @@ -2394,8 +2394,8 @@
 |  | ||||||
|  	return r; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static int
 |  | ||||||
| -get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
 |  | ||||||
| +int
 |  | ||||||
| +sshkey_get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
 |  | ||||||
|  { |  | ||||||
|  	int r; |  | ||||||
|  	struct sshbuf *b = NULL; |  | ||||||
| @@ -2477,7 +2477,7 @@
 |  | ||||||
|  		return 0; |  | ||||||
|  	if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL) |  | ||||||
|  		return SSH_ERR_INVALID_ARGUMENT; |  | ||||||
| -	if ((r = get_sigtype(sig, siglen, &sigtype)) != 0)
 |  | ||||||
| +	if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0)
 |  | ||||||
|  		return r; |  | ||||||
|  	r = strcmp(expected_alg, sigtype) == 0; |  | ||||||
|  	free(sigtype); |  | ||||||
| @@ -2739,7 +2739,7 @@
 |  | ||||||
|  	    sshbuf_len(cert), alg, 0, signer_ctx)) != 0) |  | ||||||
|  		goto out; |  | ||||||
|  	/* Check and update signature_type against what was actually used */ |  | ||||||
| -	if ((ret = get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
 |  | ||||||
| +	if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
 |  | ||||||
|  		goto out; |  | ||||||
|  	if (alg != NULL && strcmp(alg, sigtype) != 0) { |  | ||||||
|  		ret = SSH_ERR_SIGN_ALG_UNSUPPORTED; |  | ||||||
| diff --color -ru a/sshkey.h b/sshkey.h
 |  | ||||||
| --- a/sshkey.h	2022-06-23 10:25:29.521922515 +0200
 |  | ||||||
| +++ b/sshkey.h	2022-06-23 10:26:12.907762022 +0200
 |  | ||||||
| @@ -211,6 +211,7 @@
 |  | ||||||
|      const u_char *, size_t, const char *, u_int); |  | ||||||
|  int	 sshkey_check_sigtype(const u_char *, size_t, const char *); |  | ||||||
|  const char *sshkey_sigalg_by_name(const char *); |  | ||||||
| +int      sshkey_get_sigtype(const u_char *, size_t, char **);
 |  | ||||||
|   |  | ||||||
|  /* for debug */ |  | ||||||
|  void	sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *); |  | ||||||
|  | |||||||
							
								
								
									
										446
									
								
								SOURCES/openssh-8.7p1-minrsabits.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										446
									
								
								SOURCES/openssh-8.7p1-minrsabits.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,446 @@ | |||||||
|  | diff --git a/auth2-hostbased.c b/auth2-hostbased.c
 | ||||||
|  | index 36b9d2f5..6b517db4 100644
 | ||||||
|  | --- a/auth2-hostbased.c
 | ||||||
|  | +++ b/auth2-hostbased.c
 | ||||||
|  | @@ -119,6 +119,11 @@ userauth_hostbased(struct ssh *ssh, const char *method)
 | ||||||
|  |  		    "(null)" : key->cert->signature_type); | ||||||
|  |  		goto done; | ||||||
|  |  	} | ||||||
|  | +	if ((r = sshkey_check_rsa_length(key,
 | ||||||
|  | +	    options.required_rsa_size)) != 0) {
 | ||||||
|  | +		logit_r(r, "refusing %s key", sshkey_type(key));
 | ||||||
|  | +		goto done;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	if (!authctxt->valid || authctxt->user == NULL) { | ||||||
|  |  		debug2_f("disabled because of invalid user"); | ||||||
|  | diff --git a/auth2-pubkey.c b/auth2-pubkey.c
 | ||||||
|  | index 962fd342..5d59febc 100644
 | ||||||
|  | --- a/auth2-pubkey.c
 | ||||||
|  | +++ b/auth2-pubkey.c
 | ||||||
|  | @@ -175,6 +175,11 @@ userauth_pubkey(struct ssh *ssh, const char *method)
 | ||||||
|  |  		    "(null)" : key->cert->signature_type); | ||||||
|  |  		goto done; | ||||||
|  |  	} | ||||||
|  | +	if ((r = sshkey_check_rsa_length(key,
 | ||||||
|  | +	    options.required_rsa_size)) != 0) {
 | ||||||
|  | +		logit_r(r, "refusing %s key", sshkey_type(key));
 | ||||||
|  | +		goto done;
 | ||||||
|  | +	}
 | ||||||
|  |  	key_s = format_key(key); | ||||||
|  |  	if (sshkey_is_cert(key)) | ||||||
|  |  		ca_s = format_key(key->cert->signature_key); | ||||||
|  | diff --git a/readconf.c b/readconf.c
 | ||||||
|  | index 7f26c680..42be690b 100644
 | ||||||
|  | --- a/readconf.c
 | ||||||
|  | +++ b/readconf.c
 | ||||||
|  | @@ -174,7 +174,7 @@ typedef enum {
 | ||||||
|  |  	oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, | ||||||
|  |  	oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms, | ||||||
|  |  	oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, | ||||||
|  | -	oSecurityKeyProvider, oKnownHostsCommand,
 | ||||||
|  | +	oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize,
 | ||||||
|  |  	oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported | ||||||
|  |  } OpCodes; | ||||||
|  |   | ||||||
|  | @@ -320,6 +320,8 @@ static struct {
 | ||||||
|  |  	{ "proxyjump", oProxyJump }, | ||||||
|  |  	{ "securitykeyprovider", oSecurityKeyProvider }, | ||||||
|  |  	{ "knownhostscommand", oKnownHostsCommand }, | ||||||
|  | +	{ "requiredrsasize", oRequiredRSASize },
 | ||||||
|  | +	{ "rsaminsize", oRequiredRSASize }, /* alias */
 | ||||||
|  |   | ||||||
|  |  	{ NULL, oBadOption } | ||||||
|  |  }; | ||||||
|  | @@ -2176,6 +2177,10 @@ parse_pubkey_algos:
 | ||||||
|  |  			*charptr = xstrdup(arg); | ||||||
|  |  		break; | ||||||
|  |   | ||||||
|  | +	case oRequiredRSASize:
 | ||||||
|  | +		intptr = &options->required_rsa_size;
 | ||||||
|  | +		goto parse_int;
 | ||||||
|  | +
 | ||||||
|  |  	case oDeprecated: | ||||||
|  |  		debug("%s line %d: Deprecated option \"%s\"", | ||||||
|  |  		    filename, linenum, keyword); | ||||||
|  | @@ -2423,6 +2428,7 @@ initialize_options(Options * options)
 | ||||||
|  |  	options->hostbased_accepted_algos = NULL; | ||||||
|  |  	options->pubkey_accepted_algos = NULL; | ||||||
|  |  	options->known_hosts_command = NULL; | ||||||
|  | +	options->required_rsa_size = -1;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  | @@ -2619,6 +2625,8 @@ fill_default_options(Options * options)
 | ||||||
|  |  	if (options->sk_provider == NULL) | ||||||
|  |  		options->sk_provider = xstrdup("$SSH_SK_PROVIDER"); | ||||||
|  |  #endif | ||||||
|  | +	if (options->required_rsa_size == -1)
 | ||||||
|  | +		options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
 | ||||||
|  |   | ||||||
|  |  	/* Expand KEX name lists */ | ||||||
|  |  	all_cipher = cipher_alg_list(',', 0); | ||||||
|  | @@ -3308,6 +3316,7 @@ dump_client_config(Options *o, const char *host)
 | ||||||
|  |  	dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); | ||||||
|  |  	dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); | ||||||
|  |  	dump_cfg_int(oServerAliveInterval, o->server_alive_interval); | ||||||
|  | +	dump_cfg_int(oRequiredRSASize, o->required_rsa_size);
 | ||||||
|  |   | ||||||
|  |  	/* String options */ | ||||||
|  |  	dump_cfg_string(oBindAddress, o->bind_address); | ||||||
|  | diff --git a/readconf.h b/readconf.h
 | ||||||
|  | index f647bd42..ffb5ec4f 100644
 | ||||||
|  | --- a/readconf.h
 | ||||||
|  | +++ b/readconf.h
 | ||||||
|  | @@ -176,6 +176,8 @@ typedef struct {
 | ||||||
|  |   | ||||||
|  |  	char   *known_hosts_command; | ||||||
|  |   | ||||||
|  | +	int	required_rsa_size;	/* minimum size of RSA keys */
 | ||||||
|  | +
 | ||||||
|  |  	char	*ignored_unknown; /* Pattern list of unknown tokens to ignore */ | ||||||
|  |  }       Options; | ||||||
|  |   | ||||||
|  | diff --git a/servconf.c b/servconf.c
 | ||||||
|  | index 29df0463..423772b1 100644
 | ||||||
|  | --- a/servconf.c
 | ||||||
|  | +++ b/servconf.c
 | ||||||
|  | @@ -195,6 +195,7 @@ initialize_server_options(ServerOptions *options)
 | ||||||
|  |  	options->fingerprint_hash = -1; | ||||||
|  |  	options->disable_forwarding = -1; | ||||||
|  |  	options->expose_userauth_info = -1; | ||||||
|  | +	options->required_rsa_size = -1;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ | ||||||
|  | @@ -441,6 +442,8 @@ fill_default_server_options(ServerOptions *options)
 | ||||||
|  |  		options->expose_userauth_info = 0; | ||||||
|  |  	if (options->sk_provider == NULL) | ||||||
|  |  		options->sk_provider = xstrdup("internal"); | ||||||
|  | +	if (options->required_rsa_size == -1)
 | ||||||
|  | +		options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
 | ||||||
|  |   | ||||||
|  |  	assemble_algorithms(options); | ||||||
|  |   | ||||||
|  | @@ -517,6 +520,7 @@ typedef enum {
 | ||||||
|  |  	sStreamLocalBindMask, sStreamLocalBindUnlink, | ||||||
|  |  	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, | ||||||
|  |  	sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, | ||||||
|  | +	sRequiredRSASize,
 | ||||||
|  |  	sDeprecated, sIgnore, sUnsupported | ||||||
|  |  } ServerOpCodes; | ||||||
|  |   | ||||||
|  | @@ -676,6 +680,8 @@ static struct {
 | ||||||
|  |  	{ "rdomain", sRDomain, SSHCFG_ALL }, | ||||||
|  |  	{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, | ||||||
|  |  	{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, | ||||||
|  | +	{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
 | ||||||
|  | +	{ "rsaminsize", sRequiredRSASize, SSHCFG_ALL }, /* alias */
 | ||||||
|  |  	{ NULL, sBadOption, 0 } | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -2438,6 +2443,10 @@ process_server_config_line_depth(ServerOptions *options, char *line,
 | ||||||
|  |  			*charptr = xstrdup(arg); | ||||||
|  |  		break; | ||||||
|  |   | ||||||
|  | +	case sRequiredRSASize:
 | ||||||
|  | +		intptr = &options->required_rsa_size;
 | ||||||
|  | +		goto parse_int;
 | ||||||
|  | +
 | ||||||
|  |  	case sDeprecated: | ||||||
|  |  	case sIgnore: | ||||||
|  |  	case sUnsupported: | ||||||
|  | @@ -2610,6 +2619,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
 | ||||||
|  |  	M_CP_INTOPT(rekey_limit); | ||||||
|  |  	M_CP_INTOPT(rekey_interval); | ||||||
|  |  	M_CP_INTOPT(log_level); | ||||||
|  | +	M_CP_INTOPT(required_rsa_size);
 | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  |  	 * The bind_mask is a mode_t that may be unsigned, so we can't use | ||||||
|  | @@ -2874,6 +2884,7 @@ dump_config(ServerOptions *o)
 | ||||||
|  |  	dump_cfg_int(sMaxSessions, o->max_sessions); | ||||||
|  |  	dump_cfg_int(sClientAliveInterval, o->client_alive_interval); | ||||||
|  |  	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); | ||||||
|  | +	dump_cfg_int(sRequiredRSASize, o->required_rsa_size);
 | ||||||
|  |  	dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask); | ||||||
|  |   | ||||||
|  |  	/* formatted integer arguments */ | ||||||
|  | diff --git a/servconf.h b/servconf.h
 | ||||||
|  | index 8a04463e..9346155c 100644
 | ||||||
|  | --- a/servconf.h
 | ||||||
|  | +++ b/servconf.h
 | ||||||
|  | @@ -229,6 +229,7 @@ typedef struct {
 | ||||||
|  |  	int	expose_userauth_info; | ||||||
|  |  	u_int64_t timing_secret; | ||||||
|  |  	char   *sk_provider; | ||||||
|  | +	int	required_rsa_size;	/* minimum size of RSA keys */
 | ||||||
|  |  }       ServerOptions; | ||||||
|  |   | ||||||
|  |  /* Information about the incoming connection as used by Match */ | ||||||
|  | diff --git a/ssh.c b/ssh.c
 | ||||||
|  | index 559bf2af..25be53d5 100644
 | ||||||
|  | --- a/ssh.c
 | ||||||
|  | +++ b/ssh.c
 | ||||||
|  | @@ -516,14 +516,22 @@ resolve_canonicalize(char **hostp, int port)
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  | - * Check the result of hostkey loading, ignoring some errors and
 | ||||||
|  | - * fatal()ing for others.
 | ||||||
|  | + * Check the result of hostkey loading, ignoring some errors and either
 | ||||||
|  | + * discarding the key or fatal()ing for others.
 | ||||||
|  |   */ | ||||||
|  |  static void | ||||||
|  | -check_load(int r, const char *path, const char *message)
 | ||||||
|  | +check_load(int r, struct sshkey **k, const char *path, const char *message)
 | ||||||
|  |  { | ||||||
|  |  	switch (r) { | ||||||
|  |  	case 0: | ||||||
|  | +		/* Check RSA keys size and discard if undersized */
 | ||||||
|  | +		if (k != NULL && *k != NULL &&
 | ||||||
|  | +		    (r = sshkey_check_rsa_length(*k,
 | ||||||
|  | +		    options.required_rsa_size)) != 0) {
 | ||||||
|  | +			error_r(r, "load %s \"%s\"", message, path);
 | ||||||
|  | +			free(*k);
 | ||||||
|  | +			*k = NULL;
 | ||||||
|  | +		}
 | ||||||
|  |  		break; | ||||||
|  |  	case SSH_ERR_INTERNAL_ERROR: | ||||||
|  |  	case SSH_ERR_ALLOC_FAIL: | ||||||
|  | @@ -1578,7 +1586,7 @@ main(int ac, char **av)
 | ||||||
|  |  	if ((o) >= sensitive_data.nkeys) \ | ||||||
|  |  		fatal_f("pubkey out of array bounds"); \ | ||||||
|  |  	check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \ | ||||||
|  | -	    p, "pubkey"); \
 | ||||||
|  | +	    &(sensitive_data.keys[o]), p, "pubkey"); \
 | ||||||
|  |  } while (0) | ||||||
|  |  #define L_CERT(p,o) do { \ | ||||||
|  |  	if ((o) >= sensitive_data.nkeys) \ | ||||||
|  | @@ -1586,7 +1594,8 @@ main(int ac, char **av)
 | ||||||
|  |  #define L_CERT(p,o) do { \ | ||||||
|  |  	if ((o) >= sensitive_data.nkeys) \ | ||||||
|  |  		fatal_f("cert out of array bounds"); \ | ||||||
|  | -	check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), p, "cert"); \
 | ||||||
|  | +	check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \
 | ||||||
|  | +	    &(sensitive_data.keys[o]), p, "cert"); \
 | ||||||
|  |  } while (0) | ||||||
|  |   | ||||||
|  |  		if (options.hostbased_authentication == 1) { | ||||||
|  | @@ -2244,7 +2253,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)
 | ||||||
|  |  		filename = default_client_percent_dollar_expand(cp, cinfo); | ||||||
|  |  		free(cp); | ||||||
|  |  		check_load(sshkey_load_public(filename, &public, NULL), | ||||||
|  | -		    filename, "pubkey");
 | ||||||
|  | +		    &public, filename, "pubkey");
 | ||||||
|  |  		debug("identity file %s type %d", filename, | ||||||
|  |  		    public ? public->type : -1); | ||||||
|  |  		free(options.identity_files[i]); | ||||||
|  | @@ -2284,7 +2293,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)
 | ||||||
|  |  			continue; | ||||||
|  |  		xasprintf(&cp, "%s-cert", filename); | ||||||
|  |  		check_load(sshkey_load_public(cp, &public, NULL), | ||||||
|  | -		    filename, "pubkey");
 | ||||||
|  | +		    &public, filename, "pubkey");
 | ||||||
|  |  		debug("identity file %s type %d", cp, | ||||||
|  |  		    public ? public->type : -1); | ||||||
|  |  		if (public == NULL) { | ||||||
|  | @@ -2315,7 +2324,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo)
 | ||||||
|  |  		free(cp); | ||||||
|  |   | ||||||
|  |  		check_load(sshkey_load_public(filename, &public, NULL), | ||||||
|  | -		    filename, "certificate");
 | ||||||
|  | +		    &public, filename, "certificate");
 | ||||||
|  |  		debug("certificate file %s type %d", filename, | ||||||
|  |  		    public ? public->type : -1); | ||||||
|  |  		free(options.certificate_files[i]); | ||||||
|  | diff --git a/sshconnect2.c b/sshconnect2.c
 | ||||||
|  | index f9bd19ea..58fe98db 100644
 | ||||||
|  | --- a/sshconnect2.c
 | ||||||
|  | +++ b/sshconnect2.c
 | ||||||
|  | @@ -96,6 +96,11 @@ static const struct ssh_conn_info *xxx_conn_info;
 | ||||||
|  |  static int | ||||||
|  |  verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) | ||||||
|  |  { | ||||||
|  | +	int r;
 | ||||||
|  | +
 | ||||||
|  | +	if ((r = sshkey_check_rsa_length(hostkey,
 | ||||||
|  | +	    options.required_rsa_size)) != 0)
 | ||||||
|  | +		fatal_r(r, "Bad server host key");
 | ||||||
|  |  	if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, | ||||||
|  |  	    xxx_conn_info) == -1) | ||||||
|  |  		fatal("Host key verification failed."); | ||||||
|  | @@ -1606,6 +1611,13 @@ load_identity_file(Identity *id)
 | ||||||
|  |  			private = NULL; | ||||||
|  |  			quit = 1; | ||||||
|  |  		} | ||||||
|  | +		if (!quit && (r = sshkey_check_rsa_length(private,
 | ||||||
|  | +		    options.required_rsa_size)) != 0) {
 | ||||||
|  | +			debug_fr(r, "Skipping key %s", id->filename);
 | ||||||
|  | +			sshkey_free(private);
 | ||||||
|  | +			private = NULL;
 | ||||||
|  | +			quit = 1;
 | ||||||
|  | +		}
 | ||||||
|  |  		if (!quit && private != NULL && id->agent_fd == -1 && | ||||||
|  |  		    !(id->key && id->isprivate)) | ||||||
|  |  			maybe_add_key_to_agent(id->filename, private, comment, | ||||||
|  | @@ -1752,6 +1764,12 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt)
 | ||||||
|  | 		close(agent_fd); | ||||||
|  | 	} else { | ||||||
|  |  		for (j = 0; j < idlist->nkeys; j++) { | ||||||
|  | +			if ((r = sshkey_check_rsa_length(idlist->keys[j],
 | ||||||
|  | +			    options.required_rsa_size)) != 0) {
 | ||||||
|  | +				debug_fr(r, "ignoring %s agent key",
 | ||||||
|  | +				    sshkey_ssh_name(idlist->keys[j]));
 | ||||||
|  | +				continue;
 | ||||||
|  | +			}
 | ||||||
|  |  			found = 0; | ||||||
|  |  			TAILQ_FOREACH(id, &files, next) { | ||||||
|  |  				/* | ||||||
|  | diff --git a/sshd.c b/sshd.c
 | ||||||
|  | index 17eee9d8..395ef493 100644
 | ||||||
|  | --- a/sshd.c
 | ||||||
|  | +++ b/sshd.c
 | ||||||
|  | @@ -1870,6 +1870,13 @@ main(int ac, char **av)
 | ||||||
|  |  				fatal_r(r, "Could not demote key: \"%s\"", | ||||||
|  |  				    options.host_key_files[i]); | ||||||
|  |  		} | ||||||
|  | +		if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey,
 | ||||||
|  | +		    options.required_rsa_size)) != 0) {
 | ||||||
|  | +			error_fr(r, "Host key %s", options.host_key_files[i]);
 | ||||||
|  | +			sshkey_free(pubkey);
 | ||||||
|  | +			sshkey_free(key);
 | ||||||
|  | +			continue;
 | ||||||
|  | +		}
 | ||||||
|  |  		sensitive_data.host_keys[i] = key; | ||||||
|  |  		sensitive_data.host_pubkeys[i] = pubkey; | ||||||
|  |   | ||||||
|  | diff --git a/sshkey.c b/sshkey.c
 | ||||||
|  | index ed2b5dff..77093235 100644
 | ||||||
|  | --- a/sshkey.c
 | ||||||
|  | +++ b/sshkey.c
 | ||||||
|  | @@ -2365,18 +2365,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
 | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -#ifdef WITH_OPENSSL
 | ||||||
|  | -static int
 | ||||||
|  | -check_rsa_length(const RSA *rsa)
 | ||||||
|  | +int
 | ||||||
|  | +sshkey_check_rsa_length(const struct sshkey *k, int min_size)
 | ||||||
|  |  { | ||||||
|  | +#ifdef WITH_OPENSSL
 | ||||||
|  |  	const BIGNUM *rsa_n; | ||||||
|  | +	int nbits;
 | ||||||
|  |   | ||||||
|  | -	RSA_get0_key(rsa, &rsa_n, NULL, NULL);
 | ||||||
|  | -	if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 | ||||||
|  | +	if (k == NULL || k->rsa == NULL ||
 | ||||||
|  | +	    (k->type != KEY_RSA && k->type != KEY_RSA_CERT))
 | ||||||
|  | +		return 0;
 | ||||||
|  | +	RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
 | ||||||
|  | +	nbits = BN_num_bits(rsa_n);
 | ||||||
|  | +	if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
 | ||||||
|  | +	    (min_size > 0 && nbits < min_size))
 | ||||||
|  |  		return SSH_ERR_KEY_LENGTH; | ||||||
|  | +#endif /* WITH_OPENSSL */
 | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | -#endif
 | ||||||
|  |   | ||||||
|  |  static int | ||||||
|  |  sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, | ||||||
|  | @@ -2439,7 +2445,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
 | ||||||
|  |  			goto out; | ||||||
|  |  		} | ||||||
|  |  		rsa_n = rsa_e = NULL; /* transferred */ | ||||||
|  | -		if ((ret = check_rsa_length(key->rsa)) != 0)
 | ||||||
|  | +		if ((ret = sshkey_check_rsa_length(key, 0)) != 0)
 | ||||||
|  |  			goto out; | ||||||
|  |  #ifdef DEBUG_PK | ||||||
|  |  		RSA_print_fp(stderr, key->rsa, 8); | ||||||
|  | @@ -3642,7 +3648,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
 | ||||||
|  |  			goto out; | ||||||
|  |  		} | ||||||
|  |  		rsa_p = rsa_q = NULL; /* transferred */ | ||||||
|  | -		if ((r = check_rsa_length(k->rsa)) != 0)
 | ||||||
|  | +		if ((r = sshkey_check_rsa_length(k, 0)) != 0)
 | ||||||
|  |  			goto out; | ||||||
|  |  		if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0) | ||||||
|  |  			goto out; | ||||||
|  | @@ -4644,7 +4650,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
 | ||||||
|  |  			r = SSH_ERR_LIBCRYPTO_ERROR; | ||||||
|  |  			goto out; | ||||||
|  |  		} | ||||||
|  | -		if ((r = check_rsa_length(prv->rsa)) != 0)
 | ||||||
|  | +		if ((r = sshkey_check_rsa_length(prv, 0)) != 0)
 | ||||||
|  |  			goto out; | ||||||
|  |  	} else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA && | ||||||
|  |  	    (type == KEY_UNSPEC || type == KEY_DSA)) { | ||||||
|  | diff --git a/sshkey.h b/sshkey.h
 | ||||||
|  | index 094815e0..be254e6b 100644
 | ||||||
|  | --- a/sshkey.h
 | ||||||
|  | +++ b/sshkey.h
 | ||||||
|  | @@ -273,6 +273,7 @@ int	sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
 | ||||||
|  |  int	sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, | ||||||
|  |      int type, struct sshkey **pubkeyp); | ||||||
|  |   | ||||||
|  | +int sshkey_check_rsa_length(const struct sshkey *, int);
 | ||||||
|  |  /* XXX should be internal, but used by ssh-keygen */ | ||||||
|  |  int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); | ||||||
|  |   | ||||||
|  | diff --git a/ssh.1 b/ssh.1
 | ||||||
|  | index b4956aec..e255b9b9 100644
 | ||||||
|  | --- a/ssh.1
 | ||||||
|  | +++ b/ssh.1
 | ||||||
|  | @@ -571,6 +571,7 @@ For full details of the options listed below, and their possible values, see
 | ||||||
|  |  .It RemoteCommand | ||||||
|  |  .It RemoteForward | ||||||
|  |  .It RequestTTY | ||||||
|  | +.It RequiredRSASize
 | ||||||
|  |  .It SendEnv | ||||||
|  |  .It ServerAliveInterval | ||||||
|  |  .It ServerAliveCountMax | ||||||
|  | diff --git a/ssh_config.5 b/ssh_config.5
 | ||||||
|  | index 24a46460..d1ede18e 100644
 | ||||||
|  | --- a/ssh_config.5
 | ||||||
|  | +++ b/ssh_config.5
 | ||||||
|  | @@ -1634,6 +1634,17 @@ and
 | ||||||
|  |  .Fl T | ||||||
|  |  flags for | ||||||
|  |  .Xr ssh 1 . | ||||||
|  | +.It Cm RequiredRSASize
 | ||||||
|  | +Specifies the minimum RSA key size (in bits) that
 | ||||||
|  | +.Xr ssh 1
 | ||||||
|  | +will accept.
 | ||||||
|  | +User authentication keys smaller than this limit will be ignored.
 | ||||||
|  | +Servers that present host keys smaller than this limit will cause the
 | ||||||
|  | +connection to be terminated.
 | ||||||
|  | +The default is
 | ||||||
|  | +.Cm 1024
 | ||||||
|  | +bits.
 | ||||||
|  | +Note that this limit may only be raised from the default.
 | ||||||
|  |  .It Cm RevokedHostKeys | ||||||
|  |  Specifies revoked host public keys. | ||||||
|  |  Keys listed in this file will be refused for host authentication. | ||||||
|  | diff --git a/sshd_config.5 b/sshd_config.5
 | ||||||
|  | index 867a747d..f5a06637 100644
 | ||||||
|  | --- a/sshd_config.5
 | ||||||
|  | +++ b/sshd_config.5
 | ||||||
|  | @@ -1596,6 +1596,16 @@ is
 | ||||||
|  |  .Cm default none , | ||||||
|  |  which means that rekeying is performed after the cipher's default amount | ||||||
|  |  of data has been sent or received and no time based rekeying is done. | ||||||
|  | +.It Cm RequiredRSASize
 | ||||||
|  | +Specifies the minimum RSA key size (in bits) that
 | ||||||
|  | +.Xr sshd 8
 | ||||||
|  | +will accept.
 | ||||||
|  | +User and host-based authentication keys smaller than this limit will be
 | ||||||
|  | +refused.
 | ||||||
|  | +The default is
 | ||||||
|  | +.Cm 1024
 | ||||||
|  | +bits.
 | ||||||
|  | +Note that this limit may only be raised from the default.
 | ||||||
|  |  .It Cm RevokedKeys | ||||||
|  |  Specifies revoked public keys file, or | ||||||
|  |  .Cm none | ||||||
							
								
								
									
										63
									
								
								SOURCES/openssh-8.7p1-negotiate-supported-algs.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								SOURCES/openssh-8.7p1-negotiate-supported-algs.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | |||||||
|  | diff --color -rup a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh
 | ||||||
|  | --- a/regress/hostkey-agent.sh	2021-08-20 06:03:49.000000000 +0200
 | ||||||
|  | +++ b/regress/hostkey-agent.sh	2022-07-14 11:58:12.172786060 +0200
 | ||||||
|  | @@ -13,8 +13,12 @@ r=$?
 | ||||||
|  |  grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig | ||||||
|  |  echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig | ||||||
|  |   | ||||||
|  | +PUBKEY_ACCEPTED_ALGOS=`$SSH -G "example.com" | \
 | ||||||
|  | +    grep -i "PubkeyAcceptedAlgorithms" | cut -d ' ' -f2- | tr "," "|"`
 | ||||||
|  | +SSH_ACCEPTED_KEYTYPES=`echo "$SSH_KEYTYPES" | egrep "$PUBKEY_ACCEPTED_ALGOS"`
 | ||||||
|  | +
 | ||||||
|  |  trace "load hostkeys" | ||||||
|  | -for k in $SSH_KEYTYPES ; do
 | ||||||
|  | +for k in $SSH_ACCEPTED_KEYTYPES ; do
 | ||||||
|  |  	${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k" | ||||||
|  |  	( | ||||||
|  |  		printf 'localhost-with-alias,127.0.0.1,::1 ' | ||||||
|  | @@ -31,7 +35,7 @@ cp $OBJ/known_hosts.orig $OBJ/known_host
 | ||||||
|  |  unset SSH_AUTH_SOCK | ||||||
|  |   | ||||||
|  |  for ps in yes; do | ||||||
|  | -	for k in $SSH_KEYTYPES ; do
 | ||||||
|  | +	for k in $SSH_ACCEPTED_KEYTYPES ; do
 | ||||||
|  |  		verbose "key type $k privsep=$ps" | ||||||
|  |  		cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy | ||||||
|  |  		echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy | ||||||
|  | diff --color -rup a/sshconnect2.c b/sshconnect2.c
 | ||||||
|  | --- a/sshconnect2.c	2022-07-14 10:10:07.262975710 +0200
 | ||||||
|  | +++ b/sshconnect2.c	2022-07-14 10:10:32.068452067 +0200
 | ||||||
|  | @@ -222,6 +222,7 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | ||||||
|  |  { | ||||||
|  |  	char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; | ||||||
|  |  	char *s, *all_key; | ||||||
|  | +	char *hostkeyalgs = NULL, *pkalg = NULL;
 | ||||||
|  |  	char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; | ||||||
|  |  	int r, use_known_hosts_order = 0; | ||||||
|  |   | ||||||
|  | @@ -264,14 +265,19 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | ||||||
|  |  	    myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; | ||||||
|  |  	if (use_known_hosts_order) { | ||||||
|  |  		/* Query known_hosts and prefer algorithms that appear there */ | ||||||
|  | -		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
 | ||||||
|  | -		    compat_pkalg_proposal(ssh,
 | ||||||
|  | -		    order_hostkeyalgs(host, hostaddr, port, cinfo));
 | ||||||
|  | +		if ((hostkeyalgs = order_hostkeyalgs(host, hostaddr, port, cinfo)) == NULL)
 | ||||||
|  | +			fatal_f("order_hostkeyalgs");
 | ||||||
|  | +		pkalg = match_filter_allowlist(hostkeyalgs, options.pubkey_accepted_algos);
 | ||||||
|  | +		free(hostkeyalgs);
 | ||||||
|  |  	} else { | ||||||
|  | -		/* Use specified HostkeyAlgorithms exactly */
 | ||||||
|  | -		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
 | ||||||
|  | -		    compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
 | ||||||
|  | +		/* Use specified HostkeyAlgorithms */
 | ||||||
|  | +		pkalg = match_filter_allowlist(options.hostkeyalgorithms, options.pubkey_accepted_algos);
 | ||||||
|  |  	} | ||||||
|  | +	if (pkalg == NULL)
 | ||||||
|  | +		fatal_f("match_filter_allowlist");
 | ||||||
|  | +	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
 | ||||||
|  | +	    compat_pkalg_proposal(ssh, pkalg);
 | ||||||
|  | +	free(pkalg);
 | ||||||
|  |   | ||||||
|  |  #if defined(GSSAPI) && defined(WITH_OPENSSL) | ||||||
|  |  	if (options.gss_keyex) { | ||||||
							
								
								
									
										426
									
								
								SOURCES/openssh-8.7p1-nohostsha1proof.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										426
									
								
								SOURCES/openssh-8.7p1-nohostsha1proof.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,426 @@ | |||||||
|  | diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c
 | ||||||
|  | --- openssh-8.7p1/compat.c.sshrsacheck	2023-01-12 13:29:06.338710923 +0100
 | ||||||
|  | +++ openssh-8.7p1/compat.c	2023-01-12 13:29:06.357711165 +0100
 | ||||||
|  | @@ -43,6 +43,7 @@ void
 | ||||||
|  |  compat_banner(struct ssh *ssh, const char *version) | ||||||
|  |  { | ||||||
|  |  	int i; | ||||||
|  | +	int forbid_ssh_rsa = 0;
 | ||||||
|  |  	static struct { | ||||||
|  |  		char	*pat; | ||||||
|  |  		int	bugs; | ||||||
|  | @@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha
 | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  |  	/* process table, return first match */ | ||||||
|  | +	forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA);
 | ||||||
|  |  	ssh->compat = 0; | ||||||
|  |  	for (i = 0; check[i].pat; i++) { | ||||||
|  |  		if (match_pattern_list(version, check[i].pat, 0) == 1) { | ||||||
|  |  			debug_f("match: %s pat %s compat 0x%08x", | ||||||
|  |  			    version, check[i].pat, check[i].bugs); | ||||||
|  |  			ssh->compat = check[i].bugs; | ||||||
|  | +	if (forbid_ssh_rsa)
 | ||||||
|  | +		ssh->compat |= SSH_RH_RSASIGSHA;
 | ||||||
|  |  			return; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |  	debug_f("no match: %s", version); | ||||||
|  | +	if (forbid_ssh_rsa)
 | ||||||
|  | +		ssh->compat |= SSH_RH_RSASIGSHA;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* Always returns pointer to allocated memory, caller must free. */ | ||||||
|  | diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h
 | ||||||
|  | --- openssh-8.7p1/compat.h.sshrsacheck	2021-08-20 06:03:49.000000000 +0200
 | ||||||
|  | +++ openssh-8.7p1/compat.h	2023-01-12 13:29:06.358711178 +0100
 | ||||||
|  | @@ -30,7 +30,7 @@
 | ||||||
|  |  #define SSH_BUG_UTF8TTYMODE	0x00000001 | ||||||
|  |  #define SSH_BUG_SIGTYPE		0x00000002 | ||||||
|  |  #define SSH_BUG_SIGTYPE74	0x00000004 | ||||||
|  | -/* #define unused		0x00000008 */
 | ||||||
|  | +#define SSH_RH_RSASIGSHA	0x00000008
 | ||||||
|  |  #define SSH_OLD_SESSIONID	0x00000010 | ||||||
|  |  /* #define unused		0x00000020 */ | ||||||
|  |  #define SSH_BUG_DEBUG		0x00000040 | ||||||
|  | diff -up openssh-8.7p1/monitor.c.sshrsacheck openssh-8.7p1/monitor.c
 | ||||||
|  | --- openssh-8.7p1/monitor.c.sshrsacheck	2023-01-20 13:07:54.279676981 +0100
 | ||||||
|  | +++ openssh-8.7p1/monitor.c	2023-01-20 15:01:07.007821379 +0100
 | ||||||
|  | @@ -660,11 +660,12 @@ mm_answer_sign(struct ssh *ssh, int sock
 | ||||||
|  |  	struct sshkey *key; | ||||||
|  |  	struct sshbuf *sigbuf = NULL; | ||||||
|  |  	u_char *p = NULL, *signature = NULL; | ||||||
|  | -	char *alg = NULL;
 | ||||||
|  | +	char *alg = NULL, *effective_alg;
 | ||||||
|  |  	size_t datlen, siglen, alglen; | ||||||
|  |  	int r, is_proof = 0; | ||||||
|  |  	u_int keyid, compat; | ||||||
|  |  	const char proof_req[] = "hostkeys-prove-00@openssh.com"; | ||||||
|  | +	const char safe_rsa[]  = "rsa-sha2-256";
 | ||||||
|  |   | ||||||
|  |  	debug3_f("entering"); | ||||||
|  |   | ||||||
|  | @@ -719,18 +720,30 @@ mm_answer_sign(struct ssh *ssh, int sock
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if ((key = get_hostkey_by_index(keyid)) != NULL) { | ||||||
|  | -		if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
 | ||||||
|  | +		if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
 | ||||||
|  | +				&& (sshkey_type_plain(key->type) == KEY_RSA)) {
 | ||||||
|  | +			effective_alg = safe_rsa;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			effective_alg = alg;
 | ||||||
|  | +		}
 | ||||||
|  | +		if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, effective_alg,
 | ||||||
|  |  		    options.sk_provider, NULL, compat)) != 0) | ||||||
|  |  			fatal_fr(r, "sign"); | ||||||
|  |  	} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL && | ||||||
|  |  	    auth_sock > 0) { | ||||||
|  | +		if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
 | ||||||
|  | +				&& (sshkey_type_plain(key->type) == KEY_RSA)) {
 | ||||||
|  | +			effective_alg = safe_rsa;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			effective_alg = alg;
 | ||||||
|  | +		}
 | ||||||
|  |  		if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen, | ||||||
|  | -		    p, datlen, alg, compat)) != 0)
 | ||||||
|  | +		    p, datlen, effective_alg, compat)) != 0)
 | ||||||
|  |  			fatal_fr(r, "agent sign"); | ||||||
|  |  	} else | ||||||
|  |  		fatal_f("no hostkey from index %d", keyid); | ||||||
|  |   | ||||||
|  | -	debug3_f("%s %s signature len=%zu", alg,
 | ||||||
|  | +	debug3_f("%s (effective: %s) %s signature len=%zu", alg, effective_alg,
 | ||||||
|  |  	    is_proof ? "hostkey proof" : "KEX", siglen); | ||||||
|  |   | ||||||
|  |  	sshbuf_reset(m); | ||||||
|  | diff -up openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck openssh-8.7p1/regress/cert-userkey.sh
 | ||||||
|  | --- openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck	2023-01-25 14:26:52.885963113 +0100
 | ||||||
|  | +++ openssh-8.7p1/regress/cert-userkey.sh	2023-01-25 14:27:25.757219800 +0100
 | ||||||
|  | @@ -7,7 +7,8 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us
 | ||||||
|  |  cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak | ||||||
|  |  cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak | ||||||
|  |   | ||||||
|  | -PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
 | ||||||
|  | +#ssh-dss keys are incompatible with DEFAULT crypto policy
 | ||||||
|  | +PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss' | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
 | ||||||
|  |  EXTRA_TYPES="" | ||||||
|  |  rsa="" | ||||||
|  |   | ||||||
|  | diff -up openssh-8.7p1/regress/Makefile.sshrsacheck openssh-8.7p1/regress/Makefile
 | ||||||
|  | --- openssh-8.7p1/regress/Makefile.sshrsacheck	2023-01-20 13:07:54.169676051 +0100
 | ||||||
|  | +++ openssh-8.7p1/regress/Makefile	2023-01-20 13:07:54.290677074 +0100
 | ||||||
|  | @@ -2,7 +2,8 @@
 | ||||||
|  |   | ||||||
|  |  tests:		prep file-tests t-exec unit | ||||||
|  |   | ||||||
|  | -REGRESS_TARGETS=	t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12
 | ||||||
|  | +#ssh-dss tests will not pass on DEFAULT crypto-policy because of SHA1, skipping
 | ||||||
|  | +REGRESS_TARGETS=	t1 t2 t3 t4 t5 t7 t8 t9 t10 t11 t12
 | ||||||
|  |   | ||||||
|  |  # File based tests | ||||||
|  |  file-tests: $(REGRESS_TARGETS) | ||||||
|  | diff -up openssh-8.7p1/regress/test-exec.sh.sshrsacheck openssh-8.7p1/regress/test-exec.sh
 | ||||||
|  | --- openssh-8.7p1/regress/test-exec.sh.sshrsacheck	2023-01-25 14:24:54.778040819 +0100
 | ||||||
|  | +++ openssh-8.7p1/regress/test-exec.sh	2023-01-25 14:26:39.500858590 +0100
 | ||||||
|  | @@ -581,8 +581,9 @@ maybe_filter_sk() {
 | ||||||
|  |  	fi | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk`
 | ||||||
|  | -SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk`
 | ||||||
|  | +#ssh-dss keys are incompatible with DEFAULT crypto policy
 | ||||||
|  | +SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'`
 | ||||||
|  | +SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'`
 | ||||||
|  |   | ||||||
|  |  for t in ${SSH_KEYTYPES}; do | ||||||
|  |  	# generate user key | ||||||
|  | diff -up openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck openssh-8.7p1/regress/unittests/kex/test_kex.c
 | ||||||
|  | --- openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck	2023-01-26 13:34:52.645743677 +0100
 | ||||||
|  | +++ openssh-8.7p1/regress/unittests/kex/test_kex.c	2023-01-26 13:36:56.220745823 +0100
 | ||||||
|  | @@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype,
 | ||||||
|  |  	memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); | ||||||
|  |  	if (kex != NULL) | ||||||
|  |  		kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; | ||||||
|  | -	keyname = strdup(sshkey_ssh_name(private));
 | ||||||
|  | +	keyname = (strcmp(sshkey_ssh_name(private), "ssh-rsa")) ?
 | ||||||
|  | +		strdup(sshkey_ssh_name(private)) : strdup("rsa-sha2-256");
 | ||||||
|  |  	ASSERT_PTR_NE(keyname, NULL); | ||||||
|  |  	kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname; | ||||||
|  |  	ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0); | ||||||
|  | @@ -180,7 +181,7 @@ do_kex(char *kex)
 | ||||||
|  |  { | ||||||
|  |  #ifdef WITH_OPENSSL | ||||||
|  |  	do_kex_with_key(kex, KEY_RSA, 2048); | ||||||
|  | -	do_kex_with_key(kex, KEY_DSA, 1024);
 | ||||||
|  | +	/* do_kex_with_key(kex, KEY_DSA, 1024); */
 | ||||||
|  |  #ifdef OPENSSL_HAS_ECC | ||||||
|  |  	do_kex_with_key(kex, KEY_ECDSA, 256); | ||||||
|  |  #endif /* OPENSSL_HAS_ECC */ | ||||||
|  | diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_file.c
 | ||||||
|  | --- openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck	2023-01-26 12:04:55.946343408 +0100
 | ||||||
|  | +++ openssh-8.7p1/regress/unittests/sshkey/test_file.c	2023-01-26 12:06:35.235164432 +0100
 | ||||||
|  | @@ -110,6 +110,7 @@ sshkey_file_tests(void)
 | ||||||
|  |  	sshkey_free(k2); | ||||||
|  |  	TEST_DONE(); | ||||||
|  |   | ||||||
|  | +	/* Skip this test, SHA1 signatures are not supported
 | ||||||
|  |  	TEST_START("load RSA cert with SHA1 signature"); | ||||||
|  |  	ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha1"), &k2), 0); | ||||||
|  |  	ASSERT_PTR_NE(k2, NULL); | ||||||
|  | @@ -117,7 +118,7 @@ sshkey_file_tests(void)
 | ||||||
|  |  	ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); | ||||||
|  |  	ASSERT_STRING_EQ(k2->cert->signature_type, "ssh-rsa"); | ||||||
|  |  	sshkey_free(k2); | ||||||
|  | -	TEST_DONE();
 | ||||||
|  | +	TEST_DONE(); */
 | ||||||
|  |   | ||||||
|  |  	TEST_START("load RSA cert with SHA512 signature"); | ||||||
|  |  	ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha512"), &k2), 0); | ||||||
|  | diff -up openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c
 | ||||||
|  | --- openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck	2023-01-26 12:10:37.533168013 +0100
 | ||||||
|  | +++ openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c	2023-01-26 12:15:35.637631860 +0100
 | ||||||
|  | @@ -333,13 +333,14 @@ sshkey_fuzz_tests(void)
 | ||||||
|  |  	TEST_DONE(); | ||||||
|  |   | ||||||
|  |  #ifdef WITH_OPENSSL | ||||||
|  | +	/* Skip this test, SHA1 signatures are not supported
 | ||||||
|  |  	TEST_START("fuzz RSA sig"); | ||||||
|  |  	buf = load_file("rsa_1"); | ||||||
|  |  	ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); | ||||||
|  |  	sshbuf_free(buf); | ||||||
|  |  	sig_fuzz(k1, "ssh-rsa"); | ||||||
|  |  	sshkey_free(k1); | ||||||
|  | -	TEST_DONE();
 | ||||||
|  | +	TEST_DONE();*/
 | ||||||
|  |   | ||||||
|  |  	TEST_START("fuzz RSA SHA256 sig"); | ||||||
|  |  	buf = load_file("rsa_1"); | ||||||
|  | @@ -357,6 +358,7 @@ sshkey_fuzz_tests(void)
 | ||||||
|  |  	sshkey_free(k1); | ||||||
|  |  	TEST_DONE(); | ||||||
|  |   | ||||||
|  | +	/* Skip this test, SHA1 signatures are not supported
 | ||||||
|  |  	TEST_START("fuzz DSA sig"); | ||||||
|  |  	buf = load_file("dsa_1"); | ||||||
|  |  	ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); | ||||||
|  | @@ -364,6 +366,7 @@ sshkey_fuzz_tests(void)
 | ||||||
|  |  	sig_fuzz(k1, NULL); | ||||||
|  |  	sshkey_free(k1); | ||||||
|  |  	TEST_DONE(); | ||||||
|  | +	*/
 | ||||||
|  |   | ||||||
|  |  #ifdef OPENSSL_HAS_ECC | ||||||
|  |  	TEST_START("fuzz ECDSA sig"); | ||||||
|  | diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c
 | ||||||
|  | --- openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck	2023-01-26 11:02:52.339413463 +0100
 | ||||||
|  | +++ openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c	2023-01-26 11:58:42.324253896 +0100
 | ||||||
|  | @@ -60,6 +60,9 @@ build_cert(struct sshbuf *b, struct sshk
 | ||||||
|  |  	u_char *sigblob; | ||||||
|  |  	size_t siglen; | ||||||
|  |   | ||||||
|  | +	/* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
 | ||||||
|  | +	int expected = (sig_alg == NULL || strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
 | ||||||
|  | +
 | ||||||
|  |  	ca_buf = sshbuf_new(); | ||||||
|  |  	ASSERT_PTR_NE(ca_buf, NULL); | ||||||
|  |  	ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); | ||||||
|  | @@ -101,8 +104,9 @@ build_cert(struct sshbuf *b, struct sshk
 | ||||||
|  |  	ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */ | ||||||
|  |  	ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */ | ||||||
|  |  	ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen, | ||||||
|  | -	    sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0);
 | ||||||
|  | -	ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
 | ||||||
|  | +	    sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), expected);
 | ||||||
|  | +	if (expected == 0)
 | ||||||
|  | +		ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
 | ||||||
|  |   | ||||||
|  |  	free(sigblob); | ||||||
|  |  	sshbuf_free(ca_buf); | ||||||
|  | @@ -119,16 +123,22 @@ signature_test(struct sshkey *k, struct
 | ||||||
|  |  { | ||||||
|  |  	size_t len; | ||||||
|  |  	u_char *sig; | ||||||
|  | +	/* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
 | ||||||
|  | +	int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
 | ||||||
|  | +	if (k && (sshkey_type_plain(k->type) == KEY_DSA || sshkey_type_plain(k->type) == KEY_DSA_CERT))
 | ||||||
|  | +		expected = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||||
|  |   | ||||||
|  |  	ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, | ||||||
|  | -	    NULL, NULL, 0), 0);
 | ||||||
|  | -	ASSERT_SIZE_T_GT(len, 8);
 | ||||||
|  | -	ASSERT_PTR_NE(sig, NULL);
 | ||||||
|  | -	ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
 | ||||||
|  | -	ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
 | ||||||
|  | -	/* Fuzz test is more comprehensive, this is just a smoke test */
 | ||||||
|  | -	sig[len - 5] ^= 0x10;
 | ||||||
|  | -	ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
 | ||||||
|  | +	    NULL, NULL, 0), expected);
 | ||||||
|  | +	if (expected == 0) {
 | ||||||
|  | +		ASSERT_SIZE_T_GT(len, 8);
 | ||||||
|  | +		ASSERT_PTR_NE(sig, NULL);
 | ||||||
|  | +		ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
 | ||||||
|  | +		ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
 | ||||||
|  | +		/* Fuzz test is more comprehensive, this is just a smoke test */
 | ||||||
|  | +		sig[len - 5] ^= 0x10;
 | ||||||
|  | +		ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
 | ||||||
|  | +	}
 | ||||||
|  |  	free(sig); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -514,7 +524,7 @@ sshkey_tests(void)
 | ||||||
|  |  	ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, | ||||||
|  |  	    NULL), 0); | ||||||
|  |  	k3 = get_private("rsa_1"); | ||||||
|  | -	build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL);
 | ||||||
|  | +	build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, "rsa-sha2-256");
 | ||||||
|  |  	ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), | ||||||
|  |  	    SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); | ||||||
|  |  	ASSERT_PTR_EQ(k4, NULL); | ||||||
|  | diff -up openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck openssh-8.7p1/regress/unittests/sshsig/tests.c
 | ||||||
|  | --- openssh-8.7p1/regress/unittests/sshsig/tests.c.sshrsacheck	2023-01-26 12:19:23.659513651 +0100
 | ||||||
|  | +++ openssh-8.7p1/regress/unittests/sshsig/tests.c	2023-01-26 12:20:28.021044803 +0100
 | ||||||
|  | @@ -102,9 +102,11 @@ tests(void)
 | ||||||
|  |  	check_sig("rsa.pub", "rsa.sig", msg, namespace); | ||||||
|  |  	TEST_DONE(); | ||||||
|  |   | ||||||
|  | +	/* Skip this test, SHA1 signatures are not supported
 | ||||||
|  |  	TEST_START("check DSA signature"); | ||||||
|  |  	check_sig("dsa.pub", "dsa.sig", msg, namespace); | ||||||
|  |  	TEST_DONE(); | ||||||
|  | +	*/
 | ||||||
|  |   | ||||||
|  |  #ifdef OPENSSL_HAS_ECC | ||||||
|  |  	TEST_START("check ECDSA signature"); | ||||||
|  | diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c
 | ||||||
|  | --- openssh-8.7p1/serverloop.c.sshrsacheck	2023-01-12 14:57:08.118400073 +0100
 | ||||||
|  | +++ openssh-8.7p1/serverloop.c	2023-01-12 14:59:17.330470518 +0100
 | ||||||
|  | @@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh *
 | ||||||
|  |  			else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) | ||||||
|  |  				sigalg = "rsa-sha2-256"; | ||||||
|  |  		} | ||||||
|  | +		if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) {
 | ||||||
|  | +			sigalg = "rsa-sha2-512";
 | ||||||
|  | +			debug3_f("SHA1 signature is not supported, falling back to %s", sigalg);
 | ||||||
|  | +		}
 | ||||||
|  |  		debug3_f("sign %s key (index %d) using sigalg %s", | ||||||
|  |  		sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); | ||||||
|  |  		if ((r = sshbuf_put_cstring(sigbuf, | ||||||
|  | diff -up openssh-8.7p1/sshconnect2.c.sshrsacheck openssh-8.7p1/sshconnect2.c
 | ||||||
|  | --- openssh-8.7p1/sshconnect2.c.sshrsacheck	2023-01-25 15:33:29.140353651 +0100
 | ||||||
|  | +++ openssh-8.7p1/sshconnect2.c	2023-01-25 15:59:34.225364883 +0100
 | ||||||
|  | @@ -1461,6 +1464,14 @@ identity_sign(struct identity *id, u_cha
 | ||||||
|  |  			retried = 1; | ||||||
|  |  			goto retry_pin; | ||||||
|  |  		} | ||||||
|  | +		if ((r == SSH_ERR_LIBCRYPTO_ERROR) && strcmp("ssh-rsa", alg)) {
 | ||||||
|  | +			char rsa_safe_alg[] = "rsa-sha2-512";
 | ||||||
|  | +			debug3_f("trying to fallback to algorithm %s", rsa_safe_alg);
 | ||||||
|  | +
 | ||||||
|  | +			if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen,
 | ||||||
|  | +				rsa_safe_alg, options.sk_provider, pin, compat)) != 0)
 | ||||||
|  | +				debug_fr(r, "sshkey_sign - RSA fallback");
 | ||||||
|  | +		}
 | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | diff -up openssh-8.7p1/sshd.c.sshrsacheck openssh-8.7p1/sshd.c
 | ||||||
|  | --- openssh-8.7p1/sshd.c.sshrsacheck	2023-01-12 13:29:06.355711140 +0100
 | ||||||
|  | +++ openssh-8.7p1/sshd.c	2023-01-12 13:29:06.358711178 +0100
 | ||||||
|  | @@ -1640,6 +1651,7 @@ main(int ac, char **av)
 | ||||||
|  |  	int keytype; | ||||||
|  |  	Authctxt *authctxt; | ||||||
|  |  	struct connection_info *connection_info = NULL; | ||||||
|  | +	int forbid_ssh_rsa = 0;
 | ||||||
|  |   | ||||||
|  |  #ifdef HAVE_SECUREWARE | ||||||
|  |  	(void)set_auth_parameters(ac, av); | ||||||
|  | @@ -1938,6 +1950,33 @@ main(int ac, char **av)
 | ||||||
|  |  		    key = NULL; | ||||||
|  |  		    continue; | ||||||
|  |  		} | ||||||
|  | +		if (key && (sshkey_type_plain(key->type) == KEY_RSA || sshkey_type_plain(key->type) == KEY_RSA_CERT)) {
 | ||||||
|  | +		    size_t sign_size = 0;
 | ||||||
|  | +		    u_char *tmp = NULL;
 | ||||||
|  | +		    u_char data[] = "Test SHA1 vector";
 | ||||||
|  | +		    int res;
 | ||||||
|  | +
 | ||||||
|  | +		    res = sshkey_sign(key, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
 | ||||||
|  | +		    free(tmp);
 | ||||||
|  | +		    if (res == SSH_ERR_LIBCRYPTO_ERROR) {
 | ||||||
|  | +			verbose_f("sshd: SHA1 in signatures is disabled for RSA keys");
 | ||||||
|  | +		    	forbid_ssh_rsa = 1;
 | ||||||
|  | +		    }
 | ||||||
|  | +		}
 | ||||||
|  | +		if (key && (sshkey_type_plain(key->type) == KEY_DSA || sshkey_type_plain(key->type) == KEY_DSA_CERT)) {
 | ||||||
|  | +		    size_t sign_size = 0;
 | ||||||
|  | +		    u_char *tmp = NULL;
 | ||||||
|  | +		    u_char data[] = "Test SHA1 vector";
 | ||||||
|  | +		    int res;
 | ||||||
|  | +
 | ||||||
|  | +		    res = sshkey_sign(key, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
 | ||||||
|  | +		    free(tmp);
 | ||||||
|  | +		    if (res == SSH_ERR_LIBCRYPTO_ERROR) {
 | ||||||
|  | +			logit_f("sshd: ssh-dss is disabled, skipping key file %s", options.host_key_files[i]);
 | ||||||
|  | +			key = NULL;
 | ||||||
|  | +			continue;
 | ||||||
|  | +		    }
 | ||||||
|  | +		}
 | ||||||
|  |  		if (sshkey_is_sk(key) && | ||||||
|  |  		    key->sk_flags & SSH_SK_USER_PRESENCE_REQD) { | ||||||
|  |  			debug("host key %s requires user presence, ignoring", | ||||||
|  | @@ -2275,6 +2306,9 @@ main(int ac, char **av)
 | ||||||
|  |   | ||||||
|  |  	check_ip_options(ssh); | ||||||
|  |   | ||||||
|  | +	if (forbid_ssh_rsa)
 | ||||||
|  | +		ssh->compat |= SSH_RH_RSASIGSHA;
 | ||||||
|  | +
 | ||||||
|  |  	/* Prepare the channels layer */ | ||||||
|  |  	channel_init_channels(ssh); | ||||||
|  |  	channel_set_af(ssh, options.address_family); | ||||||
|  | diff -Nur openssh-8.7p1/ssh-keygen.c openssh-8.7p1_patched/ssh-keygen.c
 | ||||||
|  | --- openssh-8.7p1/ssh-keygen.c	2023-01-18 17:41:47.894515779 +0100
 | ||||||
|  | +++ openssh-8.7p1_patched/ssh-keygen.c	2023-01-18 17:41:44.500488818 +0100
 | ||||||
|  | @@ -491,6 +491,8 @@
 | ||||||
|  |  	BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL; | ||||||
|  |  	BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; | ||||||
|  |  	BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; | ||||||
|  | +	char rsa_safe_alg[] = "rsa-sha2-256";
 | ||||||
|  | +	char *alg = NULL;
 | ||||||
|  |   | ||||||
|  |  	if ((r = sshbuf_get_u32(b, &magic)) != 0) | ||||||
|  |  		fatal_fr(r, "parse magic"); | ||||||
|  | @@ -590,6 +592,7 @@ do_convert_private_ssh2(struct sshbuf *b
 | ||||||
|  |  		if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) | ||||||
|  |  			fatal_fr(r, "generate RSA parameters"); | ||||||
|  |  		BN_clear_free(rsa_iqmp); | ||||||
|  | +		alg = rsa_safe_alg;
 | ||||||
|  |  		break; | ||||||
|  |  	} | ||||||
|  |  	rlen = sshbuf_len(b); | ||||||
|  | @@ -598,9 +601,9 @@ do_convert_private_ssh2(struct sshbuf *b
 | ||||||
|  |   | ||||||
|  |  	/* try the key */ | ||||||
|  |  	if (sshkey_sign(key, &sig, &slen, data, sizeof(data), | ||||||
|  | -	    NULL, NULL, NULL, 0) != 0 ||
 | ||||||
|  | +	    alg, NULL, NULL, 0) != 0 ||
 | ||||||
|  |  	    sshkey_verify(key, sig, slen, data, sizeof(data), | ||||||
|  | -	    NULL, 0, NULL) != 0) {
 | ||||||
|  | +	    alg, 0, NULL) != 0) {
 | ||||||
|  |  		sshkey_free(key); | ||||||
|  |  		free(sig); | ||||||
|  |  		return NULL; | ||||||
|  | diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c
 | ||||||
|  | --- openssh-8.7p1/ssh-rsa.c.sshrsacheck	2023-01-20 13:07:54.180676144 +0100
 | ||||||
|  | +++ openssh-8.7p1/ssh-rsa.c	2023-01-20 13:07:54.290677074 +0100
 | ||||||
|  | @@ -254,7 +254,8 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||||
|  |  			ret = SSH_ERR_INVALID_ARGUMENT; | ||||||
|  |  			goto out; | ||||||
|  |  		} | ||||||
|  | -		if (hash_alg != want_alg) {
 | ||||||
|  | +		if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) {
 | ||||||
|  | +			debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg);
 | ||||||
|  |  			ret = SSH_ERR_SIGNATURE_INVALID; | ||||||
|  |  			goto out; | ||||||
|  |  		} | ||||||
							
								
								
									
										174
									
								
								SOURCES/openssh-8.7p1-recursive-scp.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								SOURCES/openssh-8.7p1-recursive-scp.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,174 @@ | |||||||
|  | diff -up openssh-8.7p1/scp.c.scp-sftpdirs openssh-8.7p1/scp.c
 | ||||||
|  | --- openssh-8.7p1/scp.c.scp-sftpdirs	2022-02-07 12:31:07.407740407 +0100
 | ||||||
|  | +++ openssh-8.7p1/scp.c	2022-02-07 12:31:07.409740424 +0100
 | ||||||
|  | @@ -1324,7 +1324,7 @@ source_sftp(int argc, char *src, char *t
 | ||||||
|  |   | ||||||
|  |  	if (src_is_dir && iamrecursive) { | ||||||
|  |  		if (upload_dir(conn, src, abs_dst, pflag, | ||||||
|  | -		    SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) {
 | ||||||
|  | +		    SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
 | ||||||
|  |  			error("failed to upload directory %s to %s", | ||||||
|  |  				src, abs_dst); | ||||||
|  |  			errs = 1; | ||||||
|  | diff -up openssh-8.7p1/sftp-client.c.scp-sftpdirs openssh-8.7p1/sftp-client.c
 | ||||||
|  | --- openssh-8.7p1/sftp-client.c.scp-sftpdirs	2021-08-20 06:03:49.000000000 +0200
 | ||||||
|  | +++ openssh-8.7p1/sftp-client.c	2022-02-07 12:47:59.117516131 +0100
 | ||||||
|  | @@ -971,7 +971,7 @@ do_fsetstat(struct sftp_conn *conn, cons
 | ||||||
|  |   | ||||||
|  |  /* Implements both the realpath and expand-path operations */ | ||||||
|  |  static char * | ||||||
|  | -do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
 | ||||||
|  | +do_realpath_expand(struct sftp_conn *conn, const char *path, int expand, int create_dir)
 | ||||||
|  |  { | ||||||
|  |  	struct sshbuf *msg; | ||||||
|  |  	u_int expected_id, count, id; | ||||||
|  | @@ -1012,9 +1012,38 @@ do_realpath_expand(struct sftp_conn *con
 | ||||||
|  |   | ||||||
|  |  		if ((r = sshbuf_get_u32(msg, &status)) != 0) | ||||||
|  |  			fatal_fr(r, "parse status"); | ||||||
|  | -		error("Couldn't canonicalize: %s", fx2txt(status));
 | ||||||
|  | -		sshbuf_free(msg);
 | ||||||
|  | -		return NULL;
 | ||||||
|  | +		if ((status == SSH2_FX_NO_SUCH_FILE) && create_dir)  {
 | ||||||
|  | +			memset(&a, '\0', sizeof(a));
 | ||||||
|  | +			if ((r = do_mkdir(conn, path, &a, 0)) != 0) {
 | ||||||
|  | +				sshbuf_free(msg);
 | ||||||
|  | +				return NULL;
 | ||||||
|  | +			}
 | ||||||
|  | +
 | ||||||
|  | +			send_string_request(conn, id, SSH2_FXP_REALPATH,
 | ||||||
|  | +					path, strlen(path));
 | ||||||
|  | +
 | ||||||
|  | +			get_msg(conn, msg);
 | ||||||
|  | +			if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
 | ||||||
|  | +					(r = sshbuf_get_u32(msg, &id)) != 0)
 | ||||||
|  | +				fatal_fr(r, "parse");
 | ||||||
|  | +
 | ||||||
|  | +			if (id != expected_id)
 | ||||||
|  | +				fatal("ID mismatch (%u != %u)", id, expected_id);
 | ||||||
|  | +
 | ||||||
|  | +			if (type == SSH2_FXP_STATUS) {
 | ||||||
|  | +				u_int status;
 | ||||||
|  | +
 | ||||||
|  | +				if ((r = sshbuf_get_u32(msg, &status)) != 0)
 | ||||||
|  | +					fatal_fr(r, "parse status");
 | ||||||
|  | +				error("Couldn't canonicalize: %s", fx2txt(status));
 | ||||||
|  | +				sshbuf_free(msg);
 | ||||||
|  | +				return NULL;
 | ||||||
|  | +			}
 | ||||||
|  | +		} else {
 | ||||||
|  | +			error("Couldn't canonicalize: %s", fx2txt(status));
 | ||||||
|  | +			sshbuf_free(msg);
 | ||||||
|  | +			return NULL;
 | ||||||
|  | +		}
 | ||||||
|  |  	} else if (type != SSH2_FXP_NAME) | ||||||
|  |  		fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", | ||||||
|  |  		    SSH2_FXP_NAME, type); | ||||||
|  | @@ -1039,9 +1067,9 @@ do_realpath_expand(struct sftp_conn *con
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  char * | ||||||
|  | -do_realpath(struct sftp_conn *conn, const char *path)
 | ||||||
|  | +do_realpath(struct sftp_conn *conn, const char *path, int create_dir)
 | ||||||
|  |  { | ||||||
|  | -	return do_realpath_expand(conn, path, 0);
 | ||||||
|  | +	return do_realpath_expand(conn, path, 0, create_dir);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int | ||||||
|  | @@ -1055,9 +1083,9 @@ do_expand_path(struct sftp_conn *conn, c
 | ||||||
|  |  { | ||||||
|  |  	if (!can_expand_path(conn)) { | ||||||
|  |  		debug3_f("no server support, fallback to realpath"); | ||||||
|  | -		return do_realpath_expand(conn, path, 0);
 | ||||||
|  | +		return do_realpath_expand(conn, path, 0, 0);
 | ||||||
|  |  	} | ||||||
|  | -	return do_realpath_expand(conn, path, 1);
 | ||||||
|  | +	return do_realpath_expand(conn, path, 1, 0);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int | ||||||
|  | @@ -1807,7 +1835,7 @@ download_dir(struct sftp_conn *conn, con
 | ||||||
|  |  	char *src_canon; | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | -	if ((src_canon = do_realpath(conn, src)) == NULL) {
 | ||||||
|  | +	if ((src_canon = do_realpath(conn, src, 0)) == NULL) {
 | ||||||
|  |  		error("Unable to canonicalize path \"%s\"", src); | ||||||
|  |  		return -1; | ||||||
|  |  	} | ||||||
|  | @@ -2115,12 +2143,12 @@ upload_dir_internal(struct sftp_conn *co
 | ||||||
|  |  int | ||||||
|  |  upload_dir(struct sftp_conn *conn, const char *src, const char *dst, | ||||||
|  |      int preserve_flag, int print_flag, int resume, int fsync_flag, | ||||||
|  | -    int follow_link_flag)
 | ||||||
|  | +    int follow_link_flag, int create_dir)
 | ||||||
|  |  { | ||||||
|  |  	char *dst_canon; | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | -	if ((dst_canon = do_realpath(conn, dst)) == NULL) {
 | ||||||
|  | +	if ((dst_canon = do_realpath(conn, dst, create_dir)) == NULL) {
 | ||||||
|  |  		error("Unable to canonicalize path \"%s\"", dst); | ||||||
|  |  		return -1; | ||||||
|  |  	} | ||||||
|  | @@ -2557,7 +2585,7 @@ crossload_dir(struct sftp_conn *from, st
 | ||||||
|  |  	char *from_path_canon; | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | -	if ((from_path_canon = do_realpath(from, from_path)) == NULL) {
 | ||||||
|  | +	if ((from_path_canon = do_realpath(from, from_path, 0)) == NULL) {
 | ||||||
|  |  		error("Unable to canonicalize path \"%s\"", from_path); | ||||||
|  |  		return -1; | ||||||
|  |  	} | ||||||
|  | diff -up openssh-8.7p1/sftp-client.h.scp-sftpdirs openssh-8.7p1/sftp-client.h
 | ||||||
|  | --- openssh-8.7p1/sftp-client.h.scp-sftpdirs	2021-08-20 06:03:49.000000000 +0200
 | ||||||
|  | +++ openssh-8.7p1/sftp-client.h	2022-02-07 12:31:07.410740433 +0100
 | ||||||
|  | @@ -111,7 +111,7 @@ int do_fsetstat(struct sftp_conn *, cons
 | ||||||
|  |  int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a); | ||||||
|  |   | ||||||
|  |  /* Canonicalise 'path' - caller must free result */ | ||||||
|  | -char *do_realpath(struct sftp_conn *, const char *);
 | ||||||
|  | +char *do_realpath(struct sftp_conn *, const char *, int);
 | ||||||
|  |   | ||||||
|  |  /* Canonicalisation with tilde expansion (requires server extension) */ | ||||||
|  |  char *do_expand_path(struct sftp_conn *, const char *); | ||||||
|  | @@ -159,7 +159,7 @@ int do_upload(struct sftp_conn *, const
 | ||||||
|  |   * times if 'pflag' is set | ||||||
|  |   */ | ||||||
|  |  int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int, | ||||||
|  | -    int, int);
 | ||||||
|  | +    int, int, int);
 | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * Download a 'from_path' from the 'from' connection and upload it to | ||||||
|  | diff -up openssh-8.7p1/sftp.c.scp-sftpdirs openssh-8.7p1/sftp.c
 | ||||||
|  | --- openssh-8.7p1/sftp.c.scp-sftpdirs	2021-08-20 06:03:49.000000000 +0200
 | ||||||
|  | +++ openssh-8.7p1/sftp.c	2022-02-07 12:31:07.411740442 +0100
 | ||||||
|  | @@ -760,7 +760,7 @@ process_put(struct sftp_conn *conn, cons
 | ||||||
|  |  		if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { | ||||||
|  |  			if (upload_dir(conn, g.gl_pathv[i], abs_dst, | ||||||
|  |  			    pflag || global_pflag, 1, resume, | ||||||
|  | -			    fflag || global_fflag, 0) == -1)
 | ||||||
|  | +			    fflag || global_fflag, 0, 0) == -1)
 | ||||||
|  |  				err = -1; | ||||||
|  |  		} else { | ||||||
|  |  			if (do_upload(conn, g.gl_pathv[i], abs_dst, | ||||||
|  | @@ -1577,7 +1577,7 @@ parse_dispatch_command(struct sftp_conn
 | ||||||
|  |  		if (path1 == NULL || *path1 == '\0') | ||||||
|  |  			path1 = xstrdup(startdir); | ||||||
|  |  		path1 = make_absolute(path1, *pwd); | ||||||
|  | -		if ((tmp = do_realpath(conn, path1)) == NULL) {
 | ||||||
|  | +		if ((tmp = do_realpath(conn, path1, 0)) == NULL) {
 | ||||||
|  |  			err = 1; | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  | @@ -2160,7 +2160,7 @@ interactive_loop(struct sftp_conn *conn,
 | ||||||
|  |  	} | ||||||
|  |  #endif /* USE_LIBEDIT */ | ||||||
|  |   | ||||||
|  | -	remote_path = do_realpath(conn, ".");
 | ||||||
|  | +	remote_path = do_realpath(conn, ".", 0);
 | ||||||
|  |  	if (remote_path == NULL) | ||||||
|  |  		fatal("Need cwd"); | ||||||
|  |  	startdir = xstrdup(remote_path); | ||||||
							
								
								
									
										304
									
								
								SOURCES/openssh-8.7p1-scp-clears-file.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								SOURCES/openssh-8.7p1-scp-clears-file.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,304 @@ | |||||||
|  | diff --color -rup a/scp.c b/scp.c
 | ||||||
|  | --- a/scp.c	2022-07-26 14:51:40.560120817 +0200
 | ||||||
|  | +++ b/scp.c	2022-07-26 14:52:37.118213004 +0200
 | ||||||
|  | @@ -1324,12 +1324,12 @@ source_sftp(int argc, char *src, char *t
 | ||||||
|  |   | ||||||
|  |  	if (src_is_dir && iamrecursive) { | ||||||
|  |  		if (upload_dir(conn, src, abs_dst, pflag, | ||||||
|  | -		    SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
 | ||||||
|  | +		    SFTP_PROGRESS_ONLY, 0, 0, 1, 1, 1) != 0) {
 | ||||||
|  |  			error("failed to upload directory %s to %s", | ||||||
|  |  				src, abs_dst); | ||||||
|  |  			errs = 1; | ||||||
|  |  		} | ||||||
|  | -	} else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0) {
 | ||||||
|  | +	} else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) {
 | ||||||
|  |  		error("failed to upload file %s to %s", src, abs_dst); | ||||||
|  |  		errs = 1; | ||||||
|  |  	} | ||||||
|  | @@ -1566,11 +1566,11 @@ sink_sftp(int argc, char *dst, const cha
 | ||||||
|  |  		debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst); | ||||||
|  |  		if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) { | ||||||
|  |  			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, | ||||||
|  | -			    pflag, SFTP_PROGRESS_ONLY, 0, 0, 1) == -1)
 | ||||||
|  | +			    pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1)
 | ||||||
|  |  				err = -1; | ||||||
|  |  		} else { | ||||||
|  |  			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, | ||||||
|  | -			    pflag, 0, 0) == -1)
 | ||||||
|  | +			    pflag, 0, 0, 1) == -1)
 | ||||||
|  |  				err = -1; | ||||||
|  |  		} | ||||||
|  |  		free(abs_dst); | ||||||
|  | diff --color -rup a/sftp.c b/sftp.c
 | ||||||
|  | --- a/sftp.c	2022-07-26 14:51:40.561120836 +0200
 | ||||||
|  | +++ b/sftp.c	2022-07-26 14:52:37.119213023 +0200
 | ||||||
|  | @@ -666,12 +666,12 @@ process_get(struct sftp_conn *conn, cons
 | ||||||
|  |  		if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { | ||||||
|  |  			if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL, | ||||||
|  |  			    pflag || global_pflag, 1, resume, | ||||||
|  | -			    fflag || global_fflag, 0) == -1)
 | ||||||
|  | +			    fflag || global_fflag, 0, 0) == -1)
 | ||||||
|  |  				err = -1; | ||||||
|  |  		} else { | ||||||
|  |  			if (do_download(conn, g.gl_pathv[i], abs_dst, NULL, | ||||||
|  |  			    pflag || global_pflag, resume, | ||||||
|  | -			    fflag || global_fflag) == -1)
 | ||||||
|  | +			    fflag || global_fflag, 0) == -1)
 | ||||||
|  |  				err = -1; | ||||||
|  |  		} | ||||||
|  |  		free(abs_dst); | ||||||
|  | @@ -760,12 +760,12 @@ process_put(struct sftp_conn *conn, cons
 | ||||||
|  |  		if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) { | ||||||
|  |  			if (upload_dir(conn, g.gl_pathv[i], abs_dst, | ||||||
|  |  			    pflag || global_pflag, 1, resume, | ||||||
|  | -			    fflag || global_fflag, 0, 0) == -1)
 | ||||||
|  | +			    fflag || global_fflag, 0, 0, 0) == -1)
 | ||||||
|  |  				err = -1; | ||||||
|  |  		} else { | ||||||
|  |  			if (do_upload(conn, g.gl_pathv[i], abs_dst, | ||||||
|  |  			    pflag || global_pflag, resume, | ||||||
|  | -			    fflag || global_fflag) == -1)
 | ||||||
|  | +			    fflag || global_fflag, 0) == -1)
 | ||||||
|  |  				err = -1; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | diff --color -rup a/sftp-client.c b/sftp-client.c
 | ||||||
|  | --- a/sftp-client.c	2022-07-26 14:51:40.561120836 +0200
 | ||||||
|  | +++ b/sftp-client.c	2022-07-26 15:09:54.825295533 +0200
 | ||||||
|  | @@ -1454,7 +1454,7 @@ progress_meter_path(const char *path)
 | ||||||
|  |  int | ||||||
|  |  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)
 | ||||||
|  | +    int fsync_flag, int inplace_flag)
 | ||||||
|  |  { | ||||||
|  |  	struct sshbuf *msg; | ||||||
|  |  	u_char *handle; | ||||||
|  | @@ -1498,8 +1498,8 @@ do_download(struct sftp_conn *conn, cons
 | ||||||
|  |  	    &handle, &handle_len) != 0) | ||||||
|  |  		return -1; | ||||||
|  |   | ||||||
|  | -	local_fd = open(local_path,
 | ||||||
|  | -	    O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
 | ||||||
|  | +	local_fd = open(local_path, O_WRONLY | O_CREAT |
 | ||||||
|  | +	((resume_flag || inplace_flag) ? 0 : O_TRUNC), mode | S_IWUSR);
 | ||||||
|  |  	if (local_fd == -1) { | ||||||
|  |  		error("Couldn't open local file \"%s\" for writing: %s", | ||||||
|  |  		    local_path, strerror(errno)); | ||||||
|  | @@ -1661,8 +1661,11 @@ do_download(struct sftp_conn *conn, cons
 | ||||||
|  |  	/* Sanity check */ | ||||||
|  |  	if (TAILQ_FIRST(&requests) != NULL) | ||||||
|  |  		fatal("Transfer complete, but requests still in queue"); | ||||||
|  | -	/* Truncate at highest contiguous point to avoid holes on interrupt */
 | ||||||
|  | -	if (read_error || write_error || interrupted) {
 | ||||||
|  | +	/*
 | ||||||
|  | +	 * Truncate at highest contiguous point to avoid holes on interrupt,
 | ||||||
|  | +	 * or unconditionally if writing in place.
 | ||||||
|  | +	 */
 | ||||||
|  | +	if (inplace_flag || read_error || write_error || interrupted) {
 | ||||||
|  |  		if (reordered && resume_flag) { | ||||||
|  |  			error("Unable to resume download of \"%s\": " | ||||||
|  |  			    "server reordered requests", local_path); | ||||||
|  | @@ -1724,7 +1727,7 @@ do_download(struct sftp_conn *conn, cons
 | ||||||
|  |  static int | ||||||
|  |  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, int follow_link_flag)
 | ||||||
|  | +    int resume_flag, int fsync_flag, int follow_link_flag, int inplace_flag)
 | ||||||
|  |  { | ||||||
|  |  	int i, ret = 0; | ||||||
|  |  	SFTP_DIRENT **dir_entries; | ||||||
|  | @@ -1781,7 +1784,7 @@ download_dir_internal(struct sftp_conn *
 | ||||||
|  |  			if (download_dir_internal(conn, new_src, new_dst, | ||||||
|  |  			    depth + 1, &(dir_entries[i]->a), preserve_flag, | ||||||
|  |  			    print_flag, resume_flag, | ||||||
|  | -			    fsync_flag, follow_link_flag) == -1)
 | ||||||
|  | +			    fsync_flag, follow_link_flag, inplace_flag) == -1)
 | ||||||
|  |  				ret = -1; | ||||||
|  |  		} else if (S_ISREG(dir_entries[i]->a.perm) || | ||||||
|  |  		    (follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) { | ||||||
|  | @@ -1793,7 +1796,8 @@ download_dir_internal(struct sftp_conn *
 | ||||||
|  |  			if (do_download(conn, new_src, new_dst, | ||||||
|  |  			    S_ISLNK(dir_entries[i]->a.perm) ? NULL : | ||||||
|  |  			    &(dir_entries[i]->a), | ||||||
|  | -			    preserve_flag, resume_flag, fsync_flag) == -1) {
 | ||||||
|  | +			    preserve_flag, resume_flag, fsync_flag,
 | ||||||
|  | +			    inplace_flag) == -1) {
 | ||||||
|  |  				error("Download of file %s to %s failed", | ||||||
|  |  				    new_src, new_dst); | ||||||
|  |  				ret = -1; | ||||||
|  | @@ -1831,7 +1835,7 @@ download_dir_internal(struct sftp_conn *
 | ||||||
|  |  int | ||||||
|  |  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, int follow_link_flag)
 | ||||||
|  | +    int fsync_flag, int follow_link_flag, int inplace_flag)
 | ||||||
|  |  { | ||||||
|  |  	char *src_canon; | ||||||
|  |  	int ret; | ||||||
|  | @@ -1843,26 +1847,25 @@ download_dir(struct sftp_conn *conn, con
 | ||||||
|  |   | ||||||
|  |  	ret = download_dir_internal(conn, src_canon, dst, 0, | ||||||
|  |  	    dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag, | ||||||
|  | -	    follow_link_flag);
 | ||||||
|  | +	    follow_link_flag, inplace_flag);
 | ||||||
|  |  	free(src_canon); | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int | ||||||
|  |  do_upload(struct sftp_conn *conn, const char *local_path, | ||||||
|  | -    const char *remote_path, int preserve_flag, int resume, int fsync_flag)
 | ||||||
|  | +    const char *remote_path, int preserve_flag, int resume,
 | ||||||
|  | +    int fsync_flag, int inplace_flag)
 | ||||||
|  |  { | ||||||
|  |  	int r, local_fd; | ||||||
|  | -	u_int status = SSH2_FX_OK;
 | ||||||
|  | -	u_int id;
 | ||||||
|  | -	u_char type;
 | ||||||
|  | +	u_int openmode, id, status = SSH2_FX_OK, reordered = 0;
 | ||||||
|  |  	off_t offset, progress_counter; | ||||||
|  | -	u_char *handle, *data;
 | ||||||
|  | +	u_char type, *handle, *data;
 | ||||||
|  |  	struct sshbuf *msg; | ||||||
|  |  	struct stat sb; | ||||||
|  | -	Attrib a, *c = NULL;
 | ||||||
|  | -	u_int32_t startid;
 | ||||||
|  | -	u_int32_t ackid;
 | ||||||
|  | +	Attrib a, t, *c = NULL;
 | ||||||
|  | +	u_int32_t startid, ackid;
 | ||||||
|  | +	u_int64_t highwater = 0;
 | ||||||
|  |  	struct request *ack = NULL; | ||||||
|  |  	struct requests acks; | ||||||
|  |  	size_t handle_len; | ||||||
|  | @@ -1913,10 +1916,15 @@ do_upload(struct sftp_conn *conn, const
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT;
 | ||||||
|  | +	if (resume)
 | ||||||
|  | +		openmode |= SSH2_FXF_APPEND;
 | ||||||
|  | +	else if (!inplace_flag)
 | ||||||
|  | +		openmode |= SSH2_FXF_TRUNC;
 | ||||||
|  | +
 | ||||||
|  |  	/* Send open request */ | ||||||
|  | -	if (send_open(conn, remote_path, "dest", SSH2_FXF_WRITE|SSH2_FXF_CREAT|
 | ||||||
|  | -	    (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC),
 | ||||||
|  | -	    &a, &handle, &handle_len) != 0) {
 | ||||||
|  | +	if (send_open(conn, remote_path, "dest", openmode, &a,
 | ||||||
|  | +	    &handle, &handle_len) != 0) {
 | ||||||
|  |  		close(local_fd); | ||||||
|  |  		return -1; | ||||||
|  |  	} | ||||||
|  | @@ -1999,6 +2007,12 @@ do_upload(struct sftp_conn *conn, const
 | ||||||
|  |  			    ack->id, ack->len, (unsigned long long)ack->offset); | ||||||
|  |  			++ackid; | ||||||
|  |  			progress_counter += ack->len; | ||||||
|  | +			if (!reordered && ack->offset <= highwater)
 | ||||||
|  | +				highwater = ack->offset + ack->len;
 | ||||||
|  | +			else if (!reordered && ack->offset > highwater) {
 | ||||||
|  | +				debug3_f("server reordered ACKs");
 | ||||||
|  | +				reordered = 1;
 | ||||||
|  | +			}
 | ||||||
|  |  			free(ack); | ||||||
|  |  		} | ||||||
|  |  		offset += len; | ||||||
|  | @@ -2017,6 +2031,14 @@ do_upload(struct sftp_conn *conn, const
 | ||||||
|  |  		status = SSH2_FX_FAILURE; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	if (inplace_flag || (resume && (status != SSH2_FX_OK || interrupted))) {
 | ||||||
|  | +		debug("truncating at %llu", (unsigned long long)highwater);
 | ||||||
|  | +		attrib_clear(&t);
 | ||||||
|  | +		t.flags = SSH2_FILEXFER_ATTR_SIZE;
 | ||||||
|  | +		t.size = highwater;
 | ||||||
|  | +		do_fsetstat(conn, handle, handle_len, &t);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	if (close(local_fd) == -1) { | ||||||
|  |  		error("Couldn't close local file \"%s\": %s", local_path, | ||||||
|  |  		    strerror(errno)); | ||||||
|  | @@ -2041,7 +2063,7 @@ do_upload(struct sftp_conn *conn, const
 | ||||||
|  |  static int | ||||||
|  |  upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, | ||||||
|  |      int depth, int preserve_flag, int print_flag, int resume, int fsync_flag, | ||||||
|  | -    int follow_link_flag)
 | ||||||
|  | +    int follow_link_flag, int inplace_flag)
 | ||||||
|  |  { | ||||||
|  |  	int ret = 0; | ||||||
|  |  	DIR *dirp; | ||||||
|  | @@ -2119,12 +2141,13 @@ upload_dir_internal(struct sftp_conn *co
 | ||||||
|  |   | ||||||
|  |  			if (upload_dir_internal(conn, new_src, new_dst, | ||||||
|  |  			    depth + 1, preserve_flag, print_flag, resume, | ||||||
|  | -			    fsync_flag, follow_link_flag) == -1)
 | ||||||
|  | +			    fsync_flag, follow_link_flag, inplace_flag) == -1)
 | ||||||
|  |  				ret = -1; | ||||||
|  |  		} else if (S_ISREG(sb.st_mode) || | ||||||
|  |  		    (follow_link_flag && S_ISLNK(sb.st_mode))) { | ||||||
|  |  			if (do_upload(conn, new_src, new_dst, | ||||||
|  | -			    preserve_flag, resume, fsync_flag) == -1) {
 | ||||||
|  | +			    preserve_flag, resume, fsync_flag,
 | ||||||
|  | +			    inplace_flag) == -1) {
 | ||||||
|  |  				error("Uploading of file %s to %s failed!", | ||||||
|  |  				    new_src, new_dst); | ||||||
|  |  				ret = -1; | ||||||
|  | @@ -2144,7 +2167,7 @@ upload_dir_internal(struct sftp_conn *co
 | ||||||
|  |  int | ||||||
|  |  upload_dir(struct sftp_conn *conn, const char *src, const char *dst, | ||||||
|  |      int preserve_flag, int print_flag, int resume, int fsync_flag, | ||||||
|  | -    int follow_link_flag, int create_dir)
 | ||||||
|  | +    int follow_link_flag, int create_dir, int inplace_flag)
 | ||||||
|  |  { | ||||||
|  |  	char *dst_canon; | ||||||
|  |  	int ret; | ||||||
|  | @@ -2155,7 +2178,7 @@ upload_dir(struct sftp_conn *conn, const
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, | ||||||
|  | -	    print_flag, resume, fsync_flag, follow_link_flag);
 | ||||||
|  | +	    print_flag, resume, fsync_flag, follow_link_flag, inplace_flag);
 | ||||||
|  |   | ||||||
|  |  	free(dst_canon); | ||||||
|  |  	return ret; | ||||||
|  | diff --color -rup a/sftp-client.h b/sftp-client.h
 | ||||||
|  | --- a/sftp-client.h	2022-07-26 14:51:40.561120836 +0200
 | ||||||
|  | +++ b/sftp-client.h	2022-07-26 14:52:37.120213042 +0200
 | ||||||
|  | @@ -138,28 +138,29 @@ int do_fsync(struct sftp_conn *conn, u_c
 | ||||||
|  |   * Download 'remote_path' to 'local_path'. Preserve permissions and times | ||||||
|  |   * if 'pflag' is set | ||||||
|  |   */ | ||||||
|  | -int do_download(struct sftp_conn *, const char *, const char *,
 | ||||||
|  | -    Attrib *, int, int, int);
 | ||||||
|  | +int do_download(struct sftp_conn *, const char *, const char *, Attrib *,
 | ||||||
|  | +    int, int, int, int);
 | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * Recursively download 'remote_directory' to 'local_directory'. Preserve | ||||||
|  |   * times if 'pflag' is set | ||||||
|  |   */ | ||||||
|  | -int download_dir(struct sftp_conn *, const char *, const char *,
 | ||||||
|  | -    Attrib *, int, int, int, int, int);
 | ||||||
|  | +int download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
 | ||||||
|  | +    int, int, int, int, int, int);
 | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * Upload 'local_path' to 'remote_path'. Preserve permissions and times | ||||||
|  |   * if 'pflag' is set | ||||||
|  |   */ | ||||||
|  | -int do_upload(struct sftp_conn *, const char *, const char *, int, int, int);
 | ||||||
|  | +int do_upload(struct sftp_conn *, const char *, const char *,
 | ||||||
|  | +    int, int, int, int);
 | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * Recursively upload 'local_directory' to 'remote_directory'. Preserve | ||||||
|  |   * times if 'pflag' is set | ||||||
|  |   */ | ||||||
|  | -int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int,
 | ||||||
|  | -    int, int, int);
 | ||||||
|  | +int upload_dir(struct sftp_conn *, const char *, const char *,
 | ||||||
|  | +    int, int, int, int, int, int, int);
 | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * Download a 'from_path' from the 'from' connection and upload it to | ||||||
| @ -30,10 +30,10 @@ diff -up openssh-8.7p1/scp.c.kill-scp openssh-8.7p1/scp.c | |||||||
| --- openssh-8.7p1/scp.c.kill-scp	2021-09-16 11:42:56.013650519 +0200
 | --- openssh-8.7p1/scp.c.kill-scp	2021-09-16 11:42:56.013650519 +0200
 | ||||||
| +++ openssh-8.7p1/scp.c	2021-09-16 11:53:03.249713836 +0200
 | +++ openssh-8.7p1/scp.c	2021-09-16 11:53:03.249713836 +0200
 | ||||||
| @@ -596,6 +596,14 @@ main(int argc, char **argv)
 | @@ -596,6 +596,14 @@ main(int argc, char **argv)
 | ||||||
|  	argc -= optind; |  	if (iamremote) | ||||||
|  	argv += optind; |  		mode = MODE_SCP; | ||||||
|   |   | ||||||
| +	{
 | +	if (mode == MODE_SCP) {
 | ||||||
| +		FILE *f = fopen(_PATH_SCP_KILL_SWITCH, "r");
 | +		FILE *f = fopen(_PATH_SCP_KILL_SWITCH, "r");
 | ||||||
| +		if (f != NULL) {
 | +		if (f != NULL) {
 | ||||||
| +			fclose(f);
 | +			fclose(f);
 | ||||||
|  | |||||||
							
								
								
									
										129
									
								
								SOURCES/openssh-8.7p1-sftp-default-protocol.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								SOURCES/openssh-8.7p1-sftp-default-protocol.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | |||||||
|  | diff --git a/scp.1 b/scp.1
 | ||||||
|  | index 68aac04b..a96e95ad 100644
 | ||||||
|  | --- a/scp.1
 | ||||||
|  | +++ b/scp.1
 | ||||||
|  | @@ -8,9 +8,9 @@
 | ||||||
|  |  .\" | ||||||
|  |  .\" Created: Sun May  7 00:14:37 1995 ylo | ||||||
|  |  .\" | ||||||
|  | -.\" $OpenBSD: scp.1,v 1.100 2021/08/11 14:07:54 naddy Exp $
 | ||||||
|  | +.\" $OpenBSD: scp.1,v 1.101 2021/09/08 23:31:39 djm Exp $
 | ||||||
|  |  .\" | ||||||
|  | -.Dd $Mdocdate: August 11 2021 $
 | ||||||
|  | +.Dd $Mdocdate: September 8 2021 $
 | ||||||
|  |  .Dt SCP 1 | ||||||
|  |  .Os | ||||||
|  |  .Sh NAME | ||||||
|  | @@ -18,7 +18,7 @@
 | ||||||
|  |  .Nd OpenSSH secure file copy | ||||||
|  |  .Sh SYNOPSIS | ||||||
|  |  .Nm scp | ||||||
|  | -.Op Fl 346ABCOpqRrsTv
 | ||||||
|  | +.Op Fl 346ABCOpqRrTv
 | ||||||
|  |  .Op Fl c Ar cipher | ||||||
|  |  .Op Fl D Ar sftp_server_path | ||||||
|  |  .Op Fl F Ar ssh_config | ||||||
|  | @@ -37,9 +37,6 @@ It uses
 | ||||||
|  |  .Xr ssh 1 | ||||||
|  |  for data transfer, and uses the same authentication and provides the | ||||||
|  |  same security as a login session. | ||||||
|  | -The scp protocol requires execution of the remote user's shell to perform
 | ||||||
|  | -.Xr glob 3
 | ||||||
|  | -pattern matching.
 | ||||||
|  |  .Pp | ||||||
|  |  .Nm | ||||||
|  |  will ask for passwords or passphrases if they are needed for | ||||||
|  | @@ -79,7 +76,9 @@ The options are as follows:
 | ||||||
|  |  Copies between two remote hosts are transferred through the local host. | ||||||
|  |  Without this option the data is copied directly between the two remote | ||||||
|  |  hosts. | ||||||
|  | -Note that, when using the legacy SCP protocol (the default), this option
 | ||||||
|  | +Note that, when using the legacy SCP protocol (via the
 | ||||||
|  | +.Fl O
 | ||||||
|  | +flag), this option
 | ||||||
|  |  selects batch mode for the second host as | ||||||
|  |  .Nm | ||||||
|  |  cannot ask for passwords or passphrases for both hosts. | ||||||
|  | @@ -146,9 +145,10 @@ Limits the used bandwidth, specified in Kbit/s.
 | ||||||
|  |  .It Fl O | ||||||
|  |  Use the legacy SCP protocol for file transfers instead of the SFTP protocol. | ||||||
|  |  Forcing the use of the SCP protocol may be necessary for servers that do | ||||||
|  | -not implement SFTP or for backwards-compatibility for particular filename
 | ||||||
|  | -wildcard patterns.
 | ||||||
|  | -This mode is the default.
 | ||||||
|  | +not implement SFTP, for backwards-compatibility for particular filename
 | ||||||
|  | +wildcard patterns and for expanding paths with a
 | ||||||
|  | +.Sq ~
 | ||||||
|  | +prefix for older SFTP servers.
 | ||||||
|  |  .It Fl o Ar ssh_option | ||||||
|  |  Can be used to pass options to | ||||||
|  |  .Nm ssh | ||||||
|  | @@ -258,16 +258,6 @@ to use for the encrypted connection.
 | ||||||
|  |  The program must understand | ||||||
|  |  .Xr ssh 1 | ||||||
|  |  options. | ||||||
|  | -.It Fl s
 | ||||||
|  | -Use the SFTP protocol for file transfers instead of the legacy SCP protocol.
 | ||||||
|  | -Using SFTP avoids invoking a shell on the remote side and provides
 | ||||||
|  | -more predictable filename handling, as the SCP protocol
 | ||||||
|  | -relied on the remote shell for expanding
 | ||||||
|  | -.Xr glob 3
 | ||||||
|  | -wildcards.
 | ||||||
|  | -.Pp
 | ||||||
|  | -A near-future release of OpenSSH will make the SFTP protocol the default.
 | ||||||
|  | -This option will be deleted before the end of 2022.
 | ||||||
|  |  .It Fl T | ||||||
|  |  Disable strict filename checking. | ||||||
|  |  By default when copying files from a remote host to a local directory | ||||||
|  | @@ -299,11 +289,23 @@ debugging connection, authentication, and configuration problems.
 | ||||||
|  |  .Xr ssh_config 5 , | ||||||
|  |  .Xr sftp-server 8 , | ||||||
|  |  .Xr sshd 8 | ||||||
|  | +.Sh CAVEATS
 | ||||||
|  | +The original scp protocol (selected by the
 | ||||||
|  | +.Fl O
 | ||||||
|  | +flag) requires execution of the remote user's shell to perform
 | ||||||
|  | +.Xr glob 3
 | ||||||
|  | +pattern matching.
 | ||||||
|  | +This requires careful quoting of any characters that have special meaning to
 | ||||||
|  | +the remote shell, such as quote characters.
 | ||||||
|  |  .Sh HISTORY | ||||||
|  |  .Nm | ||||||
|  |  is based on the rcp program in | ||||||
|  |  .Bx | ||||||
|  |  source code from the Regents of the University of California. | ||||||
|  | +.Pp
 | ||||||
|  | +Since OpenSSH 8.8 (8.7 in Red Hat/Fedora builds),
 | ||||||
|  | +.Nm
 | ||||||
|  | +has use the SFTP protocol for transfers by default.
 | ||||||
|  |  .Sh AUTHORS | ||||||
|  |  .An Timo Rinne Aq Mt tri@iki.fi | ||||||
|  |  .An Tatu Ylonen Aq Mt ylo@cs.hut.fi | ||||||
|  | diff --git a/scp.c b/scp.c
 | ||||||
|  | index e039350c..c7cf7529 100644
 | ||||||
|  | --- a/scp.c
 | ||||||
|  | +++ b/scp.c
 | ||||||
|  | @@ -1,4 +1,4 @@
 | ||||||
|  | -/* $OpenBSD: scp.c,v 1.232 2021/08/11 14:07:54 naddy Exp $ */
 | ||||||
|  | +/* $OpenBSD: scp.c,v 1.233 2021/09/08 23:31:39 djm Exp $ */
 | ||||||
|  |  /* | ||||||
|  |   * scp - secure remote copy.  This is basically patched BSD rcp which | ||||||
|  |   * uses ssh to do the data transfer (instead of using rcmd). | ||||||
|  | @@ -448,7 +448,7 @@ main(int argc, char **argv)
 | ||||||
|  |  	const char *errstr; | ||||||
|  |  	extern char *optarg; | ||||||
|  |  	extern int optind; | ||||||
|  | -	enum scp_mode_e mode = MODE_SCP;
 | ||||||
|  | +	enum scp_mode_e mode = MODE_SFTP;
 | ||||||
|  |  	char *sftp_direct = NULL; | ||||||
|  |   | ||||||
|  |  	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ | ||||||
|  | @@ -1983,7 +1983,7 @@ void
 | ||||||
|  |  usage(void) | ||||||
|  |  { | ||||||
|  |  	(void) fprintf(stderr, | ||||||
|  | -	    "usage: scp [-346ABCOpqRrsTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n"
 | ||||||
|  | +	    "usage: scp [-346ABCOpqRrTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n"
 | ||||||
|  |  	    "           [-i identity_file] [-J destination] [-l limit]\n" | ||||||
|  |  	    "           [-o ssh_option] [-P port] [-S program] source ... target\n"); | ||||||
|  |  	exit(1); | ||||||
							
								
								
									
										167
									
								
								SOURCES/openssh-8.7p1-sftpscp-dir-create.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								SOURCES/openssh-8.7p1-sftpscp-dir-create.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,167 @@ | |||||||
|  | diff -up openssh-8.7p1/scp.c.sftpdirs openssh-8.7p1/scp.c
 | ||||||
|  | --- openssh-8.7p1/scp.c.sftpdirs	2022-02-02 14:11:12.553447509 +0100
 | ||||||
|  | +++ openssh-8.7p1/scp.c	2022-02-02 14:12:56.081316414 +0100
 | ||||||
|  | @@ -130,6 +130,7 @@
 | ||||||
|  |  #include "misc.h" | ||||||
|  |  #include "progressmeter.h" | ||||||
|  |  #include "utf8.h" | ||||||
|  | +#include "sftp.h"
 | ||||||
|  |   | ||||||
|  |  #include "sftp-common.h" | ||||||
|  |  #include "sftp-client.h" | ||||||
|  | @@ -660,7 +661,7 @@ main(int argc, char **argv)
 | ||||||
|  |  	 * Finally check the exit status of the ssh process, if one was forked | ||||||
|  |  	 * and no error has occurred yet | ||||||
|  |  	 */ | ||||||
|  | -	if (do_cmd_pid != -1 && errs == 0) {
 | ||||||
|  | +	if (do_cmd_pid != -1 && (mode == MODE_SFTP || errs == 0)) {
 | ||||||
|  |  		if (remin != -1) | ||||||
|  |  		    (void) close(remin); | ||||||
|  |  		if (remout != -1) | ||||||
|  | @@ -1264,13 +1265,18 @@ tolocal(int argc, char **argv, enum scp_
 | ||||||
|  |  static char * | ||||||
|  |  prepare_remote_path(struct sftp_conn *conn, const char *path) | ||||||
|  |  { | ||||||
|  | +	size_t nslash;
 | ||||||
|  | +
 | ||||||
|  |  	/* Handle ~ prefixed paths */ | ||||||
|  | -	if (*path != '~')
 | ||||||
|  | -		return xstrdup(path);
 | ||||||
|  |  	if (*path == '\0' || strcmp(path, "~") == 0) | ||||||
|  |  		return xstrdup("."); | ||||||
|  | -	if (strncmp(path, "~/", 2) == 0)
 | ||||||
|  | -		return xstrdup(path + 2);
 | ||||||
|  | +	if (*path != '~')
 | ||||||
|  | +		return xstrdup(path);
 | ||||||
|  | +	if (strncmp(path, "~/", 2) == 0) {
 | ||||||
|  | +		if ((nslash = strspn(path + 2, "/")) == strlen(path + 2))
 | ||||||
|  | +			return xstrdup(".");
 | ||||||
|  | +		return xstrdup(path + 2 + nslash);
 | ||||||
|  | +	}
 | ||||||
|  |  	if (can_expand_path(conn)) | ||||||
|  |  		return do_expand_path(conn, path); | ||||||
|  |  	/* No protocol extension */ | ||||||
|  | @@ -1282,10 +1288,16 @@ void
 | ||||||
|  |  source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) | ||||||
|  |  { | ||||||
|  |  	char *target = NULL, *filename = NULL, *abs_dst = NULL; | ||||||
|  | -	int target_is_dir;
 | ||||||
|  | -
 | ||||||
|  | +	int src_is_dir, target_is_dir;
 | ||||||
|  | +	Attrib a;
 | ||||||
|  | +	struct stat st;
 | ||||||
|  | +
 | ||||||
|  | +	memset(&a, '\0', sizeof(a));
 | ||||||
|  | +	if (stat(src, &st) != 0)
 | ||||||
|  | +		fatal("stat local \"%s\": %s", src, strerror(errno));
 | ||||||
|  | +	src_is_dir = S_ISDIR(st.st_mode);
 | ||||||
|  |  	if ((filename = basename(src)) == NULL) | ||||||
|  | -		fatal("basename %s: %s", src, strerror(errno));
 | ||||||
|  | +		fatal("basename \"%s\": %s", src, strerror(errno));
 | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  |  	 * No need to glob here - the local shell already took care of | ||||||
|  | @@ -1295,8 +1307,12 @@ source_sftp(int argc, char *src, char *t
 | ||||||
|  |  		cleanup_exit(255); | ||||||
|  |  	target_is_dir = remote_is_dir(conn, target); | ||||||
|  |  	if (targetshouldbedirectory && !target_is_dir) { | ||||||
|  | -		fatal("Target is not a directory, but more files selected "
 | ||||||
|  | -		    "for upload");
 | ||||||
|  | +		debug("target directory \"%s\" does not exist", target);
 | ||||||
|  | +		a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS;
 | ||||||
|  | +		a.perm = st.st_mode | 0700; /* ensure writable */
 | ||||||
|  | +		if (do_mkdir(conn, target, &a, 1) != 0)
 | ||||||
|  | +			cleanup_exit(255); /* error already logged */
 | ||||||
|  | +		target_is_dir = 1;
 | ||||||
|  |  	} | ||||||
|  |  	if (target_is_dir) | ||||||
|  |  		abs_dst = path_append(target, filename); | ||||||
|  | @@ -1306,14 +1322,17 @@ source_sftp(int argc, char *src, char *t
 | ||||||
|  |  	} | ||||||
|  |  	debug3_f("copying local %s to remote %s", src, abs_dst); | ||||||
|  |   | ||||||
|  | -	if (local_is_dir(src) && iamrecursive) {
 | ||||||
|  | +	if (src_is_dir && iamrecursive) {
 | ||||||
|  |  		if (upload_dir(conn, src, abs_dst, pflag, | ||||||
|  |  		    SFTP_PROGRESS_ONLY, 0, 0, 1) != 0) { | ||||||
|  | -			fatal("failed to upload directory %s to %s",
 | ||||||
|  | +			error("failed to upload directory %s to %s",
 | ||||||
|  |  				src, abs_dst); | ||||||
|  | +			errs = 1;
 | ||||||
|  |  		} | ||||||
|  | -	} else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0)
 | ||||||
|  | -		fatal("failed to upload file %s to %s", src, abs_dst);
 | ||||||
|  | +	} else if (do_upload(conn, src, abs_dst, pflag, 0, 0) != 0) {
 | ||||||
|  | +		error("failed to upload file %s to %s", src, abs_dst);
 | ||||||
|  | +		errs = 1;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	free(abs_dst); | ||||||
|  |  	free(target); | ||||||
|  | @@ -1487,14 +1506,15 @@ sink_sftp(int argc, char *dst, const cha
 | ||||||
|  |  	char *abs_dst = NULL; | ||||||
|  |  	glob_t g; | ||||||
|  |  	char *filename, *tmp = NULL; | ||||||
|  | -	int i, r, err = 0;
 | ||||||
|  | +	int i, r, err = 0, dst_is_dir;
 | ||||||
|  | +	struct stat st;
 | ||||||
|  |   | ||||||
|  |  	memset(&g, 0, sizeof(g)); | ||||||
|  | +
 | ||||||
|  |  	/* | ||||||
|  |  	 * Here, we need remote glob as SFTP can not depend on remote shell | ||||||
|  |  	 * expansions | ||||||
|  |  	 */ | ||||||
|  | -
 | ||||||
|  |  	if ((abs_src = prepare_remote_path(conn, src)) == NULL) { | ||||||
|  |  		err = -1; | ||||||
|  |  		goto out; | ||||||
|  | @@ -1510,11 +1530,24 @@ sink_sftp(int argc, char *dst, const cha
 | ||||||
|  |  		goto out; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if (g.gl_matchc > 1 && !local_is_dir(dst)) {
 | ||||||
|  | -		error("Multiple files match pattern, but destination "
 | ||||||
|  | -		    "\"%s\" is not a directory", dst);
 | ||||||
|  | -		err = -1;
 | ||||||
|  | -		goto out;
 | ||||||
|  | +	if ((r = stat(dst, &st)) != 0)
 | ||||||
|  | +		debug2_f("stat local \"%s\": %s", dst, strerror(errno));
 | ||||||
|  | +	dst_is_dir = r == 0 && S_ISDIR(st.st_mode);
 | ||||||
|  | +
 | ||||||
|  | +	if (g.gl_matchc > 1 && !dst_is_dir) {
 | ||||||
|  | +		if (r == 0) {
 | ||||||
|  | +			error("Multiple files match pattern, but destination "
 | ||||||
|  | +			    "\"%s\" is not a directory", dst);
 | ||||||
|  | +			err = -1;
 | ||||||
|  | +			goto out;
 | ||||||
|  | +		}
 | ||||||
|  | +		debug2_f("creating destination \"%s\"", dst);
 | ||||||
|  | +		if (mkdir(dst, 0777) != 0) {
 | ||||||
|  | +			error("local mkdir \"%s\": %s", dst, strerror(errno));
 | ||||||
|  | +			err = -1;
 | ||||||
|  | +			goto out;
 | ||||||
|  | +		}
 | ||||||
|  | +		dst_is_dir = 1;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	for (i = 0; g.gl_pathv[i] && !interrupted; i++) { | ||||||
|  | @@ -1525,7 +1558,7 @@ sink_sftp(int argc, char *dst, const cha
 | ||||||
|  |  			goto out; | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  | -		if (local_is_dir(dst))
 | ||||||
|  | +		if (dst_is_dir)
 | ||||||
|  |  			abs_dst = path_append(dst, filename); | ||||||
|  |  		else | ||||||
|  |  			abs_dst = xstrdup(dst); | ||||||
|  | @@ -1551,7 +1584,8 @@ out:
 | ||||||
|  |  	free(tmp); | ||||||
|  |  	globfree(&g); | ||||||
|  |  	if (err == -1) { | ||||||
|  | -		fatal("Failed to download file '%s'", src);
 | ||||||
|  | +		error("Failed to download '%s'", src);
 | ||||||
|  | +		errs = 1;
 | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
							
								
								
									
										53
									
								
								SOURCES/openssh-8.7p1-ssh-manpage.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								SOURCES/openssh-8.7p1-ssh-manpage.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | |||||||
|  | diff --color -ru a/ssh.1 b/ssh.1
 | ||||||
|  | --- a/ssh.1	2022-07-12 11:47:51.307295880 +0200
 | ||||||
|  | +++ b/ssh.1	2022-07-12 11:50:28.793363263 +0200
 | ||||||
|  | @@ -493,6 +493,7 @@
 | ||||||
|  |  .It AddressFamily | ||||||
|  |  .It BatchMode | ||||||
|  |  .It BindAddress | ||||||
|  | +.It BindInterface
 | ||||||
|  |  .It CanonicalDomains | ||||||
|  |  .It CanonicalizeFallbackLocal | ||||||
|  |  .It CanonicalizeHostname | ||||||
|  | @@ -510,6 +511,7 @@
 | ||||||
|  |  .It ControlPath | ||||||
|  |  .It ControlPersist | ||||||
|  |  .It DynamicForward | ||||||
|  | +.It EnableSSHKeysign
 | ||||||
|  |  .It EscapeChar | ||||||
|  |  .It ExitOnForwardFailure | ||||||
|  |  .It FingerprintHash | ||||||
|  | @@ -538,6 +540,8 @@
 | ||||||
|  |  .It IdentitiesOnly | ||||||
|  |  .It IdentityAgent | ||||||
|  |  .It IdentityFile | ||||||
|  | +.It IgnoreUnknown
 | ||||||
|  | +.It Include
 | ||||||
|  |  .It IPQoS | ||||||
|  |  .It KbdInteractiveAuthentication | ||||||
|  |  .It KbdInteractiveDevices | ||||||
|  | @@ -546,6 +550,7 @@
 | ||||||
|  |  .It LocalCommand | ||||||
|  |  .It LocalForward | ||||||
|  |  .It LogLevel | ||||||
|  | +.It LogVerbose
 | ||||||
|  |  .It MACs | ||||||
|  |  .It Match | ||||||
|  |  .It NoHostAuthenticationForLocalhost | ||||||
|  | @@ -566,6 +571,8 @@
 | ||||||
|  |  .It RemoteCommand | ||||||
|  |  .It RemoteForward | ||||||
|  |  .It RequestTTY | ||||||
|  | +.It RevokedHostKeys
 | ||||||
|  | +.It SecurityKeyProvider
 | ||||||
|  |  .It RequiredRSASize | ||||||
|  |  .It SendEnv | ||||||
|  |  .It ServerAliveInterval | ||||||
|  | @@ -575,6 +582,7 @@
 | ||||||
|  |  .It StreamLocalBindMask | ||||||
|  |  .It StreamLocalBindUnlink | ||||||
|  |  .It StrictHostKeyChecking | ||||||
|  | +.It SyslogFacility
 | ||||||
|  |  .It TCPKeepAlive | ||||||
|  |  .It Tunnel | ||||||
|  |  .It TunnelDevice | ||||||
| @ -1,15 +1,15 @@ | |||||||
| diff --git a/auth.c b/auth.c
 | diff --git a/misc.c b/misc.c
 | ||||||
| index b8d1040d..0134d694 100644
 | index b8d1040d..0134d694 100644
 | ||||||
| --- a/auth.c
 | --- a/misc.c
 | ||||||
| +++ b/auth.c
 | +++ b/misc.c
 | ||||||
| @@ -56,6 +56,7 @@
 | @@ -56,6 +56,7 @@
 | ||||||
|  |  #ifdef HAVE_PATHS_H | ||||||
|  # include <paths.h> |  # include <paths.h> | ||||||
|  #endif |  | ||||||
|  #include <pwd.h> |  #include <pwd.h> | ||||||
| +#include <grp.h>
 | +#include <grp.h>
 | ||||||
|  #ifdef HAVE_LOGIN_H |  | ||||||
|  #include <login.h> |  | ||||||
|  #endif |  #endif | ||||||
|  |  #ifdef SSH_TUN_OPENBSD | ||||||
|  |  #include <net/if.h> | ||||||
| @@ -2695,6 +2696,12 @@ subprocess(const char *tag, const char *command,
 | @@ -2695,6 +2696,12 @@ subprocess(const char *tag, const char *command,
 | ||||||
|  		} |  		} | ||||||
|  		closefrom(STDERR_FILENO + 1); |  		closefrom(STDERR_FILENO + 1); | ||||||
| @ -20,6 +20,6 @@ index b8d1040d..0134d694 100644 | |||||||
| +			    pw->pw_name, (u_int)pw->pw_gid, strerror(errno));
 | +			    pw->pw_name, (u_int)pw->pw_gid, strerror(errno));
 | ||||||
| +			_exit(1);
 | +			_exit(1);
 | ||||||
| +		}
 | +		}
 | ||||||
| 		/* Don't use permanently_set_uid() here to avoid fatal() */ |  		if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) { | ||||||
|  		if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { |  | ||||||
|  			error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, |  			error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, | ||||||
|  |  			    strerror(errno)); | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								SOURCES/openssh-8.7p1.tar.gz.asc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								SOURCES/openssh-8.7p1.tar.gz.asc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | -----BEGIN PGP SIGNATURE----- | ||||||
|  | 
 | ||||||
|  | iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmEfKn8ACgkQKj9BTnNg | ||||||
|  | YLo2qQ/9EHkk64DFIOZz9xmKdogiVvuYue9LE1ex52rgLhxkeAmXQ0Ta2VjK0S81 | ||||||
|  | 9/oWJP5N+gcHLO01Og2bVuUPim/S1Op69a5hmFWaYvIlKCeCBONwE1O+n6IIhf+p | ||||||
|  | HUXkY9cFXOoSEHhQ1D+/f8axv7WtZ4ZtHlxejqcsjyyIDqG+i4kReiZJP0D06dUk | ||||||
|  | cv2U6YsQ9hTvXBTeUANCgLzH6DvEoyQyy7LOpaHsO1VKMlctslrVWdWRiAn7V934 | ||||||
|  | 8TuhZB0NoHAGZIgFFCINSfFAxnqxPyZtLdTxSF5EwPXqdnwFfGk4nprLZA1vT2yT | ||||||
|  | HeZiXhx919L+trDVmCycqcSCj8vOlNWl9A8VaodTW01SG75D7b1f5XqLGmSP4ujf | ||||||
|  | +9UnYKVm0OAU8jpbGXd1D2REuXRspRU6NPNW/3MkO2I46sG+KHhD6OMipOaiY8p2 | ||||||
|  | WrCsryadBThUqSKAo/zdIAJgVVt23Y7ykIIkhxebaRBIS4v6fdXg4aIjHfOjlsDX | ||||||
|  | Mh2JFEbP93bKC0wCJWcR7NXFR4nN2ddTen1jLC+m+ABMae0AoMCFy7VW4FK33ZAJ | ||||||
|  | +Plovu62bBUXeVhXhLC76vdQo7geRpBs0RQV0gtj6HlZL5BReEKwApPEVce8K9F5 | ||||||
|  | +ZYbmF5ZQNMcdR9zZ+QV+ykv6y4SG1+rPI9/Ufo/ZZp5jRnsq+M= | ||||||
|  | =xI/+ | ||||||
|  | -----END PGP SIGNATURE----- | ||||||
| @ -30,3 +30,28 @@ index d29a03b4..d7283136 100644 | |||||||
|  	if (*cp != '\n' && *cp != '\r') { |  	if (*cp != '\n' && *cp != '\r') { | ||||||
|  		error("%s: bad greeting", c->c_name); |  		error("%s: bad greeting", c->c_name); | ||||||
|  		confree(s); |  		confree(s); | ||||||
|  | diff --git a/sshsig.c b/sshsig.c
 | ||||||
|  | index 1e3b6398..eb2a931e 100644
 | ||||||
|  | --- a/sshsig.c
 | ||||||
|  | +++ b/sshsig.c
 | ||||||
|  | @@ -491,7 +491,7 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp)
 | ||||||
|  |  { | ||||||
|  |  	char *hex, rbuf[8192], hash[SSH_DIGEST_MAX_LENGTH]; | ||||||
|  |  	ssize_t n, total = 0; | ||||||
|  | -	struct ssh_digest_ctx *ctx;
 | ||||||
|  | +	struct ssh_digest_ctx *ctx = NULL;
 | ||||||
|  |  	int alg, oerrno, r = SSH_ERR_INTERNAL_ERROR; | ||||||
|  |  	struct sshbuf *b = NULL; | ||||||
|  |   | ||||||
|  | @@ -549,9 +548,11 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp)
 | ||||||
|  |  	/* success */ | ||||||
|  |  	r = 0; | ||||||
|  |   out: | ||||||
|  | +	oerrno = errno;
 | ||||||
|  |  	sshbuf_free(b); | ||||||
|  |  	ssh_digest_free(ctx); | ||||||
|  |  	explicit_bzero(hash, sizeof(hash)); | ||||||
|  | +	errno = oerrno;
 | ||||||
|  |  	return r; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | |||||||
							
								
								
									
										52
									
								
								SOURCES/openssh-9.3p1-openssl-compat.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								SOURCES/openssh-9.3p1-openssl-compat.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | --- openssh-9.3p1/openbsd-compat/openssl-compat.c	2023-03-15 22:28:19.000000000 +0100
 | ||||||
|  | +++ /home/dbelyavs/work/upstream/openssh-portable/openbsd-compat/openssl-compat.c	2023-05-25 14:19:42.870841944 +0200
 | ||||||
|  | @@ -33,10 +33,10 @@
 | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * OpenSSL version numbers: MNNFFPPS: major minor fix patch status | ||||||
|  | - * We match major, minor, fix and status (not patch) for <1.0.0.
 | ||||||
|  | - * After that, we acceptable compatible fix versions (so we
 | ||||||
|  | - * allow 1.0.1 to work with 1.0.0). Going backwards is only allowed
 | ||||||
|  | - * within a patch series.
 | ||||||
|  | + * Versions >=3 require only major versions to match.
 | ||||||
|  | + * For versions <3, we accept compatible fix versions (so we allow 1.0.1
 | ||||||
|  | + * to work with 1.0.0). Going backwards is only allowed within a patch series.
 | ||||||
|  | + * See https://www.openssl.org/policies/releasestrat.html
 | ||||||
|  |   */ | ||||||
|  |   | ||||||
|  |  int | ||||||
|  | @@ -48,15 +48,17 @@
 | ||||||
|  |  	if (headerver == libver) | ||||||
|  |  		return 1; | ||||||
|  |   | ||||||
|  | -	/* for versions < 1.0.0, major,minor,fix,status must match */
 | ||||||
|  | -	if (headerver < 0x1000000f) {
 | ||||||
|  | -		mask = 0xfffff00fL; /* major,minor,fix,status */
 | ||||||
|  | +	/*
 | ||||||
|  | +	 * For versions >= 3.0, only the major and status must match.
 | ||||||
|  | +	 */
 | ||||||
|  | +	if (headerver >= 0x3000000f) {
 | ||||||
|  | +		mask = 0xf000000fL; /* major,status */
 | ||||||
|  |  		return (headerver & mask) == (libver & mask); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  | -	 * For versions >= 1.0.0, major,minor,status must match and library
 | ||||||
|  | -	 * fix version must be equal to or newer than the header.
 | ||||||
|  | +	 * For versions >= 1.0.0, but <3, major,minor,status must match and
 | ||||||
|  | +	 * library fix version must be equal to or newer than the header.
 | ||||||
|  |  	 */ | ||||||
|  |  	mask = 0xfff0000fL; /* major,minor,status */ | ||||||
|  |  	hfix = (headerver & 0x000ff000) >> 12; | ||||||
|  | diff -up openssh-8.7p1/configure.ac.check openssh-8.7p1/configure.ac
 | ||||||
|  | --- openssh-8.7p1/configure.ac.check	2023-11-27 14:54:32.959113758 +0100
 | ||||||
|  | +++ openssh-8.7p1/configure.ac	2023-11-27 14:54:49.467500523 +0100
 | ||||||
|  | @@ -2821,7 +2821,7 @@ if test "x$openssl" = "xyes" ; then
 | ||||||
|  |  				;; | ||||||
|  |  			101*)   ;; # 1.1.x | ||||||
|  |  			200*)   ;; # LibreSSL | ||||||
|  | -			300*)   ;; # OpenSSL development branch.
 | ||||||
|  | +			30*)   ;; # OpenSSL 3.x series
 | ||||||
|  |  		        *) | ||||||
|  |  				AC_MSG_ERROR([Unknown/unsupported OpenSSL version ("$ssl_library_ver")]) | ||||||
|  |  		                ;; | ||||||
| @ -14,7 +14,7 @@ diff -u -p -r1.166 auth2.c | |||||||
|  	double elapsed = monotime_double() - start, req = seconds, remain; |  	double elapsed = monotime_double() - start, req = seconds, remain; | ||||||
|   |   | ||||||
| +	if (elapsed > MAX_FAIL_DELAY_SECONDS) {
 | +	if (elapsed > MAX_FAIL_DELAY_SECONDS) {
 | ||||||
| +		debug3("elapsed %0.3lfms exceeded the max delay "
 | +		debug3_f("elapsed %0.3lfms exceeded the max delay "
 | ||||||
| +		    "requested %0.3lfms)", elapsed*1000, req*1000);
 | +		    "requested %0.3lfms)", elapsed*1000, req*1000);
 | ||||||
| +		return;
 | +		return;
 | ||||||
| +	}
 | +	}
 | ||||||
|  | |||||||
| @ -98,7 +98,7 @@ index aa5e792d..d478ff6e 100644 | |||||||
| +		ssh_packet_disconnect(ssh, "strict KEX violation: "
 | +		ssh_packet_disconnect(ssh, "strict KEX violation: "
 | ||||||
| +		    "unexpected packet type %u (seqnr %u)", type, seq);
 | +		    "unexpected packet type %u (seqnr %u)", type, seq);
 | ||||||
| +	}
 | +	}
 | ||||||
| +	error("type %u seq %u", type, seq);
 | +	error_f("type %u seq %u", type, seq);
 | ||||||
|  	if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || |  	if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || | ||||||
|  	    (r = sshpkt_put_u32(ssh, seq)) != 0 || |  	    (r = sshpkt_put_u32(ssh, seq)) != 0 || | ||||||
|  	    (r = sshpkt_send(ssh)) != 0) |  	    (r = sshpkt_send(ssh)) != 0) | ||||||
| @ -115,9 +115,9 @@ index aa5e792d..d478ff6e 100644 | |||||||
|  		if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) |  		if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) | ||||||
|  			return r; |  			return r; | ||||||
| @@ -681,7 +705,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
 | @@ -681,7 +705,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
 | ||||||
|  	if (kex == NULL) |  		error_f("no kex"); | ||||||
|  		return SSH_ERR_INVALID_ARGUMENT; |  		return SSH_ERR_INTERNAL_ERROR; | ||||||
|   |  	} | ||||||
| -	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
 | -	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
 | ||||||
| +	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error);
 | +	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error);
 | ||||||
|  	ptr = sshpkt_ptr(ssh, &dlen); |  	ptr = sshpkt_ptr(ssh, &dlen); | ||||||
| @ -178,7 +178,7 @@ index aa5e792d..d478ff6e 100644 | |||||||
| +			    "kex-strict-s-v00@openssh.com");
 | +			    "kex-strict-s-v00@openssh.com");
 | ||||||
| +		}
 | +		}
 | ||||||
| +		if (kex->kex_strict) {
 | +		if (kex->kex_strict) {
 | ||||||
| +			debug3("will use strict KEX ordering");
 | +			debug3_f("will use strict KEX ordering");
 | ||||||
| +			if (seq != 0)
 | +			if (seq != 0)
 | ||||||
| +				ssh_packet_disconnect(ssh,
 | +				ssh_packet_disconnect(ssh,
 | ||||||
| +				    "strict KEX violation: "
 | +				    "strict KEX violation: "
 | ||||||
| @ -223,7 +223,7 @@ index 52017def..beb214f9 100644 | |||||||
|  	sshbuf_reset(state->outgoing_packet); |  	sshbuf_reset(state->outgoing_packet); | ||||||
|   |   | ||||||
| +	if (type == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
 | +	if (type == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
 | ||||||
| +		debug("resetting send seqnr %u", state->p_send.seqnr);
 | +		debug_f("resetting send seqnr %u", state->p_send.seqnr);
 | ||||||
| +		state->p_send.seqnr = 0;
 | +		state->p_send.seqnr = 0;
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
| @ -263,12 +263,12 @@ index 52017def..beb214f9 100644 | |||||||
|  	/* reset for next packet */ |  	/* reset for next packet */ | ||||||
|  	state->packlen = 0; |  	state->packlen = 0; | ||||||
| +	if (*typep == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
 | +	if (*typep == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
 | ||||||
| +		debug("resetting read seqnr %u", state->p_read.seqnr);
 | +		debug_f("resetting read seqnr %u", state->p_read.seqnr);
 | ||||||
| +		state->p_read.seqnr = 0;
 | +		state->p_read.seqnr = 0;
 | ||||||
| +	}
 | +	}
 | ||||||
|   |   | ||||||
|  	/* do we need to rekey? */ |  	if ((r = ssh_packet_check_rekey(ssh)) != 0) | ||||||
|  	if (ssh_packet_need_rekeying(ssh, 0)) { |  		return r; | ||||||
| @@ -1720,10 +1716,39 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
 | @@ -1720,10 +1716,39 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
 | ||||||
|  		r = ssh_packet_read_poll2(ssh, typep, seqnr_p); |  		r = ssh_packet_read_poll2(ssh, typep, seqnr_p); | ||||||
|  		if (r != 0) |  		if (r != 0) | ||||||
| @ -352,7 +352,7 @@ index 52017def..beb214f9 100644 | |||||||
|  	vsnprintf(buf, sizeof(buf), fmt, args); |  	vsnprintf(buf, sizeof(buf), fmt, args); | ||||||
|  	va_end(args); |  	va_end(args); | ||||||
|   |   | ||||||
| +	debug2("sending SSH2_MSG_DISCONNECT: %s", buf);
 | +	debug2_f("sending SSH2_MSG_DISCONNECT: %s", buf);
 | ||||||
|  	if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || |  	if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || | ||||||
|  	    (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || |  	    (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || | ||||||
|  	    (r = sshpkt_put_cstring(ssh, buf)) != 0 || |  	    (r = sshpkt_put_cstring(ssh, buf)) != 0 || | ||||||
| @ -361,14 +361,14 @@ index df6caf81..0cccbcc4 100644 | |||||||
| --- a/sshconnect2.c
 | --- a/sshconnect2.c
 | ||||||
| +++ b/sshconnect2.c
 | +++ b/sshconnect2.c
 | ||||||
| @@ -253,7 +253,8 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | @@ -253,7 +253,8 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | ||||||
|  	xxx_host = host; |  		fatal_fr(r, "kex_assemble_namelist"); | ||||||
|  	xxx_hostaddr = hostaddr; |  	free(all_key); | ||||||
|   |   | ||||||
| -	if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL)
 | -	if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL)
 | ||||||
| +	if ((s = kex_names_cat(options.kex_algorithms,
 | +	if ((s = kex_names_cat(options.kex_algorithms,
 | ||||||
| +	    "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL)
 | +	    "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL)
 | ||||||
|  		fatal("%s: kex_names_cat", __func__); |  		fatal_f("kex_names_cat"); | ||||||
|  	myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); |  	myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, s); | ||||||
|  	myproposal[PROPOSAL_ENC_ALGS_CTOS] = |  	myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||||||
| @@ -358,7 +358,6 @@ struct cauthmethod {
 | @@ -358,7 +358,6 @@ struct cauthmethod {
 | ||||||
|  }; |  }; | ||||||
| @ -412,22 +412,22 @@ diff -up openssh-8.7p1/sshd.c.kexstrict openssh-8.7p1/sshd.c | |||||||
| --- openssh-8.7p1/sshd.c.kexstrict	2023-11-27 13:19:18.855433602 +0100
 | --- openssh-8.7p1/sshd.c.kexstrict	2023-11-27 13:19:18.855433602 +0100
 | ||||||
| +++ openssh-8.7p1/sshd.c	2023-11-27 13:28:10.441325314 +0100
 | +++ openssh-8.7p1/sshd.c	2023-11-27 13:28:10.441325314 +0100
 | ||||||
| @@ -2531,10 +2531,14 @@ do_ssh2_kex(struct ssh *ssh)
 | @@ -2531,10 +2531,14 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||||
|  { |  | ||||||
|  	char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; |  | ||||||
|  	struct kex *kex; |  	struct kex *kex; | ||||||
|  |  	char *hostkey_types = NULL; | ||||||
|  |  	char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL; | ||||||
| +	char *cp;
 | +	char *cp;
 | ||||||
|  	int r; |  	int r; | ||||||
|   |   | ||||||
| -	myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(
 | -	myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh,
 | ||||||
| -	    options.kex_algorithms);
 | -	    options.kex_algorithms);
 | ||||||
| +	if ((cp = kex_names_cat(options.kex_algorithms, 
 | +	if ((cp = kex_names_cat(options.kex_algorithms, 
 | ||||||
| +	   "kex-strict-s-v00@openssh.com")) == NULL)
 | +	   "kex-strict-s-v00@openssh.com")) == NULL)
 | ||||||
| +		fatal("kex_names_cat");
 | +		fatal_f("kex_names_cat");
 | ||||||
| +
 | +
 | ||||||
| +	myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(cp);
 | +	myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh, cp);
 | ||||||
|  	myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal( |  	myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||||||
|  	    options.ciphers); |  	    myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc = | ||||||
|  	myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal( |  	    compat_cipher_proposal(ssh, options.ciphers); | ||||||
| @@ -2586,7 +2586,7 @@ do_ssh2_kex(struct ssh *ssh)
 | @@ -2586,7 +2586,7 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||||
|  	if (gss && orig) |  	if (gss && orig) | ||||||
|  		xasprintf(&newstr, "%s,%s", gss, orig); |  		xasprintf(&newstr, "%s,%s", gss, orig); | ||||||
| @ -438,10 +438,10 @@ diff -up openssh-8.7p1/sshd.c.kexstrict openssh-8.7p1/sshd.c | |||||||
|  		newstr = orig; |  		newstr = orig; | ||||||
|   |   | ||||||
| @@ -2650,6 +2654,7 @@ do_ssh2_kex(struct ssh *ssh)
 | @@ -2650,6 +2654,7 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||||
|  	packet_send(); |  | ||||||
|  	packet_write_wait(); |  | ||||||
|  #endif |  #endif | ||||||
|  |  	free(prop_kex); | ||||||
|  |  	free(prop_enc); | ||||||
| +	free(cp);
 | +	free(cp);
 | ||||||
|  |  	free(prop_hostkey); | ||||||
|  	debug("KEX done"); |  	debug("KEX done"); | ||||||
|  } |  } | ||||||
|   |  | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ index 35c48e62..48d93ddf 100644 | |||||||
| --- a/ssh.c
 | --- a/ssh.c
 | ||||||
| +++ b/ssh.c
 | +++ b/ssh.c
 | ||||||
| @@ -626,6 +626,41 @@ ssh_conn_info_free(struct ssh_conn_info *cinfo)
 | @@ -626,6 +626,41 @@ ssh_conn_info_free(struct ssh_conn_info *cinfo)
 | ||||||
|  	} |  	free(cinfo); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| +static int
 | +static int
 | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								SOURCES/openssh-server-systemd-sysusers.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								SOURCES/openssh-server-systemd-sysusers.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | #Type Name ID  GECOS                     Home directory        Shell | ||||||
|  | u     sshd 74  "Privilege-separated SSH" /usr/share/empty.sshd - | ||||||
							
								
								
									
										2
									
								
								SOURCES/openssh-systemd-sysusers.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								SOURCES/openssh-systemd-sysusers.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | #Type Name     ID | ||||||
|  | g     ssh_keys 101 | ||||||
| @ -9,7 +9,6 @@ buffer.c | |||||||
| cleanup.c | cleanup.c | ||||||
| cipher.h | cipher.h | ||||||
| compat.h | compat.h | ||||||
| defines.h |  | ||||||
| entropy.c | entropy.c | ||||||
| entropy.h | entropy.h | ||||||
| fatal.c | fatal.c | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c	2018-08-24 10:22:56.281930322 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/get_command_line.c	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -27,6 +27,7 @@
 | @@ -27,6 +27,7 @@
 | ||||||
|   * or implied, of Jamie Beverly. |   * or implied, of Jamie Beverly. | ||||||
|   */ |   */ | ||||||
| @ -9,7 +9,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat openss | |||||||
|  #include <stdio.h> |  #include <stdio.h> | ||||||
|  #include <errno.h> |  #include <errno.h> | ||||||
|  #include <string.h> |  #include <string.h> | ||||||
| @@ -65,8 +66,8 @@ proc_pid_cmdline(char *** inargv)
 | @@ -66,8 +67,8 @@ proc_pid_cmdline(char *** inargv)
 | ||||||
|                  case EOF: |                  case EOF: | ||||||
|                  case '\0': |                  case '\0': | ||||||
|                      if (len > 0) {  |                      if (len > 0) {  | ||||||
| @ -20,7 +20,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat openss | |||||||
|                          strncpy(argv[count++], argbuf, len); |                          strncpy(argv[count++], argbuf, len); | ||||||
|                          memset(argbuf, '\0', MAX_LEN_PER_CMDLINE_ARG + 1); |                          memset(argbuf, '\0', MAX_LEN_PER_CMDLINE_ARG + 1); | ||||||
|                          len = 0; |                          len = 0; | ||||||
| @@ -105,9 +106,9 @@ pamsshagentauth_free_command_line(char *
 | @@ -106,9 +107,9 @@ pamsshagentauth_free_command_line(char *
 | ||||||
|  { |  { | ||||||
|      size_t i; |      size_t i; | ||||||
|      for (i = 0; i < n_args; i++) |      for (i = 0; i < n_args; i++) | ||||||
| @ -32,9 +32,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/get_command_line.c.psaa-compat openss | |||||||
|      return; |      return; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/identity.h
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/identity.h	2018-08-24 10:18:05.009393312 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/identity.h	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -30,8 +30,8 @@
 | @@ -30,8 +30,8 @@
 | ||||||
|  #include "openbsd-compat/sys-queue.h" |  #include "openbsd-compat/sys-queue.h" | ||||||
|  #include "xmalloc.h" |  #include "xmalloc.h" | ||||||
| @ -55,9 +55,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-compat openssh/pam_ss | |||||||
|      char    *filename;      /* comment for agent-only keys */ |      char    *filename;      /* comment for agent-only keys */ | ||||||
|      int tried; |      int tried; | ||||||
|      int isprivate;      /* key points to the private key */ |      int isprivate;      /* key points to the private key */ | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat	2018-08-24 10:18:05.007393297 +0200
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c.psaa-compat	2020-09-23 10:52:16.421001434 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c	2018-08-24 10:18:32.937612513 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -36,8 +36,8 @@
 | @@ -36,8 +36,8 @@
 | ||||||
|  #include "openbsd-compat/sys-queue.h" |  #include "openbsd-compat/sys-queue.h" | ||||||
|  #include "xmalloc.h" |  #include "xmalloc.h" | ||||||
| @ -119,7 +119,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat | |||||||
|                                  const char * ruser, const char * servicename) |                                  const char * ruser, const char * servicename) | ||||||
|  { |  { | ||||||
|      u_char *cookie = NULL; |      u_char *cookie = NULL; | ||||||
| @@ -114,22 +116,23 @@ pamsshagentauth_session_id2_gen(Buffer *
 | @@ -114,22 +120,23 @@ pamsshagentauth_session_id2_gen(Buffer *
 | ||||||
|      char ** reported_argv = NULL; |      char ** reported_argv = NULL; | ||||||
|      size_t count = 0; |      size_t count = 0; | ||||||
|      char * action_logbuf = NULL; |      char * action_logbuf = NULL; | ||||||
| @ -147,13 +147,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat | |||||||
|          } |          } | ||||||
|          cookie[i] = (u_char) rnd; |          cookie[i] = (u_char) rnd; | ||||||
|          rnd >>= 8; |          rnd >>= 8; | ||||||
| @@ -139,12 +141,13 @@ pamsshagentauth_session_id2_gen(Buffer *
 | @@ -144,7 +151,8 @@ pamsshagentauth_session_id2_gen(Buffer *
 | ||||||
|      if (count > 0) {  |  | ||||||
|          free_logbuf = 1; |  | ||||||
|          action_logbuf = log_action(reported_argv, count); |  | ||||||
| -        agent_action(&action_agentbuf, reported_argv, count);
 |  | ||||||
| +        agent_action(&action_agentbuf, reported_argv, count);
 |  | ||||||
|          pamsshagentauth_free_command_line(reported_argv, count); |  | ||||||
|      } |      } | ||||||
|      else { |      else { | ||||||
|          action_logbuf = "unknown on this platform"; |          action_logbuf = "unknown on this platform"; | ||||||
| @ -163,7 +157,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat | |||||||
|      } |      } | ||||||
|       |       | ||||||
|      /* |      /* | ||||||
| @@ -161,35 +163,39 @@ pamsshagentauth_session_id2_gen(Buffer *
 | @@ -161,35 +169,39 @@ pamsshagentauth_session_id2_gen(Buffer *
 | ||||||
|      retc = getcwd(pwd, sizeof(pwd) - 1); |      retc = getcwd(pwd, sizeof(pwd) - 1); | ||||||
|      time(&ts); |      time(&ts); | ||||||
|   |   | ||||||
| @ -207,6 +201,14 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat | |||||||
| -        pamsshagentauth_buffer_free(&action_agentbuf);
 | -        pamsshagentauth_buffer_free(&action_agentbuf);
 | ||||||
| +        free(action_logbuf);
 | +        free(action_logbuf);
 | ||||||
| +        sshbuf_free(action_agentbuf);
 | +        sshbuf_free(action_agentbuf);
 | ||||||
|  | +    }
 | ||||||
|  | +    /* debug3("hostname: %s", hostname); */
 | ||||||
|  | +    if (reti >= 0) {
 | ||||||
|  | +        if ((r = sshbuf_put_cstring(*session_id2, hostname)) != 0)
 | ||||||
|  | +            fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||||
|  | +    } else {
 | ||||||
|  | +        if ((r = sshbuf_put_cstring(*session_id2, "")) != 0)
 | ||||||
|  | +            fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||||
|      } |      } | ||||||
| -    /* pamsshagentauth_debug3("hostname: %s", hostname); */
 | -    /* pamsshagentauth_debug3("hostname: %s", hostname); */
 | ||||||
| -    if(reti >= 0)
 | -    if(reti >= 0)
 | ||||||
| @ -215,21 +217,13 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat | |||||||
| -        pamsshagentauth_buffer_put_cstring(session_id2, "");
 | -        pamsshagentauth_buffer_put_cstring(session_id2, "");
 | ||||||
| -    /* pamsshagentauth_debug3("ts: %ld", ts); */
 | -    /* pamsshagentauth_debug3("ts: %ld", ts); */
 | ||||||
| -    pamsshagentauth_buffer_put_int64(session_id2, (uint64_t) ts);
 | -    pamsshagentauth_buffer_put_int64(session_id2, (uint64_t) ts);
 | ||||||
| +    /* debug3("hostname: %s", hostname); */
 |  | ||||||
| +    if (reti >= 0) {
 |  | ||||||
| +        if ((r = sshbuf_put_cstring(*session_id2, hostname)) != 0)
 |  | ||||||
| +            fatal("%s: buffer error: %s", __func__, ssh_err(r));
 |  | ||||||
| +    } else {
 |  | ||||||
| +        if ((r = sshbuf_put_cstring(*session_id2, "")) != 0)
 |  | ||||||
| +            fatal("%s: buffer error: %s", __func__, ssh_err(r));
 |  | ||||||
| +    }
 |  | ||||||
| +    /* debug3("ts: %ld", ts); */
 | +    /* debug3("ts: %ld", ts); */
 | ||||||
| +    if ((r = sshbuf_put_u64(*session_id2, (uint64_t) ts)) != 0)
 | +    if ((r = sshbuf_put_u64(*session_id2, (uint64_t) ts)) != 0)
 | ||||||
| +        fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | +        fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||||
|   |   | ||||||
|      free(cookie); |      free(cookie); | ||||||
|      return; |      return; | ||||||
| @@ -278,7 +280,8 @@ ssh_get_authentication_connection_for_ui
 | @@ -278,7 +290,8 @@ ssh_get_authentication_connection_for_ui
 | ||||||
|   |   | ||||||
|  	auth = xmalloc(sizeof(*auth)); |  	auth = xmalloc(sizeof(*auth)); | ||||||
|  	auth->fd = sock; |  	auth->fd = sock; | ||||||
| @ -239,7 +233,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat | |||||||
|  	auth->howmany = 0; |  	auth->howmany = 0; | ||||||
|   |   | ||||||
|  	return auth; |  	return auth; | ||||||
| @@ -287,43 +289,42 @@ ssh_get_authentication_connection_for_ui
 | @@ -287,9 +300,9 @@ ssh_get_authentication_connection_for_ui
 | ||||||
|  int |  int | ||||||
|  pamsshagentauth_find_authorized_keys(const char * user, const char * ruser, const char * servicename) |  pamsshagentauth_find_authorized_keys(const char * user, const char * ruser, const char * servicename) | ||||||
|  { |  { | ||||||
| @ -251,11 +245,8 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat | |||||||
|      AuthenticationConnection *ac; |      AuthenticationConnection *ac; | ||||||
|      char *comment; |      char *comment; | ||||||
|      uint8_t retval = 0; |      uint8_t retval = 0; | ||||||
|      uid_t uid = getpwnam(ruser)->pw_uid; | @@ -299,31 +312,30 @@ pamsshagentauth_find_authorized_keys(con
 | ||||||
|   |      pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename); | ||||||
|      OpenSSL_add_all_digests(); |  | ||||||
| -    pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename);
 |  | ||||||
| +    pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename);
 |  | ||||||
|   |   | ||||||
|      if ((ac = ssh_get_authentication_connection_for_uid(uid))) { |      if ((ac = ssh_get_authentication_connection_for_uid(uid))) { | ||||||
| -        pamsshagentauth_verbose("Contacted ssh-agent of user %s (%u)", ruser, uid);
 | -        pamsshagentauth_verbose("Contacted ssh-agent of user %s (%u)", ruser, uid);
 | ||||||
| @ -294,10 +285,10 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-compat | |||||||
|      EVP_cleanup(); |      EVP_cleanup(); | ||||||
|      return retval; |      return retval; | ||||||
|  } |  } | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat	2018-08-24 10:18:05.008393305 +0200
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c.psaa-compat	2020-09-23 10:52:16.423001461 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c	2018-08-24 10:18:05.009393312 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c	2020-09-23 10:53:10.631727657 +0200
 | ||||||
| @@ -104,7 +104,7 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | @@ -106,7 +106,7 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||||
|   * a patch 8-) |   * a patch 8-) | ||||||
|   */ |   */ | ||||||
|  #if ! HAVE___PROGNAME || HAVE_BUNDLE |  #if ! HAVE___PROGNAME || HAVE_BUNDLE | ||||||
| @ -306,7 +297,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open | |||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
|      for(i = argc, argv_ptr = (char **) argv; i > 0; ++argv_ptr, i--) { |      for(i = argc, argv_ptr = (char **) argv; i > 0; ++argv_ptr, i--) { | ||||||
| @@ -130,11 +130,11 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | @@ -132,11 +132,11 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||||
|  #endif |  #endif | ||||||
|      } |      } | ||||||
|   |   | ||||||
| @ -320,7 +311,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open | |||||||
|   |   | ||||||
|      if(ruser_ptr) { |      if(ruser_ptr) { | ||||||
|          strncpy(ruser, ruser_ptr, sizeof(ruser) - 1); |          strncpy(ruser, ruser_ptr, sizeof(ruser) - 1); | ||||||
| @@ -149,12 +149,12 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | @@ -151,12 +151,12 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||||
|  #ifdef ENABLE_SUDO_HACK |  #ifdef ENABLE_SUDO_HACK | ||||||
|          if( (strlen(sudo_service_name) > 0) && strncasecmp(servicename, sudo_service_name, sizeof(sudo_service_name) - 1) == 0 && getenv("SUDO_USER") ) { |          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 ); |              strncpy(ruser, getenv("SUDO_USER"), sizeof(ruser) - 1 ); | ||||||
| @ -335,7 +326,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open | |||||||
|                  goto cleanexit; |                  goto cleanexit; | ||||||
|              } |              } | ||||||
|              strncpy(ruser, getpwuid(getuid())->pw_name, sizeof(ruser) - 1); |              strncpy(ruser, getpwuid(getuid())->pw_name, sizeof(ruser) - 1); | ||||||
| @@ -163,11 +163,11 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | @@ -165,11 +165,11 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||||
|   |   | ||||||
|      /* Might as well explicitely confirm the user exists here */ |      /* Might as well explicitely confirm the user exists here */ | ||||||
|      if(! getpwnam(ruser) ) { |      if(! getpwnam(ruser) ) { | ||||||
| @ -349,7 +340,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open | |||||||
|          goto cleanexit; |          goto cleanexit; | ||||||
|      } |      } | ||||||
|   |   | ||||||
| @@ -177,8 +177,8 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | @@ -179,8 +179,8 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||||
|           */ |           */ | ||||||
|          parse_authorized_key_file(user, authorized_keys_file_input); |          parse_authorized_key_file(user, authorized_keys_file_input); | ||||||
|      } else { |      } else { | ||||||
| @ -360,7 +351,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open | |||||||
|      } |      } | ||||||
|   |   | ||||||
|      /* |      /* | ||||||
| @@ -187,19 +187,19 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | @@ -189,7 +189,7 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||||
|       */ |       */ | ||||||
|   |   | ||||||
|      if(user && strlen(ruser) > 0) { |      if(user && strlen(ruser) > 0) { | ||||||
| @ -368,11 +359,26 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open | |||||||
| +        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);
 | ||||||
|   |   | ||||||
|          /* |          /* | ||||||
|  |           * Attempt to read data from the sshd if we're being called as an auth agent. | ||||||
|  | @@ -197,10 +197,10 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||||
|  |          const char* ssh_user_auth = pam_getenv(pamh, "SSH_AUTH_INFO_0"); | ||||||
|  |          int sshd_service = strncasecmp(servicename, sshd_service_name, sizeof(sshd_service_name) - 1); | ||||||
|  |          if (sshd_service == 0 && ssh_user_auth != NULL) { | ||||||
|  | -            pamsshagentauth_verbose("Got SSH_AUTH_INFO_0: `%.20s...'", ssh_user_auth);
 | ||||||
|  | +            verbose("Got SSH_AUTH_INFO_0: `%.20s...'", ssh_user_auth);
 | ||||||
|  |              if (userauth_pubkey_from_pam(ruser, ssh_user_auth) > 0) { | ||||||
|  |                  retval = PAM_SUCCESS; | ||||||
|  | -                pamsshagentauth_logit("Authenticated (sshd): `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | ||||||
|  | +                logit("Authenticated (sshd): `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | ||||||
|  |                  goto cleanexit; | ||||||
|  |              } | ||||||
|  |          } | ||||||
|  | @@ -208,13 +208,13 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||||
|           * 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 |           * 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)) { */ |          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);
 | -            pamsshagentauth_logit("Authenticated (agent): `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | ||||||
| +            logit("Authenticated: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | +            logit("Authenticated (agent): `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | ||||||
|              retval = PAM_SUCCESS; |              retval = PAM_SUCCESS; | ||||||
|          } else { |          } else { | ||||||
| -            pamsshagentauth_logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | -            pamsshagentauth_logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | ||||||
| @ -384,9 +390,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c.psaa-compat open | |||||||
|      } |      } | ||||||
|   |   | ||||||
|  cleanexit: |  cleanexit: | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c	2018-08-24 10:18:05.009393312 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -66,8 +66,8 @@
 | @@ -66,8 +66,8 @@
 | ||||||
|  #include "xmalloc.h" |  #include "xmalloc.h" | ||||||
|  #include "match.h" |  #include "match.h" | ||||||
| @ -451,9 +457,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c.psaa-compa | |||||||
|  { |  { | ||||||
|      return |      return | ||||||
|          pamsshagentauth_user_key_allowed2(getpwuid(authorized_keys_file_allowed_owner_uid), |          pamsshagentauth_user_key_allowed2(getpwuid(authorized_keys_file_allowed_owner_uid), | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h	2018-08-24 10:18:05.010393320 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -32,7 +32,7 @@
 | @@ -32,7 +32,7 @@
 | ||||||
|  #define _PAM_USER_KEY_ALLOWED_H |  #define _PAM_USER_KEY_ALLOWED_H | ||||||
|   |   | ||||||
| @ -463,9 +469,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h.psaa-compa | |||||||
|  void parse_authorized_key_file(const char *, const char *); |  void parse_authorized_key_file(const char *, const char *); | ||||||
|   |   | ||||||
|  #endif |  #endif | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c	2018-08-24 10:18:05.010393320 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -45,44 +45,46 @@
 | @@ -45,44 +45,46 @@
 | ||||||
|  #include "xmalloc.h" |  #include "xmalloc.h" | ||||||
|  #include "ssh.h" |  #include "ssh.h" | ||||||
| @ -740,9 +746,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.c.psaa-compat o | |||||||
| +    restore_uid();
 | +    restore_uid();
 | ||||||
|      return found_key; |      return found_key; | ||||||
|  } |  } | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h	2018-08-24 10:18:05.010393320 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -32,7 +32,7 @@
 | @@ -32,7 +32,7 @@
 | ||||||
|  #define _PAM_USER_KEY_ALLOWED_H |  #define _PAM_USER_KEY_ALLOWED_H | ||||||
|   |   | ||||||
| @ -753,9 +759,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/pam_user_key_allowed2.h.psaa-compat o | |||||||
| +int pamsshagentauth_user_key_command_allowed2(char *, char *, struct passwd *, struct sshkey *);
 | +int pamsshagentauth_user_key_command_allowed2(char *, char *, struct passwd *, struct sshkey *);
 | ||||||
|   |   | ||||||
|  #endif |  #endif | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c	2018-08-24 10:18:05.010393320 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/secure_filename.c	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -53,8 +53,8 @@
 | @@ -53,8 +53,8 @@
 | ||||||
|  #include "xmalloc.h" |  #include "xmalloc.h" | ||||||
|  #include "match.h" |  #include "match.h" | ||||||
| @ -797,9 +803,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/secure_filename.c.psaa-compat openssh | |||||||
|  			    buf); |  			    buf); | ||||||
|  			break; |  			break; | ||||||
|  		} |  		} | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c	2018-08-24 10:22:13.202657025 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -37,10 +37,11 @@
 | @@ -37,10 +37,11 @@
 | ||||||
|  #include "xmalloc.h" |  #include "xmalloc.h" | ||||||
|  #include "ssh.h" |  #include "ssh.h" | ||||||
| @ -814,7 +820,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-compat | |||||||
|  #include "pathnames.h" |  #include "pathnames.h" | ||||||
|  #include "misc.h" |  #include "misc.h" | ||||||
|  #include "secure_filename.h" |  #include "secure_filename.h" | ||||||
| @@ -48,54 +48,59 @@
 | @@ -48,54 +49,59 @@
 | ||||||
|  #include "identity.h" |  #include "identity.h" | ||||||
|  #include "pam_user_authorized_keys.h" |  #include "pam_user_authorized_keys.h" | ||||||
|   |   | ||||||
| @ -833,8 +839,8 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-compat | |||||||
|      char           *pkalg = NULL; |      char           *pkalg = NULL; | ||||||
|      u_char         *pkblob = NULL, *sig = NULL; |      u_char         *pkblob = NULL, *sig = NULL; | ||||||
| -    u_int           blen = 0, slen = 0;
 | -    u_int           blen = 0, slen = 0;
 | ||||||
| +    size_t          blen = 0, slen = 0;
 |  | ||||||
| -    int             authenticated = 0;
 | -    int             authenticated = 0;
 | ||||||
|  | +    size_t          blen = 0, slen = 0;
 | ||||||
| +    int             r, authenticated = 0;
 | +    int             r, authenticated = 0;
 | ||||||
|   |   | ||||||
| -    pkalg = (char *) key_ssh_name(id->key);
 | -    pkalg = (char *) key_ssh_name(id->key);
 | ||||||
| @ -879,7 +885,7 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-compat | |||||||
|   |   | ||||||
|      /* test for correct signature */ |      /* test for correct signature */ | ||||||
| -    if(pamsshagentauth_key_verify(id->key, sig, slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) == 1)
 | -    if(pamsshagentauth_key_verify(id->key, sig, slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) == 1)
 | ||||||
| +    if (sshkey_verify(id->key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) == 0)
 | +    if (sshkey_verify(id->key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0, NULL) == 0)
 | ||||||
|          authenticated = 1; |          authenticated = 1; | ||||||
|   |   | ||||||
|    user_auth_clean_exit: |    user_auth_clean_exit: | ||||||
| @ -896,9 +902,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-compat | |||||||
|      CRYPTO_cleanup_all_ex_data(); |      CRYPTO_cleanup_all_ex_data(); | ||||||
|      return authenticated; |      return authenticated; | ||||||
|  } |  } | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h	2018-08-24 10:18:05.010393320 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -31,7 +31,7 @@
 | @@ -31,7 +31,7 @@
 | ||||||
|  #ifndef _USERAUTH_PUBKEY_FROM_ID_H |  #ifndef _USERAUTH_PUBKEY_FROM_ID_H | ||||||
|  #define _USERAUTH_PUBKEY_FROM_ID_H |  #define _USERAUTH_PUBKEY_FROM_ID_H | ||||||
| @ -909,9 +915,9 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h.psaa-compat | |||||||
| +int userauth_pubkey_from_id(const char *, Identity *, struct sshbuf *);
 | +int userauth_pubkey_from_id(const char *, Identity *, struct sshbuf *);
 | ||||||
|   |   | ||||||
|  #endif |  #endif | ||||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/uuencode.c.psaa-compat openssh/pam_ssh_agent_auth-0.10.3/uuencode.c
 | diff -up openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c.psaa-compat openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c
 | ||||||
| --- openssh/pam_ssh_agent_auth-0.10.3/uuencode.c.psaa-compat	2016-11-13 04:24:32.000000000 +0100
 | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c.psaa-compat	2019-07-08 18:36:13.000000000 +0200
 | ||||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/uuencode.c	2018-08-24 10:18:05.010393320 +0200
 | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/uuencode.c	2020-09-23 10:52:16.424001475 +0200
 | ||||||
| @@ -56,7 +56,7 @@ pamsshagentauth_uudecode(const char *src
 | @@ -56,7 +56,7 @@ pamsshagentauth_uudecode(const char *src
 | ||||||
|  	/* and remove trailing whitespace because __b64_pton needs this */ |  	/* and remove trailing whitespace because __b64_pton needs this */ | ||||||
|  	*p = '\0'; |  	*p = '\0'; | ||||||
| @ -937,3 +943,50 @@ diff -up openssh/pam_ssh_agent_auth-0.10.3/uuencode.c.psaa-compat openssh/pam_ss | |||||||
| -	pamsshagentauth_xfree(buf);
 | -	pamsshagentauth_xfree(buf);
 | ||||||
| +	free(buf);
 | +	free(buf);
 | ||||||
|  } |  } | ||||||
|  | --- openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_pam.c.compat	2020-09-23 11:32:30.783695267 +0200
 | ||||||
|  | +++ openssh/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_pam.c	2020-09-23 11:33:21.383389036 +0200
 | ||||||
|  | @@ -33,7 +33,8 @@
 | ||||||
|  |  #include <string.h> | ||||||
|  |   | ||||||
|  |  #include "defines.h" | ||||||
|  | -#include "key.h"
 | ||||||
|  | +#include <includes.h>
 | ||||||
|  | +#include "sshkey.h"
 | ||||||
|  |  #include "log.h" | ||||||
|  |   | ||||||
|  |  #include "pam_user_authorized_keys.h" | ||||||
|  | @@ -42,28 +42,28 @@
 | ||||||
|  |      int authenticated = 0; | ||||||
|  |      const char method[] = "publickey "; | ||||||
|  |   | ||||||
|  | -    char* ai = pamsshagentauth_xstrdup(ssh_auth_info);
 | ||||||
|  | +    char* ai = xstrdup(ssh_auth_info);
 | ||||||
|  |      char* saveptr; | ||||||
|  |   | ||||||
|  |      char* auth_line = strtok_r(ai, "\n", &saveptr); | ||||||
|  |      while (auth_line != NULL) { | ||||||
|  |          if (strncmp(auth_line, method, sizeof(method) - 1) == 0) { | ||||||
|  |              char* key_str = auth_line + sizeof(method) - 1; | ||||||
|  | -            Key* key = pamsshagentauth_key_new(KEY_UNSPEC);
 | ||||||
|  | +            struct sshkey* key = sshkey_new(KEY_UNSPEC);
 | ||||||
|  |              if (key == NULL) { | ||||||
|  |                  continue; | ||||||
|  |              } | ||||||
|  | -            int r = pamsshagentauth_key_read(key, &key_str);
 | ||||||
|  | +            int r = sshkey_read(key, &key_str);
 | ||||||
|  |              if (r == 1) { | ||||||
|  |                  if (pam_user_key_allowed(ruser, key)) { | ||||||
|  |                      authenticated = 1; | ||||||
|  | -                    pamsshagentauth_key_free(key);
 | ||||||
|  | +                    sshkey_free(key);
 | ||||||
|  |                      break; | ||||||
|  |                  } | ||||||
|  |              } else { | ||||||
|  | -                pamsshagentauth_verbose("Failed to create key for %s: %d", auth_line, r);
 | ||||||
|  | +                verbose("Failed to create key for %s: %d", auth_line, r);
 | ||||||
|  |              } | ||||||
|  | -            pamsshagentauth_key_free(key);
 | ||||||
|  | +            sshkey_free(key);
 | ||||||
|  |          } | ||||||
|  |          auth_line = strtok_r(NULL, "\n", &saveptr); | ||||||
|  |      } | ||||||
|  | |||||||
							
								
								
									
										19
									
								
								SOURCES/pam_ssh_agent_auth-0.10.4-rsasha2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								SOURCES/pam_ssh_agent_auth-0.10.4-rsasha2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | diff -up openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.rsasha2 openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c
 | ||||||
|  | --- openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c.rsasha2	2022-07-15 15:08:12.865585410 +0200
 | ||||||
|  | +++ openssh-8.7p1/pam_ssh_agent_auth-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c	2022-07-15 15:16:25.164282372 +0200
 | ||||||
|  | @@ -87,8 +87,13 @@ userauth_pubkey_from_id(const char *ruse
 | ||||||
|  |          (r = sshbuf_put_string(b, pkblob, blen)) != 0) | ||||||
|  |          fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||||
|  |   | ||||||
|  | -    if (ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) != 0)
 | ||||||
|  | -        goto user_auth_clean_exit;
 | ||||||
|  | +    if (sshkey_type_plain(id->key->type) == KEY_RSA
 | ||||||
|  | +	&& ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), "rsa-sha2-256", 0) == 0) {
 | ||||||
|  | +	/* Do nothing */
 | ||||||
|  | +    } else {
 | ||||||
|  | +        if (ssh_agent_sign(id->ac->fd, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0) != 0)
 | ||||||
|  | +            goto user_auth_clean_exit;
 | ||||||
|  | +    }
 | ||||||
|  |   | ||||||
|  |      /* test for correct signature */ | ||||||
|  |      if (sshkey_verify(id->key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0, NULL) == 0) | ||||||
| @ -159,21 +159,23 @@ diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in.psaa-build openssh- | |||||||
|  LIBS=@LIBS@ |  LIBS=@LIBS@ | ||||||
|  AR=@AR@ |  AR=@AR@ | ||||||
|  AWK=@AWK@ |  AWK=@AWK@ | ||||||
| @@ -61,7 +61,7 @@ INSTALL=@INSTALL@
 | @@ -61,8 +61,8 @@ INSTALL=@INSTALL@
 | ||||||
|  PERL=@PERL@ |  PERL=@PERL@ | ||||||
|  SED=@SED@ |  SED=@SED@ | ||||||
|  ENT=@ENT@ |  ENT=@ENT@ | ||||||
| -LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
 | -LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
 | ||||||
|  | -LDFLAGS_SHARED = @LDFLAGS_SHARED@
 | ||||||
| +LDFLAGS=-L.. -L../openbsd-compat/ @LDFLAGS@
 | +LDFLAGS=-L.. -L../openbsd-compat/ @LDFLAGS@
 | ||||||
|  LDFLAGS_SHARED = @LDFLAGS_SHARED@ | +LDFLAGS_SHARED =-Wl,-z,defs @LDFLAGS_SHARED@
 | ||||||
|  EXEEXT=@EXEEXT@ |  EXEEXT=@EXEEXT@ | ||||||
|   |   | ||||||
|  |  INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ | ||||||
| @@ -74,7 +74,7 @@ SSHOBJS=xmalloc.o atomicio.o authfd.o bu
 | @@ -74,7 +74,7 @@ SSHOBJS=xmalloc.o atomicio.o authfd.o bu
 | ||||||
|   |   | ||||||
|  ED25519OBJS=ed25519-donna/ed25519.o |  ED25519OBJS=ed25519-donna/ed25519.o | ||||||
|   |   | ||||||
| -PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o
 | -PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o userauth_pubkey_from_pam.o
 | ||||||
| +PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o secure_filename.o
 | +PAM_SSH_AGENT_AUTH_OBJS=pam_user_key_allowed2.o iterate_ssh_agent_keys.o userauth_pubkey_from_id.o pam_user_authorized_keys.o get_command_line.o userauth_pubkey_from_pam.o secure_filename.o
 | ||||||
|   |   | ||||||
|   |   | ||||||
|  MANPAGES_IN	= pam_ssh_agent_auth.pod |  MANPAGES_IN	= pam_ssh_agent_auth.pod | ||||||
| @ -189,8 +191,8 @@ diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in.psaa-build openssh- | |||||||
|   |   | ||||||
| -pam_ssh_agent_auth.so: $(LIBCOMPAT) $(SSHOBJS) $(ED25519OBJS) $(PAM_SSH_AGENT_AUTH_OBJS)  pam_ssh_agent_auth.o
 | -pam_ssh_agent_auth.so: $(LIBCOMPAT) $(SSHOBJS) $(ED25519OBJS) $(PAM_SSH_AGENT_AUTH_OBJS)  pam_ssh_agent_auth.o
 | ||||||
| -	$(LD) $(LDFLAGS_SHARED) -o $@ $(SSHOBJS) $(ED25519OBJS) $(PAM_SSH_AGENT_AUTH_OBJS) $(LDFLAGS) -lopenbsd-compat pam_ssh_agent_auth.o $(LIBS) -lpam
 | -	$(LD) $(LDFLAGS_SHARED) -o $@ $(SSHOBJS) $(ED25519OBJS) $(PAM_SSH_AGENT_AUTH_OBJS) $(LDFLAGS) -lopenbsd-compat pam_ssh_agent_auth.o $(LIBS) -lpam
 | ||||||
| +pam_ssh_agent_auth.so: $(PAM_SSH_AGENT_AUTH_OBJS)  pam_ssh_agent_auth.o ../uidswap.o
 | +pam_ssh_agent_auth.so: $(PAM_SSH_AGENT_AUTH_OBJS)  pam_ssh_agent_auth.o ../uidswap.o ../ssh-sk-client.o
 | ||||||
| +	$(LD) $(LDFLAGS_SHARED) -o $@ $(PAM_SSH_AGENT_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat pam_ssh_agent_auth.o ../uidswap.o $(LIBS) -lpam
 | +	$(LD) $(LDFLAGS_SHARED) -o $@ $(PAM_SSH_AGENT_AUTH_OBJS) ../ssh-sk-client.o $(LDFLAGS) -lssh -lopenbsd-compat pam_ssh_agent_auth.o ../uidswap.o $(LIBS) -lpam
 | ||||||
|   |   | ||||||
|  $(MANPAGES): $(MANPAGES_IN) |  $(MANPAGES): $(MANPAGES_IN) | ||||||
|  	pod2man --section=8 --release=v0.10.3 --name=pam_ssh_agent_auth --official --center "PAM" pam_ssh_agent_auth.pod > pam_ssh_agent_auth.8 |  	pod2man --section=8 --release=v0.10.3 --name=pam_ssh_agent_auth --official --center "PAM" pam_ssh_agent_auth.pod > pam_ssh_agent_auth.8 | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								SOURCES/ssh-agent.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								SOURCES/ssh-agent.service
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | # Requires SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket" | ||||||
|  | # set in environment, handled for example in plasma via | ||||||
|  | # /etc/xdg/plasma-workspace/env/ssh-agent.sh | ||||||
|  | [Unit] | ||||||
|  | ConditionEnvironment=!SSH_AGENT_PID | ||||||
|  | Description=OpenSSH key agent | ||||||
|  | Documentation=man:ssh-agent(1) man:ssh-add(1) man:ssh(1) | ||||||
|  | 
 | ||||||
|  | [Service] | ||||||
|  | Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket | ||||||
|  | ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK | ||||||
|  | PassEnvironment=SSH_AGENT_PID | ||||||
|  | SuccessExitStatus=2 | ||||||
|  | Type=forking | ||||||
| @ -6,9 +6,8 @@ Wants=sshd-keygen.target | |||||||
| 
 | 
 | ||||||
| [Service] | [Service] | ||||||
| Type=notify | Type=notify | ||||||
| EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config |  | ||||||
| EnvironmentFile=-/etc/sysconfig/sshd | EnvironmentFile=-/etc/sysconfig/sshd | ||||||
| ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY | ExecStart=/usr/sbin/sshd -D $OPTIONS | ||||||
| ExecReload=/bin/kill -HUP $MAINPID | ExecReload=/bin/kill -HUP $MAINPID | ||||||
| KillMode=process | KillMode=process | ||||||
| Restart=on-failure | Restart=on-failure | ||||||
|  | |||||||
| @ -5,13 +5,3 @@ | |||||||
| # example using  systemctl enable sshd-keygen@dsa.service  to allow creation | # example using  systemctl enable sshd-keygen@dsa.service  to allow creation | ||||||
| # of DSA key or  systemctl mask sshd-keygen@rsa.service  to disable RSA key | # of DSA key or  systemctl mask sshd-keygen@rsa.service  to disable RSA key | ||||||
| # creation. | # creation. | ||||||
| 
 |  | ||||||
| # Do not change this option unless you have hardware random |  | ||||||
| # generator and you REALLY know what you are doing |  | ||||||
| 
 |  | ||||||
| SSH_USE_STRONG_RNG=0 |  | ||||||
| # SSH_USE_STRONG_RNG=1 |  | ||||||
| 
 |  | ||||||
| # System-wide crypto policy: |  | ||||||
| # To opt-out, uncomment the following line |  | ||||||
| # CRYPTO_POLICY= |  | ||||||
|  | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user