forked from rpms/openssh
		
	import openssh-8.6p1-7.el9.1
This commit is contained in:
		
						commit
						ac08a66175
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| SOURCES/gpgkey-736060BA.gpg | ||||
| SOURCES/openssh-8.6p1.tar.gz | ||||
| SOURCES/pam_ssh_agent_auth-0.10.4.tar.gz | ||||
							
								
								
									
										3
									
								
								.openssh.metadata
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.openssh.metadata
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| dbb35b4e9ae3f72b930a82c6fd5e83e9dcd7b193 SOURCES/gpgkey-736060BA.gpg | ||||
| 8f9f0c94317baeb97747d6258f3997b4542762c0 SOURCES/openssh-8.6p1.tar.gz | ||||
| 66dd8274346fd006ff40f525c082cfb701085b5f SOURCES/pam_ssh_agent_auth-0.10.4.tar.gz | ||||
							
								
								
									
										18
									
								
								SOURCES/openssh-4.3p2-askpass-grab-info.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								SOURCES/openssh-4.3p2-askpass-grab-info.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| diff -up openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info openssh-8.6p1/contrib/gnome-ssh-askpass2.c
 | ||||
| --- openssh-8.6p1/contrib/gnome-ssh-askpass2.c.grab-info	2021-04-19 13:57:11.720113536 +0200
 | ||||
| +++ openssh-8.6p1/contrib/gnome-ssh-askpass2.c	2021-04-19 13:59:29.842163204 +0200
 | ||||
| @@ -70,8 +70,12 @@ report_failed_grab (GtkWidget *parent_wi
 | ||||
|   | ||||
|  	err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0, | ||||
|  	    GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, | ||||
| -	    "Could not grab %s. A malicious client may be eavesdropping "
 | ||||
| -	    "on your session.", what);
 | ||||
| +	    "SSH password dialog could not grab the %s input.\n"
 | ||||
| +	    "This might be caused by application such as screensaver, "
 | ||||
| +	    "however it could also mean that someone may be eavesdropping "
 | ||||
| +	    "on your session.\n"
 | ||||
| +	    "Either close the application which grabs the %s or "
 | ||||
| +	    "log out and log in again to prevent this from happening.", what, what);
 | ||||
|  	gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); | ||||
|   | ||||
|  	gtk_dialog_run(GTK_DIALOG(err)); | ||||
							
								
								
									
										83
									
								
								SOURCES/openssh-5.1p1-askpass-progress.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								SOURCES/openssh-5.1p1-askpass-progress.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,83 @@ | ||||
| diff -up openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress openssh-7.4p1/contrib/gnome-ssh-askpass2.c
 | ||||
| --- openssh-7.4p1/contrib/gnome-ssh-askpass2.c.progress	2016-12-19 05:59:41.000000000 +0100
 | ||||
| +++ openssh-7.4p1/contrib/gnome-ssh-askpass2.c	2016-12-23 13:31:16.545211926 +0100
 | ||||
| @@ -53,6 +53,7 @@
 | ||||
|  #include <unistd.h> | ||||
|   | ||||
|  #include <X11/Xlib.h> | ||||
| +#include <glib.h>
 | ||||
|  #include <gtk/gtk.h> | ||||
|  #include <gdk/gdkx.h> | ||||
|  #include <gdk/gdkkeysyms.h> | ||||
| @@ -81,14 +82,25 @@ ok_dialog(GtkWidget *entry, gpointer dia
 | ||||
|  	return 1; | ||||
|  } | ||||
|   | ||||
| +static void
 | ||||
| +move_progress(GtkWidget *entry, gpointer progress)
 | ||||
| +{
 | ||||
| +	gdouble step;
 | ||||
| +	g_return_if_fail(GTK_IS_PROGRESS_BAR(progress));
 | ||||
| +	
 | ||||
| +	step = g_random_double_range(0.03, 0.1);
 | ||||
| +	gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(progress), step);
 | ||||
| +	gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress));
 | ||||
| +}
 | ||||
| +
 | ||||
|  static int | ||||
|  passphrase_dialog(char *message, int prompt_type) | ||||
|  { | ||||
|  	const char *failed; | ||||
|  	char *passphrase, *local; | ||||
|  	int result, grab_tries, grab_server, grab_pointer; | ||||
|  	int buttons, default_response; | ||||
| -	GtkWidget *parent_window, *dialog, *entry;
 | ||||
| +	GtkWidget *parent_window, *dialog, *entry, *progress, *hbox;
 | ||||
|  	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); | ||||
|   | ||||
|  	if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) { | ||||
| +		hbox = gtk_hbox_new(FALSE, 0);
 | ||||
| +		gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
 | ||||
| +		    FALSE, 0);
 | ||||
| +		gtk_widget_show(hbox);
 | ||||
| +
 | ||||
| 		entry = gtk_entry_new(); | ||||
| 		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(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
 | ||||
| -		    entry, FALSE, FALSE, 0);
 | ||||
| +		    GTK_BOX(hbox), entry, TRUE, FALSE, 0);
 | ||||
| +		gtk_entry_set_width_chars(GTK_ENTRY(entry), 2);
 | ||||
|  		gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); | ||||
|  		gtk_widget_grab_focus(entry); | ||||
|  		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);
 | ||||
| +		gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
 | ||||
| +		    hbox, FALSE, FALSE, 8);
 | ||||
| +		gtk_widget_show(hbox);
 | ||||
| +
 | ||||
| +		progress = gtk_progress_bar_new();
 | ||||
| +
 | ||||
| +		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress),
 | ||||
| +		    "Passphrase length hidden intentionally");
 | ||||
| +		gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE,
 | ||||
| +		    TRUE, 5);
 | ||||
| +		gtk_widget_show(progress);
 | ||||
| +		g_signal_connect(G_OBJECT(entry), "changed",
 | ||||
| +				 G_CALLBACK(move_progress), progress);
 | ||||
| +
 | ||||
|  	} | ||||
|   | ||||
|  	/* Grab focus */ | ||||
							
								
								
									
										12
									
								
								SOURCES/openssh-5.8p2-sigpipe.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								SOURCES/openssh-5.8p2-sigpipe.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| diff -up openssh-5.8p2/ssh-keyscan.c.sigpipe openssh-5.8p2/ssh-keyscan.c
 | ||||
| --- openssh-5.8p2/ssh-keyscan.c.sigpipe	2011-08-23 18:30:33.873025916 +0200
 | ||||
| +++ openssh-5.8p2/ssh-keyscan.c	2011-08-23 18:32:24.574025362 +0200
 | ||||
| @@ -715,6 +715,8 @@ main(int argc, char **argv)
 | ||||
|  		fdlim_set(maxfd); | ||||
|  	fdcon = xcalloc(maxfd, sizeof(con)); | ||||
|   | ||||
| +	signal(SIGPIPE, SIG_IGN);
 | ||||
| +
 | ||||
|  	read_wait_nfdset = howmany(maxfd, NFDBITS); | ||||
|  	read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask)); | ||||
|   | ||||
							
								
								
									
										24
									
								
								SOURCES/openssh-5.9p1-ipv6man.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								SOURCES/openssh-5.9p1-ipv6man.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| diff -up openssh-5.9p0/ssh.1.ipv6man openssh-5.9p0/ssh.1
 | ||||
| --- openssh-5.9p0/ssh.1.ipv6man	2011-08-05 22:17:32.000000000 +0200
 | ||||
| +++ openssh-5.9p0/ssh.1	2011-08-31 13:08:34.880024485 +0200
 | ||||
| @@ -1400,6 +1400,8 @@ manual page for more information.
 | ||||
|  .Nm | ||||
|  exits with the exit status of the remote command or with 255 | ||||
|  if an error occurred. | ||||
| +.Sh IPV6
 | ||||
| +IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
 | ||||
|  .Sh SEE ALSO | ||||
|  .Xr scp 1 , | ||||
|  .Xr sftp 1 , | ||||
| diff -up openssh-5.9p0/sshd.8.ipv6man openssh-5.9p0/sshd.8
 | ||||
| --- openssh-5.9p0/sshd.8.ipv6man	2011-08-05 22:17:32.000000000 +0200
 | ||||
| +++ openssh-5.9p0/sshd.8	2011-08-31 13:10:34.129039094 +0200
 | ||||
| @@ -940,6 +940,8 @@ concurrently for different ports, this c
 | ||||
|  started last). | ||||
|  The content of this file is not sensitive; it can be world-readable. | ||||
|  .El | ||||
| +.Sh IPV6
 | ||||
| +IPv6 address can be used everywhere where IPv4 address. In all entries must be the IPv6 address enclosed in square brackets. Note: The square brackets are metacharacters for the shell and must be escaped in shell.
 | ||||
|  .Sh SEE ALSO | ||||
|  .Xr scp 1 , | ||||
|  .Xr sftp 1 , | ||||
							
								
								
									
										101
									
								
								SOURCES/openssh-6.3p1-ctr-evp-fast.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								SOURCES/openssh-6.3p1-ctr-evp-fast.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,101 @@ | ||||
| diff -up openssh-5.9p1/cipher-ctr.c.ctr-evp openssh-5.9p1/cipher-ctr.c
 | ||||
| --- openssh-5.9p1/cipher-ctr.c.ctr-evp	2012-01-11 09:24:06.000000000 +0100
 | ||||
| +++ openssh-5.9p1/cipher-ctr.c	2012-01-11 15:54:04.675956600 +0100
 | ||||
| @@ -38,7 +38,7 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, in
 | ||||
|   | ||||
|  struct ssh_aes_ctr_ctx | ||||
|  { | ||||
| -	AES_KEY		aes_ctx;
 | ||||
| +	EVP_CIPHER_CTX	ecbctx;
 | ||||
|  	u_char		aes_counter[AES_BLOCK_SIZE]; | ||||
|  }; | ||||
|   | ||||
| @@ -63,21 +63,42 @@ ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char
 | ||||
|  { | ||||
|  	struct ssh_aes_ctr_ctx *c; | ||||
|  	size_t n = 0; | ||||
| -	u_char buf[AES_BLOCK_SIZE];
 | ||||
| +	u_char ctrbuf[AES_BLOCK_SIZE*256];
 | ||||
| +	u_char buf[AES_BLOCK_SIZE*256];
 | ||||
|   | ||||
|  	if (len == 0) | ||||
|  		return (1); | ||||
|  	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) | ||||
|  		return (0); | ||||
|   | ||||
| -	while ((len--) > 0) {
 | ||||
| +	for (; len > 0; len -= sizeof(u_int)) {
 | ||||
| +		u_int r,a,b;
 | ||||
| +
 | ||||
|  		if (n == 0) { | ||||
| -			AES_encrypt(c->aes_counter, buf, &c->aes_ctx);
 | ||||
| -			ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
 | ||||
| +			int outl, i, buflen;
 | ||||
| +
 | ||||
| +			buflen = MIN(len, sizeof(ctrbuf));
 | ||||
| +
 | ||||
| +			for(i = 0; i < buflen; i += AES_BLOCK_SIZE) {
 | ||||
| +				memcpy(&ctrbuf[i], c->aes_counter, AES_BLOCK_SIZE);
 | ||||
| +				ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
 | ||||
| +			}
 | ||||
| +
 | ||||
| +			EVP_EncryptUpdate(&c->ecbctx, buf, &outl,
 | ||||
| +				ctrbuf, buflen);
 | ||||
|  		} | ||||
| -		*(dest++) = *(src++) ^ buf[n];
 | ||||
| -		n = (n + 1) % AES_BLOCK_SIZE;
 | ||||
| +
 | ||||
| +		memcpy(&a, src, sizeof(a));
 | ||||
| +		memcpy(&b, &buf[n], sizeof(b));
 | ||||
| +		r = a ^ b;
 | ||||
| +		memcpy(dest, &r, sizeof(r));
 | ||||
| +		src += sizeof(a);
 | ||||
| +		dest += sizeof(r);
 | ||||
| +
 | ||||
| +		n = (n + sizeof(b)) % sizeof(buf);
 | ||||
|  	} | ||||
| +	memset(ctrbuf, '\0', sizeof(ctrbuf));
 | ||||
| +	memset(buf, '\0', sizeof(buf));
 | ||||
|  	return (1); | ||||
|  } | ||||
|   | ||||
| @@ -91,9 +112,28 @@ ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, co
 | ||||
|  		c = xmalloc(sizeof(*c)); | ||||
|  		EVP_CIPHER_CTX_set_app_data(ctx, c); | ||||
|  	} | ||||
| -	if (key != NULL)
 | ||||
| -		AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
 | ||||
| -		    &c->aes_ctx);
 | ||||
| +
 | ||||
| +	EVP_CIPHER_CTX_init(&c->ecbctx);
 | ||||
| +
 | ||||
| +	if (key != NULL) {
 | ||||
| +		const EVP_CIPHER *cipher;
 | ||||
| +		switch(EVP_CIPHER_CTX_key_length(ctx)*8) {
 | ||||
| +			case 128:
 | ||||
| +				cipher = EVP_aes_128_ecb();
 | ||||
| +				break;
 | ||||
| +			case 192:
 | ||||
| +				cipher = EVP_aes_192_ecb();
 | ||||
| +				break;
 | ||||
| +			case 256:
 | ||||
| +				cipher = EVP_aes_256_ecb();
 | ||||
| +				break;
 | ||||
| +			default:
 | ||||
| +				fatal("ssh_aes_ctr_init: wrong aes key length");
 | ||||
| +		}
 | ||||
| +		if(!EVP_EncryptInit_ex(&c->ecbctx, cipher, NULL, key, NULL))
 | ||||
| +			fatal("ssh_aes_ctr_init: cannot initialize aes encryption");
 | ||||
| +		EVP_CIPHER_CTX_set_padding(&c->ecbctx, 0);
 | ||||
| +	}
 | ||||
|  	if (iv != NULL) | ||||
|  		memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); | ||||
|  	return (1); | ||||
| @@ -105,6 +145,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
 | ||||
|  	struct ssh_aes_ctr_ctx *c; | ||||
|   | ||||
|  	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { | ||||
| +		EVP_CIPHER_CTX_cleanup(&c->ecbctx);
 | ||||
|  		memset(c, 0, sizeof(*c)); | ||||
|  		free(c); | ||||
|  		EVP_CIPHER_CTX_set_app_data(ctx, NULL); | ||||
							
								
								
									
										16
									
								
								SOURCES/openssh-6.4p1-fromto-remote.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								SOURCES/openssh-6.4p1-fromto-remote.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| diff --git a/scp.c b/scp.c
 | ||||
| index d98fa67..25d347b 100644
 | ||||
| --- a/scp.c
 | ||||
| +++ b/scp.c
 | ||||
| @@ -638,7 +638,10 @@ toremote(char *targ, int argc, char **argv)
 | ||||
|  			addargs(&alist, "%s", ssh_program); | ||||
|  			addargs(&alist, "-x"); | ||||
|  			addargs(&alist, "-oClearAllForwardings=yes"); | ||||
| -			addargs(&alist, "-n");
 | ||||
| +			if (isatty(fileno(stdin)))
 | ||||
| +				addargs(&alist, "-t");
 | ||||
| +			else
 | ||||
| +				addargs(&alist, "-n");
 | ||||
|  			for (j = 0; j < remote_remote_args.num; j++) { | ||||
|  				addargs(&alist, "%s", | ||||
|  				    remote_remote_args.list[j]); | ||||
							
								
								
									
										263
									
								
								SOURCES/openssh-6.6.1p1-log-in-chroot.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								SOURCES/openssh-6.6.1p1-log-in-chroot.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,263 @@ | ||||
| diff -up openssh-8.6p1/log.c.log-in-chroot openssh-8.6p1/log.c
 | ||||
| --- openssh-8.6p1/log.c.log-in-chroot	2021-04-16 05:55:25.000000000 +0200
 | ||||
| +++ openssh-8.6p1/log.c	2021-05-06 11:32:25.179006811 +0200
 | ||||
| @@ -194,6 +194,11 @@ void
 | ||||
|  log_init(const char *av0, LogLevel level, SyslogFacility facility, | ||||
|      int on_stderr) | ||||
|  { | ||||
| +	log_init_handler(av0, level, facility, on_stderr, 1);
 | ||||
| +}
 | ||||
| +
 | ||||
| +void
 | ||||
| +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) | ||||
|  	struct syslog_data sdata = SYSLOG_DATA_INIT; | ||||
|  #endif | ||||
| @@ -206,8 +211,10 @@ log_init(const char *av0, LogLevel level
 | ||||
|  		exit(1); | ||||
|  	} | ||||
|   | ||||
| -	log_handler = NULL;
 | ||||
| -	log_handler_ctx = NULL;
 | ||||
| +	if (reset_handler) {
 | ||||
| +		log_handler = NULL;
 | ||||
| +		log_handler_ctx = NULL;
 | ||||
| +	}
 | ||||
|   | ||||
|  	log_on_stderr = on_stderr; | ||||
|  	if (on_stderr) | ||||
| diff -up openssh-8.6p1/log.h.log-in-chroot openssh-8.6p1/log.h
 | ||||
| --- openssh-8.6p1/log.h.log-in-chroot	2021-05-06 11:32:25.179006811 +0200
 | ||||
| +++ openssh-8.6p1/log.h	2021-05-06 11:34:22.349925757 +0200
 | ||||
| @@ -52,6 +52,7 @@ typedef enum {
 | ||||
|  typedef void (log_handler_fn)(LogLevel, int, const char *, void *); | ||||
|   | ||||
|  void     log_init(const char *, LogLevel, SyslogFacility, int); | ||||
| +void     log_init_handler(const char *, LogLevel, SyslogFacility, int, int);
 | ||||
|  LogLevel log_level_get(void); | ||||
|  int      log_change_level(LogLevel); | ||||
|  int      log_is_on_stderr(void); | ||||
| diff -up openssh-8.6p1/monitor.c.log-in-chroot openssh-8.6p1/monitor.c
 | ||||
| --- openssh-8.6p1/monitor.c.log-in-chroot	2021-05-06 11:32:25.153006607 +0200
 | ||||
| +++ openssh-8.6p1/monitor.c	2021-05-06 11:33:37.671575348 +0200
 | ||||
| @@ -297,6 +297,8 @@ monitor_child_preauth(struct ssh *ssh, s
 | ||||
|  		close(pmonitor->m_log_sendfd); | ||||
|  	pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; | ||||
|   | ||||
| +	pmonitor->m_state = "preauth";
 | ||||
| +
 | ||||
|  	authctxt = (Authctxt *)ssh->authctxt; | ||||
|  	memset(authctxt, 0, sizeof(*authctxt)); | ||||
|  	ssh->authctxt = authctxt; | ||||
| @@ -408,6 +410,8 @@ monitor_child_postauth(struct ssh *ssh,
 | ||||
|  	close(pmonitor->m_recvfd); | ||||
|  	pmonitor->m_recvfd = -1; | ||||
|   | ||||
| +	pmonitor->m_state = "postauth";
 | ||||
| +
 | ||||
|  	monitor_set_child_handler(pmonitor->m_pid); | ||||
|  	ssh_signal(SIGHUP, &monitor_child_handler); | ||||
|  	ssh_signal(SIGTERM, &monitor_child_handler); | ||||
| @@ -480,7 +484,7 @@ monitor_read_log(struct monitor *pmonito
 | ||||
|  	/* Log it */ | ||||
|  	if (log_level_name(level) == NULL) | ||||
|  		fatal_f("invalid log level %u (corrupted message?)", level); | ||||
| -	sshlogdirect(level, forced, "%s [preauth]", msg);
 | ||||
| +	sshlogdirect(level, forced, "%s [%s]", msg, pmonitor->m_state);
 | ||||
|   | ||||
|  	sshbuf_free(logmsg); | ||||
|  	free(msg); | ||||
| @@ -1868,13 +1872,28 @@ monitor_init(void)
 | ||||
|  	mon = xcalloc(1, sizeof(*mon)); | ||||
|  	monitor_openfds(mon, 1); | ||||
|   | ||||
| +	mon->m_state = "";
 | ||||
| +
 | ||||
|  	return mon; | ||||
|  } | ||||
|   | ||||
|  void | ||||
| -monitor_reinit(struct monitor *mon)
 | ||||
| +monitor_reinit(struct monitor *mon, const char *chroot_dir)
 | ||||
|  { | ||||
| -	monitor_openfds(mon, 0);
 | ||||
| +	struct stat dev_log_stat;
 | ||||
| +	char *dev_log_path;
 | ||||
| +	int do_logfds = 0;
 | ||||
| +
 | ||||
| +	if (chroot_dir != NULL) {
 | ||||
| +		xasprintf(&dev_log_path, "%s/dev/log", chroot_dir);
 | ||||
| +
 | ||||
| +		if (stat(dev_log_path, &dev_log_stat) != 0) {
 | ||||
| +			debug_f("/dev/log doesn't exist in %s chroot - will try to log via monitor using [postauth] suffix", chroot_dir);
 | ||||
| +			do_logfds = 1;
 | ||||
| +		}
 | ||||
| +		free(dev_log_path);
 | ||||
| +	}
 | ||||
| +	monitor_openfds(mon, do_logfds);
 | ||||
|  } | ||||
|   | ||||
|  #ifdef GSSAPI | ||||
| diff -up openssh-8.6p1/monitor.h.log-in-chroot openssh-8.6p1/monitor.h
 | ||||
| --- openssh-8.6p1/monitor.h.log-in-chroot	2021-05-06 11:32:25.153006607 +0200
 | ||||
| +++ openssh-8.6p1/monitor.h	2021-05-06 11:32:25.180006819 +0200
 | ||||
| @@ -80,10 +80,11 @@ struct monitor {
 | ||||
|  	int			 m_log_sendfd; | ||||
|  	struct kex		**m_pkex; | ||||
|  	pid_t			 m_pid; | ||||
| +	char		*m_state;
 | ||||
|  }; | ||||
|   | ||||
|  struct monitor *monitor_init(void); | ||||
| -void monitor_reinit(struct monitor *);
 | ||||
| +void monitor_reinit(struct monitor *, const char *);
 | ||||
|   | ||||
|  struct Authctxt; | ||||
|  void monitor_child_preauth(struct ssh *, struct monitor *); | ||||
| diff -up openssh-8.6p1/session.c.log-in-chroot openssh-8.6p1/session.c
 | ||||
| --- openssh-8.6p1/session.c.log-in-chroot	2021-05-06 11:32:25.166006709 +0200
 | ||||
| +++ openssh-8.6p1/session.c	2021-05-06 11:32:25.181006827 +0200
 | ||||
| @@ -160,6 +160,7 @@ login_cap_t *lc;
 | ||||
|   | ||||
|  static int is_child = 0; | ||||
|  static int in_chroot = 0; | ||||
| +static int have_dev_log = 1;
 | ||||
|   | ||||
|  /* File containing userauth info, if ExposeAuthInfo set */ | ||||
|  static char *auth_info_file = NULL; | ||||
| @@ -661,6 +662,7 @@ do_exec(struct ssh *ssh, Session *s, con
 | ||||
|  	int ret; | ||||
|  	const char *forced = NULL, *tty = NULL; | ||||
|  	char session_type[1024]; | ||||
| +	struct stat dev_log_stat;
 | ||||
|   | ||||
|  	if (options.adm_forced_command) { | ||||
|  		original_command = command; | ||||
| @@ -720,6 +722,10 @@ do_exec(struct ssh *ssh, Session *s, con
 | ||||
|  			tty += 5; | ||||
|  	} | ||||
|   | ||||
| +	if (lstat("/dev/log", &dev_log_stat) != 0) {
 | ||||
| +		have_dev_log = 0;
 | ||||
| +	}
 | ||||
| +
 | ||||
|  	verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", | ||||
|  	    session_type, | ||||
|  	    tty == NULL ? "" : " on ", | ||||
| @@ -1524,14 +1530,6 @@ child_close_fds(struct ssh *ssh)
 | ||||
|   | ||||
|  	/* Stop directing logs to a high-numbered fd before we close it */ | ||||
|  	log_redirect_stderr_to(NULL); | ||||
| -
 | ||||
| -	/*
 | ||||
| -	 * Close any extra open file descriptors so that we don't have them
 | ||||
| -	 * hanging around in clients.  Note that we want to do this after
 | ||||
| -	 * initgroups, because at least on Solaris 2.3 it leaves file
 | ||||
| -	 * descriptors open.
 | ||||
| -	 */
 | ||||
| -	closefrom(STDERR_FILENO + 1);
 | ||||
|  } | ||||
|   | ||||
|  /* | ||||
| @@ -1665,8 +1663,6 @@ do_child(struct ssh *ssh, Session *s, co
 | ||||
|  			exit(1); | ||||
|  	} | ||||
|   | ||||
| -	closefrom(STDERR_FILENO + 1);
 | ||||
| -
 | ||||
|  	do_rc_files(ssh, s, shell); | ||||
|   | ||||
|  	/* restore SIGPIPE for child */ | ||||
| @@ -1691,9 +1687,17 @@ do_child(struct ssh *ssh, Session *s, co
 | ||||
|  		argv[i] = NULL; | ||||
|  		optind = optreset = 1; | ||||
|  		__progname = argv[0]; | ||||
| -		exit(sftp_server_main(i, argv, s->pw));
 | ||||
| +		exit(sftp_server_main(i, argv, s->pw, have_dev_log));
 | ||||
|  	} | ||||
|   | ||||
| +	/*
 | ||||
| +	 * Close any extra open file descriptors so that we don't have them
 | ||||
| +	 * hanging around in clients.  Note that we want to do this after
 | ||||
| +	 * initgroups, because at least on Solaris 2.3 it leaves file
 | ||||
| +	 * descriptors open.
 | ||||
| +	 */
 | ||||
| +	closefrom(STDERR_FILENO + 1);
 | ||||
| +
 | ||||
|  	fflush(NULL); | ||||
|   | ||||
|  	/* Get the last component of the shell name. */ | ||||
| diff -up openssh-8.6p1/sftp.h.log-in-chroot openssh-8.6p1/sftp.h
 | ||||
| --- openssh-8.6p1/sftp.h.log-in-chroot	2021-04-16 05:55:25.000000000 +0200
 | ||||
| +++ openssh-8.6p1/sftp.h	2021-05-06 11:32:25.181006827 +0200
 | ||||
| @@ -97,5 +97,5 @@
 | ||||
|   | ||||
|  struct passwd; | ||||
|   | ||||
| -int	sftp_server_main(int, char **, struct passwd *);
 | ||||
| +int	sftp_server_main(int, char **, struct passwd *, int);
 | ||||
|  void	sftp_server_cleanup_exit(int) __attribute__((noreturn)); | ||||
| diff -up openssh-8.6p1/sftp-server.c.log-in-chroot openssh-8.6p1/sftp-server.c
 | ||||
| --- openssh-8.6p1/sftp-server.c.log-in-chroot	2021-04-16 05:55:25.000000000 +0200
 | ||||
| +++ openssh-8.6p1/sftp-server.c	2021-05-06 11:32:25.181006827 +0200
 | ||||
| @@ -1644,7 +1644,7 @@ sftp_server_usage(void)
 | ||||
|  } | ||||
|   | ||||
|  int | ||||
| -sftp_server_main(int argc, char **argv, struct passwd *user_pw)
 | ||||
| +sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler)
 | ||||
|  { | ||||
|  	fd_set *rset, *wset; | ||||
|  	int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; | ||||
| @@ -1657,7 +1657,7 @@ sftp_server_main(int argc, char **argv,
 | ||||
|  	extern char *__progname; | ||||
|   | ||||
|  	__progname = ssh_get_progname(argv[0]); | ||||
| -	log_init(__progname, log_level, log_facility, log_stderr);
 | ||||
| +	log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
 | ||||
|   | ||||
|  	pw = pwcopy(user_pw); | ||||
|   | ||||
| @@ -1730,7 +1730,7 @@ sftp_server_main(int argc, char **argv,
 | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| -	log_init(__progname, log_level, log_facility, log_stderr);
 | ||||
| +	log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
 | ||||
|   | ||||
|  	/* | ||||
|  	 * On platforms where we can, avoid making /proc/self/{mem,maps} | ||||
| diff -up openssh-8.6p1/sftp-server-main.c.log-in-chroot openssh-8.6p1/sftp-server-main.c
 | ||||
| --- openssh-8.6p1/sftp-server-main.c.log-in-chroot	2021-04-16 05:55:25.000000000 +0200
 | ||||
| +++ openssh-8.6p1/sftp-server-main.c	2021-05-06 11:32:25.181006827 +0200
 | ||||
| @@ -50,5 +50,5 @@ main(int argc, char **argv)
 | ||||
|  		return 1; | ||||
|  	} | ||||
|   | ||||
| -	return (sftp_server_main(argc, argv, user_pw));
 | ||||
| +	return (sftp_server_main(argc, argv, user_pw, 0));
 | ||||
|  } | ||||
| diff -up openssh-8.6p1/sshd.c.log-in-chroot openssh-8.6p1/sshd.c
 | ||||
| --- openssh-8.6p1/sshd.c.log-in-chroot	2021-05-06 11:32:25.177006795 +0200
 | ||||
| +++ openssh-8.6p1/sshd.c	2021-05-06 11:32:25.182006834 +0200
 | ||||
| @@ -559,7 +559,7 @@ privsep_postauth(struct ssh *ssh, Authct
 | ||||
|  	} | ||||
|   | ||||
|  	/* New socket pair */ | ||||
| -	monitor_reinit(pmonitor);
 | ||||
| +	monitor_reinit(pmonitor, options.chroot_directory);
 | ||||
|   | ||||
|  	pmonitor->m_pid = fork(); | ||||
|  	if (pmonitor->m_pid == -1) | ||||
| @@ -578,6 +578,11 @@ privsep_postauth(struct ssh *ssh, Authct
 | ||||
|   | ||||
|  	close(pmonitor->m_sendfd); | ||||
|  	pmonitor->m_sendfd = -1; | ||||
| +	close(pmonitor->m_log_recvfd);
 | ||||
| +	pmonitor->m_log_recvfd = -1;
 | ||||
| +
 | ||||
| +	if (pmonitor->m_log_sendfd != -1)
 | ||||
| +		set_log_handler(mm_log_handler, pmonitor);
 | ||||
|   | ||||
|  	/* Demote the private keys to public keys. */ | ||||
|  	demote_sensitive_data(); | ||||
							
								
								
									
										14
									
								
								SOURCES/openssh-6.6.1p1-scp-non-existing-directory.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								SOURCES/openssh-6.6.1p1-scp-non-existing-directory.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| --- a/scp.c	
 | ||||
| +++ a/scp.c	
 | ||||
| @@ -1084,6 +1084,10 @@ sink(int argc, char **argv)
 | ||||
|  			free(vect[0]); | ||||
|  			continue; | ||||
|  		} | ||||
| +		if (buf[0] == 'C' && ! exists && np[strlen(np)-1] == '/') {
 | ||||
| +			errno = ENOTDIR;
 | ||||
| +			goto bad;
 | ||||
| +		}
 | ||||
|  		omode = mode; | ||||
|  		mode |= S_IWUSR; | ||||
|  		if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) { | ||||
| -- 
 | ||||
							
								
								
									
										133
									
								
								SOURCES/openssh-6.6.1p1-selinux-contexts.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								SOURCES/openssh-6.6.1p1-selinux-contexts.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,133 @@ | ||||
| diff --git a/openbsd-compat/port-linux-sshd.c b/openbsd-compat/port-linux-sshd.c
 | ||||
| index 8f32464..18a2ca4 100644
 | ||||
| --- a/openbsd-compat/port-linux-sshd.c
 | ||||
| +++ b/openbsd-compat/port-linux-sshd.c
 | ||||
| @@ -32,6 +32,7 @@
 | ||||
|  #include "misc.h"      /* servconf.h needs misc.h for struct ForwardOptions */ | ||||
|  #include "servconf.h" | ||||
|  #include "port-linux.h" | ||||
| +#include "misc.h"
 | ||||
|  #include "sshkey.h" | ||||
|  #include "hostfile.h" | ||||
|  #include "auth.h" | ||||
| @@ -445,7 +446,7 @@ sshd_selinux_setup_exec_context(char *pwname)
 | ||||
|  void | ||||
|  sshd_selinux_copy_context(void) | ||||
|  { | ||||
| -	security_context_t *ctx;
 | ||||
| +	char *ctx;
 | ||||
|   | ||||
|  	if (!sshd_selinux_enabled()) | ||||
|  		return; | ||||
| @@ -461,6 +462,72 @@ sshd_selinux_copy_context(void)
 | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| +void
 | ||||
| +sshd_selinux_change_privsep_preauth_context(void)
 | ||||
| +{
 | ||||
| +	int len;
 | ||||
| +	char line[1024], *preauth_context = NULL, *cp, *arg;
 | ||||
| +	const char *contexts_path;
 | ||||
| +	FILE *contexts_file;
 | ||||
| +	struct stat sb;
 | ||||
| +
 | ||||
| +	contexts_path = selinux_openssh_contexts_path();
 | ||||
| +	if (contexts_path == NULL) {
 | ||||
| +		debug3_f("Failed to get the path to SELinux context");
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if ((contexts_file = fopen(contexts_path, "r")) == NULL) {
 | ||||
| +		debug_f("Failed to open SELinux context file");
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if (fstat(fileno(contexts_file), &sb) != 0 ||
 | ||||
| +	    sb.st_uid != 0 || (sb.st_mode & 022) != 0) {
 | ||||
| +		logit_f("SELinux context file needs to be owned by root"
 | ||||
| +		    " and not writable by anyone else");
 | ||||
| +		fclose(contexts_file);
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	while (fgets(line, sizeof(line), contexts_file)) {
 | ||||
| +		/* Strip trailing whitespace */
 | ||||
| +		for (len = strlen(line) - 1; len > 0; len--) {
 | ||||
| +			if (strchr(" \t\r\n", line[len]) == NULL)
 | ||||
| +				break;
 | ||||
| +			line[len] = '\0';
 | ||||
| +		}
 | ||||
| +
 | ||||
| +		if (line[0] == '\0')
 | ||||
| +			continue;
 | ||||
| +
 | ||||
| +		cp = line;
 | ||||
| +		arg = strdelim(&cp);
 | ||||
| +		if (arg && *arg == '\0')
 | ||||
| +			arg = strdelim(&cp);
 | ||||
| +
 | ||||
| +		if (arg && strcmp(arg, "privsep_preauth") == 0) {
 | ||||
| +			arg = strdelim(&cp);
 | ||||
| +			if (!arg || *arg == '\0') {
 | ||||
| +				debug_f("privsep_preauth is empty");
 | ||||
| +				fclose(contexts_file);
 | ||||
| +				return;
 | ||||
| +			}
 | ||||
| +			preauth_context = xstrdup(arg);
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +	fclose(contexts_file);
 | ||||
| +
 | ||||
| +	if (preauth_context == NULL) {
 | ||||
| +		debug_f("Unable to find 'privsep_preauth' option in"
 | ||||
| +		    " SELinux context file");
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	ssh_selinux_change_context(preauth_context);
 | ||||
| +	free(preauth_context);
 | ||||
| +}
 | ||||
| +
 | ||||
|  #endif | ||||
|  #endif | ||||
|   | ||||
| diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
 | ||||
| index 22ea8ef..1fc963d 100644
 | ||||
| --- a/openbsd-compat/port-linux.c
 | ||||
| +++ b/openbsd-compat/port-linux.c
 | ||||
| @@ -179,7 +179,7 @@ ssh_selinux_change_context(const char *newname)
 | ||||
|  	strlcpy(newctx + len, newname, newlen - len); | ||||
|  	if ((cx = index(cx + 1, ':'))) | ||||
|  		strlcat(newctx, cx, newlen); | ||||
| -	debug3("%s: setting context from '%s' to '%s'", __func__,
 | ||||
| +	debug_f("setting context from '%s' to '%s'",
 | ||||
|  	    oldctx, newctx); | ||||
|  	if (setcon(newctx) < 0) | ||||
|  		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
 | ||||
| index cb51f99..8b7cda2 100644
 | ||||
| --- a/openbsd-compat/port-linux.h
 | ||||
| +++ b/openbsd-compat/port-linux.h
 | ||||
| @@ -29,6 +29,7 @@ int sshd_selinux_enabled(void);
 | ||||
|  void sshd_selinux_copy_context(void); | ||||
|  void sshd_selinux_setup_exec_context(char *); | ||||
|  int sshd_selinux_setup_env_variables(void); | ||||
| +void sshd_selinux_change_privsep_preauth_context(void);
 | ||||
|  #endif | ||||
|   | ||||
|  #ifdef LINUX_OOM_ADJUST | ||||
| diff --git a/sshd.c b/sshd.c
 | ||||
| index 2871fe9..39b9c08 100644
 | ||||
| --- a/sshd.c
 | ||||
| +++ b/sshd.c
 | ||||
| @@ -629,7 +629,7 @@ privsep_preauth_child(void)
 | ||||
|  	demote_sensitive_data(); | ||||
|   | ||||
|  #ifdef WITH_SELINUX | ||||
| -	ssh_selinux_change_context("sshd_net_t");
 | ||||
| +	sshd_selinux_change_privsep_preauth_context();
 | ||||
|  #endif | ||||
|   | ||||
|  	/* Demote the child */ | ||||
							
								
								
									
										131
									
								
								SOURCES/openssh-6.6p1-GSSAPIEnablek5users.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								SOURCES/openssh-6.6p1-GSSAPIEnablek5users.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | ||||
| diff -up openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users openssh-7.4p1/gss-serv-krb5.c
 | ||||
| --- openssh-7.4p1/gss-serv-krb5.c.GSSAPIEnablek5users	2016-12-23 15:18:40.615216100 +0100
 | ||||
| +++ openssh-7.4p1/gss-serv-krb5.c	2016-12-23 15:18:40.628216102 +0100
 | ||||
| @@ -279,7 +279,6 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
 | ||||
|  	FILE *fp; | ||||
|  	char file[MAXPATHLEN]; | ||||
|  	char *line = NULL; | ||||
| -	char kuser[65]; /* match krb5_kuserok() */
 | ||||
|  	struct stat st; | ||||
|  	struct passwd *pw = the_authctxt->pw; | ||||
|  	int found_principal = 0; | ||||
| @@ -288,7 +287,7 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
 | ||||
|   | ||||
|  	snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); | ||||
|  	/* If both .k5login and .k5users DNE, self-login is ok. */ | ||||
| -	if (!k5login_exists && (access(file, F_OK) == -1)) {
 | ||||
| +	if ( !options.enable_k5users || (!k5login_exists && (access(file, F_OK) == -1))) {
 | ||||
|                  return ssh_krb5_kuserok(krb_context, principal, luser, | ||||
|                                          k5login_exists); | ||||
|  	} | ||||
| diff -up openssh-7.4p1/servconf.c.GSSAPIEnablek5users openssh-7.4p1/servconf.c
 | ||||
| --- openssh-7.4p1/servconf.c.GSSAPIEnablek5users	2016-12-23 15:18:40.615216100 +0100
 | ||||
| +++ openssh-7.4p1/servconf.c	2016-12-23 15:35:36.354401156 +0100
 | ||||
| @@ -168,6 +168,7 @@ initialize_server_options(ServerOptions
 | ||||
|  	options->gss_store_rekey = -1; | ||||
|  	options->gss_kex_algorithms = NULL; | ||||
|  	options->use_kuserok = -1; | ||||
| +	options->enable_k5users = -1;
 | ||||
|  	options->password_authentication = -1; | ||||
|  	options->kbd_interactive_authentication = -1; | ||||
|  	options->challenge_response_authentication = -1; | ||||
| @@ -345,6 +346,8 @@ fill_default_server_options(ServerOption
 | ||||
|  #endif | ||||
|  	if (options->use_kuserok == -1) | ||||
|  		options->use_kuserok = 1; | ||||
| +	if (options->enable_k5users == -1)
 | ||||
| +		options->enable_k5users = 0;
 | ||||
|  	if (options->password_authentication == -1) | ||||
|  		options->password_authentication = 1; | ||||
|  	if (options->kbd_interactive_authentication == -1) | ||||
| @@ -418,7 +421,7 @@ typedef enum {
 | ||||
|  	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms, | ||||
|  	sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, | ||||
|  	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, | ||||
| -	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
 | ||||
| +	sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
 | ||||
|  	sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, | ||||
|  	sAcceptEnv, sSetEnv, sPermitTunnel, | ||||
|  	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, | ||||
| @@ -497,14 +500,16 @@ static struct {
 | ||||
|  	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL }, | ||||
| +	{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
 | ||||
|  #else | ||||
|  	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL }, | ||||
|  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL }, | ||||
| +	{ "gssapienablek5users", sUnsupported, SSHCFG_ALL },
 | ||||
|  #endif | ||||
|  	{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL }, | ||||
| @@ -1653,6 +1658,10 @@ process_server_config_line(ServerOptions
 | ||||
|  		intptr = &options->use_kuserok; | ||||
|  		goto parse_flag; | ||||
|   | ||||
| +	case sGssEnablek5users:
 | ||||
| +		intptr = &options->enable_k5users;
 | ||||
| +		goto parse_flag;
 | ||||
| +
 | ||||
|  	case sPermitListen: | ||||
|  	case sPermitOpen: | ||||
|  		if (opcode == sPermitListen) { | ||||
| @@ -2026,6 +2035,7 @@ copy_set_server_options(ServerOptions *d
 | ||||
|  	M_CP_INTOPT(ip_qos_interactive); | ||||
|  	M_CP_INTOPT(ip_qos_bulk); | ||||
|  	M_CP_INTOPT(use_kuserok); | ||||
| +	M_CP_INTOPT(enable_k5users);
 | ||||
|  	M_CP_INTOPT(rekey_limit); | ||||
|  	M_CP_INTOPT(rekey_interval); | ||||
|  	M_CP_INTOPT(log_level); | ||||
| @@ -2320,6 +2330,7 @@ dump_config(ServerOptions *o)
 | ||||
|  # endif | ||||
|  	dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); | ||||
|  	dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); | ||||
| +	dump_cfg_fmtint(sGssEnablek5users, o->enable_k5users);
 | ||||
|  #endif | ||||
|  #ifdef GSSAPI | ||||
|  	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); | ||||
| diff -up openssh-7.4p1/servconf.h.GSSAPIEnablek5users openssh-7.4p1/servconf.h
 | ||||
| --- openssh-7.4p1/servconf.h.GSSAPIEnablek5users	2016-12-23 15:18:40.616216100 +0100
 | ||||
| +++ openssh-7.4p1/servconf.h	2016-12-23 15:18:40.629216102 +0100
 | ||||
| @@ -174,6 +174,7 @@ typedef struct {
 | ||||
| 	int     kerberos_unique_ccache;		/* If true, the acquired ticket will | ||||
| 						 * be stored in per-session ccache */ | ||||
|  	int	use_kuserok; | ||||
| +	int		enable_k5users;
 | ||||
|  	int     gss_authentication;	/* If true, permit GSSAPI authentication */ | ||||
|  	int     gss_keyex;		/* If true, permit GSSAPI key exchange */ | ||||
|  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */ | ||||
| diff -up openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users openssh-7.4p1/sshd_config.5
 | ||||
| --- openssh-7.4p1/sshd_config.5.GSSAPIEnablek5users	2016-12-23 15:18:40.630216103 +0100
 | ||||
| +++ openssh-7.4p1/sshd_config.5	2016-12-23 15:36:21.607408435 +0100
 | ||||
| @@ -628,6 +628,12 @@ Specifies whether to automatically destr
 | ||||
|  on logout. | ||||
|  The default is | ||||
|  .Cm yes . | ||||
| +.It Cm GSSAPIEnablek5users
 | ||||
| +Specifies whether to look at .k5users file for GSSAPI authentication
 | ||||
| +access control. Further details are described in
 | ||||
| +.Xr ksu 1 .
 | ||||
| +The default is
 | ||||
| +.Cm no .
 | ||||
|  .It Cm GSSAPIKeyExchange | ||||
|  Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange | ||||
|  doesn't rely on ssh keys to verify host identity. | ||||
| 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	2016-12-23 15:18:40.631216103 +0100
 | ||||
| @@ -80,6 +80,7 @@ GSSAPIAuthentication yes
 | ||||
|  #GSSAPICleanupCredentials yes | ||||
|  #GSSAPIStrictAcceptorCheck yes | ||||
|  #GSSAPIKeyExchange no | ||||
| +#GSSAPIEnablek5users no
 | ||||
|   | ||||
|  # Set this to 'yes' to enable PAM authentication, account processing, | ||||
|  # and session processing. If this is enabled, PAM authentication will | ||||
							
								
								
									
										39
									
								
								SOURCES/openssh-6.6p1-allow-ip-opts.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								SOURCES/openssh-6.6p1-allow-ip-opts.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| diff -up openssh/sshd.c.ip-opts openssh/sshd.c
 | ||||
| --- openssh/sshd.c.ip-opts	2016-07-25 13:58:48.998507834 +0200
 | ||||
| +++ openssh/sshd.c	2016-07-25 14:01:28.346469878 +0200
 | ||||
| @@ -1507,12 +1507,29 @@ check_ip_options(struct ssh *ssh)
 | ||||
|   | ||||
|  	if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, | ||||
|  	    &option_size) >= 0 && option_size != 0) { | ||||
| -		text[0] = '\0';
 | ||||
| -		for (i = 0; i < option_size; i++)
 | ||||
| -			snprintf(text + i*3, sizeof(text) - i*3,
 | ||||
| -			    " %2.2x", opts[i]);
 | ||||
| -		fatal("Connection from %.100s port %d with IP opts: %.800s",
 | ||||
| -		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text);
 | ||||
| +		i = 0;
 | ||||
| +		do {
 | ||||
| +			switch (opts[i]) {
 | ||||
| +				case 0:
 | ||||
| +				case 1:
 | ||||
| +					++i;
 | ||||
| +					break;
 | ||||
| +				case 130:
 | ||||
| +				case 133:
 | ||||
| +				case 134:
 | ||||
| +					i += opts[i + 1];
 | ||||
| +					break;
 | ||||
| +				default:
 | ||||
| +				/* Fail, fatally, if we detect either loose or strict
 | ||||
| +			 	 * source routing options. */
 | ||||
| +					text[0] = '\0';
 | ||||
| +					for (i = 0; i < option_size; i++)
 | ||||
| +						snprintf(text + i*3, sizeof(text) - i*3,
 | ||||
| +							" %2.2x", opts[i]);
 | ||||
| +					fatal("Connection from %.100s port %d with IP options:%.800s",
 | ||||
| +						ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text);
 | ||||
| +			}
 | ||||
| +		} while (i < option_size);
 | ||||
|  	} | ||||
|  	return; | ||||
|  #endif /* IP_OPTIONS */ | ||||
							
								
								
									
										280
									
								
								SOURCES/openssh-6.6p1-force_krb.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								SOURCES/openssh-6.6p1-force_krb.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,280 @@ | ||||
| diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
 | ||||
| index 413b845..54dd383 100644
 | ||||
| --- a/gss-serv-krb5.c
 | ||||
| +++ b/gss-serv-krb5.c
 | ||||
| @@ -32,7 +32,9 @@
 | ||||
|  #include <sys/types.h> | ||||
|   | ||||
|  #include <stdarg.h> | ||||
| +#include <stdio.h>
 | ||||
|  #include <string.h> | ||||
| +#include <unistd.h>
 | ||||
|   | ||||
|  #include "xmalloc.h" | ||||
|  #include "sshkey.h" | ||||
| @@ -45,6 +47,7 @@
 | ||||
|   | ||||
|  #include "ssh-gss.h" | ||||
|   | ||||
| +extern Authctxt *the_authctxt;
 | ||||
|  extern ServerOptions options; | ||||
|   | ||||
|  #ifdef HEIMDAL | ||||
| @@ -56,6 +59,13 @@ extern ServerOptions options;
 | ||||
|  # include <gssapi/gssapi_krb5.h> | ||||
|  #endif | ||||
|   | ||||
| +/* all commands are allowed by default */
 | ||||
| +char **k5users_allowed_cmds = NULL;
 | ||||
| +
 | ||||
| +static int ssh_gssapi_k5login_exists();
 | ||||
| +static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *,
 | ||||
| +    int);
 | ||||
| +
 | ||||
|  static krb5_context krb_context = NULL; | ||||
|   | ||||
|  /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ | ||||
| @@ -88,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
 | ||||
|  	krb5_principal princ; | ||||
|  	int retval; | ||||
|  	const char *errmsg; | ||||
| +	int k5login_exists;
 | ||||
|   | ||||
|  	if (ssh_gssapi_krb5_init() == 0) | ||||
|  		return 0; | ||||
| @@ -99,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
 | ||||
|  		krb5_free_error_message(krb_context, errmsg); | ||||
|  		return 0; | ||||
|  	} | ||||
| -	if (krb5_kuserok(krb_context, princ, name)) {
 | ||||
| +	/* krb5_kuserok() returns 1 if .k5login DNE and this is self-login.
 | ||||
| +	 * We have to make sure to check .k5users in that case. */
 | ||||
| +	k5login_exists = ssh_gssapi_k5login_exists();
 | ||||
| +	/* NOTE: .k5login and .k5users must opened as root, not the user,
 | ||||
| +	 * because if they are on a krb5-protected filesystem, user credentials
 | ||||
| +	 * to access these files aren't available yet. */
 | ||||
| +	if (krb5_kuserok(krb_context, princ, name) && k5login_exists) {
 | ||||
|  		retval = 1; | ||||
|  		logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", | ||||
|  		    name, (char *)client->displayname.value); | ||||
| +	} else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value,
 | ||||
| +		name, k5login_exists)) {
 | ||||
| +		retval = 1;
 | ||||
| +		logit("Authorized to %s, krb5 principal %s "
 | ||||
| +		    "(ssh_gssapi_krb5_cmdok)",
 | ||||
| +		    name, (char *)client->displayname.value);
 | ||||
|  	} else | ||||
|  		retval = 0; | ||||
|   | ||||
| @@ -110,6 +133,137 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
 | ||||
|  	return retval; | ||||
|  } | ||||
|   | ||||
| +/* Test for existence of .k5login.
 | ||||
| + * We need this as part of our .k5users check, because krb5_kuserok()
 | ||||
| + * returns success if .k5login DNE and user is logging in as himself.
 | ||||
| + * With .k5login absent and .k5users present, we don't want absence
 | ||||
| + * of .k5login to authorize self-login.  (absence of both is required)
 | ||||
| + * Returns 1 if .k5login is available, 0 otherwise.
 | ||||
| + */
 | ||||
| +static int
 | ||||
| +ssh_gssapi_k5login_exists()
 | ||||
| +{
 | ||||
| +	char file[MAXPATHLEN];
 | ||||
| +	struct passwd *pw = the_authctxt->pw;
 | ||||
| +
 | ||||
| +	snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
 | ||||
| +	return access(file, F_OK) == 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +/* check .k5users for login or command authorization
 | ||||
| + * Returns 1 if principal is authorized, 0 otherwise.
 | ||||
| + * If principal is authorized, (global) k5users_allowed_cmds may be populated.
 | ||||
| + */
 | ||||
| +static int
 | ||||
| +ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
 | ||||
| +    const char *luser, int k5login_exists)
 | ||||
| +{
 | ||||
| +	FILE *fp;
 | ||||
| +	char file[MAXPATHLEN];
 | ||||
| +	char *line = NULL;
 | ||||
| +	char kuser[65]; /* match krb5_kuserok() */
 | ||||
| +	struct stat st;
 | ||||
| +	struct passwd *pw = the_authctxt->pw;
 | ||||
| +	int found_principal = 0;
 | ||||
| +	int ncommands = 0, allcommands = 0;
 | ||||
| +	u_long linenum = 0;
 | ||||
| +	size_t linesize = 0;
 | ||||
| +
 | ||||
| +	snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
 | ||||
| +	/* If both .k5login and .k5users DNE, self-login is ok. */
 | ||||
| +	if (!k5login_exists && (access(file, F_OK) == -1)) {
 | ||||
| +		return (krb5_aname_to_localname(krb_context, principal,
 | ||||
| +		    sizeof(kuser), kuser) == 0) &&
 | ||||
| +		    (strcmp(kuser, luser) == 0);
 | ||||
| +	}
 | ||||
| +	if ((fp = fopen(file, "r")) == NULL) {
 | ||||
| +		int saved_errno = errno;
 | ||||
| +		/* 2nd access check to ease debugging if file perms are wrong.
 | ||||
| +		 * But we don't want to report this if .k5users simply DNE. */
 | ||||
| +		if (access(file, F_OK) == 0) {
 | ||||
| +			logit("User %s fopen %s failed: %s",
 | ||||
| +			    pw->pw_name, file, strerror(saved_errno));
 | ||||
| +		}
 | ||||
| +		return 0;
 | ||||
| +	}
 | ||||
| +	/* .k5users must be owned either by the user or by root */
 | ||||
| +	if (fstat(fileno(fp), &st) == -1) {
 | ||||
| +		/* can happen, but very wierd error so report it */
 | ||||
| +		logit("User %s fstat %s failed: %s",
 | ||||
| +		    pw->pw_name, file, strerror(errno));
 | ||||
| +		fclose(fp);
 | ||||
| +		return 0;
 | ||||
| +	}
 | ||||
| +	if (!(st.st_uid == pw->pw_uid || st.st_uid == 0)) {
 | ||||
| +		logit("User %s %s is not owned by root or user",
 | ||||
| +		    pw->pw_name, file);
 | ||||
| +		fclose(fp);
 | ||||
| +		return 0;
 | ||||
| +	}
 | ||||
| +	/* .k5users must be a regular file.  krb5_kuserok() doesn't do this
 | ||||
| +	  * check, but we don't want to be deficient if they add a check. */
 | ||||
| +	if (!S_ISREG(st.st_mode)) {
 | ||||
| +		logit("User %s %s is not a regular file", pw->pw_name, file);
 | ||||
| +		fclose(fp);
 | ||||
| +		return 0;
 | ||||
| +	}
 | ||||
| +	/* file exists; initialize k5users_allowed_cmds (to none!) */
 | ||||
| +	k5users_allowed_cmds = xcalloc(++ncommands,
 | ||||
| +	    sizeof(*k5users_allowed_cmds));
 | ||||
| +
 | ||||
| +	/* Check each line.  ksu allows unlimited length lines. */
 | ||||
| +	while (!allcommands && getline(&line, &linesize, fp) != -1) {
 | ||||
| +		linenum++;
 | ||||
| +		char *token;
 | ||||
| +
 | ||||
| +		/* we parse just like ksu, even though we could do better */
 | ||||
| +		if ((token = strtok(line, " \t\n")) == NULL)
 | ||||
| +			continue;
 | ||||
| +		if (strcmp(name, token) == 0) {
 | ||||
| +			/* we matched on client principal */
 | ||||
| +			found_principal = 1;
 | ||||
| +			if ((token = strtok(NULL, " \t\n")) == NULL) {
 | ||||
| +				/* only shell is allowed */
 | ||||
| +				k5users_allowed_cmds[ncommands-1] =
 | ||||
| +				    xstrdup(pw->pw_shell);
 | ||||
| +				k5users_allowed_cmds =
 | ||||
| +				    xreallocarray(k5users_allowed_cmds, ++ncommands,
 | ||||
| +					sizeof(*k5users_allowed_cmds));
 | ||||
| +				break;
 | ||||
| +			}
 | ||||
| +			/* process the allowed commands */
 | ||||
| +			while (token) {
 | ||||
| +				if (strcmp(token, "*") == 0) {
 | ||||
| +					allcommands = 1;
 | ||||
| +					break;
 | ||||
| +				}
 | ||||
| +				k5users_allowed_cmds[ncommands-1] =
 | ||||
| +				    xstrdup(token);
 | ||||
| +				k5users_allowed_cmds =
 | ||||
| +				    xreallocarray(k5users_allowed_cmds, ++ncommands,
 | ||||
| +					sizeof(*k5users_allowed_cmds));
 | ||||
| +				token = strtok(NULL, " \t\n");
 | ||||
| +			}
 | ||||
| +		}
 | ||||
| +       }
 | ||||
| +	free(line);
 | ||||
| +	if (k5users_allowed_cmds) {
 | ||||
| +		/* terminate vector */
 | ||||
| +		k5users_allowed_cmds[ncommands-1] = NULL;
 | ||||
| +		/* if all commands are allowed, free vector */
 | ||||
| +		if (allcommands) {
 | ||||
| +			int i;
 | ||||
| +			for (i = 0; i < ncommands; i++) {
 | ||||
| +				free(k5users_allowed_cmds[i]);
 | ||||
| +			}
 | ||||
| +			free(k5users_allowed_cmds);
 | ||||
| +			k5users_allowed_cmds = NULL;
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +	fclose(fp);
 | ||||
| +	return found_principal;
 | ||||
| +}
 | ||||
| + 
 | ||||
|   | ||||
|  /* This writes out any forwarded credentials from the structure populated | ||||
|   * during userauth. Called after we have setuid to the user */ | ||||
| diff --git a/session.c b/session.c
 | ||||
| index 28659ec..9c94d8e 100644
 | ||||
| --- a/session.c
 | ||||
| +++ b/session.c
 | ||||
| @@ -789,6 +789,29 @@ do_exec(Session *s, const char *command)
 | ||||
|  		command = auth_opts->force_command; | ||||
|  		forced = "(key-option)"; | ||||
|  	} | ||||
| +#ifdef GSSAPI
 | ||||
| +#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */
 | ||||
| +	else if (k5users_allowed_cmds) {
 | ||||
| +		const char *match = command;
 | ||||
| +		int allowed = 0, i = 0;
 | ||||
| +
 | ||||
| +		if (!match)
 | ||||
| +			match = s->pw->pw_shell;
 | ||||
| +		while (k5users_allowed_cmds[i]) {
 | ||||
| +			if (strcmp(match, k5users_allowed_cmds[i++]) == 0) {
 | ||||
| +				debug("Allowed command '%.900s'", match);
 | ||||
| +				allowed = 1;
 | ||||
| +				break;
 | ||||
| +			}
 | ||||
| +		}
 | ||||
| +		if (!allowed) {
 | ||||
| +			debug("command '%.900s' not allowed", match);
 | ||||
| +			return 1;
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +#endif
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  	s->forced = 0; | ||||
|  	if (forced != NULL) { | ||||
|  		s->forced = 1; | ||||
| diff --git a/ssh-gss.h b/ssh-gss.h
 | ||||
| index 0374c88..509109a 100644
 | ||||
| --- a/ssh-gss.h
 | ||||
| +++ b/ssh-gss.h
 | ||||
| @@ -49,6 +49,10 @@
 | ||||
|  #  endif /* !HAVE_DECL_GSS_C_NT_... */ | ||||
|   | ||||
|  # endif /* !HEIMDAL */ | ||||
| +
 | ||||
| +/* .k5users support */
 | ||||
| +extern char **k5users_allowed_cmds;
 | ||||
| +
 | ||||
|  #endif /* KRB5 */ | ||||
|   | ||||
|  /* draft-ietf-secsh-gsskeyex-06 */ | ||||
| diff --git a/sshd.8 b/sshd.8
 | ||||
| index adcaaf9..824163b 100644
 | ||||
| --- a/sshd.8
 | ||||
| +++ b/sshd.8
 | ||||
| @@ -324,6 +324,7 @@ Finally, the server and the client enter an authentication dialog.
 | ||||
|  The client tries to authenticate itself using | ||||
|  host-based authentication, | ||||
|  public key authentication, | ||||
| +GSSAPI authentication,
 | ||||
|  challenge-response authentication, | ||||
|  or password authentication. | ||||
|  .Pp | ||||
| @@ -800,6 +801,12 @@ This file is used in exactly the same way as
 | ||||
|  but allows host-based authentication without permitting login with | ||||
|  rlogin/rsh. | ||||
|  .Pp | ||||
| +.It Pa ~/.k5login
 | ||||
| +.It Pa ~/.k5users
 | ||||
| +These files enforce GSSAPI/Kerberos authentication access control.
 | ||||
| +Further details are described in
 | ||||
| +.Xr ksu 1 .
 | ||||
| +.Pp
 | ||||
|  .It Pa ~/.ssh/ | ||||
|  This directory is the default location for all user-specific configuration | ||||
|  and authentication information. | ||||
							
								
								
									
										484
									
								
								SOURCES/openssh-6.6p1-keycat.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										484
									
								
								SOURCES/openssh-6.6p1-keycat.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,484 @@ | ||||
| diff -up openssh/misc.c.keycat openssh/misc.c
 | ||||
| --- openssh/misc.c.keycat	2015-06-24 10:57:50.158849606 +0200
 | ||||
| +++ openssh/misc.c	2015-06-24 11:04:23.989868638 +0200
 | ||||
| @@ -966,6 +966,13 @@ subprocess(const char *tag, struct passw
 | ||||
|  			error("%s: dup2: %s", tag, strerror(errno)); | ||||
|  			_exit(1); | ||||
|  		} | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +		if (sshd_selinux_setup_env_variables() < 0) {
 | ||||
| +			error ("failed to copy environment:  %s",
 | ||||
| +			    strerror(errno));
 | ||||
| +			_exit(127);
 | ||||
| +		}
 | ||||
| +#endif
 | ||||
|  		if (env != NULL) | ||||
|  			execve(av[0], av, env); | ||||
|  		else | ||||
| 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	2015-06-24 10:57:50.157849608 +0200
 | ||||
| @@ -0,0 +1,12 @@
 | ||||
| +The ssh-keycat retrieves the content of the ~/.ssh/authorized_keys
 | ||||
| +of an user in any environment. This includes environments with
 | ||||
| +polyinstantiation of home directories and SELinux MLS policy enabled.
 | ||||
| +
 | ||||
| +To use ssh-keycat, set these options in /etc/ssh/sshd_config file:
 | ||||
| +        AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat
 | ||||
| +        AuthorizedKeysCommandUser root
 | ||||
| +
 | ||||
| +Do not forget to enable public key authentication:
 | ||||
| +        PubkeyAuthentication yes
 | ||||
| +
 | ||||
| +
 | ||||
| diff -up openssh/Makefile.in.keycat openssh/Makefile.in
 | ||||
| --- openssh/Makefile.in.keycat	2015-06-24 10:57:50.152849621 +0200
 | ||||
| +++ openssh/Makefile.in	2015-06-24 10:57:50.157849608 +0200
 | ||||
| @@ -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_KEYCAT=$(libexecdir)/ssh-keycat
 | ||||
|  SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper | ||||
|  SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper | ||||
|  PRIVSEP_PATH=@PRIVSEP_PATH@ | ||||
| @@ -52,6 +52,7 @@ K5LIBS=@K5LIBS@
 | ||||
|  K5LIBS=@K5LIBS@ | ||||
|  GSSLIBS=@GSSLIBS@ | ||||
|  SSHDLIBS=@SSHDLIBS@ | ||||
| +KEYCATLIBS=@KEYCATLIBS@
 | ||||
|  LIBEDIT=@LIBEDIT@ | ||||
|  LIBFIDO2=@LIBFIDO2@ | ||||
|  AR=@AR@ | ||||
| @@ -65,7 +66,7 @@ EXEEXT=@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-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=\ | ||||
|  	ssh-xmss.o \ | ||||
| @@ -190,6 +191,9 @@ ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT)
 | ||||
|  ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS) | ||||
|  	$(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
 | ||||
| +	$(LD) -o $@ ssh-keycat.o uidswap.o $(LDFLAGS) -lssh -lopenbsd-compat $(KEYCATLIBS) $(LIBS)
 | ||||
| +
 | ||||
|  ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS) | ||||
|  	$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) | ||||
|   | ||||
| @@ -321,6 +325,7 @@ install-files:
 | ||||
|  	$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) | ||||
|  	$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) | ||||
|  	$(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) 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/openbsd-compat/port-linux.h.keycat openssh/openbsd-compat/port-linux.h
 | ||||
| --- openssh/openbsd-compat/port-linux.h.keycat	2015-06-24 10:57:50.150849626 +0200
 | ||||
| +++ openssh/openbsd-compat/port-linux.h	2015-06-24 10:57:50.160849601 +0200
 | ||||
| @@ -25,8 +25,10 @@ void ssh_selinux_setup_pty(char *, const
 | ||||
|  void ssh_selinux_change_context(const char *); | ||||
|  void ssh_selinux_setfscreatecon(const char *); | ||||
|   | ||||
| +int sshd_selinux_enabled(void);
 | ||||
|  void sshd_selinux_copy_context(void); | ||||
|  void sshd_selinux_setup_exec_context(char *); | ||||
| +int sshd_selinux_setup_env_variables(void);
 | ||||
|  #endif | ||||
|   | ||||
|  #ifdef LINUX_OOM_ADJUST | ||||
| diff -up openssh/openbsd-compat/port-linux-sshd.c.keycat openssh/openbsd-compat/port-linux-sshd.c
 | ||||
| --- openssh/openbsd-compat/port-linux-sshd.c.keycat	2015-06-24 10:57:50.150849626 +0200
 | ||||
| +++ openssh/openbsd-compat/port-linux-sshd.c	2015-06-24 10:57:50.159849603 +0200
 | ||||
| @@ -54,6 +54,20 @@ extern Authctxt *the_authctxt;
 | ||||
|  extern int inetd_flag; | ||||
|  extern int rexeced_flag; | ||||
|   | ||||
| +/* Wrapper around is_selinux_enabled() to log its return value once only */
 | ||||
| +int
 | ||||
| +sshd_selinux_enabled(void)
 | ||||
| +{
 | ||||
| +	static int enabled = -1;
 | ||||
| +
 | ||||
| +	if (enabled == -1) {
 | ||||
| +		enabled = (is_selinux_enabled() == 1);
 | ||||
| +		debug("SELinux support %s", enabled ? "enabled" : "disabled");
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	return (enabled);
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* Send audit message */ | ||||
|  static int | ||||
|  sshd_selinux_send_audit_message(int success, security_context_t default_context, | ||||
| @@ -308,7 +322,7 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
|   | ||||
|  /* Setup environment variables for pam_selinux */ | ||||
|  static int | ||||
| -sshd_selinux_setup_pam_variables(void)
 | ||||
| +sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
 | ||||
|  { | ||||
|  	const char *reqlvl; | ||||
|  	char *role; | ||||
| @@ -319,16 +333,16 @@ sshd_selinux_setup_pam_variables(void)
 | ||||
|   | ||||
|  	ssh_selinux_get_role_level(&role, &reqlvl); | ||||
|   | ||||
| -	rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
 | ||||
| +	rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : "");
 | ||||
|   | ||||
|  	if (inetd_flag && !rexeced_flag) { | ||||
|  		use_current = "1"; | ||||
|  	} else { | ||||
|  		use_current = ""; | ||||
| -		rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
 | ||||
| +		rv = rv || set_it("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
 | ||||
|  	} | ||||
|   | ||||
| -	rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current);
 | ||||
| +	rv = rv || set_it("SELINUX_USE_CURRENT_RANGE", use_current);
 | ||||
|   | ||||
|  	if (role != NULL) | ||||
|  		free(role); | ||||
| @@ -336,6 +350,24 @@ sshd_selinux_setup_pam_variables(void)
 | ||||
|  	return rv; | ||||
|  } | ||||
|   | ||||
| +static int
 | ||||
| +sshd_selinux_setup_pam_variables(void)
 | ||||
| +{
 | ||||
| +	return sshd_selinux_setup_variables(do_pam_putenv);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_setenv(char *name, const char *value)
 | ||||
| +{
 | ||||
| +	return setenv(name, value, 1);
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
| +sshd_selinux_setup_env_variables(void)
 | ||||
| +{
 | ||||
| +	return sshd_selinux_setup_variables(do_setenv);
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* Set the execution context to the default for the specified user */ | ||||
|  void | ||||
|  sshd_selinux_setup_exec_context(char *pwname) | ||||
| @@ -344,7 +376,7 @@ sshd_selinux_setup_exec_context(char *pw
 | ||||
|  	int r = 0; | ||||
|  	security_context_t default_ctx = NULL; | ||||
|   | ||||
| -	if (!ssh_selinux_enabled())
 | ||||
| +	if (!sshd_selinux_enabled())
 | ||||
|  		return; | ||||
|   | ||||
|  	if (options.use_pam) { | ||||
| @@ -415,7 +447,7 @@ sshd_selinux_copy_context(void)
 | ||||
|  { | ||||
|  	security_context_t *ctx; | ||||
|   | ||||
| -	if (!ssh_selinux_enabled())
 | ||||
| +	if (!sshd_selinux_enabled())
 | ||||
|  		return; | ||||
|   | ||||
|  	if (getexeccon((security_context_t *)&ctx) != 0) { | ||||
| diff -up openssh/platform.c.keycat openssh/platform.c
 | ||||
| --- openssh/platform.c.keycat	2015-06-24 10:57:50.147849633 +0200
 | ||||
| +++ openssh/platform.c	2015-06-24 10:57:50.160849601 +0200
 | ||||
| @@ -103,7 +103,7 @@ platform_setusercontext(struct passwd *p
 | ||||
|  { | ||||
|  #ifdef WITH_SELINUX | ||||
|  	/* Cache selinux status for later use */ | ||||
| -	(void)ssh_selinux_enabled();
 | ||||
| +	(void)sshd_selinux_enabled();
 | ||||
|  #endif | ||||
|   | ||||
|  #ifdef USE_SOLARIS_PROJECTS | ||||
| diff -up openssh/ssh-keycat.c.keycat openssh/ssh-keycat.c
 | ||||
| --- openssh/ssh-keycat.c.keycat	2015-06-24 10:57:50.161849599 +0200
 | ||||
| +++ openssh/ssh-keycat.c	2015-06-24 10:57:50.161849599 +0200
 | ||||
| @@ -0,0 +1,241 @@
 | ||||
| +/*
 | ||||
| + * Redistribution and use in source and binary forms, with or without
 | ||||
| + * modification, are permitted provided that the following conditions
 | ||||
| + * are met:
 | ||||
| + * 1. Redistributions of source code must retain the above copyright
 | ||||
| + *    notice, and the entire permission notice in its entirety,
 | ||||
| + *    including the disclaimer of warranties.
 | ||||
| + * 2. Redistributions in binary form must reproduce the above copyright
 | ||||
| + *    notice, this list of conditions and the following disclaimer in the
 | ||||
| + *    documentation and/or other materials provided with the distribution.
 | ||||
| + * 3. The name of the author may not be used to endorse or promote
 | ||||
| + *    products derived from this software without specific prior
 | ||||
| + *    written permission.
 | ||||
| + *
 | ||||
| + * ALTERNATIVELY, this product may be distributed under the terms of
 | ||||
| + * the GNU Public License, in which case the provisions of the GPL are
 | ||||
| + * required INSTEAD OF the above restrictions.  (This clause is
 | ||||
| + * necessary due to a potential bad interaction between the GPL and
 | ||||
| + * the restrictions contained in a BSD-style copyright.)
 | ||||
| + *
 | ||||
| + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 | ||||
| + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | ||||
| + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | ||||
| + * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 | ||||
| + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | ||||
| + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | ||||
| + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | ||||
| + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | ||||
| + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | ||||
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 | ||||
| + * OF THE POSSIBILITY OF SUCH DAMAGE.
 | ||||
| + */
 | ||||
| +
 | ||||
| +/*
 | ||||
| + * Copyright (c) 2011 Red Hat, Inc.
 | ||||
| + * Written by Tomas Mraz <tmraz@redhat.com>
 | ||||
| +*/
 | ||||
| +
 | ||||
| +#define _GNU_SOURCE
 | ||||
| +
 | ||||
| +#include "config.h"
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <sys/types.h>
 | ||||
| +#include <sys/stat.h>
 | ||||
| +#include <pwd.h>
 | ||||
| +#include <fcntl.h>
 | ||||
| +#include <unistd.h>
 | ||||
| +#ifdef HAVE_STDINT_H
 | ||||
| +#include <stdint.h>
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#include <security/pam_appl.h>
 | ||||
| +
 | ||||
| +#include "uidswap.h"
 | ||||
| +#include "misc.h"
 | ||||
| +
 | ||||
| +#define ERR_USAGE 1
 | ||||
| +#define ERR_PAM_START 2
 | ||||
| +#define ERR_OPEN_SESSION 3
 | ||||
| +#define ERR_CLOSE_SESSION 4
 | ||||
| +#define ERR_PAM_END 5
 | ||||
| +#define ERR_GETPWNAM 6
 | ||||
| +#define ERR_MEMORY 7
 | ||||
| +#define ERR_OPEN 8
 | ||||
| +#define ERR_FILE_MODE 9
 | ||||
| +#define ERR_FDOPEN 10
 | ||||
| +#define ERR_STAT 11
 | ||||
| +#define ERR_WRITE 12
 | ||||
| +#define ERR_PAM_PUTENV 13
 | ||||
| +#define BUFLEN 4096
 | ||||
| +
 | ||||
| +/* Just ignore the messages in the conversation function */
 | ||||
| +static int
 | ||||
| +dummy_conv(int num_msg, const struct pam_message **msgm,
 | ||||
| +	   struct pam_response **response, void *appdata_ptr)
 | ||||
| +{
 | ||||
| +	struct pam_response *rsp;
 | ||||
| +
 | ||||
| +	(void)msgm;
 | ||||
| +	(void)appdata_ptr;
 | ||||
| +
 | ||||
| +	if (num_msg <= 0)
 | ||||
| +		return PAM_CONV_ERR;
 | ||||
| +
 | ||||
| +	/* Just allocate the array as empty responses */
 | ||||
| +	rsp = calloc (num_msg, sizeof (struct pam_response));
 | ||||
| +	if (rsp == NULL)
 | ||||
| +		return PAM_CONV_ERR;
 | ||||
| +
 | ||||
| +	*response = rsp;
 | ||||
| +	return PAM_SUCCESS;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static struct pam_conv conv = {
 | ||||
| +	dummy_conv,
 | ||||
| +	NULL
 | ||||
| +};
 | ||||
| +
 | ||||
| +char *
 | ||||
| +make_auth_keys_name(const struct passwd *pwd)
 | ||||
| +{
 | ||||
| +	char *fname;
 | ||||
| +
 | ||||
| +	if (asprintf(&fname, "%s/.ssh/authorized_keys", pwd->pw_dir) < 0)
 | ||||
| +		return NULL;
 | ||||
| +
 | ||||
| +	return fname;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
| +dump_keys(const char *user)
 | ||||
| +{
 | ||||
| +	struct passwd *pwd;
 | ||||
| +	int fd = -1;
 | ||||
| +	FILE *f = NULL;
 | ||||
| +	char *fname = NULL;
 | ||||
| +	int rv = 0;
 | ||||
| +	char buf[BUFLEN];
 | ||||
| +	size_t len;
 | ||||
| +	struct stat st;
 | ||||
| +
 | ||||
| +	if ((pwd = getpwnam(user)) == NULL) {
 | ||||
| +		return ERR_GETPWNAM;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if ((fname = make_auth_keys_name(pwd)) == NULL) {
 | ||||
| +		return ERR_MEMORY;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	temporarily_use_uid(pwd);
 | ||||
| +
 | ||||
| +	if ((fd = open(fname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) < 0) {
 | ||||
| +		rv = ERR_OPEN;
 | ||||
| +		goto fail;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if (fstat(fd, &st) < 0) {
 | ||||
| +		rv = ERR_STAT;
 | ||||
| +		goto fail;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if (!S_ISREG(st.st_mode) || 
 | ||||
| +		(st.st_uid != pwd->pw_uid && st.st_uid != 0)) {
 | ||||
| +		rv = ERR_FILE_MODE;
 | ||||
| +		goto fail;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	unset_nonblock(fd);
 | ||||
| +
 | ||||
| +	if ((f = fdopen(fd, "r")) == NULL) {
 | ||||
| +		rv = ERR_FDOPEN;
 | ||||
| +		goto fail;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	fd = -1;
 | ||||
| +
 | ||||
| +	while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
 | ||||
| +		rv = fwrite(buf, 1, len, stdout) != len ? ERR_WRITE : 0;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +fail:
 | ||||
| +	if (fd != -1)
 | ||||
| +		close(fd);
 | ||||
| +	if (f != NULL)
 | ||||
| +		fclose(f);
 | ||||
| +	free(fname);
 | ||||
| +	restore_uid();
 | ||||
| +	return rv;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static const char *env_names[] = { "SELINUX_ROLE_REQUESTED",
 | ||||
| +	"SELINUX_LEVEL_REQUESTED",
 | ||||
| +	"SELINUX_USE_CURRENT_RANGE"
 | ||||
| +};
 | ||||
| +
 | ||||
| +extern char **environ;
 | ||||
| +
 | ||||
| +int
 | ||||
| +set_pam_environment(pam_handle_t *pamh)
 | ||||
| +{
 | ||||
| +	int i;
 | ||||
| +	size_t j;
 | ||||
| +
 | ||||
| +	for (j = 0; j < sizeof(env_names)/sizeof(env_names[0]); ++j) {
 | ||||
| +		int len = strlen(env_names[j]);
 | ||||
| +
 | ||||
| +		for (i = 0; environ[i] != NULL; ++i) {
 | ||||
| +			if (strncmp(env_names[j], environ[i], len) == 0 &&
 | ||||
| +			    environ[i][len] == '=') {
 | ||||
| +				if (pam_putenv(pamh, environ[i]) != PAM_SUCCESS)
 | ||||
| +					return ERR_PAM_PUTENV;
 | ||||
| +			}
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
| +main(int argc, char *argv[])
 | ||||
| +{
 | ||||
| +	pam_handle_t *pamh = NULL;
 | ||||
| +	int retval;
 | ||||
| +	int ev = 0;
 | ||||
| +
 | ||||
| +	if (argc != 2) {
 | ||||
| +		fprintf(stderr, "Usage: %s <user-name>\n", argv[0]);
 | ||||
| +		return ERR_USAGE;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	retval = pam_start("ssh-keycat", argv[1], &conv, &pamh);
 | ||||
| +	if (retval != PAM_SUCCESS) {
 | ||||
| +		return ERR_PAM_START;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	ev = set_pam_environment(pamh);
 | ||||
| +	if (ev != 0)
 | ||||
| +		goto finish;
 | ||||
| +
 | ||||
| +	retval = pam_open_session(pamh, PAM_SILENT);
 | ||||
| +	if (retval != PAM_SUCCESS) {
 | ||||
| +		ev = ERR_OPEN_SESSION;
 | ||||
| +		goto finish;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	ev = dump_keys(argv[1]);
 | ||||
| +
 | ||||
| +	retval = pam_close_session(pamh, PAM_SILENT);
 | ||||
| +	if (retval != PAM_SUCCESS) {
 | ||||
| +		ev = ERR_CLOSE_SESSION;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +finish:
 | ||||
| +	retval = pam_end (pamh,retval);
 | ||||
| +	if (retval != PAM_SUCCESS) {
 | ||||
| +		ev = ERR_PAM_END;
 | ||||
| +	}
 | ||||
| +	return ev;
 | ||||
| +}
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 3bbccfd..6481f1f 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -2952,6 +2952,7 @@ AC_ARG_WITH([pam],
 | ||||
|  			PAM_MSG="yes" | ||||
|   | ||||
|  			SSHDLIBS="$SSHDLIBS -lpam" | ||||
| +			KEYCATLIBS="$KEYCATLIBS -lpam"
 | ||||
|  			AC_DEFINE([USE_PAM], [1], | ||||
|  				[Define if you want to enable PAM support]) | ||||
|   | ||||
| @@ -3105,6 +3106,7 @@
 | ||||
|  					;; | ||||
|  				*) | ||||
|  					SSHDLIBS="$SSHDLIBS -ldl" | ||||
| +					KEYCATLIBS="$KEYCATLIBS -ldl"
 | ||||
|  					;; | ||||
|  				esac | ||||
|  			fi | ||||
| @@ -4042,6 +4044,7 @@ AC_ARG_WITH([selinux],
 | ||||
|  	fi ] | ||||
|  ) | ||||
|  AC_SUBST([SSHDLIBS]) | ||||
| +AC_SUBST([KEYCATLIBS])
 | ||||
|   | ||||
|  # Check whether user wants Kerberos 5 support | ||||
|  KRB5_MSG="no" | ||||
| @@ -5031,6 +5034,9 @@ fi
 | ||||
|  if test ! -z "${SSHDLIBS}"; then | ||||
|  echo "         +for sshd: ${SSHDLIBS}" | ||||
|  fi | ||||
| +if test ! -z "${KEYCATLIBS}"; then
 | ||||
| +echo "   +for ssh-keycat: ${KEYCATLIBS}"
 | ||||
| +fi
 | ||||
|   | ||||
|  echo "" | ||||
|   | ||||
							
								
								
									
										31
									
								
								SOURCES/openssh-6.6p1-keyperm.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								SOURCES/openssh-6.6p1-keyperm.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| diff -up openssh-8.2p1/authfile.c.keyperm openssh-8.2p1/authfile.c
 | ||||
| --- openssh-8.2p1/authfile.c.keyperm	2020-02-14 01:40:54.000000000 +0100
 | ||||
| +++ openssh-8.2p1/authfile.c	2020-02-17 11:55:12.841729758 +0100
 | ||||
| @@ -31,6 +31,7 @@
 | ||||
|   | ||||
|  #include <errno.h> | ||||
|  #include <fcntl.h> | ||||
| +#include <grp.h>
 | ||||
|  #include <stdio.h> | ||||
|  #include <stdarg.h> | ||||
|  #include <stdlib.h> | ||||
| @@ -101,7 +102,19 @@ sshkey_perm_ok(int fd, const char *filen
 | ||||
|  #ifdef HAVE_CYGWIN | ||||
|  	if (check_ntsec(filename)) | ||||
|  #endif | ||||
| +
 | ||||
|  	if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { | ||||
| +		if (st.st_mode & 040) {
 | ||||
| +			struct group *gr;
 | ||||
| +
 | ||||
| +			if ((gr = getgrnam("ssh_keys")) && (st.st_gid == gr->gr_gid)) {
 | ||||
| +				/* The only additional bit is read
 | ||||
| +				 * for ssh_keys group, which is fine */
 | ||||
| +				if ((st.st_mode & 077) == 040 ) {
 | ||||
| +					return 0;
 | ||||
| +				}
 | ||||
| +			}
 | ||||
| +		}
 | ||||
|  		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); | ||||
|  		error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @"); | ||||
|  		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); | ||||
							
								
								
									
										289
									
								
								SOURCES/openssh-6.6p1-kuserok.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								SOURCES/openssh-6.6p1-kuserok.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,289 @@ | ||||
| diff -up openssh-7.4p1/auth-krb5.c.kuserok openssh-7.4p1/auth-krb5.c
 | ||||
| --- openssh-7.4p1/auth-krb5.c.kuserok	2016-12-23 14:36:07.640465939 +0100
 | ||||
| +++ openssh-7.4p1/auth-krb5.c	2016-12-23 14:36:07.644465936 +0100
 | ||||
| @@ -56,6 +56,21 @@
 | ||||
|   | ||||
|  extern ServerOptions	 options; | ||||
|   | ||||
| +int
 | ||||
| +ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client,
 | ||||
| +                 int k5login_exists)
 | ||||
| +{
 | ||||
| +	if (options.use_kuserok || !k5login_exists)
 | ||||
| +		return krb5_kuserok(krb5_ctx, krb5_user, client);
 | ||||
| +	else {
 | ||||
| +		char kuser[65];
 | ||||
| +
 | ||||
| +		if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser))
 | ||||
| +			return 0;
 | ||||
| +		return strcmp(kuser, client) == 0;
 | ||||
| +	}
 | ||||
| +}
 | ||||
| +
 | ||||
|  static int | ||||
|  krb5_init(void *context) | ||||
|  { | ||||
| @@ -160,8 +175,9 @@ auth_krb5_password(Authctxt *authctxt, c
 | ||||
|  	if (problem) | ||||
|  		goto out; | ||||
|   | ||||
| -	if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
 | ||||
| -	    authctxt->pw->pw_name)) {
 | ||||
| +	/* Use !options.use_kuserok here to make ssh_krb5_kuserok() not
 | ||||
| +	 * depend on the existance of .k5login */
 | ||||
| +	if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name, !options.use_kuserok)) {
 | ||||
|  		problem = -1; | ||||
|  		goto out; | ||||
|  	} | ||||
| diff -up openssh-7.4p1/gss-serv-krb5.c.kuserok openssh-7.4p1/gss-serv-krb5.c
 | ||||
| --- openssh-7.4p1/gss-serv-krb5.c.kuserok	2016-12-23 14:36:07.640465939 +0100
 | ||||
| +++ openssh-7.4p1/gss-serv-krb5.c	2016-12-23 14:36:07.644465936 +0100
 | ||||
| @@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr
 | ||||
|      int); | ||||
|   | ||||
|  static krb5_context krb_context = NULL; | ||||
| +extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *, int);
 | ||||
|   | ||||
|  /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ | ||||
|   | ||||
| @@ -92,6 +93,103 @@ ssh_gssapi_krb5_init(void)
 | ||||
|   * Returns true if the user is OK to log in, otherwise returns 0 | ||||
|   */ | ||||
|   | ||||
| +/* The purpose of the function is to find out if a Kerberos principal is
 | ||||
| + * allowed to log in as the given local user. This is a general problem with
 | ||||
| + * Kerberized services because by design the Kerberos principals are
 | ||||
| + * completely independent from the local user names. This is one of the
 | ||||
| + * reasons why Kerberos is working well on different operating systems like
 | ||||
| + * Windows and UNIX/Linux. Nevertheless a relationship between a Kerberos
 | ||||
| + * principal and a local user name must be established because otherwise every
 | ||||
| + * access would be granted for every principal with a valid ticket.
 | ||||
| + *
 | ||||
| + * Since it is a general issue libkrb5 provides some functions for
 | ||||
| + * applications to find out about the relationship between the Kerberos
 | ||||
| + * principal and a local user name. They are krb5_kuserok() and
 | ||||
| + * krb5_aname_to_localname().
 | ||||
| + *
 | ||||
| + * krb5_kuserok() can be used to "Determine if a principal is authorized to
 | ||||
| + * log in as a local user" (from the MIT Kerberos documentation of this
 | ||||
| + * function). Which is exactly what we are looking for and should be the
 | ||||
| + * preferred choice. It accepts the Kerberos principal and a local user name
 | ||||
| + * and let libkrb5 or its plugins determine if they relate to each other or
 | ||||
| + * not.
 | ||||
| + *
 | ||||
| + * krb5_aname_to_localname() can use used to "Convert a principal name to a
 | ||||
| + * local name" (from the MIT Kerberos documentation of this function). It
 | ||||
| + * accepts a Kerberos principle and returns a local name and it is up to the
 | ||||
| + * application to do any additional checks. There are two issues using
 | ||||
| + * krb5_aname_to_localname(). First, since POSIX user names are case
 | ||||
| + * sensitive, the calling application in general has no other choice than
 | ||||
| + * doing a case-sensitive string comparison between the name returned by
 | ||||
| + * krb5_aname_to_localname() and the name used at the login prompt. When the
 | ||||
| + * users are provided by a case in-sensitive server, e.g. Active Directory,
 | ||||
| + * this might lead to login failures because the user typing the name at the
 | ||||
| + * login prompt might not be aware of the right case. Another issue might be
 | ||||
| + * caused if there are multiple alias names available for a single user. E.g.
 | ||||
| + * the canonical name of a user is user@group.department.example.com but there
 | ||||
| + * exists a shorter login name, e.g. user@example.com, to safe typing at the
 | ||||
| + * login prompt. Here krb5_aname_to_localname() can only return the canonical
 | ||||
| + * name, but if the short alias is used at the login prompt authentication
 | ||||
| + * will fail as well. All this can be avoided by using krb5_kuserok() and
 | ||||
| + * configuring krb5.conf or using a suitable plugin to meet the needs of the
 | ||||
| + * given environment.
 | ||||
| + *
 | ||||
| + * The Fedora and RHEL version of openssh contain two patches which modify the
 | ||||
| + * access control behavior:
 | ||||
| + *  - openssh-6.6p1-kuserok.patch
 | ||||
| + *  - openssh-6.6p1-force_krb.patch
 | ||||
| + *
 | ||||
| + * openssh-6.6p1-kuserok.patch adds a new option KerberosUseKuserok for
 | ||||
| + * sshd_config which controls if krb5_kuserok() is used to check if the
 | ||||
| + * principle is authorized or if krb5_aname_to_localname() should be used.
 | ||||
| + * The reason to add this patch was that krb5_kuserok() by default checks if
 | ||||
| + * a .k5login file exits in the users home-directory. With this the user can
 | ||||
| + * give access to his account for any given principal which might be
 | ||||
| + * in violation with company policies and it would be useful if this can be
 | ||||
| + * rejected. Nevertheless the patch ignores the fact that krb5_kuserok() does
 | ||||
| + * no only check .k5login but other sources as well and checking .k5login can
 | ||||
| + * be disabled for all applications in krb5.conf as well. With this new
 | ||||
| + * option KerberosUseKuserok set to 'no' (and this is the default for RHEL7
 | ||||
| + * and Fedora 21) openssh can only use krb5_aname_to_localname() with the
 | ||||
| + * restrictions mentioned above.
 | ||||
| + *
 | ||||
| + * openssh-6.6p1-force_krb.patch adds a ksu like behaviour to ssh, i.e. when
 | ||||
| + * using GSSAPI authentication only commands configured in the .k5user can be
 | ||||
| + * executed. Here the wrong assumption that krb5_kuserok() only checks
 | ||||
| + * .k5login is made as well. In contrast ksu checks .k5login directly and
 | ||||
| + * does not use krb5_kuserok() which might be more useful for the given
 | ||||
| + * purpose. Additionally this patch is not synced with
 | ||||
| + * openssh-6.6p1-kuserok.patch.
 | ||||
| + *
 | ||||
| + * The current patch tries to restore the usage of krb5_kuserok() so that e.g.
 | ||||
| + * localauth plugins can be used. It does so by adding a forth parameter to
 | ||||
| + * ssh_krb5_kuserok() which indicates whether .k5login exists or not. If it
 | ||||
| + * does not exists krb5_kuserok() is called even if KerberosUseKuserok is set
 | ||||
| + * to 'no' because the intent of the option is to not check .k5login and if it
 | ||||
| + * does not exists krb5_kuserok() returns a result without checking .k5login.
 | ||||
| + * If .k5login does exists and KerberosUseKuserok is 'no' we fall back to
 | ||||
| + * krb5_aname_to_localname(). This is in my point of view an acceptable
 | ||||
| + * limitation and does not break the current behaviour.
 | ||||
| + *
 | ||||
| + * Additionally with this patch ssh_krb5_kuserok() is called in
 | ||||
| + * ssh_gssapi_krb5_cmdok() instead of only krb5_aname_to_localname() is
 | ||||
| + * neither .k5login nor .k5users exists to allow plugin evaluation via
 | ||||
| + * krb5_kuserok() as well.
 | ||||
| + *
 | ||||
| + * I tried to keep the patch as minimal as possible, nevertheless I see some
 | ||||
| + * areas for improvement which, if they make sense, have to be evaluated
 | ||||
| + * carefully because they might change existing behaviour and cause breaks
 | ||||
| + * during upgrade:
 | ||||
| + * - I wonder if disabling .k5login usage make sense in sshd or if it should
 | ||||
| + *   be better disabled globally in krb5.conf
 | ||||
| + * - if really needed openssh-6.6p1-kuserok.patch should be fixed to really
 | ||||
| + *   only disable checking .k5login and maybe .k5users
 | ||||
| + * - the ksu behaviour should be configurable and maybe check the .k5login and
 | ||||
| + *   .k5users files directly like ksu itself does
 | ||||
| + * - to make krb5_aname_to_localname() more useful an option for sshd to use
 | ||||
| + *   the canonical name (the one returned by getpwnam()) instead of the name
 | ||||
| + *   given at the login prompt might be useful */
 | ||||
| +
 | ||||
|  static int | ||||
|  ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) | ||||
|  { | ||||
| @@ -116,7 +214,8 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client
 | ||||
|  	/* NOTE: .k5login and .k5users must opened as root, not the user, | ||||
|  	 * because if they are on a krb5-protected filesystem, user credentials | ||||
|  	 * to access these files aren't available yet. */ | ||||
| -	if (krb5_kuserok(krb_context, princ, name) && k5login_exists) {
 | ||||
| +	if (ssh_krb5_kuserok(krb_context, princ, name, k5login_exists)
 | ||||
| +			&& k5login_exists) {
 | ||||
|  		retval = 1; | ||||
|  		logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", | ||||
|  		    name, (char *)client->displayname.value); | ||||
| @@ -190,9 +289,8 @@ ssh_gssapi_krb5_cmdok(krb5_principal pri
 | ||||
|  	snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); | ||||
|  	/* If both .k5login and .k5users DNE, self-login is ok. */ | ||||
|  	if (!k5login_exists && (access(file, F_OK) == -1)) { | ||||
| -		return (krb5_aname_to_localname(krb_context, principal,
 | ||||
| -		    sizeof(kuser), kuser) == 0) &&
 | ||||
| -		    (strcmp(kuser, luser) == 0);
 | ||||
| +                return ssh_krb5_kuserok(krb_context, principal, luser,
 | ||||
| +                                        k5login_exists);
 | ||||
|  	} | ||||
|  	if ((fp = fopen(file, "r")) == NULL) { | ||||
|  		int saved_errno = errno; | ||||
| diff -up openssh-7.4p1/servconf.c.kuserok openssh-7.4p1/servconf.c
 | ||||
| --- openssh-7.4p1/servconf.c.kuserok	2016-12-23 14:36:07.630465944 +0100
 | ||||
| +++ openssh-7.4p1/servconf.c	2016-12-23 15:11:52.278133344 +0100
 | ||||
| @@ -116,6 +116,7 @@ initialize_server_options(ServerOptions
 | ||||
|  	options->gss_strict_acceptor = -1; | ||||
|  	options->gss_store_rekey = -1; | ||||
|  	options->gss_kex_algorithms = NULL; | ||||
| +	options->use_kuserok = -1;
 | ||||
|  	options->password_authentication = -1; | ||||
|  	options->kbd_interactive_authentication = -1; | ||||
|  	options->challenge_response_authentication = -1; | ||||
| @@ -278,6 +279,8 @@ fill_default_server_options(ServerOption
 | ||||
|  	if (options->gss_kex_algorithms == NULL) | ||||
|  		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX); | ||||
|  #endif | ||||
| +	if (options->use_kuserok == -1)
 | ||||
| +		options->use_kuserok = 1;
 | ||||
|  	if (options->password_authentication == -1) | ||||
|  		options->password_authentication = 1; | ||||
|  	if (options->kbd_interactive_authentication == -1) | ||||
| @@ -399,7 +402,7 @@ typedef enum {
 | ||||
|  	sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, | ||||
|  	sRhostsRSAAuthentication, sRSAAuthentication, | ||||
|  	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, | ||||
| -	sKerberosGetAFSToken, sKerberosUniqueCCache,
 | ||||
| +	sKerberosGetAFSToken, sKerberosUniqueCCache, sKerberosUseKuserok,
 | ||||
|  	sChallengeResponseAuthentication, | ||||
|  	sPasswordAuthentication, sKbdInteractiveAuthentication, | ||||
|  	sListenAddress, sAddressFamily, | ||||
| @@ -478,12 +481,14 @@ static struct {
 | ||||
|  	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  #endif | ||||
|  	{ "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL }, | ||||
| +	{ "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL },
 | ||||
|  #else | ||||
|  	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL }, | ||||
|  	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "kerberosuniqueccache", sUnsupported, SSHCFG_GLOBAL }, | ||||
| +	{ "kerberosusekuserok", sUnsupported, SSHCFG_ALL },
 | ||||
|  #endif | ||||
|  	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, | ||||
| @@ -1644,6 +1649,10 @@ process_server_config_line(ServerOptions
 | ||||
|  		*inc_flags &= ~SSHCFG_MATCH_ONLY; | ||||
|  		break; | ||||
|   | ||||
| +	case sKerberosUseKuserok:
 | ||||
| +		intptr = &options->use_kuserok;
 | ||||
| +		goto parse_flag;
 | ||||
| +
 | ||||
|  	case sPermitListen: | ||||
|  	case sPermitOpen: | ||||
|  		if (opcode == sPermitListen) { | ||||
| @@ -2016,6 +2025,7 @@ copy_set_server_options(ServerOptions *d
 | ||||
|  	M_CP_INTOPT(client_alive_interval); | ||||
|  	M_CP_INTOPT(ip_qos_interactive); | ||||
|  	M_CP_INTOPT(ip_qos_bulk); | ||||
| +	M_CP_INTOPT(use_kuserok);
 | ||||
|  	M_CP_INTOPT(rekey_limit); | ||||
|  	M_CP_INTOPT(rekey_interval); | ||||
|  	M_CP_INTOPT(log_level); | ||||
| @@ -2309,6 +2319,7 @@ dump_config(ServerOptions *o)
 | ||||
|  	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); | ||||
|  # endif | ||||
|  	dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache); | ||||
| +	dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok);
 | ||||
|  #endif | ||||
|  #ifdef GSSAPI | ||||
| 	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); | ||||
| diff -up openssh-7.4p1/servconf.h.kuserok openssh-7.4p1/servconf.h
 | ||||
| --- openssh-7.4p1/servconf.h.kuserok	2016-12-23 14:36:07.630465944 +0100
 | ||||
| +++ openssh-7.4p1/servconf.h	2016-12-23 14:36:07.645465936 +0100
 | ||||
| @@ -118,6 +118,7 @@ typedef struct {
 | ||||
|  						 * authenticated with Kerberos. */ | ||||
|  	int     kerberos_unique_ccache;		/* If true, the acquired ticket will | ||||
|  						 * be stored in per-session ccache */ | ||||
| +	int	use_kuserok;
 | ||||
|  	int     gss_authentication;	/* If true, permit GSSAPI authentication */ | ||||
|  	int     gss_keyex;		/* If true, permit GSSAPI key exchange */ | ||||
|  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */ | ||||
| diff -up openssh-7.4p1/sshd_config.5.kuserok openssh-7.4p1/sshd_config.5
 | ||||
| --- openssh-7.4p1/sshd_config.5.kuserok	2016-12-23 14:36:07.637465940 +0100
 | ||||
| +++ openssh-7.4p1/sshd_config.5	2016-12-23 15:14:03.117162222 +0100
 | ||||
| @@ -850,6 +850,10 @@ Specifies whether to automatically destr
 | ||||
|  .Cm no | ||||
|  can lead to overwriting previous tickets by subseqent connections to the same | ||||
|  user account. | ||||
| +.It Cm KerberosUseKuserok
 | ||||
| +Specifies whether to look at .k5login file for user's aliases.
 | ||||
| +The default is
 | ||||
| +.Cm yes .
 | ||||
|  .It Cm KexAlgorithms | ||||
|  Specifies the available KEX (Key Exchange) algorithms. | ||||
|  Multiple algorithms must be comma-separated. | ||||
| @@ -1078,6 +1082,7 @@ Available keywords are
 | ||||
|  .Cm IPQoS , | ||||
|  .Cm KbdInteractiveAuthentication , | ||||
|  .Cm KerberosAuthentication , | ||||
| +.Cm KerberosUseKuserok ,
 | ||||
|  .Cm LogLevel , | ||||
|  .Cm MaxAuthTries , | ||||
|  .Cm MaxSessions , | ||||
| diff -up openssh-7.4p1/sshd_config.kuserok openssh-7.4p1/sshd_config
 | ||||
| --- openssh-7.4p1/sshd_config.kuserok	2016-12-23 14:36:07.631465943 +0100
 | ||||
| +++ openssh-7.4p1/sshd_config	2016-12-23 14:36:07.646465935 +0100
 | ||||
| @@ -73,6 +73,7 @@ ChallengeResponseAuthentication no
 | ||||
|  #KerberosOrLocalPasswd yes | ||||
|  #KerberosTicketCleanup yes | ||||
|  #KerberosGetAFSToken no | ||||
| +#KerberosUseKuserok yes
 | ||||
|   | ||||
|  # GSSAPI options | ||||
|  #GSSAPIAuthentication no | ||||
							
								
								
									
										121
									
								
								SOURCES/openssh-6.6p1-privsep-selinux.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								SOURCES/openssh-6.6p1-privsep-selinux.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,121 @@ | ||||
| diff -up openssh-7.4p1/openbsd-compat/port-linux.h.privsep-selinux openssh-7.4p1/openbsd-compat/port-linux.h
 | ||||
| --- openssh-7.4p1/openbsd-compat/port-linux.h.privsep-selinux	2016-12-23 18:58:52.972122201 +0100
 | ||||
| +++ openssh-7.4p1/openbsd-compat/port-linux.h	2016-12-23 18:58:52.974122201 +0100
 | ||||
| @@ -23,6 +23,7 @@ void ssh_selinux_setup_pty(char *, const
 | ||||
|  void ssh_selinux_change_context(const char *); | ||||
|  void ssh_selinux_setfscreatecon(const char *); | ||||
|   | ||||
| +void sshd_selinux_copy_context(void);
 | ||||
|  void sshd_selinux_setup_exec_context(char *); | ||||
|  #endif | ||||
|   | ||||
| diff -up openssh-7.4p1/openbsd-compat/port-linux-sshd.c.privsep-selinux openssh-7.4p1/openbsd-compat/port-linux-sshd.c
 | ||||
| --- 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
 | ||||
| @@ -419,6 +419,28 @@ sshd_selinux_setup_exec_context(char *pw
 | ||||
|  	debug3_f("done"); | ||||
|  } | ||||
|   | ||||
| +void
 | ||||
| +sshd_selinux_copy_context(void)
 | ||||
| +{
 | ||||
| +	security_context_t *ctx;
 | ||||
| +
 | ||||
| +	if (!ssh_selinux_enabled())
 | ||||
| +		return;
 | ||||
| +
 | ||||
| +	if (getexeccon((security_context_t *)&ctx) != 0) {
 | ||||
| +		logit_f("getexeccon failed with %s", strerror(errno));
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +	if (ctx != NULL) {
 | ||||
| +		/* unset exec context before we will lose this capabililty */
 | ||||
| +		if (setexeccon(NULL) != 0)
 | ||||
| +			fatal_f("setexeccon failed with %s", strerror(errno));
 | ||||
| +		if (setcon(ctx) != 0)
 | ||||
| +			fatal_f("setcon failed with %s", strerror(errno));
 | ||||
| +		freecon(ctx);
 | ||||
| +	}
 | ||||
| +}
 | ||||
| +
 | ||||
|  #endif | ||||
|  #endif | ||||
|   | ||||
| diff -up openssh-7.4p1/session.c.privsep-selinux openssh-7.4p1/session.c
 | ||||
| --- openssh-7.4p1/session.c.privsep-selinux	2016-12-19 05:59:41.000000000 +0100
 | ||||
| +++ openssh-7.4p1/session.c	2016-12-23 18:58:52.974122201 +0100
 | ||||
| @@ -1331,7 +1331,7 @@ do_setusercontext(struct passwd *pw)
 | ||||
|   | ||||
|  	platform_setusercontext(pw); | ||||
|   | ||||
| -	if (platform_privileged_uidswap()) {
 | ||||
| +	if (platform_privileged_uidswap() && (!is_child || !use_privsep)) {
 | ||||
|  #ifdef HAVE_LOGIN_CAP | ||||
|  		if (setusercontext(lc, pw, pw->pw_uid, | ||||
|  		    (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { | ||||
| @@ -1361,6 +1361,9 @@ do_setusercontext(struct passwd *pw)
 | ||||
| 			    (unsigned long long)pw->pw_uid); | ||||
| 			chroot_path = percent_expand(tmp, "h", pw->pw_dir, | ||||
| 			    "u", pw->pw_name, "U", uidstr, (char *)NULL); | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +			sshd_selinux_copy_context();
 | ||||
| +#endif
 | ||||
|  			safely_chroot(chroot_path, pw->pw_uid); | ||||
|  			free(tmp); | ||||
|  			free(chroot_path); | ||||
| @@ -1396,6 +1399,11 @@ do_setusercontext(struct passwd *pw)
 | ||||
|  		/* Permanently switch to the desired uid. */ | ||||
|  		permanently_set_uid(pw); | ||||
|  #endif | ||||
| +
 | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +		if (in_chroot == 0)
 | ||||
| +			sshd_selinux_copy_context();
 | ||||
| +#endif
 | ||||
|  	} else if (options.chroot_directory != NULL && | ||||
|  	    strcasecmp(options.chroot_directory, "none") != 0) { | ||||
|  		fatal("server lacks privileges to chroot to ChrootDirectory"); | ||||
| @@ -1413,9 +1421,6 @@ do_pwchange(Session *s)
 | ||||
|  	if (s->ttyfd != -1) { | ||||
|  		fprintf(stderr, | ||||
|  		    "You must change your password now and login again!\n"); | ||||
| -#ifdef WITH_SELINUX
 | ||||
| -		setexeccon(NULL);
 | ||||
| -#endif
 | ||||
|  #ifdef PASSWD_NEEDS_USERNAME | ||||
|  		execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name, | ||||
|  		    (char *)NULL); | ||||
| @@ -1625,9 +1630,6 @@ do_child(Session *s, const char *command
 | ||||
|  		argv[i] = NULL; | ||||
|  		optind = optreset = 1; | ||||
|  		__progname = argv[0]; | ||||
| -#ifdef WITH_SELINUX
 | ||||
| -		ssh_selinux_change_context("sftpd_t");
 | ||||
| -#endif
 | ||||
|  		exit(sftp_server_main(i, argv, s->pw)); | ||||
|  	} | ||||
|   | ||||
| diff -up openssh-7.4p1/sshd.c.privsep-selinux openssh-7.4p1/sshd.c
 | ||||
| --- openssh-7.4p1/sshd.c.privsep-selinux	2016-12-23 18:58:52.973122201 +0100
 | ||||
| +++ openssh-7.4p1/sshd.c	2016-12-23 18:59:13.808124269 +0100
 | ||||
| @@ -540,6 +540,10 @@ privsep_preauth_child(void)
 | ||||
|  	/* Demote the private keys to public keys. */ | ||||
|  	demote_sensitive_data(); | ||||
|   | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	ssh_selinux_change_context("sshd_net_t");
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  	/* Demote the child */ | ||||
|  	if (privsep_chroot) { | ||||
|  		/* Change our root directory */ | ||||
| @@ -633,6 +637,9 @@ privsep_postauth(Authctxt *authctxt)
 | ||||
|  { | ||||
|  #ifdef DISABLE_FD_PASSING | ||||
|  	if (1) { | ||||
| +#elif defined(WITH_SELINUX)
 | ||||
| +	if (0) {
 | ||||
| +		/* even root user can be confined by SELinux */
 | ||||
|  #else | ||||
|  	if (authctxt->pw->pw_uid == 0) { | ||||
|  #endif | ||||
							
								
								
									
										569
									
								
								SOURCES/openssh-6.7p1-coverity.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										569
									
								
								SOURCES/openssh-6.7p1-coverity.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,569 @@ | ||||
| diff -up openssh-8.5p1/addr.c.coverity openssh-8.5p1/addr.c
 | ||||
| --- openssh-8.5p1/addr.c.coverity	2021-03-02 11:31:47.000000000 +0100
 | ||||
| +++ openssh-8.5p1/addr.c	2021-03-24 12:03:33.782968159 +0100
 | ||||
| @@ -312,8 +312,10 @@ addr_pton(const char *p, struct xaddr *n
 | ||||
|  	if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) | ||||
|  		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
 | ||||
| @@ -409,8 +409,10 @@ sshauthopt_parse(const char *opts, const
 | ||||
|  				errstr = "invalid environment string"; | ||||
|  				goto fail; | ||||
|  			} | ||||
| -			if ((cp = strdup(opt)) == NULL)
 | ||||
| +			if ((cp = strdup(opt)) == NULL) {
 | ||||
| +				free(opt);
 | ||||
|  				goto alloc_fail; | ||||
| +			}
 | ||||
|  			cp[tmp - opt] = '\0'; /* truncate at '=' */ | ||||
|  			if (!valid_env_name(cp)) { | ||||
|  				free(cp); | ||||
| @@ -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); | ||||
| @@ -3804,7 +3804,7 @@ int
 | ||||
|  channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) | ||||
|  { | ||||
|  	int r, success = 0, idx = -1; | ||||
| -	char *host_to_connect, *listen_host, *listen_path;
 | ||||
| +	char *host_to_connect = NULL, *listen_host = NULL, *listen_path = NULL;
 | ||||
|  	int port_to_connect, listen_port; | ||||
|   | ||||
|  	/* Send the forward request to the remote side. */ | ||||
| @@ -3832,7 +3832,6 @@ channel_request_remote_forwarding(struct
 | ||||
|  	success = 1; | ||||
|  	if (success) { | ||||
|  		/* Record that connection to this host/port is permitted. */ | ||||
| -		host_to_connect = listen_host = listen_path = NULL;
 | ||||
|  		port_to_connect = listen_port = 0; | ||||
|  		if (fwd->connect_path != NULL) { | ||||
|  			host_to_connect = xstrdup(fwd->connect_path); | ||||
| @@ -3853,6 +3852,9 @@ channel_request_remote_forwarding(struct
 | ||||
|  		    host_to_connect, port_to_connect, | ||||
|  		    listen_host, listen_path, listen_port, NULL); | ||||
|  	} | ||||
| +	free(host_to_connect);
 | ||||
| +	free(listen_host);
 | ||||
| +	free(listen_path);
 | ||||
|  	return idx; | ||||
|  } | ||||
|   | ||||
| diff -up openssh-8.5p1/compat.c.coverity openssh-8.5p1/compat.c
 | ||||
| --- openssh-8.5p1/compat.c.coverity	2021-03-24 12:03:33.768968062 +0100
 | ||||
| +++ openssh-8.5p1/compat.c	2021-03-24 12:03:33.783968166 +0100
 | ||||
| @@ -191,10 +191,12 @@ compat_kex_proposal(struct ssh *ssh, cha
 | ||||
|  		return p; | ||||
|  	debug2_f("original KEX proposal: %s", p); | ||||
|  	if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) | ||||
| +		/* coverity[overwrite_var : FALSE] */
 | ||||
|  		if ((p = match_filter_denylist(p, | ||||
|  		    "curve25519-sha256@libssh.org")) == NULL) | ||||
|  			fatal("match_filter_denylist failed"); | ||||
|  	if ((ssh->compat & SSH_OLD_DHGEX) != 0) { | ||||
| +		/* coverity[overwrite_var : FALSE] */
 | ||||
|  		if ((p = match_filter_denylist(p, | ||||
|  		    "diffie-hellman-group-exchange-sha256," | ||||
|  		    "diffie-hellman-group-exchange-sha1")) == NULL) | ||||
| 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_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,
 | ||||
|  	 */ | ||||
|   | ||||
|  	/* Use strncpy because we don't necessarily want null termination */ | ||||
| +	/* coverity[buffer_size_warning : FALSE] */
 | ||||
|  	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 (nullfd > STDERR_FILENO) | ||||
|  		close(nullfd); | ||||
| +	/* coverity[leaked_handle : FALSE]*/
 | ||||
| +	/* coverity[leaked_handle : FALSE]*/
 | ||||
|  } | ||||
|   | ||||
|  char * | ||||
| @@ -2511,6 +2513,7 @@ stdfd_devnull(int do_stdin, int do_stdou
 | ||||
|  	} | ||||
|  	if (devnull > STDERR_FILENO) | ||||
|  		close(devnull); | ||||
| +	/* coverity[leaked_handle : FALSE]*/
 | ||||
|  	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); | ||||
|   | ||||
|  	/* Drain any buffered messages from the child */ | ||||
| -	while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
 | ||||
| +	while (pmonitor->m_log_recvfd >= 0 && monitor_read_log(pmonitor) == 0)
 | ||||
|  		; | ||||
|   | ||||
|  	if (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
 | ||||
| --- 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
 | ||||
| @@ -525,10 +525,10 @@ mm_pty_allocate(int *ptyfd, int *ttyfd,
 | ||||
|  	if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || | ||||
|  	    (tmp2 = dup(pmonitor->m_recvfd)) == -1) { | ||||
|  		error_f("cannot allocate fds for pty"); | ||||
| -		if (tmp1 > 0)
 | ||||
| +		if (tmp1 >= 0)
 | ||||
|  			close(tmp1); | ||||
| -		if (tmp2 > 0)
 | ||||
| -			close(tmp2);
 | ||||
| +		/*DEAD CODE if (tmp2 >= 0)
 | ||||
| +			close(tmp2);*/
 | ||||
|  		return 0; | ||||
|  	} | ||||
|  	close(tmp1); | ||||
| diff -up openssh-7.4p1/openbsd-compat/bindresvport.c.coverity openssh-7.4p1/openbsd-compat/bindresvport.c
 | ||||
| --- openssh-7.4p1/openbsd-compat/bindresvport.c.coverity	2016-12-19 05:59:41.000000000 +0100
 | ||||
| +++ openssh-7.4p1/openbsd-compat/bindresvport.c	2016-12-23 16:40:26.901788691 +0100
 | ||||
| @@ -58,7 +58,7 @@ bindresvport_sa(int sd, struct sockaddr
 | ||||
|  	struct sockaddr_in6 *in6; | ||||
|  	u_int16_t *portp; | ||||
|  	u_int16_t port; | ||||
| -	socklen_t salen;
 | ||||
| +	socklen_t salen = sizeof(struct sockaddr_storage);
 | ||||
|  	int i; | ||||
|   | ||||
|  	if (sa == NULL) { | ||||
| diff -up openssh-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);
 | ||||
|  				return -1; | ||||
|  			} | ||||
|  			free(arg2); | ||||
| diff -up openssh-7.4p1/scp.c.coverity openssh-7.4p1/scp.c
 | ||||
| --- openssh-7.4p1/scp.c.coverity	2016-12-23 16:40:26.856788681 +0100
 | ||||
| +++ openssh-7.4p1/scp.c	2016-12-23 16:40:26.901788691 +0100
 | ||||
| @@ -157,7 +157,7 @@ killchild(int signo)
 | ||||
|  { | ||||
|  	if (do_cmd_pid > 1) { | ||||
|  		kill(do_cmd_pid, signo ? signo : SIGTERM); | ||||
| -		waitpid(do_cmd_pid, NULL, 0);
 | ||||
| +		(void) waitpid(do_cmd_pid, NULL, 0);
 | ||||
|  	} | ||||
|   | ||||
|  	if (signo) | ||||
| diff -up openssh-7.4p1/servconf.c.coverity openssh-7.4p1/servconf.c
 | ||||
| --- openssh-7.4p1/servconf.c.coverity	2016-12-23 16:40:26.896788690 +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
 | ||||
|  		if (*activep && *charptr == NULL) { | ||||
|  			*charptr = tilde_expand_filename(arg, getuid()); | ||||
|  			/* increase optional counter */ | ||||
| -			if (intptr != NULL)
 | ||||
| -				*intptr = *intptr + 1;
 | ||||
| +			/* DEAD CODE intptr is still NULL ;)
 | ||||
| +  			 if (intptr != NULL)
 | ||||
| +				*intptr = *intptr + 1; */
 | ||||
|  		} | ||||
|  		break; | ||||
|   | ||||
| diff -up openssh-7.4p1/serverloop.c.coverity openssh-7.4p1/serverloop.c
 | ||||
| --- openssh-7.4p1/serverloop.c.coverity	2016-12-19 05:59:41.000000000 +0100
 | ||||
| +++ openssh-7.4p1/serverloop.c	2016-12-23 16:40:26.902788691 +0100
 | ||||
| @@ -125,13 +125,13 @@ notify_setup(void)
 | ||||
|  static void | ||||
|  notify_parent(void) | ||||
|  { | ||||
| -	if (notify_pipe[1] != -1)
 | ||||
| +	if (notify_pipe[1] >= 0)
 | ||||
|  		(void)write(notify_pipe[1], "", 1); | ||||
|  } | ||||
|  static void | ||||
|  notify_prepare(fd_set *readset) | ||||
|  { | ||||
| -	if (notify_pipe[0] != -1)
 | ||||
| +	if (notify_pipe[0] >= 0)
 | ||||
|  		FD_SET(notify_pipe[0], readset); | ||||
|  } | ||||
|  static void | ||||
| @@ -139,8 +139,8 @@ notify_done(fd_set *readset)
 | ||||
|  { | ||||
|  	char c; | ||||
|   | ||||
| -	if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset))
 | ||||
| -		while (read(notify_pipe[0], &c, 1) != -1)
 | ||||
| +	if (notify_pipe[0] >= 0 && FD_ISSET(notify_pipe[0], readset))
 | ||||
| +		while (read(notify_pipe[0], &c, 1) >= 0)
 | ||||
|  			debug2_f("reading"); | ||||
|  } | ||||
|   | ||||
| @@ -518,7 +518,7 @@ server_request_tun(void)
 | ||||
|  		debug_f("invalid tun"); | ||||
|  		goto done; | ||||
|  	} | ||||
| -	if (auth_opts->force_tun_device != -1) {
 | ||||
| +	if (auth_opts->force_tun_device >= 0) {
 | ||||
|  		if (tun != SSH_TUNID_ANY && | ||||
|  		    auth_opts->force_tun_device != (int)tun) | ||||
|  			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 */ | ||||
| diff -up openssh-7.4p1/sftp.c.coverity openssh-7.4p1/sftp.c
 | ||||
| --- openssh-7.4p1/sftp.c.coverity	2016-12-19 05:59:41.000000000 +0100
 | ||||
| +++ openssh-7.4p1/sftp.c	2016-12-23 16:40:26.903788691 +0100
 | ||||
| @@ -224,7 +224,7 @@ killchild(int signo)
 | ||||
|  	pid = sshpid; | ||||
|  	if (pid > 1) { | ||||
|  		kill(pid, SIGTERM); | ||||
| -		waitpid(pid, NULL, 0);
 | ||||
| +		(void) waitpid(pid, NULL, 0);
 | ||||
|  	} | ||||
|   | ||||
|  	_exit(1); | ||||
| @@ -762,6 +762,8 @@ process_put(struct sftp_conn *conn, cons
 | ||||
|  			    fflag || global_fflag) == -1) | ||||
|  				err = -1; | ||||
|  		} | ||||
| +		free(abs_dst);
 | ||||
| +		abs_dst = NULL;
 | ||||
|  	} | ||||
|   | ||||
|  out: | ||||
| @@ -985,6 +987,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 -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
 | ||||
| --- 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
 | ||||
| @@ -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)
 | ||||
|  	sanitise_stdfd(); | ||||
|   | ||||
|  	/* drop */ | ||||
| -	setegid(getgid());
 | ||||
| -	setgid(getgid());
 | ||||
| +	(void) setegid(getgid());
 | ||||
| +	(void) setgid(getgid());
 | ||||
|   | ||||
|  	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
 | ||||
| --- 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
 | ||||
| @@ -691,8 +691,10 @@ privsep_preauth(Authctxt *authctxt)
 | ||||
|   | ||||
|  		privsep_preauth_child(ssh); | ||||
|  		setproctitle("%s", "[net]"); | ||||
| -		if (box != NULL)
 | ||||
| +		if (box != NULL) {
 | ||||
|  			ssh_sandbox_child(box); | ||||
| +			free(box);
 | ||||
| +		}
 | ||||
|   | ||||
|  		return 0; | ||||
|  	} | ||||
| @@ -1386,6 +1388,9 @@ server_accept_loop(int *sock_in, int *so
 | ||||
|  			explicit_bzero(rnd, sizeof(rnd)); | ||||
|  		} | ||||
|  	} | ||||
| +
 | ||||
| +	if (fdset != NULL)
 | ||||
| +		free(fdset);
 | ||||
|  } | ||||
|   | ||||
|  /* | ||||
| @@ -2474,7 +2479,7 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||
|  	if (options.rekey_limit || options.rekey_interval) | ||||
|  		ssh_packet_set_rekey_limits(ssh, options.rekey_limit, | ||||
|  		    options.rekey_interval); | ||||
| -
 | ||||
| +	/* coverity[leaked_storage : FALSE]*/
 | ||||
|  	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( | ||||
|  	    ssh, list_hostkey_types()); | ||||
|   | ||||
| @@ -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; | ||||
							
								
								
									
										100
									
								
								SOURCES/openssh-6.7p1-sftp-force-permission.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								SOURCES/openssh-6.7p1-sftp-force-permission.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,100 @@ | ||||
| diff -up openssh-7.2p2/sftp-server.8.sftp-force-mode openssh-7.2p2/sftp-server.8
 | ||||
| --- openssh-7.2p2/sftp-server.8.sftp-force-mode	2016-03-09 19:04:48.000000000 +0100
 | ||||
| +++ openssh-7.2p2/sftp-server.8	2016-06-23 16:18:20.463854117 +0200
 | ||||
| @@ -38,6 +38,7 @@
 | ||||
|  .Op Fl P Ar denied_requests | ||||
|  .Op Fl p Ar allowed_requests | ||||
|  .Op Fl u Ar umask | ||||
| +.Op Fl m Ar force_file_perms
 | ||||
|  .Ek | ||||
|  .Nm | ||||
|  .Fl Q Ar protocol_feature | ||||
| @@ -138,6 +139,12 @@ Sets an explicit
 | ||||
|  .Xr umask 2 | ||||
|  to be applied to newly-created files and directories, instead of the | ||||
|  user's default mask. | ||||
| +.It Fl m Ar force_file_perms
 | ||||
| +Sets explicit file permissions to be applied to newly-created files instead
 | ||||
| +of the default or client requested mode.  Numeric values include:
 | ||||
| +777, 755, 750, 666, 644, 640, etc.  Using both -m and -u switches makes the
 | ||||
| +umask (-u) effective only for newly created directories and explicit mode (-m)
 | ||||
| +for newly created files.
 | ||||
|  .El | ||||
|  .Pp | ||||
|  On some systems, | ||||
| diff -up openssh-7.2p2/sftp-server.c.sftp-force-mode openssh-7.2p2/sftp-server.c
 | ||||
| --- openssh-7.2p2/sftp-server.c.sftp-force-mode	2016-06-23 16:18:20.446854128 +0200
 | ||||
| +++ openssh-7.2p2/sftp-server.c	2016-06-23 16:20:37.950766082 +0200
 | ||||
| @@ -69,6 +69,10 @@ struct sshbuf *oqueue;
 | ||||
|  /* Version of client */ | ||||
|  static u_int version; | ||||
|   | ||||
| +/* Force file permissions */
 | ||||
| +int permforce = 0;
 | ||||
| +long permforcemode;
 | ||||
| +
 | ||||
|  /* SSH2_FXP_INIT received */ | ||||
|  static int init_done; | ||||
|   | ||||
| @@ -683,6 +687,7 @@ process_open(u_int32_t id)
 | ||||
|  	Attrib a; | ||||
|  	char *name; | ||||
|  	int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; | ||||
| +	mode_t old_umask = 0;
 | ||||
|   | ||||
|  	if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || | ||||
|  	    (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ | ||||
| @@ -692,6 +697,10 @@ process_open(u_int32_t id)
 | ||||
|  	debug3("request %u: open flags %d", id, pflags); | ||||
|  	flags = flags_from_portable(pflags); | ||||
|  	mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; | ||||
| +	if (permforce == 1) {   /* Force perm if -m is set */
 | ||||
| +		mode = permforcemode;
 | ||||
| +		old_umask = umask(0); /* so umask does not interfere */
 | ||||
| +	}	
 | ||||
|  	logit("open \"%s\" flags %s mode 0%o", | ||||
|  	    name, string_from_portable(pflags), mode); | ||||
|  	if (readonly && | ||||
| @@ -713,6 +722,8 @@ process_open(u_int32_t id)
 | ||||
|  			} | ||||
|  		} | ||||
|  	} | ||||
| +	if (permforce == 1)
 | ||||
| +		(void) umask(old_umask); /* restore umask to something sane */
 | ||||
|  	if (status != SSH2_FX_OK) | ||||
|  		send_status(id, status); | ||||
|  	free(name); | ||||
| @@ -1494,7 +1505,7 @@ sftp_server_usage(void)
 | ||||
|  	fprintf(stderr, | ||||
|  	    "usage: %s [-ehR] [-d start_directory] [-f log_facility] " | ||||
|  	    "[-l log_level]\n\t[-P denied_requests] " | ||||
| -	    "[-p allowed_requests] [-u umask]\n"
 | ||||
| +	    "[-p allowed_requests] [-u umask] [-m force_file_perms]\n"
 | ||||
|  	    "       %s -Q protocol_feature\n", | ||||
|  	    __progname, __progname); | ||||
|  	exit(1); | ||||
| @@ -1520,7 +1531,7 @@ sftp_server_main(int argc, char **argv,
 | ||||
|  	pw = pwcopy(user_pw); | ||||
|   | ||||
|  	while (!skipargs && (ch = getopt(argc, argv, | ||||
| -	    "d:f:l:P:p:Q:u:cehR")) != -1) {
 | ||||
| +	    "d:f:l:P:p:Q:u:m:cehR")) != -1) {
 | ||||
|  		switch (ch) { | ||||
|  		case 'Q': | ||||
|  			if (strcasecmp(optarg, "requests") != 0) { | ||||
| @@ -1580,6 +1591,15 @@ sftp_server_main(int argc, char **argv,
 | ||||
|  				fatal("Invalid umask \"%s\"", optarg); | ||||
|  			(void)umask((mode_t)mask); | ||||
|  			break; | ||||
| +		case 'm':
 | ||||
| +			/* Force permissions on file received via sftp */
 | ||||
| +			permforce = 1;
 | ||||
| +			permforcemode = strtol(optarg, &cp, 8);
 | ||||
| +			if (permforcemode < 0 || permforcemode > 0777 ||
 | ||||
| +			    *cp != '\0' || (permforcemode == 0 &&
 | ||||
| +			    errno != 0))
 | ||||
| +				fatal("Invalid file mode \"%s\"", optarg);
 | ||||
| +			break;
 | ||||
|  		case 'h': | ||||
|  		default: | ||||
|  			sftp_server_usage(); | ||||
							
								
								
									
										12
									
								
								SOURCES/openssh-6.8p1-sshdT-output.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								SOURCES/openssh-6.8p1-sshdT-output.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| diff -up openssh/servconf.c.sshdt openssh/servconf.c
 | ||||
| --- openssh/servconf.c.sshdt	2015-06-24 11:42:29.041078704 +0200
 | ||||
| +++ openssh/servconf.c	2015-06-24 11:44:39.734745802 +0200
 | ||||
| @@ -2317,7 +2317,7 @@ dump_config(ServerOptions *o)
 | ||||
|  	dump_cfg_string(sXAuthLocation, o->xauth_location); | ||||
|  	dump_cfg_string(sCiphers, o->ciphers); | ||||
|  	dump_cfg_string(sMacs, o->macs); | ||||
| -	dump_cfg_string(sBanner, o->banner);
 | ||||
| +	dump_cfg_string(sBanner, o->banner != NULL ? o->banner : "none");
 | ||||
|  	dump_cfg_string(sForceCommand, o->adm_forced_command); | ||||
|  	dump_cfg_string(sChrootDirectory, o->chroot_directory); | ||||
|  	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); | ||||
							
								
								
									
										187
									
								
								SOURCES/openssh-7.1p2-audit-race-condition.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								SOURCES/openssh-7.1p2-audit-race-condition.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,187 @@ | ||||
| diff -up openssh-7.4p1/monitor_wrap.c.audit-race openssh-7.4p1/monitor_wrap.c
 | ||||
| --- openssh-7.4p1/monitor_wrap.c.audit-race	2016-12-23 16:35:52.694685771 +0100
 | ||||
| +++ openssh-7.4p1/monitor_wrap.c	2016-12-23 16:35:52.697685772 +0100
 | ||||
| @@ -1107,4 +1107,50 @@ mm_audit_destroy_sensitive_data(const ch
 | ||||
|  	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_SERVER_KEY_FREE, m); | ||||
|  	sshbuf_free(m); | ||||
|  } | ||||
| +
 | ||||
| +int mm_forward_audit_messages(int fdin)
 | ||||
| +{
 | ||||
| +	u_char buf[4];
 | ||||
| +	u_int blen, msg_len;
 | ||||
| +	struct sshbuf *m;
 | ||||
| +	int r, ret = 0;
 | ||||
| +
 | ||||
| +	debug3_f("entering");
 | ||||
| +	if ((m = sshbuf_new()) == NULL)
 | ||||
| + 		fatal_f("sshbuf_new failed");
 | ||||
| +	do {
 | ||||
| +		blen = atomicio(read, fdin, buf, sizeof(buf));
 | ||||
| +		if (blen == 0) /* closed pipe */
 | ||||
| +			break;
 | ||||
| +		if (blen != sizeof(buf)) {
 | ||||
| +			error_f("Failed to read the buffer from child");
 | ||||
| +			ret = -1;
 | ||||
| +			break;
 | ||||
| +		}
 | ||||
| +
 | ||||
| +		msg_len = get_u32(buf);
 | ||||
| +		if (msg_len > 256 * 1024)
 | ||||
| +			fatal_f("read: bad msg_len %d", msg_len);
 | ||||
| +		sshbuf_reset(m);
 | ||||
| +		if ((r = sshbuf_reserve(m, msg_len, NULL)) != 0)
 | ||||
| +			fatal_fr(r, "buffer error");
 | ||||
| +		if (atomicio(read, fdin, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
 | ||||
| +			error_f("Failed to read the the buffer content from the child");
 | ||||
| +			ret = -1;
 | ||||
| +			break;
 | ||||
| +		}
 | ||||
| +		if (atomicio(vwrite, pmonitor->m_recvfd, buf, blen) != blen || 
 | ||||
| +		    atomicio(vwrite, pmonitor->m_recvfd, sshbuf_mutable_ptr(m), msg_len) != msg_len) {
 | ||||
| +			error_f("Failed to write the message to the monitor");
 | ||||
| +			ret = -1;
 | ||||
| +			break;
 | ||||
| +		}
 | ||||
| +	} while (1);
 | ||||
| +	sshbuf_free(m);
 | ||||
| +	return ret;
 | ||||
| +}
 | ||||
| +void mm_set_monitor_pipe(int fd)
 | ||||
| +{
 | ||||
| +	pmonitor->m_recvfd = fd;
 | ||||
| +}
 | ||||
|  #endif /* SSH_AUDIT_EVENTS */ | ||||
| diff -up openssh-7.4p1/monitor_wrap.h.audit-race openssh-7.4p1/monitor_wrap.h
 | ||||
| --- openssh-7.4p1/monitor_wrap.h.audit-race	2016-12-23 16:35:52.694685771 +0100
 | ||||
| +++ openssh-7.4p1/monitor_wrap.h	2016-12-23 16:35:52.698685772 +0100
 | ||||
| @@ -83,6 +83,8 @@ void mm_audit_unsupported_body(int);
 | ||||
|  void mm_audit_kex_body(struct ssh *, int, char *, char *, char *, char *, pid_t, uid_t); | ||||
|  void mm_audit_session_key_free_body(struct ssh *, int, pid_t, uid_t); | ||||
|  void mm_audit_destroy_sensitive_data(struct ssh *, const char *, pid_t, uid_t); | ||||
| +int mm_forward_audit_messages(int);
 | ||||
| +void mm_set_monitor_pipe(int);
 | ||||
|  #endif | ||||
|   | ||||
|  struct Session; | ||||
| diff -up openssh-7.4p1/session.c.audit-race openssh-7.4p1/session.c
 | ||||
| --- openssh-7.4p1/session.c.audit-race	2016-12-23 16:35:52.695685771 +0100
 | ||||
| +++ openssh-7.4p1/session.c	2016-12-23 16:37:26.339730596 +0100
 | ||||
| @@ -162,6 +162,10 @@ static Session *sessions = NULL;
 | ||||
|  login_cap_t *lc; | ||||
|  #endif | ||||
|   | ||||
| +#ifdef SSH_AUDIT_EVENTS
 | ||||
| +int paudit[2];
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  static int is_child = 0; | ||||
|  static int in_chroot = 0; | ||||
|  static int have_dev_log = 1; | ||||
| @@ -289,6 +293,8 @@ xauth_valid_string(const char *s)
 | ||||
|  	return 1; | ||||
|  } | ||||
|   | ||||
| +void child_destory_sensitive_data(struct ssh *ssh);
 | ||||
| +
 | ||||
|  #define USE_PIPES 1 | ||||
|  /* | ||||
|   * This is called to fork and execute a command when we have no tty.  This | ||||
| @@ -424,6 +430,8 @@ do_exec_no_pty(Session *s, const char *c
 | ||||
|  		close(err[0]); | ||||
|  #endif | ||||
|   | ||||
| +		child_destory_sensitive_data(ssh);
 | ||||
| +
 | ||||
|  		/* Do processing for the child (exec command etc). */ | ||||
|  		do_child(ssh, s, command); | ||||
|  		/* NOTREACHED */ | ||||
| @@ -547,6 +555,9 @@ do_exec_pty(Session *s, const char *comm
 | ||||
|  		/* Close the extra descriptor for the pseudo tty. */ | ||||
|  		close(ttyfd); | ||||
|   | ||||
| +		/* Do this early, so we will not block large MOTDs */
 | ||||
| +		child_destory_sensitive_data(ssh);
 | ||||
| +
 | ||||
|  		/* record login, etc. similar to login(1) */ | ||||
|  #ifndef HAVE_OSF_SIA | ||||
|  		do_login(ssh, s, command); | ||||
| @@ -717,6 +728,8 @@ do_exec(Session *s, const char *command)
 | ||||
|  	} | ||||
|  	if (s->command != NULL && s->ptyfd == -1) | ||||
|  		s->command_handle = PRIVSEP(audit_run_command(ssh, s->command)); | ||||
| +	if (pipe(paudit) < 0)
 | ||||
| +		fatal("pipe: %s", strerror(errno));
 | ||||
|  #endif | ||||
|  	if (s->ttyfd != -1) | ||||
|  		ret = do_exec_pty(ssh, s, command); | ||||
| @@ -732,6 +745,20 @@ do_exec(Session *s, const char *command)
 | ||||
|  	 */ | ||||
|  	sshbuf_reset(loginmsg); | ||||
|   | ||||
| +#ifdef SSH_AUDIT_EVENTS
 | ||||
| +	close(paudit[1]);
 | ||||
| +	if (use_privsep && ret == 0) {
 | ||||
| +		/*
 | ||||
| +		 * Read the audit messages from forked child and send them
 | ||||
| +		 * back to monitor. We don't want to communicate directly,
 | ||||
| +		 * because the messages might get mixed up.
 | ||||
| +		 * Continue after the pipe gets closed (all messages sent).
 | ||||
| +		 */
 | ||||
| +		ret = mm_forward_audit_messages(paudit[0]);
 | ||||
| +	}
 | ||||
| +	close(paudit[0]);
 | ||||
| +#endif /* SSH_AUDIT_EVENTS */
 | ||||
| +
 | ||||
|  	return ret; | ||||
|  } | ||||
|   | ||||
| @@ -1538,6 +1565,34 @@ child_close_fds(void)
 | ||||
|  	log_redirect_stderr_to(NULL); | ||||
|  } | ||||
|   | ||||
| +void
 | ||||
| +child_destory_sensitive_data(struct ssh *ssh)
 | ||||
| +{
 | ||||
| +#ifdef SSH_AUDIT_EVENTS
 | ||||
| +	int pparent = paudit[1];
 | ||||
| +	close(paudit[0]);
 | ||||
| +	/* Hack the monitor pipe to avoid race condition with parent */
 | ||||
| +	if (use_privsep)
 | ||||
| +		mm_set_monitor_pipe(pparent);
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +	/* remove hostkey from the child's memory */
 | ||||
| +	destroy_sensitive_data(ssh, use_privsep);
 | ||||
| +	/*
 | ||||
| +	 * We can audit this, because we hacked the pipe to direct the
 | ||||
| +	 * messages over postauth child. But this message requires answer
 | ||||
| +	 * which we can't do using one-way pipe.
 | ||||
| +	 */
 | ||||
| +	packet_destroy_all(ssh, 0, 1);
 | ||||
| +	/* XXX this will clean the rest but should not audit anymore */
 | ||||
| +	/* packet_clear_keys(ssh); */
 | ||||
| +
 | ||||
| +#ifdef SSH_AUDIT_EVENTS
 | ||||
| +	/* Notify parent that we are done */
 | ||||
| +	close(pparent);
 | ||||
| +#endif
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* | ||||
|   * Performs common processing for the child, such as setting up the | ||||
|   * environment, closing extra file descriptors, setting the user and group | ||||
| @@ -1554,13 +1608,6 @@ do_child(Session *s, const char *command
 | ||||
|   | ||||
|  	sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); | ||||
|   | ||||
| -	/* remove hostkey from the child's memory */
 | ||||
| -	destroy_sensitive_data(ssh, 1);
 | ||||
| -	ssh_packet_clear_keys(ssh);
 | ||||
| -	/* Don't audit this - both us and the parent would be talking to the
 | ||||
| -	   monitor over a single socket, with no synchronization. */
 | ||||
| -	packet_destroy_all(ssh, 0, 1);
 | ||||
| -
 | ||||
|  	/* Force a password change */ | ||||
|  	if (s->authctxt->force_pwchange) { | ||||
|  		do_setusercontext(pw); | ||||
							
								
								
									
										87
									
								
								SOURCES/openssh-7.2p2-k5login_directory.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								SOURCES/openssh-7.2p2-k5login_directory.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| diff --git a/auth-krb5.c b/auth-krb5.c
 | ||||
| index 2b02a04..19b9364 100644
 | ||||
| --- a/auth-krb5.c
 | ||||
| +++ b/auth-krb5.c
 | ||||
| @@ -375,5 +375,21 @@ cleanup:
 | ||||
|  		return (krb5_cc_resolve(ctx, ccname, ccache)); | ||||
|  	} | ||||
|  } | ||||
| +
 | ||||
| +/*
 | ||||
| + * Reads  k5login_directory  option from the  krb5.conf
 | ||||
| + */
 | ||||
| +krb5_error_code
 | ||||
| +ssh_krb5_get_k5login_directory(krb5_context ctx, char **k5login_directory) {
 | ||||
| +	profile_t p;
 | ||||
| +	int ret = 0;
 | ||||
| +
 | ||||
| +	ret = krb5_get_profile(ctx, &p);
 | ||||
| +	if (ret)
 | ||||
| +		return ret;
 | ||||
| +
 | ||||
| +	return profile_get_string(p, "libdefaults", "k5login_directory", NULL, NULL,
 | ||||
| +		k5login_directory);
 | ||||
| +}
 | ||||
|  #endif /* !HEIMDAL */ | ||||
|  #endif /* KRB5 */ | ||||
| diff --git a/auth.h b/auth.h
 | ||||
| index f9d191c..c432d2f 100644
 | ||||
| --- a/auth.h
 | ||||
| +++ b/auth.h
 | ||||
| @@ -222,6 +222,8 @@ int	 sys_auth_passwd(Authctxt *, const char *);
 | ||||
|   | ||||
|  #if defined(KRB5) && !defined(HEIMDAL) | ||||
|  krb5_error_code ssh_krb5_cc_new_unique(krb5_context, krb5_ccache *, int *); | ||||
| +krb5_error_code ssh_krb5_get_k5login_directory(krb5_context ctx,
 | ||||
| +	char **k5login_directory);
 | ||||
|  #endif | ||||
|   | ||||
|  #endif /* AUTH_H */ | ||||
| diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
 | ||||
| index a7c0c5f..df8cc9a 100644
 | ||||
| --- a/gss-serv-krb5.c
 | ||||
| +++ b/gss-serv-krb5.c
 | ||||
| @@ -244,8 +244,27 @@ ssh_gssapi_k5login_exists()
 | ||||
|  { | ||||
|  	char file[MAXPATHLEN]; | ||||
|  	struct passwd *pw = the_authctxt->pw; | ||||
| +	char *k5login_directory = NULL;
 | ||||
| +	int ret = 0;
 | ||||
| +
 | ||||
| +	ret = ssh_krb5_get_k5login_directory(krb_context, &k5login_directory);
 | ||||
| +	debug3_f("k5login_directory = %s (rv=%d)", k5login_directory, ret);
 | ||||
| +	if (k5login_directory == NULL || ret != 0) {
 | ||||
| +		/* If not set, the library will look for  k5login
 | ||||
| +		 * files in the user's home directory, with the filename  .k5login.
 | ||||
| +		 */
 | ||||
| +		snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
 | ||||
| +	} else {
 | ||||
| +		/* If set, the library will look for a local user's k5login file
 | ||||
| +		 * within the named directory, with a filename corresponding to the
 | ||||
| +		 * local username.
 | ||||
| +		 */
 | ||||
| +		snprintf(file, sizeof(file), "%s%s%s", k5login_directory, 
 | ||||
| +			k5login_directory[strlen(k5login_directory)-1] != '/' ? "/" : "",
 | ||||
| +			pw->pw_name);
 | ||||
| +	}
 | ||||
| +	debug_f("Checking existence of file %s", file);
 | ||||
|   | ||||
| -	snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
 | ||||
|  	return access(file, F_OK) == 0; | ||||
|  } | ||||
|   | ||||
| diff --git a/sshd.8 b/sshd.8
 | ||||
| index 5c4f15b..135e290 100644
 | ||||
| --- a/sshd.8
 | ||||
| +++ b/sshd.8
 | ||||
| @@ -806,6 +806,10 @@ rlogin/rsh.
 | ||||
|  These files enforce GSSAPI/Kerberos authentication access control. | ||||
|  Further details are described in | ||||
|  .Xr ksu 1 . | ||||
| +The location of the k5login file depends on the configuration option
 | ||||
| +.Cm k5login_directory
 | ||||
| +in the
 | ||||
| +.Xr krb5.conf 5 .
 | ||||
|  .Pp | ||||
|  .It Pa ~/.ssh/ | ||||
|  This directory is the default location for all user-specific configuration | ||||
							
								
								
									
										52
									
								
								SOURCES/openssh-7.2p2-s390-closefrom.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								SOURCES/openssh-7.2p2-s390-closefrom.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| Zseries only: Leave the hardware filedescriptors open. | ||||
| 
 | ||||
| All filedescriptors above 2 are getting closed when a new | ||||
| sshd process to handle a new client connection is | ||||
| spawned. As the process also chroot into an empty filesystem | ||||
| without any device nodes, there is no chance to reopen the | ||||
| files. This patch filters out the reqired fds in the | ||||
| closefrom function so these are skipped in the close loop. | ||||
| 
 | ||||
| Author: Harald Freudenberger <freude@de.ibm.com> | ||||
| 
 | ||||
| ---
 | ||||
|  openbsd-compat/bsd-closefrom.c |   26 ++++++++++++++++++++++++++ | ||||
|  1 file changed, 26 insertions(+) | ||||
| 
 | ||||
| --- a/openbsd-compat/bsd-closefrom.c
 | ||||
| +++ b/openbsd-compat/bsd-closefrom.c
 | ||||
| @@ -82,7 +82,33 @@ closefrom(int lowfd)
 | ||||
|  	    fd = strtol(dent->d_name, &endp, 10); | ||||
|  	    if (dent->d_name != endp && *endp == '\0' && | ||||
|  		fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) | ||||
| +#ifdef __s390__
 | ||||
| +		{
 | ||||
| +		    /*
 | ||||
| +		     * the filedescriptors used to communicate with
 | ||||
| +		     * the device drivers to provide hardware support
 | ||||
| +		     * should survive. HF <freude@de.ibm.com>
 | ||||
| +		     */
 | ||||
| +		    char fpath[PATH_MAX], lpath[PATH_MAX];
 | ||||
| +		    len = snprintf(fpath, sizeof(fpath), "%s/%s",
 | ||||
| +				   fdpath, dent->d_name);
 | ||||
| +		    if (len > 0 && (size_t)len <= sizeof(fpath)) {
 | ||||
| +			len = readlink(fpath, lpath, sizeof(lpath));
 | ||||
| +			if (len > 0) {
 | ||||
| +			    lpath[len] = 0;
 | ||||
| +			    if (strstr(lpath, "dev/z90crypt")
 | ||||
| +				|| strstr(lpath, "dev/zcrypt")
 | ||||
| +				|| strstr(lpath, "dev/prandom")
 | ||||
| +				|| strstr(lpath, "dev/shm/icastats"))
 | ||||
| +				fd = -1;
 | ||||
| +			}
 | ||||
| +		    }
 | ||||
| +		    if (fd >= 0)
 | ||||
| +			(void) close((int) fd);
 | ||||
| +		}
 | ||||
| +#else
 | ||||
|  		(void) close((int) fd); | ||||
| +#endif
 | ||||
|  	} | ||||
|  	(void) closedir(dirp); | ||||
|  	return; | ||||
| 
 | ||||
							
								
								
									
										53
									
								
								SOURCES/openssh-7.2p2-x11.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								SOURCES/openssh-7.2p2-x11.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| diff -up openssh-7.2p2/channels.c.x11 openssh-7.2p2/channels.c
 | ||||
| --- openssh-7.2p2/channels.c.x11	2016-03-09 19:04:48.000000000 +0100
 | ||||
| +++ openssh-7.2p2/channels.c	2016-06-03 10:42:04.775164520 +0200
 | ||||
| @@ -3990,21 +3990,24 @@ x11_create_display_inet(int x11_display_
 | ||||
|  } | ||||
|   | ||||
|  static int | ||||
| -connect_local_xsocket_path(const char *pathname)
 | ||||
| +connect_local_xsocket_path(const char *pathname, int len)
 | ||||
|  { | ||||
|  	int sock; | ||||
|  	struct sockaddr_un addr; | ||||
|   | ||||
| +	if (len <= 0)
 | ||||
| +		return -1;
 | ||||
|  	sock = socket(AF_UNIX, SOCK_STREAM, 0); | ||||
|  	if (sock == -1) | ||||
|  		error("socket: %.100s", strerror(errno)); | ||||
|  	memset(&addr, 0, sizeof(addr)); | ||||
|  	addr.sun_family = AF_UNIX; | ||||
| -	strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);
 | ||||
| -	if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
 | ||||
| +	if (len > sizeof addr.sun_path)
 | ||||
| +		len = sizeof addr.sun_path;
 | ||||
| +	memcpy(addr.sun_path, pathname, len);
 | ||||
| +	if (connect(sock, (struct sockaddr *)&addr, sizeof addr - (sizeof addr.sun_path - len) ) == 0)
 | ||||
|  		return sock; | ||||
|  	close(sock); | ||||
| -	error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
 | ||||
|  	return -1; | ||||
|  } | ||||
|   | ||||
| @@ -4012,8 +4015,18 @@ static int
 | ||||
|  connect_local_xsocket(u_int dnr) | ||||
|  { | ||||
|  	char buf[1024]; | ||||
| -	snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr);
 | ||||
| -	return connect_local_xsocket_path(buf);
 | ||||
| +	int len, ret;
 | ||||
| +	len = snprintf(buf + 1, sizeof (buf) - 1, _PATH_UNIX_X, dnr);
 | ||||
| +#ifdef linux
 | ||||
| +	/* try abstract socket first */
 | ||||
| +	buf[0] = '\0';
 | ||||
| +	if ((ret = connect_local_xsocket_path(buf, len + 1)) >= 0)
 | ||||
| +		return ret;
 | ||||
| +#endif
 | ||||
| +	if ((ret = connect_local_xsocket_path(buf + 1, len)) >= 0)
 | ||||
| +		return ret;
 | ||||
| +	error("connect %.100s: %.100s", buf + 1, strerror(errno));
 | ||||
| +	return -1;
 | ||||
|  } | ||||
|   | ||||
|  #ifdef __APPLE__ | ||||
							
								
								
									
										213
									
								
								SOURCES/openssh-7.3p1-x11-max-displays.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								SOURCES/openssh-7.3p1-x11-max-displays.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,213 @@ | ||||
| diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c
 | ||||
| --- openssh-7.4p1/channels.c.x11max	2016-12-23 15:46:32.071506625 +0100
 | ||||
| +++ openssh-7.4p1/channels.c	2016-12-23 15:46:32.139506636 +0100
 | ||||
| @@ -152,8 +152,8 @@ static int all_opens_permitted = 0;
 | ||||
|  #define FWD_PERMIT_ANY_HOST	"*" | ||||
|   | ||||
|  /* -- X11 forwarding */ | ||||
| -/* Maximum number of fake X11 displays to try. */
 | ||||
| -#define MAX_DISPLAYS  1000
 | ||||
| +/* Minimum port number for X11 forwarding */
 | ||||
| +#define X11_PORT_MIN 6000
 | ||||
|   | ||||
|  /* Per-channel callback for pre/post select() actions */ | ||||
|  typedef void chan_fn(struct ssh *, Channel *c, | ||||
| @@ -4228,7 +4228,7 @@ channel_send_window_changes(void)
 | ||||
|   */ | ||||
|  int | ||||
|  x11_create_display_inet(struct ssh *ssh, int x11_display_offset, | ||||
| -    int x11_use_localhost, int single_connection,
 | ||||
| +    int x11_use_localhost, int x11_max_displays, int single_connection,
 | ||||
|      u_int *display_numberp, int **chanids) | ||||
|  { | ||||
|  	Channel *nc = NULL; | ||||
| @@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_
 | ||||
|  	if (chanids == NULL) | ||||
|  		return -1; | ||||
|   | ||||
| +	/* Try to bind ports starting at 6000+X11DisplayOffset */
 | ||||
| +	x11_max_displays = x11_max_displays + x11_display_offset;
 | ||||
| +
 | ||||
|  	for (display_number = x11_display_offset; | ||||
| -	    display_number < MAX_DISPLAYS;
 | ||||
| +	    display_number < x11_max_displays;
 | ||||
|  	    display_number++) { | ||||
| -		port = 6000 + display_number;
 | ||||
| +		port = X11_PORT_MIN + display_number;
 | ||||
| +		if (port < X11_PORT_MIN) /* overflow */
 | ||||
| +			break;
 | ||||
|  		memset(&hints, 0, sizeof(hints)); | ||||
|  		hints.ai_family = ssh->chanctxt->IPv4or6; | ||||
|  		hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; | ||||
| @@ -4295,7 +4301,7 @@ x11_create_display_inet(int x11_display_
 | ||||
|  		if (num_socks > 0) | ||||
|  			break; | ||||
|  	} | ||||
| -	if (display_number >= MAX_DISPLAYS) {
 | ||||
| +	if (display_number >= x11_max_displays || port < X11_PORT_MIN ) {
 | ||||
|  		error("Failed to allocate internet-domain X11 display socket."); | ||||
|  		return -1; | ||||
|  	} | ||||
| @@ -4441,7 +4447,7 @@ x11_connect_display(void)
 | ||||
|  	memset(&hints, 0, sizeof(hints)); | ||||
|  	hints.ai_family = ssh->chanctxt->IPv4or6; | ||||
|  	hints.ai_socktype = SOCK_STREAM; | ||||
| -	snprintf(strport, sizeof strport, "%u", 6000 + display_number);
 | ||||
| +	snprintf(strport, sizeof strport, "%u", X11_PORT_MIN + display_number);
 | ||||
|  	if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { | ||||
|  		error("%.100s: unknown host. (%s)", buf, | ||||
|  		ssh_gai_strerror(gaierr)); | ||||
| @@ -4457,7 +4463,7 @@ x11_connect_display(void)
 | ||||
|  		/* Connect it to the display. */ | ||||
|  		if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { | ||||
|  			debug2("connect %.100s port %u: %.100s", buf, | ||||
| -			    6000 + display_number, strerror(errno));
 | ||||
| +			    X11_PORT_MIN + display_number, strerror(errno));
 | ||||
|  			close(sock); | ||||
|  			continue; | ||||
|  		} | ||||
| @@ -4466,8 +4472,8 @@ x11_connect_display(void)
 | ||||
|  	} | ||||
|  	freeaddrinfo(aitop); | ||||
|  	if (!ai) { | ||||
| -		error("connect %.100s port %u: %.100s", buf,
 | ||||
| -		    6000 + display_number, strerror(errno));
 | ||||
| +		error("connect %.100s port %u: %.100s", buf,
 | ||||
| +		    X11_PORT_MIN + display_number, strerror(errno));
 | ||||
|  		return -1; | ||||
|  	} | ||||
|  	set_nodelay(sock); | ||||
| diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h
 | ||||
| --- openssh-7.4p1/channels.h.x11max	2016-12-19 05:59:41.000000000 +0100
 | ||||
| +++ openssh-7.4p1/channels.h	2016-12-23 15:46:32.139506636 +0100
 | ||||
| @@ -293,7 +293,7 @@ int	 permitopen_port(const char *);
 | ||||
|   | ||||
|  void	 channel_set_x11_refuse_time(struct ssh *, u_int); | ||||
|  int	 x11_connect_display(struct ssh *); | ||||
| -int	 x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);
 | ||||
| +int	 x11_create_display_inet(struct ssh *, int, int, int, int, u_int *, int **);
 | ||||
|  void	 x11_request_forwarding_with_spoofing(struct ssh *, int, | ||||
|  	    const char *, const char *, const char *, int); | ||||
|   | ||||
| diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c
 | ||||
| --- openssh-7.4p1/servconf.c.x11max	2016-12-23 15:46:32.133506635 +0100
 | ||||
| +++ openssh-7.4p1/servconf.c	2016-12-23 15:47:27.320519121 +0100
 | ||||
| @@ -95,6 +95,7 @@ initialize_server_options(ServerOptions
 | ||||
|  	options->print_lastlog = -1; | ||||
|  	options->x11_forwarding = -1; | ||||
|  	options->x11_display_offset = -1; | ||||
| +	options->x11_max_displays = -1;
 | ||||
|  	options->x11_use_localhost = -1; | ||||
|  	options->permit_tty = -1; | ||||
|  	options->permit_user_rc = -1; | ||||
| @@ -243,6 +244,8 @@ fill_default_server_options(ServerOption
 | ||||
|  		options->x11_forwarding = 0; | ||||
|  	if (options->x11_display_offset == -1) | ||||
|  		options->x11_display_offset = 10; | ||||
| +	if (options->x11_max_displays == -1)
 | ||||
| +		options->x11_max_displays = DEFAULT_MAX_DISPLAYS;
 | ||||
|  	if (options->x11_use_localhost == -1) | ||||
|  		options->x11_use_localhost = 1; | ||||
|  	if (options->xauth_location == NULL) | ||||
| @@ -419,7 +422,7 @@ typedef enum {
 | ||||
|  	sPasswordAuthentication, sKbdInteractiveAuthentication, | ||||
|  	sListenAddress, sAddressFamily, | ||||
|  	sPrintMotd, sPrintLastLog, sIgnoreRhosts, | ||||
| -	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
 | ||||
| +	sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost,
 | ||||
|  	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, | ||||
|  	sPermitUserEnvironment, sAllowTcpForwarding, sCompression, | ||||
|  	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, | ||||
| @@ -540,6 +543,7 @@ static struct {
 | ||||
|  	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, | ||||
|  	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL }, | ||||
|  	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL }, | ||||
| +	{ "x11maxdisplays", sX11MaxDisplays, SSHCFG_ALL },
 | ||||
|  	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, | ||||
|  	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, | ||||
|  	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL }, | ||||
| @@ -1316,6 +1320,10 @@ process_server_config_line(ServerOptions
 | ||||
|  			*intptr = value; | ||||
|  		break; | ||||
|   | ||||
| +	case sX11MaxDisplays:
 | ||||
| +		intptr = &options->x11_max_displays;
 | ||||
| +		goto parse_int;
 | ||||
| +
 | ||||
|  	case sX11UseLocalhost: | ||||
|  		intptr = &options->x11_use_localhost; | ||||
|  		goto parse_flag; | ||||
| @@ -2063,6 +2071,7 @@ copy_set_server_options(ServerOptions *d
 | ||||
|  	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); | ||||
|  	M_CP_INTOPT(x11_display_offset); | ||||
|  	M_CP_INTOPT(x11_forwarding); | ||||
| +	M_CP_INTOPT(x11_max_displays);
 | ||||
|  	M_CP_INTOPT(x11_use_localhost); | ||||
|  	M_CP_INTOPT(permit_tty); | ||||
|  	M_CP_INTOPT(permit_user_rc); | ||||
| @@ -2315,6 +2324,7 @@ dump_config(ServerOptions *o)
 | ||||
|  #endif | ||||
|  	dump_cfg_int(sLoginGraceTime, o->login_grace_time); | ||||
|  	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); | ||||
| +	dump_cfg_int(sX11MaxDisplays, o->x11_max_displays);
 | ||||
|  	dump_cfg_int(sMaxAuthTries, o->max_authtries); | ||||
|  	dump_cfg_int(sMaxSessions, o->max_sessions); | ||||
|  	dump_cfg_int(sClientAliveInterval, o->client_alive_interval); | ||||
| diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h
 | ||||
| --- openssh-7.4p1/servconf.h.x11max	2016-12-23 15:46:32.133506635 +0100
 | ||||
| +++ openssh-7.4p1/servconf.h	2016-12-23 15:46:32.140506636 +0100
 | ||||
| @@ -55,6 +55,7 @@
 | ||||
|   | ||||
|  #define DEFAULT_AUTH_FAIL_MAX	6	/* Default for MaxAuthTries */ | ||||
|  #define DEFAULT_SESSIONS_MAX	10	/* Default for MaxSessions */ | ||||
| +#define DEFAULT_MAX_DISPLAYS	1000 /* Maximum number of fake X11 displays to try. */
 | ||||
|   | ||||
|  /* Magic name for internal sftp-server */ | ||||
|  #define INTERNAL_SFTP_NAME	"internal-sftp" | ||||
| @@ -85,6 +86,7 @@ typedef struct {
 | ||||
|  	int     x11_forwarding;	/* If true, permit inet (spoofing) X11 fwd. */ | ||||
|  	int     x11_display_offset;	/* What DISPLAY number to start | ||||
|  					 * searching at */ | ||||
| +	int 	x11_max_displays; /* Number of displays to search */
 | ||||
|  	int     x11_use_localhost;	/* If true, use localhost for fake X11 server. */ | ||||
|  	char   *xauth_location;	/* Location of xauth program */ | ||||
|  	int	permit_tty;	/* If false, deny pty allocation */ | ||||
| diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c
 | ||||
| --- openssh-7.4p1/session.c.x11max	2016-12-23 15:46:32.136506636 +0100
 | ||||
| +++ openssh-7.4p1/session.c	2016-12-23 15:46:32.141506636 +0100
 | ||||
| @@ -2518,8 +2518,9 @@ session_setup_x11fwd(Session *s)
 | ||||
|  		return 0; | ||||
|  	} | ||||
| 	if (x11_create_display_inet(ssh, options.x11_display_offset, | ||||
| -	    options.x11_use_localhost, s->single_connection,
 | ||||
| -	    &s->display_number, &s->x11_chanids) == -1) {
 | ||||
| +	    options.x11_use_localhost, options.x11_max_displays,
 | ||||
| +	    s->single_connection, &s->display_number,
 | ||||
| +	    &s->x11_chanids) == -1) {
 | ||||
|  		debug("x11_create_display_inet failed."); | ||||
|  		return 0; | ||||
|  	} | ||||
| diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5
 | ||||
| --- openssh-7.4p1/sshd_config.5.x11max	2016-12-23 15:46:32.134506635 +0100
 | ||||
| +++ openssh-7.4p1/sshd_config.5	2016-12-23 15:46:32.141506636 +0100
 | ||||
| @@ -1133,6 +1133,7 @@ Available keywords are
 | ||||
|  .Cm StreamLocalBindUnlink , | ||||
|  .Cm TrustedUserCAKeys , | ||||
|  .Cm X11DisplayOffset , | ||||
| +.Cm X11MaxDisplays ,
 | ||||
|  .Cm X11Forwarding | ||||
|  and | ||||
|  .Cm X11UseLocalhost . | ||||
| @@ -1566,6 +1567,12 @@ Specifies the first display number avail
 | ||||
|  X11 forwarding. | ||||
|  This prevents sshd from interfering with real X11 servers. | ||||
|  The default is 10. | ||||
| +.It Cm X11MaxDisplays
 | ||||
| +Specifies the maximum number of displays available for
 | ||||
| +.Xr sshd 8 Ns 's
 | ||||
| +X11 forwarding.
 | ||||
| +This prevents sshd from exhausting local ports.
 | ||||
| +The default is 1000.
 | ||||
|  .It Cm X11Forwarding | ||||
|  Specifies whether X11 forwarding is permitted. | ||||
|  The argument must be | ||||
							
								
								
									
										98
									
								
								SOURCES/openssh-7.4p1-systemd.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								SOURCES/openssh-7.4p1-systemd.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | ||||
| commit 0e22b79bfde45a7cf7a2e51a68ec11c4285f3b31 | ||||
| Author: Jakub Jelen <jjelen@redhat.com> | ||||
| Date:   Mon Nov 21 15:04:06 2016 +0100 | ||||
| 
 | ||||
|     systemd stuff | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 2ffc369..162ce92 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -4265,6 +4265,30 @@ AC_ARG_WITH([kerberos5],
 | ||||
|  AC_SUBST([GSSLIBS]) | ||||
|  AC_SUBST([K5LIBS]) | ||||
|   | ||||
| +# Check whether user wants systemd support
 | ||||
| +SYSTEMD_MSG="no"
 | ||||
| +AC_ARG_WITH(systemd,
 | ||||
| +	[  --with-systemd          Enable systemd support],
 | ||||
| +	[ if test "x$withval" != "xno" ; then
 | ||||
| +		AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no])
 | ||||
| +		if test "$PKGCONFIG" != "no"; then
 | ||||
| +			AC_MSG_CHECKING([for libsystemd])
 | ||||
| +			if $PKGCONFIG --exists libsystemd; then
 | ||||
| +				SYSTEMD_CFLAGS=`$PKGCONFIG --cflags libsystemd`
 | ||||
| +				SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd`
 | ||||
| +				CPPFLAGS="$CPPFLAGS $SYSTEMD_CFLAGS"
 | ||||
| +				SSHDLIBS="$SSHDLIBS $SYSTEMD_LIBS"
 | ||||
| +				AC_MSG_RESULT([yes])
 | ||||
| +				AC_DEFINE(HAVE_SYSTEMD, 1, [Define if you want systemd support.])
 | ||||
| +				SYSTEMD_MSG="yes"
 | ||||
| +			else
 | ||||
| +				AC_MSG_RESULT([no])
 | ||||
| +			fi
 | ||||
| +		fi
 | ||||
| +	fi ]
 | ||||
| +)
 | ||||
| +
 | ||||
| +
 | ||||
|  # Looking for programs, paths and files | ||||
|   | ||||
|  PRIVSEP_PATH=/var/empty | ||||
| @@ -5097,6 +5121,7 @@ echo "                   libedit support: $LIBEDIT_MSG"
 | ||||
|  echo "  Solaris process contract support: $SPC_MSG" | ||||
|  echo "           Solaris project support: $SP_MSG" | ||||
|  echo "         Solaris privilege support: $SPP_MSG" | ||||
| +echo "                   systemd support: $SYSTEMD_MSG"
 | ||||
|  echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" | ||||
|  echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" | ||||
|  echo "                  BSD Auth support: $BSD_AUTH_MSG" | ||||
| diff --git a/contrib/sshd.service b/contrib/sshd.service
 | ||||
| new file mode 100644 | ||||
| index 0000000..e0d4923
 | ||||
| --- /dev/null
 | ||||
| +++ b/contrib/sshd.service
 | ||||
| @@ -0,0 +1,16 @@
 | ||||
| +[Unit]
 | ||||
| +Description=OpenSSH server daemon
 | ||||
| +Documentation=man:sshd(8) man:sshd_config(5)
 | ||||
| +After=network.target
 | ||||
| +
 | ||||
| +[Service]
 | ||||
| +Type=notify
 | ||||
| +ExecStart=/usr/sbin/sshd -D $OPTIONS
 | ||||
| +ExecReload=/bin/kill -HUP $MAINPID
 | ||||
| +KillMode=process
 | ||||
| +Restart=on-failure
 | ||||
| +RestartPreventExitStatus=255
 | ||||
| +
 | ||||
| +[Install]
 | ||||
| +WantedBy=multi-user.target
 | ||||
| +
 | ||||
| diff --git a/sshd.c b/sshd.c
 | ||||
| index 816611c..b8b9d13 100644
 | ||||
| --- a/sshd.c
 | ||||
| +++ b/sshd.c
 | ||||
| @@ -85,6 +85,10 @@
 | ||||
|  #include <prot.h> | ||||
|  #endif | ||||
|   | ||||
| +#ifdef HAVE_SYSTEMD
 | ||||
| +#include <systemd/sd-daemon.h>
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  #include "xmalloc.h" | ||||
|  #include "ssh.h" | ||||
|  #include "ssh2.h" | ||||
| @@ -1888,6 +1892,11 @@ main(int ac, char **av)
 | ||||
|  			} | ||||
|  		} | ||||
|   | ||||
| +#ifdef HAVE_SYSTEMD
 | ||||
| +		/* Signal systemd that we are ready to accept connections */
 | ||||
| +		sd_notify(0, "READY=1");
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  		/* Accept a connection and return in a forked child */ | ||||
|  		server_accept_loop(&sock_in, &sock_out, | ||||
|  		    &newsock, config_s); | ||||
							
								
								
									
										86
									
								
								SOURCES/openssh-7.5p1-sandbox.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								SOURCES/openssh-7.5p1-sandbox.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,86 @@ | ||||
| In order to use the OpenSSL-ibmpkcs11 engine it is needed to allow flock | ||||
| and ipc calls, because this engine calls OpenCryptoki (a PKCS#11 | ||||
| implementation) which calls the libraries that will communicate with the | ||||
| crypto cards. OpenCryptoki makes use of flock and ipc and, as of now, | ||||
| this is only need on s390 architecture. | ||||
| 
 | ||||
| Signed-off-by: Eduardo Barretto <ebarretto@xxxxxxxxxxxxxxxxxx> | ||||
| ---
 | ||||
|  sandbox-seccomp-filter.c | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
| 
 | ||||
| diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
 | ||||
| index ca75cc7..6e7de31 100644
 | ||||
| --- a/sandbox-seccomp-filter.c
 | ||||
| +++ b/sandbox-seccomp-filter.c
 | ||||
| @@ -166,6 +166,9 @@ static const struct sock_filter preauth_insns[] = {
 | ||||
|  #ifdef __NR_exit_group | ||||
|  	SC_ALLOW(__NR_exit_group), | ||||
|  #endif | ||||
| +#if defined(__NR_flock) && defined(__s390__)
 | ||||
| +	SC_ALLOW(__NR_flock),
 | ||||
| +#endif
 | ||||
|  #ifdef __NR_futex | ||||
|  	SC_ALLOW(__NR_futex), | ||||
|  #endif | ||||
| @@ -178,6 +181,9 @@ static const struct sock_filter preauth_insns[] = {
 | ||||
|  #ifdef __NR_gettimeofday | ||||
|  	SC_ALLOW(__NR_gettimeofday), | ||||
|  #endif | ||||
| +#if defined(__NR_ipc) && defined(__s390__)
 | ||||
| +	SC_ALLOW(__NR_ipc),
 | ||||
| +#endif
 | ||||
|  #ifdef __NR_getuid | ||||
|  	SC_ALLOW(__NR_getuid), | ||||
|  #endif | ||||
| -- 
 | ||||
| 1.9.1 | ||||
| 
 | ||||
| getuid and geteuid are needed when using an openssl engine that calls a | ||||
| crypto card, e.g. ICA (libica). | ||||
| Those syscalls are also needed by the distros for audit code. | ||||
| 
 | ||||
| Signed-off-by: Eduardo Barretto <ebarretto@xxxxxxxxxxxxxxxxxx> | ||||
| ---
 | ||||
|  sandbox-seccomp-filter.c | 12 ++++++++++++ | ||||
|  1 file changed, 12 insertions(+) | ||||
| 
 | ||||
| diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
 | ||||
| index 6e7de31..e86aa2c 100644
 | ||||
| --- a/sandbox-seccomp-filter.c
 | ||||
| +++ b/sandbox-seccomp-filter.c
 | ||||
| @@ -175,6 +175,18 @@ static const struct sock_filter preauth_insns[] = {
 | ||||
|  #ifdef __NR_getpid | ||||
|  	SC_ALLOW(__NR_getpid), | ||||
|  #endif | ||||
| +#ifdef __NR_getuid
 | ||||
| +	SC_ALLOW(__NR_getuid),
 | ||||
| +#endif
 | ||||
| +#ifdef __NR_getuid32
 | ||||
| +	SC_ALLOW(__NR_getuid32),
 | ||||
| +#endif
 | ||||
| +#ifdef __NR_geteuid
 | ||||
| +	SC_ALLOW(__NR_geteuid),
 | ||||
| +#endif
 | ||||
| +#ifdef __NR_geteuid32
 | ||||
| +	SC_ALLOW(__NR_geteuid32),
 | ||||
| +#endif
 | ||||
|  #ifdef __NR_getrandom | ||||
|  	SC_ALLOW(__NR_getrandom), | ||||
|  #endif | ||||
| -- 1.9.1
 | ||||
| 1.9.1 | ||||
| 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	2017-12-12 13:59:14.842784083 +0100
 | ||||
| @@ -190,6 +190,9 @@ static const struct sock_filter preauth_
 | ||||
|  #ifdef __NR_geteuid32 | ||||
|  	SC_ALLOW(__NR_geteuid32), | ||||
|  #endif | ||||
| +#ifdef __NR_gettid
 | ||||
| +	SC_ALLOW(__NR_gettid),
 | ||||
| +#endif
 | ||||
|  #ifdef __NR_getrandom | ||||
|  	SC_ALLOW(__NR_getrandom), | ||||
|  #endif | ||||
| 
 | ||||
							
								
								
									
										2323
									
								
								SOURCES/openssh-7.6p1-audit.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2323
									
								
								SOURCES/openssh-7.6p1-audit.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										283
									
								
								SOURCES/openssh-7.6p1-cleanup-selinux.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								SOURCES/openssh-7.6p1-cleanup-selinux.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,283 @@ | ||||
| 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	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -72,6 +72,9 @@
 | ||||
|   | ||||
|  /* import */ | ||||
|  extern ServerOptions options; | ||||
| +extern int inetd_flag;
 | ||||
| +extern int rexeced_flag;
 | ||||
| +extern Authctxt *the_authctxt;
 | ||||
|   | ||||
|  static char * | ||||
|  format_key(const struct sshkey *key) | ||||
| @@ -511,7 +514,8 @@ match_principals_command(struct ssh *ssh
 | ||||
|  	if ((pid = subprocess("AuthorizedPrincipalsCommand", command, | ||||
|  	    ac, av, &f, | ||||
|  	    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)
 | ||||
|  		goto out; | ||||
|   | ||||
|  	uid_swapped = 1; | ||||
| @@ -981,7 +985,8 @@ user_key_command_allowed2(struct ssh *ss
 | ||||
|  	if ((pid = subprocess("AuthorizedKeysCommand", command, | ||||
|  	    ac, av, &f, | ||||
| 	    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)
 | ||||
|  		goto out; | ||||
|   | ||||
|  	uid_swapped = 1; | ||||
| diff -up openssh/misc.c.refactor openssh/misc.c
 | ||||
| --- openssh/misc.c.refactor	2019-04-04 13:19:12.235821686 +0200
 | ||||
| +++ openssh/misc.c	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -756,7 +756,8 @@ auth_get_canonical_hostname(struct ssh *
 | ||||
|  pid_t | ||||
|  subprocess(const char *tag, const char *command, | ||||
|      int ac, char **av, FILE **child, u_int flags, | ||||
| -    struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs)
 | ||||
| +    struct passwd *pw, privdrop_fn *drop_privs,
 | ||||
| +    privrestore_fn *restore_privs, int inetd, void *the_authctxt)
 | ||||
|  { | ||||
|  	FILE *f = NULL; | ||||
|  	struct stat st; | ||||
| @@ -872,7 +873,7 @@ subprocess(const char *tag, struct passw
 | ||||
|  			_exit(1); | ||||
|  		} | ||||
|  #ifdef WITH_SELINUX | ||||
| -		if (sshd_selinux_setup_env_variables() < 0) {
 | ||||
| +		if (sshd_selinux_setup_env_variables(inetd, the_authctxt) < 0) {
 | ||||
|  			error ("failed to copy environment:  %s", | ||||
|  			    strerror(errno)); | ||||
|  			_exit(127); | ||||
| diff -up openssh/misc.h.refactor openssh/misc.h
 | ||||
| --- openssh/misc.h.refactor	2019-04-04 13:19:12.251821839 +0200
 | ||||
| +++ openssh/misc.h	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -235,7 +235,7 @@ struct passwd *fakepw(void);
 | ||||
|  #define	SSH_SUBPROCESS_UNSAFE_PATH	(1<<3)	/* Don't check for safe cmd */ | ||||
|  #define	SSH_SUBPROCESS_PRESERVE_ENV	(1<<4)	/* Keep parent environment */ | ||||
|  pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int, | ||||
| -    struct passwd *, privdrop_fn *, privrestore_fn *);
 | ||||
| +    struct passwd *, privdrop_fn *, privrestore_fn *, int, void *);
 | ||||
|   | ||||
|  typedef struct arglist arglist; | ||||
|  struct arglist { | ||||
| 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	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -26,8 +26,8 @@ void ssh_selinux_setfscreatecon(const ch
 | ||||
|   | ||||
|  int sshd_selinux_enabled(void); | ||||
|  void sshd_selinux_copy_context(void); | ||||
| -void sshd_selinux_setup_exec_context(char *);
 | ||||
| -int sshd_selinux_setup_env_variables(void);
 | ||||
| +void sshd_selinux_setup_exec_context(char *, int, int(char *, const char *), void *, int);
 | ||||
| +int sshd_selinux_setup_env_variables(int inetd, void *);
 | ||||
|  void sshd_selinux_change_privsep_preauth_context(void); | ||||
|  #endif | ||||
|   | ||||
| diff -up openssh/openbsd-compat/port-linux-sshd.c.refactor openssh/openbsd-compat/port-linux-sshd.c
 | ||||
| --- openssh/openbsd-compat/port-linux-sshd.c.refactor	2019-04-04 13:19:12.256821887 +0200
 | ||||
| +++ openssh/openbsd-compat/port-linux-sshd.c	2019-04-04 13:19:12.276822078 +0200
 | ||||
| @@ -49,11 +49,6 @@
 | ||||
|  #include <unistd.h> | ||||
|  #endif | ||||
|   | ||||
| -extern ServerOptions options;
 | ||||
| -extern Authctxt *the_authctxt;
 | ||||
| -extern int inetd_flag;
 | ||||
| -extern int rexeced_flag;
 | ||||
| -
 | ||||
|  /* Wrapper around is_selinux_enabled() to log its return value once only */ | ||||
|  int | ||||
|  sshd_selinux_enabled(void) | ||||
| @@ -223,7 +218,8 @@ get_user_context(const char *sename, con
 | ||||
|  } | ||||
|   | ||||
|  static void | ||||
| -ssh_selinux_get_role_level(char **role, const char **level)
 | ||||
| +ssh_selinux_get_role_level(char **role, const char **level,
 | ||||
| +    Authctxt *the_authctxt)
 | ||||
|  { | ||||
|  	*role = NULL; | ||||
|  	*level = NULL; | ||||
| @@ -241,8 +237,8 @@ ssh_selinux_get_role_level(char **role,
 | ||||
|   | ||||
|  /* Return the default security context for the given username */ | ||||
|  static int | ||||
| -sshd_selinux_getctxbyname(char *pwname,
 | ||||
| -	security_context_t *default_sc, security_context_t *user_sc)
 | ||||
| +sshd_selinux_getctxbyname(char *pwname, security_context_t *default_sc,
 | ||||
| +    security_context_t *user_sc, int inetd, Authctxt *the_authctxt)
 | ||||
|  { | ||||
|  	char *sename, *lvl; | ||||
|  	char *role; | ||||
| @@ -250,7 +246,7 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
|  	int r = 0; | ||||
|  	context_t con = NULL; | ||||
|   | ||||
| -	ssh_selinux_get_role_level(&role, &reqlvl);
 | ||||
| +	ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
 | ||||
|   | ||||
|  #ifdef HAVE_GETSEUSERBYNAME | ||||
|  	if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { | ||||
| @@ -272,7 +268,7 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
|   | ||||
|  	if (r == 0) { | ||||
|  		/* If launched from xinetd, we must use current level */ | ||||
| -		if (inetd_flag && !rexeced_flag) {
 | ||||
| +		if (inetd) {
 | ||||
|  			security_context_t sshdsc=NULL; | ||||
|   | ||||
|  			if (getcon_raw(&sshdsc) < 0) | ||||
| @@ -333,7 +329,8 @@ sshd_selinux_getctxbyname(char *pwname,
 | ||||
|   | ||||
|  /* Setup environment variables for pam_selinux */ | ||||
|  static int | ||||
| -sshd_selinux_setup_variables(int(*set_it)(char *, const char *))
 | ||||
| +sshd_selinux_setup_variables(int(*set_it)(char *, const char *), int inetd,
 | ||||
| +    Authctxt *the_authctxt)
 | ||||
|  { | ||||
|  	const char *reqlvl; | ||||
|  	char *role; | ||||
| @@ -342,11 +339,11 @@ sshd_selinux_setup_variables(int(*set_it
 | ||||
|   | ||||
|  	debug3_f("setting execution context"); | ||||
|   | ||||
| -	ssh_selinux_get_role_level(&role, &reqlvl);
 | ||||
| +	ssh_selinux_get_role_level(&role, &reqlvl, the_authctxt);
 | ||||
|   | ||||
|  	rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : ""); | ||||
|   | ||||
| -	if (inetd_flag && !rexeced_flag) {
 | ||||
| +	if (inetd) {
 | ||||
|  		use_current = "1"; | ||||
|  	} else { | ||||
|  		use_current = ""; | ||||
| @@ -362,9 +359,10 @@ sshd_selinux_setup_variables(int(*set_it
 | ||||
|  } | ||||
|   | ||||
|  static int | ||||
| -sshd_selinux_setup_pam_variables(void)
 | ||||
| +sshd_selinux_setup_pam_variables(int inetd,
 | ||||
| +    int(pam_setenv)(char *, const char *), Authctxt *the_authctxt)
 | ||||
|  { | ||||
| -	return sshd_selinux_setup_variables(do_pam_putenv);
 | ||||
| +	return sshd_selinux_setup_variables(pam_setenv, inetd, the_authctxt);
 | ||||
|  } | ||||
|   | ||||
|  static int | ||||
| @@ -374,25 +372,28 @@ do_setenv(char *name, const char *value)
 | ||||
|  } | ||||
|   | ||||
|  int | ||||
| -sshd_selinux_setup_env_variables(void)
 | ||||
| +sshd_selinux_setup_env_variables(int inetd, void *the_authctxt)
 | ||||
|  { | ||||
| -	return sshd_selinux_setup_variables(do_setenv);
 | ||||
| +	Authctxt *authctxt = (Authctxt *) the_authctxt;
 | ||||
| +	return sshd_selinux_setup_variables(do_setenv, inetd, authctxt);
 | ||||
|  } | ||||
|   | ||||
|  /* Set the execution context to the default for the specified user */ | ||||
|  void | ||||
| -sshd_selinux_setup_exec_context(char *pwname)
 | ||||
| +sshd_selinux_setup_exec_context(char *pwname, int inetd,
 | ||||
| +    int(pam_setenv)(char *, const char *), void *the_authctxt, int use_pam)
 | ||||
|  { | ||||
|  	security_context_t user_ctx = NULL; | ||||
|  	int r = 0; | ||||
|  	security_context_t default_ctx = NULL; | ||||
| +	Authctxt *authctxt = (Authctxt *) the_authctxt;
 | ||||
|   | ||||
|  	if (!sshd_selinux_enabled()) | ||||
|  		return; | ||||
|   | ||||
| -	if (options.use_pam) {
 | ||||
| +	if (use_pam) {
 | ||||
|  		/* do not compute context, just setup environment for pam_selinux */ | ||||
| -		if (sshd_selinux_setup_pam_variables()) {
 | ||||
| +		if (sshd_selinux_setup_pam_variables(inetd, pam_setenv, authctxt)) {
 | ||||
|  			switch (security_getenforce()) { | ||||
|  			case -1: | ||||
|  				fatal_f("security_getenforce() failed"); | ||||
| @@ -410,7 +411,7 @@ sshd_selinux_setup_exec_context(char *pw
 | ||||
|   | ||||
|  	debug3_f("setting execution context"); | ||||
|   | ||||
| -	r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
 | ||||
| +	r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx, inetd, authctxt);
 | ||||
|  	if (r >= 0) { | ||||
|  		r = setexeccon(user_ctx); | ||||
|  		if (r < 0) { | ||||
| diff -up openssh/platform.c.refactor openssh/platform.c
 | ||||
| --- openssh/platform.c.refactor	2019-04-04 13:19:12.204821389 +0200
 | ||||
| +++ openssh/platform.c	2019-04-04 13:19:12.277822088 +0200
 | ||||
| @@ -32,6 +32,9 @@
 | ||||
|   | ||||
|  extern int use_privsep; | ||||
|  extern ServerOptions options; | ||||
| +extern int inetd_flag;
 | ||||
| +extern int rexeced_flag;
 | ||||
| +extern Authctxt *the_authctxt;
 | ||||
|   | ||||
|  void | ||||
|  platform_pre_listen(void) | ||||
| @@ -183,7 +186,9 @@ platform_setusercontext_post_groups(stru
 | ||||
|  	} | ||||
|  #endif /* HAVE_SETPCRED */ | ||||
|  #ifdef WITH_SELINUX | ||||
| -	sshd_selinux_setup_exec_context(pw->pw_name);
 | ||||
| +	sshd_selinux_setup_exec_context(pw->pw_name,
 | ||||
| +	    (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt,
 | ||||
| +	    options.use_pam);
 | ||||
|  #endif | ||||
|  } | ||||
|   | ||||
| diff -up openssh/sshd.c.refactor openssh/sshd.c
 | ||||
| --- openssh/sshd.c.refactor	2019-04-04 13:19:12.275822068 +0200
 | ||||
| +++ openssh/sshd.c	2019-04-04 13:19:51.270195262 +0200
 | ||||
| @@ -158,7 +158,7 @@ int debug_flag = 0;
 | ||||
|  static int test_flag = 0; | ||||
|   | ||||
|  /* Flag indicating that the daemon is being started from inetd. */ | ||||
| -static int inetd_flag = 0;
 | ||||
| +int inetd_flag = 0;
 | ||||
|   | ||||
|  /* Flag indicating that sshd should not detach and become a daemon. */ | ||||
|  static int no_daemon_flag = 0; | ||||
| @@ -171,7 +171,7 @@ static char **saved_argv;
 | ||||
|  static int saved_argc; | ||||
|   | ||||
|  /* re-exec */ | ||||
| -static int rexeced_flag = 0;
 | ||||
| +int rexeced_flag = 0;
 | ||||
|  static int rexec_flag = 1; | ||||
|  static int rexec_argc = 0; | ||||
|  static char **rexec_argv; | ||||
| @@ -2192,7 +2192,9 @@ main(int ac, char **av)
 | ||||
|  	} | ||||
|  #endif | ||||
|  #ifdef WITH_SELINUX | ||||
| -	sshd_selinux_setup_exec_context(authctxt->pw->pw_name);
 | ||||
| +	sshd_selinux_setup_exec_context(authctxt->pw->pw_name,
 | ||||
| +	    (inetd_flag && !rexeced_flag), do_pam_putenv, the_authctxt,
 | ||||
| +	    options.use_pam);
 | ||||
|  #endif | ||||
|  #ifdef 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); | ||||
							
								
								
									
										454
									
								
								SOURCES/openssh-7.7p1-fips.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										454
									
								
								SOURCES/openssh-7.7p1-fips.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,454 @@ | ||||
| diff -up openssh-8.6p1/cipher-ctr.c.fips openssh-8.6p1/cipher-ctr.c
 | ||||
| --- openssh-8.6p1/cipher-ctr.c.fips	2021-05-06 12:08:36.423926297 +0200
 | ||||
| +++ openssh-8.6p1/cipher-ctr.c	2021-05-06 12:08:36.497926869 +0200
 | ||||
| @@ -179,7 +179,8 @@ evp_aes_128_ctr(void)
 | ||||
|  	aes_ctr.do_cipher = ssh_aes_ctr; | ||||
|  #ifndef SSH_OLD_EVP | ||||
|  	aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | | ||||
| -	    EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
 | ||||
| +	    EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV |
 | ||||
| +	    EVP_CIPH_FLAG_FIPS;
 | ||||
|  #endif | ||||
|  	return (&aes_ctr); | ||||
|  } | ||||
| diff -up openssh-8.6p1/dh.c.fips openssh-8.6p1/dh.c
 | ||||
| --- openssh-8.6p1/dh.c.fips	2021-04-16 05:55:25.000000000 +0200
 | ||||
| +++ openssh-8.6p1/dh.c	2021-05-06 12:12:10.107634472 +0200
 | ||||
| @@ -164,6 +164,12 @@ choose_dh(int min, int wantbits, int max
 | ||||
|  	int best, bestcount, which, linenum; | ||||
|  	struct dhgroup dhg; | ||||
|   | ||||
| +	if (FIPS_mode()) {
 | ||||
| +		logit("Using arbitrary primes is not allowed in FIPS mode."
 | ||||
| +		    " Falling back to known groups.");
 | ||||
| +		return (dh_new_group_fallback(max));
 | ||||
| +	}
 | ||||
| +
 | ||||
|  	if ((f = fopen(get_moduli_filename(), "r")) == NULL) { | ||||
|  		logit("WARNING: could not open %s (%s), using fixed modulus", | ||||
|  		    get_moduli_filename(), strerror(errno)); | ||||
| @@ -502,4 +508,38 @@ dh_estimate(int bits)
 | ||||
|  	return 8192; | ||||
|  } | ||||
|   | ||||
| +/*
 | ||||
| + * Compares the received DH parameters with known-good groups,
 | ||||
| + * which might be either from group14, group16 or group18.
 | ||||
| + */
 | ||||
| +int
 | ||||
| +dh_is_known_group(const DH *dh)
 | ||||
| +{
 | ||||
| +	const BIGNUM *p, *g;
 | ||||
| +	const BIGNUM *known_p, *known_g;
 | ||||
| +	DH *known = NULL;
 | ||||
| +	int bits = 0, rv = 0;
 | ||||
| +
 | ||||
| +	DH_get0_pqg(dh, &p, NULL, &g);
 | ||||
| +	bits = BN_num_bits(p);
 | ||||
| +
 | ||||
| +	if (bits <= 3072) {
 | ||||
| +		known = dh_new_group14();
 | ||||
| +	} else if (bits <= 6144) {
 | ||||
| +		known = dh_new_group16();
 | ||||
| +	} else {
 | ||||
| +		known = dh_new_group18();
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	DH_get0_pqg(known, &known_p, NULL, &known_g);
 | ||||
| +
 | ||||
| +	if (BN_cmp(g, known_g) == 0 &&
 | ||||
| +	    BN_cmp(p, known_p) == 0) {
 | ||||
| +		rv = 1;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	DH_free(known);
 | ||||
| +	return rv;
 | ||||
| +}
 | ||||
| +
 | ||||
|  #endif /* WITH_OPENSSL */ | ||||
| diff -up openssh-8.6p1/dh.h.fips openssh-8.6p1/dh.h
 | ||||
| --- openssh-8.6p1/dh.h.fips	2021-05-06 12:08:36.498926877 +0200
 | ||||
| +++ openssh-8.6p1/dh.h	2021-05-06 12:11:28.393298005 +0200
 | ||||
| @@ -45,6 +45,7 @@ DH	*dh_new_group_fallback(int);
 | ||||
|   | ||||
|  int	 dh_gen_key(DH *, int); | ||||
|  int	 dh_pub_is_valid(const DH *, const BIGNUM *); | ||||
| +int	 dh_is_known_group(const DH *);
 | ||||
|   | ||||
|  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
 | ||||
| @@ -203,7 +203,10 @@ kex_names_valid(const char *names)
 | ||||
|  	for ((p = strsep(&cp, ",")); p && *p != '\0'; | ||||
|  	    (p = strsep(&cp, ","))) { | ||||
|  		if (kex_alg_by_name(p) == NULL) { | ||||
| -			error("Unsupported KEX algorithm \"%.100s\"", p);
 | ||||
| +			if (FIPS_mode())
 | ||||
| +				error("\"%.100s\" is not allowed in FIPS mode", p);
 | ||||
| +			else
 | ||||
| +				error("Unsupported KEX algorithm \"%.100s\"", p);
 | ||||
|  			free(s); | ||||
|  			return 0; | ||||
|  		} | ||||
| diff -up openssh-8.6p1/kexgexc.c.fips openssh-8.6p1/kexgexc.c
 | ||||
| --- openssh-8.6p1/kexgexc.c.fips	2021-04-16 05:55:25.000000000 +0200
 | ||||
| +++ openssh-8.6p1/kexgexc.c	2021-05-06 12:08:36.498926877 +0200
 | ||||
| @@ -28,6 +28,7 @@
 | ||||
|   | ||||
|  #ifdef WITH_OPENSSL | ||||
|   | ||||
| +#include <openssl/crypto.h>
 | ||||
|  #include <sys/types.h> | ||||
|   | ||||
|  #include <openssl/dh.h> | ||||
| @@ -115,6 +116,10 @@ input_kex_dh_gex_group(int type, u_int32
 | ||||
|  		r = SSH_ERR_ALLOC_FAIL; | ||||
|  		goto out; | ||||
|  	} | ||||
| +	if (FIPS_mode() && dh_is_known_group(kex->dh) == 0) {
 | ||||
| +		r = SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
|  	p = g = NULL; /* belong to kex->dh now */ | ||||
|   | ||||
|  	/* generate and send 'e', client DH public key */ | ||||
| diff -up openssh-8.6p1/myproposal.h.fips openssh-8.6p1/myproposal.h
 | ||||
| --- openssh-8.6p1/myproposal.h.fips	2021-04-16 05:55:25.000000000 +0200
 | ||||
| +++ openssh-8.6p1/myproposal.h	2021-05-06 12:08:36.498926877 +0200
 | ||||
| @@ -57,6 +57,20 @@
 | ||||
|  	"rsa-sha2-256," \ | ||||
|  	"ssh-rsa" | ||||
|   | ||||
| +#define	KEX_FIPS_PK_ALG	\
 | ||||
| +	"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-256-cert-v01@openssh.com," \
 | ||||
| +	"ssh-rsa-cert-v01@openssh.com," \
 | ||||
| +	"ecdsa-sha2-nistp256," \
 | ||||
| +	"ecdsa-sha2-nistp384," \
 | ||||
| +	"ecdsa-sha2-nistp521," \
 | ||||
| +	"rsa-sha2-512," \
 | ||||
| +	"rsa-sha2-256," \
 | ||||
| +	"ssh-rsa"
 | ||||
| +
 | ||||
|  #define	KEX_SERVER_ENCRYPT \ | ||||
|  	"chacha20-poly1305@openssh.com," \ | ||||
|  	"aes128-ctr,aes192-ctr,aes256-ctr," \ | ||||
| @@ -78,6 +92,27 @@
 | ||||
|   | ||||
|  #define KEX_CLIENT_MAC KEX_SERVER_MAC | ||||
|   | ||||
| +#define	KEX_FIPS_ENCRYPT \
 | ||||
| +	"aes128-ctr,aes192-ctr,aes256-ctr," \
 | ||||
| +	"aes128-cbc,3des-cbc," \
 | ||||
| +	"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
 | ||||
| +	"aes128-gcm@openssh.com,aes256-gcm@openssh.com"
 | ||||
| +#define KEX_DEFAULT_KEX_FIPS		\
 | ||||
| +	"ecdh-sha2-nistp256," \
 | ||||
| +	"ecdh-sha2-nistp384," \
 | ||||
| +	"ecdh-sha2-nistp521," \
 | ||||
| +	"diffie-hellman-group-exchange-sha256," \
 | ||||
| +	"diffie-hellman-group16-sha512," \
 | ||||
| +	"diffie-hellman-group18-sha512," \
 | ||||
| +	"diffie-hellman-group14-sha256"
 | ||||
| +#define KEX_FIPS_MAC \
 | ||||
| +	"hmac-sha1," \
 | ||||
| +	"hmac-sha2-256," \
 | ||||
| +	"hmac-sha2-512," \
 | ||||
| +	"hmac-sha1-etm@openssh.com," \
 | ||||
| +	"hmac-sha2-256-etm@openssh.com," \
 | ||||
| +	"hmac-sha2-512-etm@openssh.com"
 | ||||
| +
 | ||||
|  /* Not a KEX value, but here so all the algorithm defaults are together */ | ||||
|  #define	SSH_ALLOWED_CA_SIGALGS	\ | ||||
|  	"ssh-ed25519," \ | ||||
| diff -up openssh-8.6p1/readconf.c.fips openssh-8.6p1/readconf.c
 | ||||
| --- openssh-8.6p1/readconf.c.fips	2021-05-06 12:08:36.428926336 +0200
 | ||||
| +++ openssh-8.6p1/readconf.c	2021-05-06 12:08:36.499926885 +0200
 | ||||
| @@ -2538,11 +2538,16 @@ fill_default_options(Options * options)
 | ||||
|  	all_key = sshkey_alg_list(0, 0, 1, ','); | ||||
|  	all_sig = sshkey_alg_list(0, 1, 1, ','); | ||||
|  	/* remove unsupported algos from default lists */ | ||||
| -	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 { \ | ||||
|  		if ((r = kex_assemble_names(&options->what, \ | ||||
| diff -up openssh-8.6p1/sandbox-seccomp-filter.c.fips openssh-8.6p1/sandbox-seccomp-filter.c
 | ||||
| --- openssh-8.6p1/sandbox-seccomp-filter.c.fips	2021-05-06 12:08:36.463926606 +0200
 | ||||
| +++ openssh-8.6p1/sandbox-seccomp-filter.c	2021-05-06 12:08:36.499926885 +0200
 | ||||
| @@ -160,6 +160,9 @@ static const struct sock_filter preauth_
 | ||||
|  #ifdef __NR_open | ||||
|  	SC_DENY(__NR_open, EACCES), | ||||
|  #endif | ||||
| +#ifdef __NR_socket
 | ||||
| +	SC_DENY(__NR_socket, EACCES),
 | ||||
| +#endif
 | ||||
|  #ifdef __NR_openat | ||||
|  	SC_DENY(__NR_openat, EACCES), | ||||
|  #endif | ||||
| diff -up openssh-8.6p1/servconf.c.fips openssh-8.6p1/servconf.c
 | ||||
| --- openssh-8.6p1/servconf.c.fips	2021-05-06 12:08:36.455926545 +0200
 | ||||
| +++ openssh-8.6p1/servconf.c	2021-05-06 12:08:36.500926893 +0200
 | ||||
| @@ -226,11 +226,16 @@ assemble_algorithms(ServerOptions *o)
 | ||||
|  	all_key = sshkey_alg_list(0, 0, 1, ','); | ||||
|  	all_sig = sshkey_alg_list(0, 1, 1, ','); | ||||
|  	/* remove unsupported algos from default lists */ | ||||
| -	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 { \ | ||||
|  		if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \ | ||||
| diff -up openssh-8.6p1/ssh.c.fips openssh-8.6p1/ssh.c
 | ||||
| --- openssh-8.6p1/ssh.c.fips	2021-05-06 12:08:36.467926637 +0200
 | ||||
| +++ openssh-8.6p1/ssh.c	2021-05-06 12:08:36.500926893 +0200
 | ||||
| @@ -77,6 +77,7 @@
 | ||||
|  #include <openssl/evp.h> | ||||
|  #include <openssl/err.h> | ||||
|  #endif | ||||
| +#include <openssl/crypto.h>
 | ||||
|  #include "openbsd-compat/openssl-compat.h" | ||||
|  #include "openbsd-compat/sys-queue.h" | ||||
|   | ||||
| @@ -1516,6 +1517,10 @@ main(int ac, char **av)
 | ||||
|  		exit(0); | ||||
|  	} | ||||
|   | ||||
| +	if (FIPS_mode()) {
 | ||||
| +		debug("FIPS mode initialized");
 | ||||
| +	}
 | ||||
| +
 | ||||
|  	/* Expand SecurityKeyProvider if it refers to an environment variable */ | ||||
|  	if (options.sk_provider != NULL && *options.sk_provider == '$' && | ||||
|  	    strlen(options.sk_provider) > 1) { | ||||
| diff -up openssh-8.6p1/sshconnect2.c.fips openssh-8.6p1/sshconnect2.c
 | ||||
| --- openssh-8.6p1/sshconnect2.c.fips	2021-05-06 12:08:36.485926777 +0200
 | ||||
| +++ openssh-8.6p1/sshconnect2.c	2021-05-06 12:08:36.501926900 +0200
 | ||||
| @@ -45,6 +45,8 @@
 | ||||
|  #include <vis.h> | ||||
|  #endif | ||||
|   | ||||
| +#include <openssl/crypto.h>
 | ||||
| +
 | ||||
|  #include "openbsd-compat/sys-queue.h" | ||||
|   | ||||
|  #include "xmalloc.h" | ||||
| @@ -269,36 +271,41 @@ ssh_kex2(struct ssh *ssh, char *host, st
 | ||||
|   | ||||
|  #if defined(GSSAPI) && defined(WITH_OPENSSL) | ||||
|  	if (options.gss_keyex) { | ||||
| -		/* Add the GSSAPI mechanisms currently supported on this
 | ||||
| -		 * client to the key exchange algorithm proposal */
 | ||||
| -		orig = myproposal[PROPOSAL_KEX_ALGS];
 | ||||
| -
 | ||||
| -		if (options.gss_server_identity) {
 | ||||
| -			gss_host = xstrdup(options.gss_server_identity);
 | ||||
| -		} else if (options.gss_trust_dns) {
 | ||||
| -			gss_host = remote_hostname(ssh);
 | ||||
| -			/* Fall back to specified host if we are using proxy command
 | ||||
| -			 * and can not use DNS on that socket */
 | ||||
| -			if (strcmp(gss_host, "UNKNOWN") == 0) {
 | ||||
| -				free(gss_host);
 | ||||
| +		if (FIPS_mode()) {
 | ||||
| +			logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
 | ||||
| +			options.gss_keyex = 0;
 | ||||
| +		} else {
 | ||||
| +			/* Add the GSSAPI mechanisms currently supported on this
 | ||||
| +			 * client to the key exchange algorithm proposal */
 | ||||
| +			orig = myproposal[PROPOSAL_KEX_ALGS];
 | ||||
| +
 | ||||
| +			if (options.gss_server_identity) {
 | ||||
| +				gss_host = xstrdup(options.gss_server_identity);
 | ||||
| +			} else if (options.gss_trust_dns) {
 | ||||
| +				gss_host = remote_hostname(ssh);
 | ||||
| +				/* Fall back to specified host if we are using proxy command
 | ||||
| +				 * and can not use DNS on that socket */
 | ||||
| +				if (strcmp(gss_host, "UNKNOWN") == 0) {
 | ||||
| +					free(gss_host);
 | ||||
| +					gss_host = xstrdup(host);
 | ||||
| +				}
 | ||||
| +			} else {
 | ||||
|  				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,
 | ||||
| +			    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);
 | ||||
| +			}
 | ||||
|  		} | ||||
|  	} | ||||
|  #endif | ||||
| diff -up openssh-8.6p1/sshd.c.fips openssh-8.6p1/sshd.c
 | ||||
| --- openssh-8.6p1/sshd.c.fips	2021-05-06 12:08:36.493926838 +0200
 | ||||
| +++ openssh-8.6p1/sshd.c	2021-05-06 12:13:56.501492639 +0200
 | ||||
| @@ -66,6 +66,7 @@
 | ||||
|  #include <grp.h> | ||||
|  #include <pwd.h> | ||||
|  #include <signal.h> | ||||
| +#include <syslog.h>
 | ||||
|  #include <stdarg.h> | ||||
|  #include <stdio.h> | ||||
|  #include <stdlib.h> | ||||
| @@ -77,6 +78,7 @@
 | ||||
|  #include <openssl/dh.h> | ||||
|  #include <openssl/bn.h> | ||||
|  #include <openssl/rand.h> | ||||
| +#include <openssl/crypto.h>
 | ||||
|  #include "openbsd-compat/openssl-compat.h" | ||||
|  #endif | ||||
|   | ||||
| @@ -1619,6 +1621,7 @@ main(int ac, char **av)
 | ||||
|  #endif | ||||
|  	__progname = ssh_get_progname(av[0]); | ||||
|   | ||||
| +	OpenSSL_add_all_algorithms();
 | ||||
|  	/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ | ||||
|  	saved_argc = ac; | ||||
|  	rexec_argc = ac; | ||||
| @@ -2110,6 +2113,10 @@ main(int ac, char **av)
 | ||||
|  	/* Reinitialize the log (because of the fork above). */ | ||||
|  	log_init(__progname, options.log_level, options.log_facility, log_stderr); | ||||
|   | ||||
| +	if (FIPS_mode()) {
 | ||||
| +		debug("FIPS mode initialized");
 | ||||
| +	}
 | ||||
| +
 | ||||
|  	/* | ||||
|  	 * Chdir to the root directory so that the current disk can be | ||||
|  	 * unmounted if desired. | ||||
| @@ -2494,10 +2501,14 @@ do_ssh2_kex(struct ssh *ssh)
 | ||||
|  	if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) | ||||
|  		orig = NULL; | ||||
|   | ||||
| -	if (options.gss_keyex)
 | ||||
| -		gss = ssh_gssapi_server_mechanisms();
 | ||||
| -	else
 | ||||
| -		gss = NULL;
 | ||||
| +	if (options.gss_keyex) {
 | ||||
| +		if (FIPS_mode()) {
 | ||||
| +			logit("Disabling GSSAPIKeyExchange. Not usable in FIPS mode");
 | ||||
| +			options.gss_keyex = 0;
 | ||||
| +		} else {
 | ||||
| +			gss = ssh_gssapi_server_mechanisms();
 | ||||
| +		}
 | ||||
| +	}
 | ||||
|   | ||||
|  	if (gss && orig) | ||||
|  		xasprintf(&newstr, "%s,%s", gss, orig); | ||||
| diff -up openssh-8.6p1/sshkey.c.fips openssh-8.6p1/sshkey.c
 | ||||
| --- openssh-8.6p1/sshkey.c.fips	2021-05-06 12:08:36.493926838 +0200
 | ||||
| +++ openssh-8.6p1/sshkey.c	2021-05-06 12:08:36.502926908 +0200
 | ||||
| @@ -34,6 +34,7 @@
 | ||||
|  #include <openssl/evp.h> | ||||
|  #include <openssl/err.h> | ||||
|  #include <openssl/pem.h> | ||||
| +#include <openssl/crypto.h>
 | ||||
|  #endif | ||||
|   | ||||
|  #include "crypto_api.h" | ||||
| @@ -57,6 +58,7 @@
 | ||||
|  #define SSHKEY_INTERNAL | ||||
|  #include "sshkey.h" | ||||
|  #include "match.h" | ||||
| +#include "log.h"
 | ||||
|  #include "ssh-sk.h" | ||||
|   | ||||
|  #ifdef WITH_XMSS | ||||
| @@ -1705,6 +1707,8 @@ rsa_generate_private_key(u_int bits, RSA
 | ||||
|  	} | ||||
|  	if (!BN_set_word(f4, RSA_F4) || | ||||
|  	    !RSA_generate_key_ex(private, bits, f4, NULL)) { | ||||
| +			if (FIPS_mode())
 | ||||
| +				logit_f("the key length might be unsupported by FIPS mode approved key generation method");
 | ||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| 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
 | ||||
| @@ -205,6 +205,12 @@ type_bits_valid(int type, const char *na
 | ||||
|  #endif | ||||
|  	} | ||||
|  #ifdef WITH_OPENSSL | ||||
| +	if (FIPS_mode()) {
 | ||||
| +		if (type == KEY_DSA)
 | ||||
| +			fatal("DSA keys are not allowed in FIPS mode");
 | ||||
| +		if (type == KEY_ED25519)
 | ||||
| +			fatal("ED25519 keys are not allowed in FIPS mode");
 | ||||
| +	}
 | ||||
|  	switch (type) { | ||||
|  	case KEY_DSA: | ||||
|  		if (*bitsp != 1024) | ||||
| @@ -1098,9 +1104,17 @@ do_gen_all_hostkeys(struct passwd *pw)
 | ||||
|  			first = 1; | ||||
|  			printf("%s: generating new host keys: ", __progname); | ||||
|  		} | ||||
| +		type = sshkey_type_from_name(key_types[i].key_type);
 | ||||
| +
 | ||||
| +		/* Skip the keys that are not supported in FIPS mode */
 | ||||
| +		if (FIPS_mode() && (type == KEY_DSA || type == KEY_ED25519)) {
 | ||||
| +			logit("Skipping %s key in FIPS mode",
 | ||||
| +			    key_types[i].key_type_display);
 | ||||
| +			goto next;
 | ||||
| +		}
 | ||||
| +
 | ||||
|  		printf("%s ", key_types[i].key_type_display); | ||||
|  		fflush(stdout); | ||||
| -		type = sshkey_type_from_name(key_types[i].key_type);
 | ||||
|  		if ((fd = mkstemp(prv_tmp)) == -1) { | ||||
|  			error("Could not save your private key in %s: %s", | ||||
|  			    prv_tmp, strerror(errno)); | ||||
							
								
								
									
										633
									
								
								SOURCES/openssh-7.7p1-gssapi-new-unique.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										633
									
								
								SOURCES/openssh-7.7p1-gssapi-new-unique.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,633 @@ | ||||
| diff -up openssh-8.6p1/auth.h.ccache_name openssh-8.6p1/auth.h
 | ||||
| --- openssh-8.6p1/auth.h.ccache_name	2021-05-06 11:15:36.345143341 +0200
 | ||||
| +++ openssh-8.6p1/auth.h	2021-05-06 11:15:36.387143654 +0200
 | ||||
| @@ -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 @@
 | ||||
|  #include <unistd.h> | ||||
|  #include <string.h> | ||||
|  #include <krb5.h> | ||||
| +#include <profile.h>
 | ||||
|   | ||||
|  extern ServerOptions	 options; | ||||
|   | ||||
| @@ -77,7 +78,7 @@ auth_krb5_password(Authctxt *authctxt, c
 | ||||
|  #endif | ||||
|  	krb5_error_code problem; | ||||
|  	krb5_ccache ccache = NULL; | ||||
| -	int len;
 | ||||
| +	char *ticket_name = NULL;
 | ||||
|  	char *client, *platform_client; | ||||
|  	const char *errmsg; | ||||
|   | ||||
| @@ -163,8 +164,8 @@ auth_krb5_password(Authctxt *authctxt, c
 | ||||
|  		goto out; | ||||
|  	} | ||||
|   | ||||
| -	problem = ssh_krb5_cc_gen(authctxt->krb5_ctx,
 | ||||
| -	    &authctxt->krb5_fwd_ccache);
 | ||||
| +	problem = ssh_krb5_cc_new_unique(authctxt->krb5_ctx,
 | ||||
| +	     &authctxt->krb5_fwd_ccache, &authctxt->krb5_set_env);
 | ||||
|  	if (problem) | ||||
|  		goto out; | ||||
|   | ||||
| @@ -179,15 +180,14 @@ auth_krb5_password(Authctxt *authctxt, c
 | ||||
|  		goto out; | ||||
|  #endif | ||||
|   | ||||
| -	authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
 | ||||
| +	problem = krb5_cc_get_full_name(authctxt->krb5_ctx,
 | ||||
| +	    authctxt->krb5_fwd_ccache, &ticket_name);
 | ||||
|   | ||||
| -	len = strlen(authctxt->krb5_ticket_file) + 6;
 | ||||
| -	authctxt->krb5_ccname = xmalloc(len);
 | ||||
| -	snprintf(authctxt->krb5_ccname, len, "FILE:%s",
 | ||||
| -	    authctxt->krb5_ticket_file);
 | ||||
| +	authctxt->krb5_ccname = xstrdup(ticket_name);
 | ||||
| +	krb5_free_string(authctxt->krb5_ctx, ticket_name);
 | ||||
|   | ||||
|  #ifdef USE_PAM | ||||
| -	if (options.use_pam)
 | ||||
| +	if (options.use_pam && authctxt->krb5_set_env)
 | ||||
|  		do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); | ||||
|  #endif | ||||
|   | ||||
| @@ -223,11 +223,54 @@ auth_krb5_password(Authctxt *authctxt, c
 | ||||
|  void | ||||
|  krb5_cleanup_proc(Authctxt *authctxt) | ||||
|  { | ||||
| +	struct stat krb5_ccname_stat;
 | ||||
| +	char krb5_ccname[128], *krb5_ccname_dir_start, *krb5_ccname_dir_end;
 | ||||
| +
 | ||||
|  	debug("krb5_cleanup_proc called"); | ||||
|  	if (authctxt->krb5_fwd_ccache) { | ||||
| -		krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
 | ||||
| +		krb5_context ctx = authctxt->krb5_ctx;
 | ||||
| +		krb5_cccol_cursor cursor;
 | ||||
| +		krb5_ccache ccache;
 | ||||
| +		int ret;
 | ||||
| +
 | ||||
| +		krb5_cc_destroy(ctx, authctxt->krb5_fwd_ccache);
 | ||||
|  		authctxt->krb5_fwd_ccache = NULL; | ||||
| +
 | ||||
| +		ret = krb5_cccol_cursor_new(ctx, &cursor);
 | ||||
| +		if (ret)
 | ||||
| +			goto out;
 | ||||
| +
 | ||||
| +		ret = krb5_cccol_cursor_next(ctx, cursor, &ccache);
 | ||||
| +		if (ret == 0 && ccache != NULL) {
 | ||||
| +			/* There is at least one other ccache in collection
 | ||||
| +			 * we can switch to */
 | ||||
| +			krb5_cc_switch(ctx, ccache);
 | ||||
| +		} else if (authctxt->krb5_ccname != NULL) {
 | ||||
| +			/* Clean up the collection too */
 | ||||
| +			strncpy(krb5_ccname, authctxt->krb5_ccname, sizeof(krb5_ccname) - 10);
 | ||||
| +			krb5_ccname_dir_start = strchr(krb5_ccname, ':') + 1;
 | ||||
| +			*krb5_ccname_dir_start++ = '\0';
 | ||||
| +			if (strcmp(krb5_ccname, "DIR") == 0) {
 | ||||
| +
 | ||||
| +				strcat(krb5_ccname_dir_start, "/primary");
 | ||||
| +
 | ||||
| +				if (stat(krb5_ccname_dir_start, &krb5_ccname_stat) == 0) {
 | ||||
| +					if (unlink(krb5_ccname_dir_start) == 0) {
 | ||||
| +						krb5_ccname_dir_end = strrchr(krb5_ccname_dir_start, '/');
 | ||||
| +						*krb5_ccname_dir_end = '\0';
 | ||||
| +						if (rmdir(krb5_ccname_dir_start) == -1)
 | ||||
| +							debug("cache dir '%s' remove failed: %s",
 | ||||
| +							    krb5_ccname_dir_start, strerror(errno));
 | ||||
| +					}
 | ||||
| +					else
 | ||||
| +						debug("cache primary file '%s', remove failed: %s",
 | ||||
| +						    krb5_ccname_dir_start, strerror(errno));
 | ||||
| +				}
 | ||||
| +			}
 | ||||
| +		}
 | ||||
| +		krb5_cccol_cursor_free(ctx, &cursor);
 | ||||
|  	} | ||||
| +out:
 | ||||
|  	if (authctxt->krb5_user) { | ||||
|  		krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); | ||||
|  		authctxt->krb5_user = NULL; | ||||
| @@ -238,36 +281,188 @@ krb5_cleanup_proc(Authctxt *authctxt)
 | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| -#ifndef HEIMDAL
 | ||||
| +
 | ||||
| +#if !defined(HEIMDAL)
 | ||||
| +int
 | ||||
| +ssh_asprintf_append(char **dsc, const char *fmt, ...) {
 | ||||
| +	char *src, *old;
 | ||||
| +	va_list ap;
 | ||||
| +	int i;
 | ||||
| +
 | ||||
| +	va_start(ap, fmt);
 | ||||
| +	i = vasprintf(&src, fmt, ap);
 | ||||
| +	va_end(ap);
 | ||||
| +
 | ||||
| +	if (i == -1 || src == NULL)
 | ||||
| +		return -1;
 | ||||
| +
 | ||||
| +	old = *dsc;
 | ||||
| +
 | ||||
| +	i = asprintf(dsc, "%s%s", *dsc, src);
 | ||||
| +	if (i == -1 || src == NULL) {
 | ||||
| +		free(src);
 | ||||
| +		return -1;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	free(old);
 | ||||
| +	free(src);
 | ||||
| +
 | ||||
| +	return i;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
| +ssh_krb5_expand_template(char **result, const char *template) {
 | ||||
| +	char *p_n, *p_o, *r, *tmp_template;
 | ||||
| +
 | ||||
| +	debug3_f("called, template = %s", template);
 | ||||
| +	if (template == NULL)
 | ||||
| +		return -1;
 | ||||
| +
 | ||||
| +	tmp_template = p_n = p_o = xstrdup(template);
 | ||||
| +	r = xstrdup("");
 | ||||
| +
 | ||||
| +	while ((p_n = strstr(p_o, "%{")) != NULL) {
 | ||||
| +
 | ||||
| +		*p_n++ = '\0';
 | ||||
| +		if (ssh_asprintf_append(&r, "%s", p_o) == -1)
 | ||||
| +			goto cleanup;
 | ||||
| +
 | ||||
| +		if (strncmp(p_n, "{uid}", 5) == 0 || strncmp(p_n, "{euid}", 6) == 0 ||
 | ||||
| +			strncmp(p_n, "{USERID}", 8) == 0) {
 | ||||
| +			p_o = strchr(p_n, '}') + 1;
 | ||||
| +			if (ssh_asprintf_append(&r, "%d", geteuid()) == -1)
 | ||||
| +				goto cleanup;
 | ||||
| +			continue;
 | ||||
| +		}
 | ||||
| +		else if (strncmp(p_n, "{TEMP}", 6) == 0) {
 | ||||
| +			p_o = strchr(p_n, '}') + 1;
 | ||||
| +			if (ssh_asprintf_append(&r, "/tmp") == -1)
 | ||||
| +				goto cleanup;
 | ||||
| +			continue;
 | ||||
| +		} else {
 | ||||
| +			p_o = strchr(p_n, '}') + 1;
 | ||||
| +			*p_o = '\0';
 | ||||
| +			debug_f("unsupported token %s in %s", p_n, template);
 | ||||
| +			/* unknown token, fallback to the default */
 | ||||
| +			goto cleanup;
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if (ssh_asprintf_append(&r, "%s", p_o) == -1)
 | ||||
| +		goto cleanup;
 | ||||
| +
 | ||||
| +	*result = r;
 | ||||
| +	free(tmp_template);
 | ||||
| +	return 0;
 | ||||
| +
 | ||||
| +cleanup:
 | ||||
| +	free(r);
 | ||||
| +	free(tmp_template);
 | ||||
| +	return -1;
 | ||||
| +}
 | ||||
| +
 | ||||
| +krb5_error_code
 | ||||
| +ssh_krb5_get_cctemplate(krb5_context ctx, char **ccname) {
 | ||||
| +	profile_t p;
 | ||||
| +	int ret = 0;
 | ||||
| +	char *value = NULL;
 | ||||
| +
 | ||||
| +	debug3_f("called");
 | ||||
| +	ret = krb5_get_profile(ctx, &p);
 | ||||
| +	if (ret)
 | ||||
| +		return ret;
 | ||||
| +
 | ||||
| +	ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value);
 | ||||
| +	if (ret || !value)
 | ||||
| +		return ret;
 | ||||
| +
 | ||||
| +	ret = ssh_krb5_expand_template(ccname, value);
 | ||||
| +
 | ||||
| +	debug3_f("returning with ccname = %s", *ccname);
 | ||||
| +	return ret;
 | ||||
| +}
 | ||||
| +
 | ||||
|  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) {
 | ||||
| +	int tmpfd, ret, oerrno, type_len;
 | ||||
| +	char *ccname = NULL;
 | ||||
|  	mode_t old_umask; | ||||
| +	char *type = NULL, *colon = NULL;
 | ||||
|   | ||||
| -	ret = snprintf(ccname, sizeof(ccname),
 | ||||
| -	    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
 | ||||
| -	if (ret < 0 || (size_t)ret >= sizeof(ccname))
 | ||||
| -		return ENOMEM;
 | ||||
| -
 | ||||
| -	old_umask = umask(0177);
 | ||||
| -	tmpfd = mkstemp(ccname + strlen("FILE:"));
 | ||||
| -	oerrno = errno;
 | ||||
| -	umask(old_umask);
 | ||||
| -	if (tmpfd == -1) {
 | ||||
| -		logit("mkstemp(): %.100s", strerror(oerrno));
 | ||||
| -		return oerrno;
 | ||||
| -	}
 | ||||
| +	debug3_f("called");
 | ||||
| +	if (need_environment)
 | ||||
| +		*need_environment = 0;
 | ||||
| +	ret = ssh_krb5_get_cctemplate(ctx, &ccname);
 | ||||
| +	if (ret || !ccname || options.kerberos_unique_ccache) {
 | ||||
| +		/* Otherwise, go with the old method */
 | ||||
| +		if (ccname)
 | ||||
| +			free(ccname);
 | ||||
| +		ccname = NULL;
 | ||||
| +
 | ||||
| +		ret = asprintf(&ccname,
 | ||||
| +		    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
 | ||||
| +		if (ret < 0)
 | ||||
| +			return ENOMEM;
 | ||||
|   | ||||
| -	if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
 | ||||
| +		old_umask = umask(0177);
 | ||||
| +		tmpfd = mkstemp(ccname + strlen("FILE:"));
 | ||||
|  		oerrno = errno; | ||||
| -		logit("fchmod(): %.100s", strerror(oerrno));
 | ||||
| +		umask(old_umask);
 | ||||
| +		if (tmpfd == -1) {
 | ||||
| +			logit("mkstemp(): %.100s", strerror(oerrno));
 | ||||
| +			return oerrno;
 | ||||
| +		}
 | ||||
| +
 | ||||
| +		if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
 | ||||
| +			oerrno = errno;
 | ||||
| +			logit("fchmod(): %.100s", strerror(oerrno));
 | ||||
| +			close(tmpfd);
 | ||||
| +			return oerrno;
 | ||||
| +		}
 | ||||
| +		/* make sure the KRB5CCNAME is set for non-standard location */
 | ||||
| +		if (need_environment)
 | ||||
| +			*need_environment = 1;
 | ||||
|  		close(tmpfd); | ||||
| -		return oerrno;
 | ||||
|  	} | ||||
| -	close(tmpfd);
 | ||||
|   | ||||
| -	return (krb5_cc_resolve(ctx, ccname, ccache));
 | ||||
| +	debug3_f("setting default ccname to %s", ccname);
 | ||||
| +	/* set the default with already expanded user IDs */
 | ||||
| +	ret = krb5_cc_set_default_name(ctx, ccname);
 | ||||
| +	if (ret)
 | ||||
| +		return ret;
 | ||||
| +
 | ||||
| +	if ((colon = strstr(ccname, ":")) != NULL) {
 | ||||
| +		type_len = colon - ccname;
 | ||||
| +		type = malloc((type_len + 1) * sizeof(char));
 | ||||
| +		if (type == NULL)
 | ||||
| +			return ENOMEM;
 | ||||
| +		strncpy(type, ccname, type_len);
 | ||||
| +		type[type_len] = 0;
 | ||||
| +	} else {
 | ||||
| +		type = strdup(ccname);
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	/* If we have a credential cache from krb5.conf, we need to switch
 | ||||
| +	 * a primary cache for this collection, if it supports that (non-FILE)
 | ||||
| +	 */
 | ||||
| +	if (krb5_cc_support_switch(ctx, type)) {
 | ||||
| +		debug3_f("calling cc_new_unique(%s)", ccname);
 | ||||
| +		ret = krb5_cc_new_unique(ctx, type, NULL, ccache);
 | ||||
| +		free(type);
 | ||||
| +		if (ret)
 | ||||
| +			return ret;
 | ||||
| +
 | ||||
| +		debug3_f("calling cc_switch()");
 | ||||
| +		return krb5_cc_switch(ctx, *ccache);
 | ||||
| +	} else {
 | ||||
| +		/* Otherwise, we can not create a unique ccname here (either
 | ||||
| +		 * it is already unique from above or the type does not support
 | ||||
| +		 * collections
 | ||||
| +		 */
 | ||||
| +		free(type);
 | ||||
| +		debug3_f("calling cc_resolve(%s)", ccname);
 | ||||
| +		return (krb5_cc_resolve(ctx, ccname, ccache));
 | ||||
| +	}
 | ||||
|  } | ||||
|  #endif /* !HEIMDAL */ | ||||
|  #endif /* KRB5 */ | ||||
| diff -up openssh-8.6p1/gss-serv.c.ccache_name openssh-8.6p1/gss-serv.c
 | ||||
| --- openssh-8.6p1/gss-serv.c.ccache_name	2021-05-06 11:15:36.374143558 +0200
 | ||||
| +++ openssh-8.6p1/gss-serv.c	2021-05-06 11:15:36.387143654 +0200
 | ||||
| @@ -413,13 +413,15 @@ ssh_gssapi_cleanup_creds(void)
 | ||||
|  } | ||||
|   | ||||
|  /* 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 child's environment based | ||||
| @@ -499,9 +501,7 @@ ssh_gssapi_rekey_creds(void) {
 | ||||
|  	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-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
 | ||||
|  /* This writes out any forwarded credentials from the structure populated | ||||
|   * during userauth. Called after we have setuid to the user */ | ||||
|   | ||||
| -static void
 | ||||
| +static int
 | ||||
|  ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) | ||||
|  { | ||||
|  	krb5_ccache ccache; | ||||
| @@ -276,14 +276,15 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  	OM_uint32 maj_status, min_status; | ||||
|  	const char *new_ccname, *new_cctype; | ||||
|  	const char *errmsg; | ||||
| +	int set_env = 0;
 | ||||
|   | ||||
|  	if (client->creds == NULL) { | ||||
|  		debug("No credentials stored"); | ||||
| -		return;
 | ||||
| +		return 0;
 | ||||
|  	} | ||||
|   | ||||
|  	if (ssh_gssapi_krb5_init() == 0) | ||||
| -		return;
 | ||||
| +		return 0;
 | ||||
|   | ||||
|  #ifdef HEIMDAL | ||||
|  # ifdef HAVE_KRB5_CC_NEW_UNIQUE | ||||
| @@ -297,14 +298,14 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  		krb5_get_err_text(krb_context, problem)); | ||||
|  # endif | ||||
|  		krb5_free_error_message(krb_context, errmsg); | ||||
| -		return;
 | ||||
| +		return 0;
 | ||||
|  	} | ||||
|  #else | ||||
| -	if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) {
 | ||||
| +	if ((problem = ssh_krb5_cc_new_unique(krb_context, &ccache, &set_env)) != 0) {
 | ||||
|  		errmsg = krb5_get_error_message(krb_context, problem); | ||||
| -		logit("ssh_krb5_cc_gen(): %.100s", errmsg);
 | ||||
| +		logit("ssh_krb5_cc_new_unique(): %.100s", errmsg);
 | ||||
|  		krb5_free_error_message(krb_context, errmsg); | ||||
| -		return;
 | ||||
| +		return 0;
 | ||||
|  	} | ||||
|  #endif	/* #ifdef HEIMDAL */ | ||||
|   | ||||
| @@ -313,7 +314,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  		errmsg = krb5_get_error_message(krb_context, problem); | ||||
|  		logit("krb5_parse_name(): %.100s", errmsg); | ||||
|  		krb5_free_error_message(krb_context, errmsg); | ||||
| -		return;
 | ||||
| +		return 0;
 | ||||
|  	} | ||||
|   | ||||
|  	if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { | ||||
| @@ -322,7 +323,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  		krb5_free_error_message(krb_context, errmsg); | ||||
|  		krb5_free_principal(krb_context, princ); | ||||
|  		krb5_cc_destroy(krb_context, ccache); | ||||
| -		return;
 | ||||
| +		return 0;
 | ||||
|  	} | ||||
|   | ||||
|  	krb5_free_principal(krb_context, princ); | ||||
| @@ -331,32 +332,21 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|  	    client->creds, ccache))) { | ||||
|  		logit("gss_krb5_copy_ccache() failed"); | ||||
|  		krb5_cc_destroy(krb_context, ccache); | ||||
| -		return;
 | ||||
| +		return 0;
 | ||||
|  	} | ||||
|   | ||||
|  	new_cctype = krb5_cc_get_type(krb_context, ccache); | ||||
|  	new_ccname = krb5_cc_get_name(krb_context, ccache); | ||||
| -
 | ||||
| -	client->store.envvar = "KRB5CCNAME";
 | ||||
| -#ifdef USE_CCAPI
 | ||||
| -	xasprintf(&client->store.envval, "API:%s", new_ccname);
 | ||||
| -	client->store.filename = NULL;
 | ||||
| -#else
 | ||||
| -	if (new_ccname[0] == ':')
 | ||||
| -		new_ccname++;
 | ||||
|  	xasprintf(&client->store.envval, "%s:%s", new_cctype, new_ccname); | ||||
| -	if (strcmp(new_cctype, "DIR") == 0) {
 | ||||
| -		char *p;
 | ||||
| -		p = strrchr(client->store.envval, '/');
 | ||||
| -		if (p)
 | ||||
| -			*p = '\0';
 | ||||
| +
 | ||||
| +	if (set_env) {
 | ||||
| +		client->store.envvar = "KRB5CCNAME";
 | ||||
|  	} | ||||
|  	if ((strcmp(new_cctype, "FILE") == 0) || (strcmp(new_cctype, "DIR") == 0)) | ||||
|  		client->store.filename = xstrdup(new_ccname); | ||||
| -#endif
 | ||||
|   | ||||
|  #ifdef USE_PAM | ||||
| -	if (options.use_pam)
 | ||||
| +	if (options.use_pam && set_env)
 | ||||
|  		do_pam_putenv(client->store.envvar, client->store.envval); | ||||
|  #endif | ||||
|   | ||||
| @@ -364,7 +354,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_cl
 | ||||
|   | ||||
|  	client->store.data = krb_context; | ||||
|   | ||||
| -	return;
 | ||||
| +	return set_env;
 | ||||
|  } | ||||
|   | ||||
|  int | ||||
| diff -up openssh-8.6p1/servconf.c.ccache_name openssh-8.6p1/servconf.c
 | ||||
| --- openssh-8.6p1/servconf.c.ccache_name	2021-05-06 11:15:36.377143580 +0200
 | ||||
| +++ openssh-8.6p1/servconf.c	2021-05-06 11:15:36.388143662 +0200
 | ||||
| @@ -136,6 +136,7 @@ initialize_server_options(ServerOptions
 | ||||
|  	options->kerberos_or_local_passwd = -1; | ||||
|  	options->kerberos_ticket_cleanup = -1; | ||||
|  	options->kerberos_get_afs_token = -1; | ||||
| +	options->kerberos_unique_ccache = -1;
 | ||||
|  	options->gss_authentication=-1; | ||||
|  	options->gss_keyex = -1; | ||||
|  	options->gss_cleanup_creds = -1; | ||||
| @@ -359,6 +360,8 @@ fill_default_server_options(ServerOption
 | ||||
|  		options->kerberos_ticket_cleanup = 1; | ||||
|  	if (options->kerberos_get_afs_token == -1) | ||||
|  		options->kerberos_get_afs_token = 0; | ||||
| +	if (options->kerberos_unique_ccache == -1)
 | ||||
| +		options->kerberos_unique_ccache = 0;
 | ||||
|  	if (options->gss_authentication == -1) | ||||
|  		options->gss_authentication = 0; | ||||
|  	if (options->gss_keyex == -1) | ||||
| @@ -506,7 +509,8 @@ typedef enum {
 | ||||
|  	sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose, | ||||
|  	sRhostsRSAAuthentication, sRSAAuthentication, | ||||
|  	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, | ||||
| -	sKerberosGetAFSToken, sChallengeResponseAuthentication,
 | ||||
| +	sKerberosGetAFSToken, sKerberosUniqueCCache,
 | ||||
| +	sChallengeResponseAuthentication,
 | ||||
|  	sPasswordAuthentication, sKbdInteractiveAuthentication, | ||||
|  	sListenAddress, sAddressFamily, | ||||
|  	sPrintMotd, sPrintLastLog, sIgnoreRhosts, | ||||
| @@ -593,11 +597,13 @@ static struct {
 | ||||
|  #else | ||||
|  	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  #endif | ||||
| +	{ "kerberosuniqueccache", sKerberosUniqueCCache, SSHCFG_GLOBAL },
 | ||||
|  #else | ||||
|  	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL }, | ||||
|  	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, | ||||
| +	{ "kerberosuniqueccache", sUnsupported, SSHCFG_GLOBAL },
 | ||||
|  #endif | ||||
|  	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, | ||||
|  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, | ||||
| @@ -1573,6 +1579,10 @@ process_server_config_line_depth(ServerO
 | ||||
|  		intptr = &options->kerberos_get_afs_token; | ||||
|  		goto parse_flag; | ||||
|   | ||||
| +	case sKerberosUniqueCCache:
 | ||||
| +		intptr = &options->kerberos_unique_ccache;
 | ||||
| +		goto parse_flag;
 | ||||
| +
 | ||||
|  	case sGssAuthentication: | ||||
|  		intptr = &options->gss_authentication; | ||||
|  		goto parse_flag; | ||||
| @@ -2891,6 +2901,7 @@ dump_config(ServerOptions *o)
 | ||||
|  # ifdef USE_AFS | ||||
|  	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); | ||||
|  # endif | ||||
| +	dump_cfg_fmtint(sKerberosUniqueCCache, o->kerberos_unique_ccache);
 | ||||
|  #endif | ||||
|  #ifdef GSSAPI | ||||
|  	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); | ||||
| diff -up openssh-8.6p1/servconf.h.ccache_name openssh-8.6p1/servconf.h
 | ||||
| --- openssh-8.6p1/servconf.h.ccache_name	2021-05-06 11:15:36.377143580 +0200
 | ||||
| +++ openssh-8.6p1/servconf.h	2021-05-06 11:15:36.397143729 +0200
 | ||||
| @@ -140,6 +140,8 @@ typedef struct {
 | ||||
|  						 * file on logout. */ | ||||
|  	int     kerberos_get_afs_token;		/* If true, try to get AFS token if | ||||
|  						 * authenticated with Kerberos. */ | ||||
| +	int     kerberos_unique_ccache;		/* If true, the acquired ticket will
 | ||||
| +						 * be stored in per-session ccache */
 | ||||
|  	int     gss_authentication;	/* If true, permit GSSAPI authentication */ | ||||
|  	int     gss_keyex;		/* If true, permit GSSAPI key exchange */ | ||||
|  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */ | ||||
| diff -up openssh-8.6p1/session.c.ccache_name openssh-8.6p1/session.c
 | ||||
| --- openssh-8.6p1/session.c.ccache_name	2021-05-06 11:15:36.384143632 +0200
 | ||||
| +++ openssh-8.6p1/session.c	2021-05-06 11:15:36.397143729 +0200
 | ||||
| @@ -1038,7 +1038,8 @@ do_setup_env(struct ssh *ssh, Session *s
 | ||||
|  	/* Allow any GSSAPI methods that we've used to alter | ||||
|  	 * the child's environment as they see fit | ||||
|  	 */ | ||||
| -	ssh_gssapi_do_child(&env, &envsize);
 | ||||
| +	if (s->authctxt->krb5_set_env)
 | ||||
| +		ssh_gssapi_do_child(&env, &envsize);
 | ||||
|  #endif | ||||
|   | ||||
|  	/* Set basic environment. */ | ||||
| @@ -1114,7 +1115,7 @@ do_setup_env(struct ssh *ssh, Session *s
 | ||||
|  	} | ||||
|  #endif | ||||
|  #ifdef KRB5 | ||||
| -	if (s->authctxt->krb5_ccname)
 | ||||
| +	if (s->authctxt->krb5_ccname && s->authctxt->krb5_set_env)
 | ||||
|  		child_set_env(&env, &envsize, "KRB5CCNAME", | ||||
|  		    s->authctxt->krb5_ccname); | ||||
|  #endif | ||||
| diff -up openssh-8.6p1/sshd.c.ccache_name openssh-8.6p1/sshd.c
 | ||||
| --- openssh-8.6p1/sshd.c.ccache_name	2021-05-06 11:15:36.380143602 +0200
 | ||||
| +++ openssh-8.6p1/sshd.c	2021-05-06 11:15:36.398143736 +0200
 | ||||
| @@ -2284,7 +2284,7 @@ main(int ac, char **av)
 | ||||
|  #ifdef GSSAPI | ||||
|  	if (options.gss_authentication) { | ||||
|  		temporarily_use_uid(authctxt->pw); | ||||
| -		ssh_gssapi_storecreds();
 | ||||
| +		authctxt->krb5_set_env = ssh_gssapi_storecreds();
 | ||||
|  		restore_uid(); | ||||
|  	} | ||||
|  #endif | ||||
| diff -up openssh-8.6p1/sshd_config.5.ccache_name openssh-8.6p1/sshd_config.5
 | ||||
| --- openssh-8.6p1/sshd_config.5.ccache_name	2021-05-06 11:15:36.380143602 +0200
 | ||||
| +++ openssh-8.6p1/sshd_config.5	2021-05-06 11:15:36.398143736 +0200
 | ||||
| @@ -939,6 +939,14 @@ Specifies whether to automatically destr
 | ||||
|  file on logout. | ||||
|  The default is | ||||
|  .Cm yes . | ||||
| +.It Cm KerberosUniqueCCache
 | ||||
| +Specifies whether to store the acquired tickets in the per-session credential
 | ||||
| +cache under /tmp/ or whether to use per-user credential cache as configured in
 | ||||
| +.Pa /etc/krb5.conf .
 | ||||
| +The default value
 | ||||
| +.Cm no
 | ||||
| +can lead to overwriting previous tickets by subseqent connections to the same
 | ||||
| +user account.
 | ||||
|  .It Cm KexAlgorithms | ||||
|  Specifies the available KEX (Key Exchange) algorithms. | ||||
|  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); | ||||
							
								
								
									
										117
									
								
								SOURCES/openssh-7.7p1-redhat.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								SOURCES/openssh-7.7p1-redhat.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,117 @@ | ||||
| diff -up openssh/ssh_config.redhat openssh/ssh_config
 | ||||
| --- openssh/ssh_config.redhat	2020-02-11 23:28:35.000000000 +0100
 | ||||
| +++ openssh/ssh_config	2020-02-13 18:13:39.180641839 +0100
 | ||||
| @@ -43,3 +43,10 @@
 | ||||
|  #   ProxyCommand ssh -q -W %h:%p gateway.example.com | ||||
|  #   RekeyLimit 1G 1h | ||||
|  #   UserKnownHostsFile ~/.ssh/known_hosts.d/%k | ||||
| +#
 | ||||
| +# This system is following system-wide crypto policy.
 | ||||
| +# To modify the crypto properties (Ciphers, MACs, ...), create a  *.conf
 | ||||
| +#  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
 | ||||
| diff -up openssh/ssh_config_redhat.redhat openssh/ssh_config_redhat
 | ||||
| --- openssh/ssh_config_redhat.redhat	2020-02-13 18:13:39.180641839 +0100
 | ||||
| +++ openssh/ssh_config_redhat	2020-02-13 18:13:39.180641839 +0100
 | ||||
| @@ -0,0 +1,21 @@
 | ||||
| +# 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
 | ||||
| +Match final all
 | ||||
| +	# Follow system-wide Crypto Policy, if defined:
 | ||||
| +	Include /etc/crypto-policies/back-ends/openssh.config
 | ||||
| +
 | ||||
| +	GSSAPIAuthentication yes
 | ||||
| +
 | ||||
| +# If this option is set to yes then remote X11 clients will have full access
 | ||||
| +# to the original X11 display. As virtually no X11 client supports the untrusted
 | ||||
| +# mode correctly we set this to yes.
 | ||||
| +	ForwardX11Trusted yes
 | ||||
| +
 | ||||
| +# Send locale-related environment variables
 | ||||
| +	SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
 | ||||
| +	SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
 | ||||
| +	SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
 | ||||
| +	SendEnv XMODIFIERS
 | ||||
| +
 | ||||
| +# Uncomment this if you want to use .local domain
 | ||||
| +# Host *.local
 | ||||
| diff -up openssh/sshd_config.0.redhat openssh/sshd_config.0
 | ||||
| --- openssh/sshd_config.0.redhat	2020-02-12 14:30:04.000000000 +0100
 | ||||
| +++ openssh/sshd_config.0	2020-02-13 18:13:39.181641855 +0100
 | ||||
| @@ -970,9 +970,9 @@ DESCRIPTION
 | ||||
|   | ||||
|       SyslogFacility | ||||
|               Gives the facility code that is used when logging messages from | ||||
| -             sshd(8).  The possible values are: DAEMON, USER, AUTH, LOCAL0,
 | ||||
| -             LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.  The
 | ||||
| -             default is AUTH.
 | ||||
| +             sshd(8).  The possible values are: DAEMON, USER, AUTH, AUTHPRIV,
 | ||||
| +             LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
 | ||||
| +             The default is AUTH.
 | ||||
|   | ||||
|       TCPKeepAlive | ||||
|               Specifies whether the system should send TCP keepalive messages | ||||
| diff -up openssh/sshd_config.5.redhat openssh/sshd_config.5
 | ||||
| --- openssh/sshd_config.5.redhat	2020-02-11 23:28:35.000000000 +0100
 | ||||
| +++ openssh/sshd_config.5	2020-02-13 18:13:39.181641855 +0100
 | ||||
| @@ -1614,7 +1614,7 @@ By default no subsystems are defined.
 | ||||
|  .It Cm SyslogFacility | ||||
|  Gives the facility code that is used when logging messages from | ||||
|  .Xr sshd 8 . | ||||
| -The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
 | ||||
| +The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2,
 | ||||
|  LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. | ||||
|  The default is AUTH. | ||||
|  .It Cm TCPKeepAlive | ||||
| diff -up openssh/sshd_config.redhat openssh/sshd_config
 | ||||
| --- openssh/sshd_config.redhat	2020-02-11 23:28:35.000000000 +0100
 | ||||
| +++ openssh/sshd_config	2020-02-13 18:20:16.349913681 +0100
 | ||||
| @@ -10,6 +10,14 @@
 | ||||
|  # possible, but leave them commented.  Uncommented options override the | ||||
|  # 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
 | ||||
| +# SELinux about this change.
 | ||||
| +# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
 | ||||
| +#
 | ||||
|  #Port 22 | ||||
|  #AddressFamily any | ||||
|  #ListenAddress 0.0.0.0 | ||||
| diff -up openssh/sshd_config_redhat.redhat openssh/sshd_config_redhat
 | ||||
| --- openssh/sshd_config_redhat.redhat	2020-02-13 18:14:02.268006439 +0100
 | ||||
| +++ openssh/sshd_config_redhat	2020-02-13 18:19:20.765035947 +0100
 | ||||
| @@ -0,0 +1,28 @@
 | ||||
| +# This system is following system-wide crypto policy. The changes to
 | ||||
| +# crypto properties (Ciphers, MACs, ...) will not have any effect in
 | ||||
| +# this or following included files. To override some configuration option,
 | ||||
| +# write it before this block or include it before this file.
 | ||||
| +# Please, see manual pages for update-crypto-policies(8) and sshd_config(5).
 | ||||
| +Include /etc/crypto-policies/back-ends/opensshserver.config
 | ||||
| +
 | ||||
| +SyslogFacility AUTHPRIV
 | ||||
| +
 | ||||
| +ChallengeResponseAuthentication no
 | ||||
| +
 | ||||
| +GSSAPIAuthentication yes
 | ||||
| +GSSAPICleanupCredentials no
 | ||||
| +
 | ||||
| +UsePAM yes
 | ||||
| +
 | ||||
| +X11Forwarding yes
 | ||||
| +
 | ||||
| +# 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.
 | ||||
| +PrintMotd no
 | ||||
| +
 | ||||
| +# 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
 | ||||
| +
 | ||||
							
								
								
									
										26
									
								
								SOURCES/openssh-7.8p1-UsePAM-warning.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								SOURCES/openssh-7.8p1-UsePAM-warning.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| diff -up openssh-8.6p1/sshd.c.log-usepam-no openssh-8.6p1/sshd.c
 | ||||
| --- openssh-8.6p1/sshd.c.log-usepam-no	2021-04-19 14:00:45.099735129 +0200
 | ||||
| +++ openssh-8.6p1/sshd.c	2021-04-19 14:03:21.140920974 +0200
 | ||||
| @@ -1749,6 +1749,10 @@ main(int ac, char **av)
 | ||||
|  	parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, | ||||
|  	    cfg, &includes, NULL); | ||||
|   | ||||
| +	/* 'UsePAM no' is not supported in Fedora */
 | ||||
| +	if (! options.use_pam)
 | ||||
| +		logit("WARNING: 'UsePAM no' is not supported in Fedora and may cause several problems.");
 | ||||
| +
 | ||||
|  #ifdef WITH_OPENSSL | ||||
|  	if (options.moduli_file != NULL) | ||||
|  		dh_set_moduli_file(options.moduli_file); | ||||
| diff -up openssh-8.6p1/sshd_config.log-usepam-no openssh-8.6p1/sshd_config
 | ||||
| --- openssh-8.6p1/sshd_config.log-usepam-no	2021-04-19 14:00:45.098735121 +0200
 | ||||
| +++ openssh-8.6p1/sshd_config	2021-04-19 14:00:45.099735129 +0200
 | ||||
| @@ -87,6 +87,8 @@ 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'. | ||||
| +# WARNING: 'UsePAM no' is not supported in Fedora and may cause several
 | ||||
| +# problems.
 | ||||
|  #UsePAM no | ||||
|   | ||||
|  #AllowAgentForwarding yes | ||||
							
								
								
									
										867
									
								
								SOURCES/openssh-7.8p1-role-mls.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										867
									
								
								SOURCES/openssh-7.8p1-role-mls.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,867 @@ | ||||
| diff -up openssh/auth2.c.role-mls openssh/auth2.c
 | ||||
| --- openssh/auth2.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/auth2.c	2018-08-22 11:14:56.815430916 +0200
 | ||||
| @@ -256,6 +256,9 @@ input_userauth_request(int type, u_int32
 | ||||
|  	Authctxt *authctxt = ssh->authctxt; | ||||
|  	Authmethod *m = NULL; | ||||
|  	char *user = NULL, *service = NULL, *method = NULL, *style = NULL; | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	char *role = NULL;
 | ||||
| +#endif
 | ||||
|  	int r, authenticated = 0; | ||||
|  	double tstart = monotime_double(); | ||||
|   | ||||
| @@ -268,6 +271,11 @@ input_userauth_request(int type, u_int32
 | ||||
|  	debug("userauth-request for user %s service %s method %s", user, service, method); | ||||
|  	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); | ||||
|   | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	if ((role = strchr(user, '/')) != NULL)
 | ||||
| +		*role++ = 0;
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  	if ((style = strchr(user, ':')) != NULL) | ||||
|  		*style++ = 0; | ||||
|   | ||||
| @@ -296,8 +304,15 @@ input_userauth_request(int type, u_int32
 | ||||
|  		    use_privsep ? " [net]" : ""); | ||||
|  		authctxt->service = xstrdup(service); | ||||
|  		authctxt->style = style ? xstrdup(style) : NULL; | ||||
| -		if (use_privsep)
 | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +		authctxt->role = role ? xstrdup(role) : NULL;
 | ||||
| +#endif
 | ||||
| +		if (use_privsep) {
 | ||||
|  			mm_inform_authserv(service, style); | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +			mm_inform_authrole(role);
 | ||||
| +#endif
 | ||||
| +		}
 | ||||
|  		userauth_banner(ssh); | ||||
|  		if (auth2_setup_methods_lists(authctxt) != 0) | ||||
|  			ssh_packet_disconnect(ssh, | ||||
| diff -up openssh/auth2-gss.c.role-mls openssh/auth2-gss.c
 | ||||
| --- openssh/auth2-gss.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/auth2-gss.c	2018-08-22 11:15:42.459799171 +0200
 | ||||
| @@ -281,6 +281,7 @@ input_gssapi_mic(int type, u_int32_t ple
 | ||||
|  	Authctxt *authctxt = ssh->authctxt; | ||||
|  	Gssctxt *gssctxt; | ||||
|  	int r, authenticated = 0; | ||||
| +	char *micuser;
 | ||||
|  	struct sshbuf *b; | ||||
|  	gss_buffer_desc mic, gssbuf; | ||||
|  	const char *displayname; | ||||
| @@ -298,7 +299,13 @@ input_gssapi_mic(int type, u_int32_t ple
 | ||||
|  		fatal_f("sshbuf_new failed"); | ||||
|  	mic.value = p; | ||||
|  	mic.length = len; | ||||
| -	ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
 | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	if (authctxt->role && authctxt->role[0] != 0)
 | ||||
| +		xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role);
 | ||||
| +	else
 | ||||
| +#endif
 | ||||
| +		micuser = authctxt->user;
 | ||||
| +	ssh_gssapi_buildmic(b, micuser, authctxt->service,
 | ||||
|  	    "gssapi-with-mic", ssh->kex->session_id); | ||||
|   | ||||
|  	if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) | ||||
| @@ -311,6 +318,8 @@ input_gssapi_mic(int type, u_int32_t ple
 | ||||
|  		logit("GSSAPI MIC check failed"); | ||||
|   | ||||
|  	sshbuf_free(b); | ||||
| +	if (micuser != authctxt->user)
 | ||||
| +		free(micuser);
 | ||||
|  	free(mic.value); | ||||
|   | ||||
|  	if ((!use_privsep || mm_is_monitor()) && | ||||
| diff -up openssh/auth2-hostbased.c.role-mls openssh/auth2-hostbased.c
 | ||||
| --- openssh/auth2-hostbased.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/auth2-hostbased.c	2018-08-22 11:14:56.816430924 +0200
 | ||||
| @@ -123,7 +123,16 @@ userauth_hostbased(struct ssh *ssh)
 | ||||
|  	/* reconstruct packet */ | ||||
|  	if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 || | ||||
|  	    (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	    (authctxt->role
 | ||||
| +	    ? ( (r = sshbuf_put_u32(b, strlen(authctxt->user)+strlen(authctxt->role)+1)) != 0 ||
 | ||||
| +	        (r = sshbuf_put(b, authctxt->user, strlen(authctxt->user))) != 0 ||
 | ||||
| +	        (r = sshbuf_put_u8(b, '/') != 0) ||
 | ||||
| +	        (r = sshbuf_put(b, authctxt->role, strlen(authctxt->role))) != 0)
 | ||||
| +	    : (r = sshbuf_put_cstring(b, authctxt->user)) != 0) ||
 | ||||
| +#else
 | ||||
|  	    (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || | ||||
| +#endif
 | ||||
|  	    (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || | ||||
|  	    (r = sshbuf_put_cstring(b, "hostbased")) != 0 || | ||||
|  	    (r = sshbuf_put_string(b, pkalg, alen)) != 0 || | ||||
| diff -up openssh/auth2-pubkey.c.role-mls openssh/auth2-pubkey.c
 | ||||
| --- openssh/auth2-pubkey.c.role-mls	2018-08-22 11:14:56.816430924 +0200
 | ||||
| +++ openssh/auth2-pubkey.c	2018-08-22 11:17:07.331483958 +0200
 | ||||
| @@ -169,9 +169,16 @@ userauth_pubkey(struct ssh *ssh)
 | ||||
|  			goto done; | ||||
|  		} | ||||
|  		/* reconstruct packet */ | ||||
| -		xasprintf(&userstyle, "%s%s%s", authctxt->user,
 | ||||
| +		xasprintf(&userstyle, "%s%s%s%s%s", authctxt->user,
 | ||||
|  		    authctxt->style ? ":" : "", | ||||
| -		    authctxt->style ? authctxt->style : "");
 | ||||
| +		    authctxt->style ? authctxt->style : "",
 | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +		    authctxt->role ? "/" : "",
 | ||||
| +		    authctxt->role ? authctxt->role : ""
 | ||||
| +#else
 | ||||
| +		    "", ""
 | ||||
| +#endif
 | ||||
| +		    );
 | ||||
|  		if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || | ||||
|  		    (r = sshbuf_put_cstring(b, userstyle)) != 0 || | ||||
|  		    (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || | ||||
| diff -up openssh/auth.h.role-mls openssh/auth.h
 | ||||
| --- openssh/auth.h.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/auth.h	2018-08-22 11:14:56.816430924 +0200
 | ||||
| @@ -65,6 +65,9 @@ struct Authctxt {
 | ||||
|  	char		*service; | ||||
|  	struct passwd	*pw;		/* set if 'valid' */ | ||||
|  	char		*style; | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	char		*role;
 | ||||
| +#endif
 | ||||
|   | ||||
|  	/* Method lists for multiple authentication */ | ||||
|  	char		**auth_methods;	/* modified from server config */ | ||||
| diff -up openssh/auth-pam.c.role-mls openssh/auth-pam.c
 | ||||
| --- openssh/auth-pam.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/auth-pam.c	2018-08-22 11:14:56.816430924 +0200
 | ||||
| @@ -1172,7 +1172,7 @@ is_pam_session_open(void)
 | ||||
|   * during the ssh authentication process. | ||||
|   */ | ||||
|  int | ||||
| -do_pam_putenv(char *name, char *value)
 | ||||
| +do_pam_putenv(char *name, const char *value)
 | ||||
|  { | ||||
|  	int ret = 1; | ||||
|  	char *compound; | ||||
| 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	2018-08-22 11:14:56.817430932 +0200
 | ||||
| @@ -33,7 +33,7 @@ u_int do_pam_account(void);
 | ||||
|  void do_pam_session(struct ssh *); | ||||
|  void do_pam_setcred(int ); | ||||
|  void do_pam_chauthtok(void); | ||||
| -int do_pam_putenv(char *, char *);
 | ||||
| +int do_pam_putenv(char *, const char *);
 | ||||
|  char ** fetch_pam_environment(void); | ||||
|  char ** fetch_pam_child_environment(void); | ||||
|  void free_pam_environment(char **); | ||||
| diff -up openssh/misc.c.role-mls openssh/misc.c
 | ||||
| --- openssh/misc.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/misc.c	2018-08-22 11:14:56.817430932 +0200
 | ||||
| @@ -542,6 +542,7 @@ char *
 | ||||
|  colon(char *cp) | ||||
|  { | ||||
|  	int flag = 0; | ||||
| +	int start = 1;
 | ||||
|   | ||||
|  	if (*cp == ':')		/* Leading colon is part of file name. */ | ||||
|  		return NULL; | ||||
| @@ -557,6 +558,13 @@ colon(char *cp)
 | ||||
|  			return (cp); | ||||
|  		if (*cp == '/') | ||||
|  			return NULL; | ||||
| +		if (start) {
 | ||||
| +		/* Slash on beginning or after dots only denotes file name. */
 | ||||
| +			if (*cp == '/')
 | ||||
| +				return (0);
 | ||||
| +			if (*cp != '.')
 | ||||
| +				start = 0;
 | ||||
| +		}
 | ||||
|  	} | ||||
|  	return NULL; | ||||
|  } | ||||
| diff -up openssh-8.6p1/monitor.c.role-mls openssh-8.6p1/monitor.c
 | ||||
| --- openssh-8.6p1/monitor.c.role-mls	2021-04-16 05:55:25.000000000 +0200
 | ||||
| +++ openssh-8.6p1/monitor.c	2021-05-21 14:21:56.719414087 +0200
 | ||||
| @@ -117,6 +117,9 @@ int mm_answer_sign(struct ssh *, int, st
 | ||||
|  int mm_answer_pwnamallow(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 *); | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +int mm_answer_authrole(struct ssh *, int, struct sshbuf *);
 | ||||
| +#endif
 | ||||
|  int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); | ||||
|  int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); | ||||
|  int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); | ||||
| @@ -195,6 +198,9 @@ struct mon_table mon_dispatch_proto20[]
 | ||||
|      {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, | ||||
|      {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, | ||||
|      {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +    {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
 | ||||
| +#endif
 | ||||
|      {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, | ||||
|      {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, | ||||
|  #ifdef USE_PAM | ||||
| @@ -803,6 +809,9 @@ mm_answer_pwnamallow(struct ssh *ssh, in
 | ||||
|   | ||||
|  	/* Allow service/style information on the auth context */ | ||||
|  	monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
 | ||||
| +#endif
 | ||||
|  	monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); | ||||
|   | ||||
|  #ifdef USE_PAM | ||||
| @@ -877,6 +886,26 @@ key_base_type_match(const char *method,
 | ||||
|  	return found; | ||||
|  } | ||||
|   | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +int
 | ||||
| +mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m)
 | ||||
| +{
 | ||||
| +	int r;
 | ||||
| +	monitor_permit_authentications(1);
 | ||||
| +
 | ||||
| +	if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0)
 | ||||
| +		fatal_f("buffer error: %s", ssh_err(r));
 | ||||
| +	debug3_f("role=%s", authctxt->role);
 | ||||
| +
 | ||||
| +	if (strlen(authctxt->role) == 0) {
 | ||||
| +		free(authctxt->role);
 | ||||
| +		authctxt->role = NULL;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	return (0);
 | ||||
| +}
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  int | ||||
|  mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) | ||||
|  { | ||||
| @@ -1251,7 +1280,7 @@ monitor_valid_userblob(struct ssh *ssh,
 | ||||
|  { | ||||
|  	struct sshbuf *b; | ||||
|  	const u_char *p; | ||||
| -	char *userstyle, *cp;
 | ||||
| +	char *userstyle, *s, *cp;
 | ||||
|  	size_t len; | ||||
|  	u_char type; | ||||
|  	int r, fail = 0; | ||||
| @@ -1282,6 +1311,8 @@ monitor_valid_userblob(struct ssh *ssh,
 | ||||
|  		fail++; | ||||
|  	if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) | ||||
|  		fatal_fr(r, "parse userstyle"); | ||||
| +	if ((s = strchr(cp, '/')) != NULL)
 | ||||
| +		*s = '\0';
 | ||||
|  	xasprintf(&userstyle, "%s%s%s", authctxt->user, | ||||
|  	    authctxt->style ? ":" : "", | ||||
|  	    authctxt->style ? authctxt->style : ""); | ||||
| @@ -1317,7 +1348,7 @@ monitor_valid_hostbasedblob(const u_char
 | ||||
|  { | ||||
|  	struct sshbuf *b; | ||||
|  	const u_char *p; | ||||
| -	char *cp, *userstyle;
 | ||||
| +	char *cp, *s, *userstyle;
 | ||||
|  	size_t len; | ||||
|  	int r, fail = 0; | ||||
|  	u_char type; | ||||
| @@ -1338,6 +1370,8 @@ monitor_valid_hostbasedblob(const u_char
 | ||||
|  		fail++; | ||||
|  	if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) | ||||
|  		fatal_fr(r, "parse userstyle"); | ||||
| +	if ((s = strchr(cp, '/')) != NULL)
 | ||||
| +		*s = '\0';
 | ||||
|  	xasprintf(&userstyle, "%s%s%s", authctxt->user, | ||||
|  	    authctxt->style ? ":" : "", | ||||
|  	    authctxt->style ? authctxt->style : ""); | ||||
| diff -up openssh/monitor.h.role-mls openssh/monitor.h
 | ||||
| --- openssh/monitor.h.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/monitor.h	2018-08-22 11:14:56.818430941 +0200
 | ||||
| @@ -55,6 +55,10 @@ enum monitor_reqtype {
 | ||||
|  	MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, | ||||
|  	MONITOR_REQ_TERM = 50, | ||||
|   | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	MONITOR_REQ_AUTHROLE = 80,
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  	MONITOR_REQ_PAM_START = 100, | ||||
|  	MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, | ||||
|  	MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, | ||||
| diff -up openssh/monitor_wrap.c.role-mls openssh/monitor_wrap.c
 | ||||
| --- openssh/monitor_wrap.c.role-mls	2018-08-22 11:14:56.818430941 +0200
 | ||||
| +++ openssh/monitor_wrap.c	2018-08-22 11:21:47.938747968 +0200
 | ||||
| @@ -390,6 +390,27 @@ mm_inform_authserv(char *service, char *
 | ||||
|  	sshbuf_free(m); | ||||
|  } | ||||
|   | ||||
| +/* Inform the privileged process about role */
 | ||||
| +
 | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +void
 | ||||
| +mm_inform_authrole(char *role)
 | ||||
| +{
 | ||||
| +	int r;
 | ||||
| +	struct sshbuf *m;
 | ||||
| +
 | ||||
| +	debug3_f("entering");
 | ||||
| +
 | ||||
| +	if ((m = sshbuf_new()) == NULL)
 | ||||
| +		fatal_f("sshbuf_new failed");
 | ||||
| +	if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0)
 | ||||
| +		fatal_f("buffer error: %s", ssh_err(r));
 | ||||
| +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m);
 | ||||
| +
 | ||||
| +	sshbuf_free(m);
 | ||||
| +}
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  /* Do the password authentication */ | ||||
|  int | ||||
|  mm_auth_password(struct ssh *ssh, char *password) | ||||
| 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	2018-08-22 11:22:10.439929513 +0200
 | ||||
| @@ -44,6 +44,9 @@ DH *mm_choose_dh(int, int, int);
 | ||||
|      const u_char *, size_t, const char *, const char *, | ||||
|      const char *, u_int compat); | ||||
|  void mm_inform_authserv(char *, char *); | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +void mm_inform_authrole(char *);
 | ||||
| +#endif
 | ||||
|  struct passwd *mm_getpwnamallow(struct ssh *, const char *); | ||||
|  char *mm_auth2_read_banner(void); | ||||
|  int mm_auth_password(struct ssh *, char *); | ||||
| diff -up openssh/openbsd-compat/Makefile.in.role-mls openssh/openbsd-compat/Makefile.in
 | ||||
| --- 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
 | ||||
| @@ -92,7 +92,8 @@ PORTS=	port-aix.o \
 | ||||
|  	port-linux.o \ | ||||
|  	port-solaris.o \ | ||||
|  	port-net.o \ | ||||
| -	port-uw.o
 | ||||
| +	port-uw.o \
 | ||||
| +	port-linux-sshd.o
 | ||||
|   | ||||
|  .c.o: | ||||
|  	$(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -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	2018-08-22 11:14:56.819430949 +0200
 | ||||
| @@ -100,37 +100,6 @@ ssh_selinux_getctxbyname(char *pwname)
 | ||||
|  	return sc; | ||||
|  } | ||||
|   | ||||
| -/* Set the execution context to the default for the specified user */
 | ||||
| -void
 | ||||
| -ssh_selinux_setup_exec_context(char *pwname)
 | ||||
| -{
 | ||||
| -	char *user_ctx = NULL;
 | ||||
| -
 | ||||
| -	if (!ssh_selinux_enabled())
 | ||||
| -		return;
 | ||||
| -
 | ||||
| -	debug3("%s: setting execution context", __func__);
 | ||||
| -
 | ||||
| -	user_ctx = ssh_selinux_getctxbyname(pwname);
 | ||||
| -	if (setexeccon(user_ctx) != 0) {
 | ||||
| -		switch (security_getenforce()) {
 | ||||
| -		case -1:
 | ||||
| -			fatal("%s: security_getenforce() failed", __func__);
 | ||||
| -		case 0:
 | ||||
| -			error("%s: Failed to set SELinux execution "
 | ||||
| -			    "context for %s", __func__, pwname);
 | ||||
| -			break;
 | ||||
| -		default:
 | ||||
| -			fatal("%s: Failed to set SELinux execution context "
 | ||||
| -			    "for %s (in enforcing mode)", __func__, pwname);
 | ||||
| -		}
 | ||||
| -	}
 | ||||
| -	if (user_ctx != NULL)
 | ||||
| -		freecon(user_ctx);
 | ||||
| -
 | ||||
| -	debug3("%s: done", __func__);
 | ||||
| -}
 | ||||
| -
 | ||||
|  /* Set the TTY context for the specified user */ | ||||
|  void | ||||
|  ssh_selinux_setup_pty(char *pwname, const char *tty) | ||||
| @@ -145,7 +114,11 @@ ssh_selinux_setup_pty(char *pwname, cons
 | ||||
|   | ||||
|  	debug3("%s: setting TTY context on %s", __func__, tty); | ||||
|   | ||||
| -	user_ctx = ssh_selinux_getctxbyname(pwname);
 | ||||
| +	if (getexeccon(&user_ctx) != 0) {
 | ||||
| +		error_f("getexeccon: %s", strerror(errno));
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +
 | ||||
|   | ||||
|  	/* XXX: should these calls fatal() upon failure in enforcing mode? */ | ||||
|   | ||||
| diff -up openssh/openbsd-compat/port-linux.h.role-mls openssh/openbsd-compat/port-linux.h
 | ||||
| --- openssh/openbsd-compat/port-linux.h.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/openbsd-compat/port-linux.h	2018-08-22 11:14:56.819430949 +0200
 | ||||
| @@ -20,9 +20,10 @@
 | ||||
|  #ifdef WITH_SELINUX | ||||
|  int ssh_selinux_enabled(void); | ||||
|  void ssh_selinux_setup_pty(char *, const char *); | ||||
| -void ssh_selinux_setup_exec_context(char *);
 | ||||
|  void ssh_selinux_change_context(const char *); | ||||
|  void ssh_selinux_setfscreatecon(const char *); | ||||
| +
 | ||||
| +void sshd_selinux_setup_exec_context(char *);
 | ||||
|  #endif | ||||
|   | ||||
|  #ifdef LINUX_OOM_ADJUST | ||||
| diff -up openssh/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	2018-08-22 11:14:56.819430949 +0200
 | ||||
| @@ -0,0 +1,421 @@
 | ||||
| +/*
 | ||||
| + * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
 | ||||
| + * Copyright (c) 2014 Petr Lautrbach <plautrba@redhat.com>
 | ||||
| + *
 | ||||
| + * Permission to use, copy, modify, and distribute this software for any
 | ||||
| + * purpose with or without fee is hereby granted, provided that the above
 | ||||
| + * copyright notice and this permission notice appear in all copies.
 | ||||
| + *
 | ||||
| + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | ||||
| + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | ||||
| + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | ||||
| + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | ||||
| + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | ||||
| + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | ||||
| + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | ||||
| + */
 | ||||
| +
 | ||||
| +/*
 | ||||
| + * Linux-specific portability code - just SELinux support for sshd at present
 | ||||
| + */
 | ||||
| +
 | ||||
| +#include "includes.h"
 | ||||
| +
 | ||||
| +#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
 | ||||
| +#include <errno.h>
 | ||||
| +#include <stdarg.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +
 | ||||
| +#include "log.h"
 | ||||
| +#include "xmalloc.h"
 | ||||
| +#include "misc.h"      /* servconf.h needs misc.h for struct ForwardOptions */
 | ||||
| +#include "servconf.h"
 | ||||
| +#include "port-linux.h"
 | ||||
| +#include "sshkey.h"
 | ||||
| +#include "hostfile.h"
 | ||||
| +#include "auth.h"
 | ||||
| +
 | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +#include <selinux/selinux.h>
 | ||||
| +#include <selinux/context.h>
 | ||||
| +#include <selinux/get_context_list.h>
 | ||||
| +#include <selinux/get_default_type.h>
 | ||||
| +
 | ||||
| +#ifdef HAVE_LINUX_AUDIT
 | ||||
| +#include <libaudit.h>
 | ||||
| +#include <unistd.h>
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +extern ServerOptions options;
 | ||||
| +extern Authctxt *the_authctxt;
 | ||||
| +extern int inetd_flag;
 | ||||
| +extern int rexeced_flag;
 | ||||
| +
 | ||||
| +/* Send audit message */
 | ||||
| +static int
 | ||||
| +sshd_selinux_send_audit_message(int success, security_context_t default_context,
 | ||||
| +		       security_context_t selected_context)
 | ||||
| +{
 | ||||
| +	int rc=0;
 | ||||
| +#ifdef HAVE_LINUX_AUDIT
 | ||||
| +	char *msg = NULL;
 | ||||
| +	int audit_fd = audit_open();
 | ||||
| +	security_context_t default_raw=NULL;
 | ||||
| +	security_context_t selected_raw=NULL;
 | ||||
| +	rc = -1;
 | ||||
| +	if (audit_fd < 0) {
 | ||||
| +		if (errno == EINVAL || errno == EPROTONOSUPPORT ||
 | ||||
| +					errno == EAFNOSUPPORT)
 | ||||
| +				return 0; /* No audit support in kernel */
 | ||||
| +		error("Error connecting to audit system.");
 | ||||
| +		return rc;
 | ||||
| +	}
 | ||||
| +	if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) {
 | ||||
| +		error("Error translating default context.");
 | ||||
| +		default_raw = NULL;
 | ||||
| +	}
 | ||||
| +	if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) {
 | ||||
| +		error("Error translating selected context.");
 | ||||
| +		selected_raw = NULL;
 | ||||
| +	}
 | ||||
| +	if (asprintf(&msg, "sshd: default-context=%s selected-context=%s",
 | ||||
| +		     default_raw ? default_raw : (default_context ? default_context: "?"),
 | ||||
| +		     selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) {
 | ||||
| +		error("Error allocating memory.");
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE,
 | ||||
| +				   msg, NULL, NULL, NULL, success) <= 0) {
 | ||||
| +		error("Error sending audit message.");
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	rc = 0;
 | ||||
| +      out:
 | ||||
| +	free(msg);
 | ||||
| +	freecon(default_raw);
 | ||||
| +	freecon(selected_raw);
 | ||||
| +	close(audit_fd);
 | ||||
| +#endif
 | ||||
| +	return rc;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +mls_range_allowed(security_context_t src, security_context_t dst)
 | ||||
| +{
 | ||||
| +	struct av_decision avd;
 | ||||
| +	int retval;
 | ||||
| +	access_vector_t bit;
 | ||||
| +	security_class_t class;
 | ||||
| +
 | ||||
| +	debug_f("src:%s dst:%s", src, dst);
 | ||||
| +	class = string_to_security_class("context");
 | ||||
| +	if (!class) {
 | ||||
| +		error("string_to_security_class failed to translate security class context");
 | ||||
| +		return 1;
 | ||||
| +	}
 | ||||
| +	bit = string_to_av_perm(class, "contains");
 | ||||
| +	if (!bit) {
 | ||||
| +		error("string_to_av_perm failed to translate av perm contains");
 | ||||
| +		return 1;
 | ||||
| +	}
 | ||||
| +	retval = security_compute_av(src, dst, class, bit, &avd);
 | ||||
| +	if (retval || ((bit & avd.allowed) != bit))
 | ||||
| +		return 0;
 | ||||
| +
 | ||||
| +	return 1;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +get_user_context(const char *sename, const char *role, const char *lvl,
 | ||||
| +	security_context_t *sc) {
 | ||||
| +#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
 | ||||
| +	if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) {
 | ||||
| +	        /* User may have requested a level completely outside of his 
 | ||||
| +	           allowed range. We get a context just for auditing as the
 | ||||
| +	           range check below will certainly fail for default context. */
 | ||||
| +#endif
 | ||||
| +		if (get_default_context(sename, NULL, sc) != 0) {
 | ||||
| +			*sc = NULL;
 | ||||
| +			return -1;
 | ||||
| +		}
 | ||||
| +#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
 | ||||
| +	}
 | ||||
| +#endif
 | ||||
| +	if (role != NULL && role[0]) {
 | ||||
| +		context_t con;
 | ||||
| +		char *type=NULL;
 | ||||
| +		if (get_default_type(role, &type) != 0) {
 | ||||
| +			error("get_default_type: failed to get default type for '%s'",
 | ||||
| +				role);
 | ||||
| +			goto out;
 | ||||
| +		}
 | ||||
| +		con = context_new(*sc);
 | ||||
| +		if (!con) {
 | ||||
| +			goto out;
 | ||||
| +		}
 | ||||
| +		context_role_set(con, role);
 | ||||
| +		context_type_set(con, type);
 | ||||
| +		freecon(*sc);
 | ||||
| +		*sc = strdup(context_str(con));
 | ||||
| +		context_free(con);
 | ||||
| +		if (!*sc)
 | ||||
| +			return -1;
 | ||||
| +	}
 | ||||
| +#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
 | ||||
| +	if (lvl != NULL && lvl[0]) {
 | ||||
| +		/* verify that the requested range is obtained */
 | ||||
| +		context_t con;
 | ||||
| +		security_context_t obtained_raw;
 | ||||
| +		security_context_t requested_raw;
 | ||||
| +		con = context_new(*sc);
 | ||||
| +		if (!con) {
 | ||||
| +			goto out;
 | ||||
| +		}
 | ||||
| +		context_range_set(con, lvl);
 | ||||
| +		if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) {
 | ||||
| +			context_free(con);
 | ||||
| +			goto out;
 | ||||
| +		}
 | ||||
| +		if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) {
 | ||||
| +			freecon(obtained_raw);
 | ||||
| +			context_free(con);
 | ||||
| +			goto out;
 | ||||
| +		}
 | ||||
| +
 | ||||
| +		debug("get_user_context: obtained context '%s' requested context '%s'",
 | ||||
| +			obtained_raw, requested_raw);
 | ||||
| +		if (strcmp(obtained_raw, requested_raw)) {
 | ||||
| +			/* set the context to the real requested one but fail */
 | ||||
| +			freecon(requested_raw);
 | ||||
| +			freecon(obtained_raw);
 | ||||
| +			freecon(*sc);
 | ||||
| +			*sc = strdup(context_str(con));
 | ||||
| +			context_free(con);
 | ||||
| +			return -1;
 | ||||
| +		}
 | ||||
| +		freecon(requested_raw);
 | ||||
| +		freecon(obtained_raw);
 | ||||
| +		context_free(con);
 | ||||
| +	}
 | ||||
| +#endif
 | ||||
| +	return 0;
 | ||||
| +      out:
 | ||||
| +	freecon(*sc);
 | ||||
| +	*sc = NULL;
 | ||||
| +	return -1;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +ssh_selinux_get_role_level(char **role, const char **level)
 | ||||
| +{
 | ||||
| +	*role = NULL;
 | ||||
| +	*level = NULL;
 | ||||
| +	if (the_authctxt) {
 | ||||
| +		if (the_authctxt->role != NULL) {
 | ||||
| +			char *slash;
 | ||||
| +			*role = xstrdup(the_authctxt->role);
 | ||||
| +			if ((slash = strchr(*role, '/')) != NULL) {
 | ||||
| +				*slash = '\0';
 | ||||
| +				*level = slash + 1;
 | ||||
| +			}
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +}
 | ||||
| +
 | ||||
| +/* Return the default security context for the given username */
 | ||||
| +static int
 | ||||
| +sshd_selinux_getctxbyname(char *pwname,
 | ||||
| +	security_context_t *default_sc, security_context_t *user_sc)
 | ||||
| +{
 | ||||
| +	char *sename, *lvl;
 | ||||
| +	char *role;
 | ||||
| +	const char *reqlvl;
 | ||||
| +	int r = 0;
 | ||||
| +	context_t con = NULL;
 | ||||
| +
 | ||||
| +	ssh_selinux_get_role_level(&role, &reqlvl);
 | ||||
| +
 | ||||
| +#ifdef HAVE_GETSEUSERBYNAME
 | ||||
| +	if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
 | ||||
| +		sename = NULL;
 | ||||
| +		lvl = NULL;
 | ||||
| +	}
 | ||||
| +#else
 | ||||
| +	sename = pwname;
 | ||||
| +	lvl = "";
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +	if (r == 0) {
 | ||||
| +#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
 | ||||
| +		r = get_default_context_with_level(sename, lvl, NULL, default_sc);
 | ||||
| +#else
 | ||||
| +		r = get_default_context(sename, NULL, default_sc);
 | ||||
| +#endif
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if (r == 0) {
 | ||||
| +		/* If launched from xinetd, we must use current level */
 | ||||
| +		if (inetd_flag && !rexeced_flag) {
 | ||||
| +			security_context_t sshdsc=NULL;
 | ||||
| +
 | ||||
| +			if (getcon_raw(&sshdsc) < 0)
 | ||||
| +				fatal("failed to allocate security context");
 | ||||
| +
 | ||||
| +			if ((con=context_new(sshdsc)) == NULL)
 | ||||
| +				fatal("failed to allocate selinux context");
 | ||||
| +			reqlvl = context_range_get(con);
 | ||||
| +			freecon(sshdsc);
 | ||||
| +			if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0)
 | ||||
| +			    /* we actually don't change level */
 | ||||
| +			    reqlvl = "";
 | ||||
| +
 | ||||
| +			debug_f("current connection level '%s'", reqlvl);
 | ||||
| +
 | ||||
| +		}
 | ||||
| +
 | ||||
| +		if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) {
 | ||||
| +			r = get_user_context(sename, role, reqlvl, user_sc);
 | ||||
| +
 | ||||
| +			if (r == 0 && reqlvl != NULL && reqlvl[0]) {
 | ||||
| +				security_context_t default_level_sc = *default_sc;
 | ||||
| +				if (role != NULL && role[0]) {
 | ||||
| +					if (get_user_context(sename, role, lvl, &default_level_sc) < 0)
 | ||||
| +						default_level_sc = *default_sc;
 | ||||
| +				}
 | ||||
| +				/* verify that the requested range is contained in the user range */
 | ||||
| +				if (mls_range_allowed(default_level_sc, *user_sc)) {
 | ||||
| +					logit("permit MLS level %s (user range %s)", reqlvl, lvl);
 | ||||
| +				} else {
 | ||||
| +					r = -1;
 | ||||
| +					error("deny MLS level %s (user range %s)", reqlvl, lvl);
 | ||||
| +				}
 | ||||
| +				if (default_level_sc != *default_sc)
 | ||||
| +					freecon(default_level_sc);
 | ||||
| +			}
 | ||||
| +		} else {
 | ||||
| +			*user_sc = *default_sc;
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +	if (r != 0) {
 | ||||
| +		error_f("Failed to get default SELinux security "
 | ||||
| +		    "context for %s", pwname);
 | ||||
| +	}
 | ||||
| +
 | ||||
| +#ifdef HAVE_GETSEUSERBYNAME
 | ||||
| +	free(sename);
 | ||||
| +	free(lvl);
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +	if (role != NULL)
 | ||||
| +		free(role);
 | ||||
| +	if (con)
 | ||||
| +		context_free(con);
 | ||||
| +
 | ||||
| +	return (r);
 | ||||
| +}
 | ||||
| +
 | ||||
| +/* Setup environment variables for pam_selinux */
 | ||||
| +static int
 | ||||
| +sshd_selinux_setup_pam_variables(void)
 | ||||
| +{
 | ||||
| +	const char *reqlvl;
 | ||||
| +	char *role;
 | ||||
| +	char *use_current;
 | ||||
| +	int rv;
 | ||||
| +
 | ||||
| +	debug3_f("setting execution context");
 | ||||
| +
 | ||||
| +	ssh_selinux_get_role_level(&role, &reqlvl);
 | ||||
| +
 | ||||
| +	rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
 | ||||
| +
 | ||||
| +	if (inetd_flag && !rexeced_flag) {
 | ||||
| +		use_current = "1";
 | ||||
| +	} else {
 | ||||
| +		use_current = "";
 | ||||
| +		rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current);
 | ||||
| +
 | ||||
| +	if (role != NULL)
 | ||||
| +		free(role);
 | ||||
| +
 | ||||
| +	return rv;
 | ||||
| +}
 | ||||
| +
 | ||||
| +/* Set the execution context to the default for the specified user */
 | ||||
| +void
 | ||||
| +sshd_selinux_setup_exec_context(char *pwname)
 | ||||
| +{
 | ||||
| +	security_context_t user_ctx = NULL;
 | ||||
| +	int r = 0;
 | ||||
| +	security_context_t default_ctx = NULL;
 | ||||
| +
 | ||||
| +	if (!ssh_selinux_enabled())
 | ||||
| +		return;
 | ||||
| +
 | ||||
| +	if (options.use_pam) {
 | ||||
| +		/* do not compute context, just setup environment for pam_selinux */
 | ||||
| +		if (sshd_selinux_setup_pam_variables()) {
 | ||||
| +			switch (security_getenforce()) {
 | ||||
| +			case -1:
 | ||||
| +				fatal_f("security_getenforce() failed");
 | ||||
| +			case 0:
 | ||||
| +				error_f("SELinux PAM variable setup failure. Continuing in permissive mode.");
 | ||||
| +			break;
 | ||||
| +			default:
 | ||||
| +				fatal_f("SELinux PAM variable setup failure. Aborting connection.");
 | ||||
| +			}
 | ||||
| +		}
 | ||||
| +		return;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	debug3_f("setting execution context");
 | ||||
| +
 | ||||
| +	r = sshd_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
 | ||||
| +	if (r >= 0) {
 | ||||
| +		r = setexeccon(user_ctx);
 | ||||
| +		if (r < 0) {
 | ||||
| +			error_f("Failed to set SELinux execution context %s for %s",
 | ||||
| +			    user_ctx, pwname);
 | ||||
| +		}
 | ||||
| +#ifdef HAVE_SETKEYCREATECON
 | ||||
| +		else if (setkeycreatecon(user_ctx) < 0) {
 | ||||
| +			error_f("Failed to set SELinux keyring creation context %s for %s",
 | ||||
| +			    user_ctx, pwname);
 | ||||
| +		}
 | ||||
| +#endif
 | ||||
| +	}
 | ||||
| +	if (user_ctx == NULL) {
 | ||||
| +		user_ctx = default_ctx;
 | ||||
| +	}
 | ||||
| +	if (r < 0 || user_ctx != default_ctx) {
 | ||||
| +		/* audit just the case when user changed a role or there was
 | ||||
| +		   a failure */
 | ||||
| +		sshd_selinux_send_audit_message(r >= 0, default_ctx, user_ctx);
 | ||||
| +	}
 | ||||
| +	if (r < 0) {
 | ||||
| +		switch (security_getenforce()) {
 | ||||
| +		case -1:
 | ||||
| +			fatal_f("security_getenforce() failed");
 | ||||
| +		case 0:
 | ||||
| +			error_f("ELinux failure. Continuing in permissive mode.");
 | ||||
| +			break;
 | ||||
| +		default:
 | ||||
| +			fatal_f("SELinux failure. Aborting connection.");
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +	if (user_ctx != NULL && user_ctx != default_ctx)
 | ||||
| +		freecon(user_ctx);
 | ||||
| +	if (default_ctx != NULL)
 | ||||
| +		freecon(default_ctx);
 | ||||
| +
 | ||||
| +	debug3_f("done");
 | ||||
| +}
 | ||||
| +
 | ||||
| +#endif
 | ||||
| +#endif
 | ||||
| +
 | ||||
| diff -up openssh/platform.c.role-mls openssh/platform.c
 | ||||
| --- openssh/platform.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/platform.c	2018-08-22 11:14:56.819430949 +0200
 | ||||
| @@ -183,7 +183,7 @@ platform_setusercontext_post_groups(stru
 | ||||
|  	} | ||||
|  #endif /* HAVE_SETPCRED */ | ||||
|  #ifdef WITH_SELINUX | ||||
| -	ssh_selinux_setup_exec_context(pw->pw_name);
 | ||||
| +	sshd_selinux_setup_exec_context(pw->pw_name);
 | ||||
|  #endif | ||||
|  } | ||||
|   | ||||
| diff -up openssh/sshd.c.role-mls openssh/sshd.c
 | ||||
| --- openssh/sshd.c.role-mls	2018-08-20 07:57:29.000000000 +0200
 | ||||
| +++ openssh/sshd.c	2018-08-22 11:14:56.820430957 +0200
 | ||||
| @@ -2186,6 +2186,9 @@ main(int ac, char **av)
 | ||||
|  		restore_uid(); | ||||
|  	} | ||||
|  #endif | ||||
| +#ifdef WITH_SELINUX
 | ||||
| +	sshd_selinux_setup_exec_context(authctxt->pw->pw_name);
 | ||||
| +#endif
 | ||||
|  #ifdef USE_PAM | ||||
|  	if (options.use_pam) { | ||||
|  		do_pam_setcred(1); | ||||
							
								
								
									
										16
									
								
								SOURCES/openssh-7.8p1-scp-ipv6.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								SOURCES/openssh-7.8p1-scp-ipv6.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| diff --git a/scp.c b/scp.c
 | ||||
| index 60682c68..9344806e 100644
 | ||||
| --- a/scp.c
 | ||||
| +++ b/scp.c
 | ||||
| @@ -714,7 +714,9 @@ toremote(int argc, char **argv)
 | ||||
|  			addargs(&alist, "%s", host); | ||||
|  			addargs(&alist, "%s", cmd); | ||||
|  			addargs(&alist, "%s", src); | ||||
| -			addargs(&alist, "%s%s%s:%s",
 | ||||
| +			addargs(&alist,
 | ||||
| +			    /* IPv6 address needs to be enclosed with sqare brackets */
 | ||||
| +			    strchr(host, ':') != NULL ? "%s%s[%s]:%s" : "%s%s%s:%s",
 | ||||
|  			    tuser ? tuser : "", tuser ? "@" : "", | ||||
|  			    thost, targ); | ||||
|  			if (do_local_cmd(&alist) != 0) | ||||
| 
 | ||||
							
								
								
									
										498
									
								
								SOURCES/openssh-8.0p1-crypto-policies.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								SOURCES/openssh-8.0p1-crypto-policies.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,498 @@ | ||||
| diff -up openssh-8.6p1/ssh_config.5.crypto-policies openssh-8.6p1/ssh_config.5
 | ||||
| --- openssh-8.6p1/ssh_config.5.crypto-policies	2021-04-19 15:18:32.071920379 +0200
 | ||||
| +++ openssh-8.6p1/ssh_config.5	2021-04-19 15:21:18.400179265 +0200
 | ||||
| @@ -368,15 +368,13 @@ or
 | ||||
|  .Qq *.c.example.com | ||||
|  domains. | ||||
|  .It Cm CASignatureAlgorithms | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies which algorithms are allowed for signing of certificates | ||||
|  by certificate authorities (CAs). | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||
| -sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||
| -rsa-sha2-512,rsa-sha2-256
 | ||||
| -.Ed
 | ||||
| -.Pp
 | ||||
|  .Xr ssh 1 | ||||
|  will not accept host certificates signed using algorithms other than those | ||||
|  specified. | ||||
| @@ -436,20 +434,25 @@ If the option is set to
 | ||||
|  (the default), | ||||
|  the check will not be executed. | ||||
|  .It Cm Ciphers | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies the ciphers allowed and their order of preference. | ||||
|  Multiple ciphers must be comma-separated. | ||||
|  If the specified list begins with a | ||||
|  .Sq + | ||||
| -character, then the specified ciphers will be appended to the default set
 | ||||
| -instead of replacing them.
 | ||||
| +character, then the specified ciphers will be appended to the built-in
 | ||||
| +openssh default set instead of replacing them.
 | ||||
|  If the specified list begins with a | ||||
|  .Sq - | ||||
|  character, then the specified ciphers (including wildcards) will be removed | ||||
| -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 ciphers will be placed at the head of the | ||||
| -default set.
 | ||||
| +built-in openssh default set.
 | ||||
|  .Pp | ||||
|  The supported ciphers are: | ||||
|  .Bd -literal -offset indent | ||||
| @@ -465,13 +468,6 @@ aes256-gcm@openssh.com
 | ||||
|  chacha20-poly1305@openssh.com | ||||
|  .Ed | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -chacha20-poly1305@openssh.com,
 | ||||
| -aes128-ctr,aes192-ctr,aes256-ctr,
 | ||||
| -aes128-gcm@openssh.com,aes256-gcm@openssh.com
 | ||||
| -.Ed
 | ||||
| -.Pp
 | ||||
|  The list of available ciphers may also be obtained using | ||||
|  .Qq ssh -Q cipher . | ||||
|  .It Cm ClearAllForwardings | ||||
| @@ -826,6 +822,11 @@ command line will be passed untouched to
 | ||||
|  The default is | ||||
|  .Dq no . | ||||
|  .It Cm GSSAPIKexAlgorithms | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  The list of key exchange algorithms that are offered for GSSAPI | ||||
|  key exchange. Possible values are | ||||
|  .Bd -literal -offset 3n | ||||
| @@ -838,10 +839,8 @@ gss-nistp256-sha256-,
 | ||||
|  gss-curve25519-sha256- | ||||
|  .Ed | ||||
|  .Pp | ||||
| -The default is
 | ||||
| -.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. | ||||
| +.Pp
 | ||||
|  .It Cm HashKnownHosts | ||||
|  Indicates that | ||||
|  .Xr ssh 1 | ||||
| @@ -1169,29 +1168,25 @@ it may be zero or more of:
 | ||||
|  and | ||||
|  .Cm pam . | ||||
|  .It Cm KexAlgorithms | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies the available KEX (Key Exchange) algorithms. | ||||
|  Multiple algorithms must be comma-separated. | ||||
|  If the specified list begins with a | ||||
|  .Sq + | ||||
| -character, then the specified methods will be appended to the default set
 | ||||
| -instead of replacing them.
 | ||||
| +character, then the specified methods will be appended to the built-in
 | ||||
| +openssh default set instead of replacing them.
 | ||||
|  If the specified list begins with a | ||||
|  .Sq - | ||||
|  character, then the specified methods (including wildcards) will be removed | ||||
| -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:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -curve25519-sha256,curve25519-sha256@libssh.org,
 | ||||
| -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
 | ||||
| -diffie-hellman-group-exchange-sha256,
 | ||||
| -diffie-hellman-group16-sha512,
 | ||||
| -diffie-hellman-group18-sha512,
 | ||||
| -diffie-hellman-group14-sha256
 | ||||
| -.Ed
 | ||||
| +built-in openssh default set.
 | ||||
|  .Pp | ||||
|  The list of available key exchange algorithms may also be obtained using | ||||
|  .Qq ssh -Q kex . | ||||
| @@ -1301,37 +1296,33 @@ function, and all code in the
 | ||||
|  file. | ||||
|  This option is intended for debugging and no overrides are enabled by default. | ||||
|  .It Cm MACs | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies the MAC (message authentication code) algorithms | ||||
|  in order of preference. | ||||
|  The MAC algorithm is used for data integrity protection. | ||||
|  Multiple algorithms must be comma-separated. | ||||
|  If the specified list begins with a | ||||
|  .Sq + | ||||
| -character, then the specified algorithms will be appended to the default set
 | ||||
| -instead of replacing them.
 | ||||
| +character, then the specified algorithms will be appended to the built-in
 | ||||
| +openssh default set instead of replacing them.
 | ||||
|  If the specified list begins with a | ||||
|  .Sq - | ||||
|  character, then the specified algorithms (including wildcards) will be removed | ||||
| -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.
 | ||||
| +built-in openssh default set.
 | ||||
|  .Pp | ||||
|  The algorithms that contain | ||||
|  .Qq -etm | ||||
|  calculate the MAC after encryption (encrypt-then-mac). | ||||
|  These are considered safer and their use recommended. | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -umac-64-etm@openssh.com,umac-128-etm@openssh.com,
 | ||||
| -hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
 | ||||
| -hmac-sha1-etm@openssh.com,
 | ||||
| -umac-64@openssh.com,umac-128@openssh.com,
 | ||||
| -hmac-sha2-256,hmac-sha2-512,hmac-sha1
 | ||||
| -.Ed
 | ||||
| -.Pp
 | ||||
|  The list of available MAC algorithms may also be obtained using | ||||
|  .Qq ssh -Q mac . | ||||
|  .It Cm NoHostAuthenticationForLocalhost | ||||
| @@ -1503,37 +1494,25 @@ instead of continuing to execute and pas
 | ||||
|  The default is | ||||
|  .Cm no . | ||||
|  .It Cm PubkeyAcceptedAlgorithms | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies the signature algorithms that will be used for public key | ||||
|  authentication as a comma-separated list of patterns. | ||||
|  If the specified list begins with a | ||||
|  .Sq + | ||||
| -character, then the algorithms after it will be appended to the default
 | ||||
| -instead of replacing it.
 | ||||
| +character, then the algorithms after it will be appended to the built-in
 | ||||
| +openssh default instead of replacing it.
 | ||||
|  If the specified list begins with a | ||||
|  .Sq - | ||||
|  character, then the specified algorithms (including wildcards) will be removed | ||||
| -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:
 | ||||
| -.Bd -literal -offset 3n
 | ||||
| -ssh-ed25519-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | ||||
| -sk-ssh-ed25519-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-ed25519,
 | ||||
| -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||
| -sk-ssh-ed25519@openssh.com,
 | ||||
| -sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||
| -rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | ||||
| -.Ed
 | ||||
| +built-in openssh default set.
 | ||||
|  .Pp | ||||
|  The list of available signature algorithms may also be obtained using | ||||
|  .Qq ssh -Q PubkeyAcceptedAlgorithms . | ||||
| diff -up openssh-8.6p1/sshd_config.5.crypto-policies openssh-8.6p1/sshd_config.5
 | ||||
| --- openssh-8.6p1/sshd_config.5.crypto-policies	2021-04-19 15:18:32.062920311 +0200
 | ||||
| +++ openssh-8.6p1/sshd_config.5	2021-04-19 15:20:42.591908243 +0200
 | ||||
| @@ -373,15 +373,13 @@ If the argument is
 | ||||
|  then no banner is displayed. | ||||
|  By default, no banner is displayed. | ||||
|  .It Cm CASignatureAlgorithms | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies which algorithms are allowed for signing of certificates | ||||
|  by certificate authorities (CAs). | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||
| -sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||
| -rsa-sha2-512,rsa-sha2-256
 | ||||
| -.Ed
 | ||||
| -.Pp
 | ||||
|  Certificates signed using other algorithms will not be accepted for | ||||
|  public key or host-based authentication. | ||||
|  .It Cm ChallengeResponseAuthentication | ||||
| @@ -445,20 +443,25 @@ The default is
 | ||||
|  indicating not to | ||||
|  .Xr chroot 2 . | ||||
|  .It Cm Ciphers | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies the ciphers allowed. | ||||
|  Multiple ciphers must be comma-separated. | ||||
|  If the specified list begins with a | ||||
|  .Sq + | ||||
| -character, then the specified ciphers will be appended to the default set
 | ||||
| -instead of replacing them.
 | ||||
| +character, then the specified ciphers will be appended to the built-in
 | ||||
| +openssh default set instead of replacing them.
 | ||||
|  If the specified list begins with a | ||||
|  .Sq - | ||||
|  character, then the specified ciphers (including wildcards) will be removed | ||||
| -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 ciphers will be placed at the head of the | ||||
| -default set.
 | ||||
| +built-in openssh default set.
 | ||||
|  .Pp | ||||
|  The supported ciphers are: | ||||
|  .Pp | ||||
| @@ -485,13 +488,6 @@ aes256-gcm@openssh.com
 | ||||
|  chacha20-poly1305@openssh.com | ||||
|  .El | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -chacha20-poly1305@openssh.com,
 | ||||
| -aes128-ctr,aes192-ctr,aes256-ctr,
 | ||||
| -aes128-gcm@openssh.com,aes256-gcm@openssh.com
 | ||||
| -.Ed
 | ||||
| -.Pp
 | ||||
|  The list of available ciphers may also be obtained using | ||||
|  .Qq ssh -Q cipher . | ||||
|  .It Cm ClientAliveCountMax | ||||
| @@ -680,21 +676,22 @@ For this to work
 | ||||
|  .Cm GSSAPIKeyExchange | ||||
|  needs to be enabled in the server and also used by the client. | ||||
|  .It Cm GSSAPIKexAlgorithms | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  The list of key exchange algorithms that are accepted by GSSAPI | ||||
|  key exchange. Possible values are | ||||
|  .Bd -literal -offset 3n | ||||
| -gss-gex-sha1-,
 | ||||
| -gss-group1-sha1-,
 | ||||
| -gss-group14-sha1-,
 | ||||
| -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- | ||||
|  .Ed | ||||
| -.Pp
 | ||||
| -The default is
 | ||||
| -.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. | ||||
|  .It Cm HostbasedAcceptedAlgorithms | ||||
|  Specifies the signature algorithms that will be accepted for hostbased | ||||
| @@ -794,26 +791,13 @@ is specified, the location of the socket
 | ||||
|  .Ev SSH_AUTH_SOCK | ||||
|  environment variable. | ||||
|  .It Cm HostKeyAlgorithms | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies the host key signature algorithms | ||||
|  that the server offers. | ||||
| -The default for this option is:
 | ||||
| -.Bd -literal -offset 3n
 | ||||
| -ssh-ed25519-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | ||||
| -sk-ssh-ed25519-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-ed25519,
 | ||||
| -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||
| -sk-ssh-ed25519@openssh.com,
 | ||||
| -sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||
| -rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | ||||
| -.Ed
 | ||||
| -.Pp
 | ||||
|  The list of available signature algorithms may also be obtained using | ||||
|  .Qq ssh -Q HostKeyAlgorithms . | ||||
|  .It Cm IgnoreRhosts | ||||
| @@ -958,20 +942,25 @@ Specifies whether to look at .k5login fi
 | ||||
|  The default is | ||||
|  .Cm yes . | ||||
|  .It Cm KexAlgorithms | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies the available KEX (Key Exchange) algorithms. | ||||
|  Multiple algorithms must be comma-separated. | ||||
|  Alternately if the specified list begins with a | ||||
|  .Sq + | ||||
| -character, then the specified methods will be appended to the default set
 | ||||
| -instead of replacing them.
 | ||||
| +character, then the specified methods will be appended to the built-in
 | ||||
| +openssh default set instead of replacing them.
 | ||||
|  If the specified list begins with a | ||||
|  .Sq - | ||||
|  character, then the specified methods (including wildcards) will be removed | ||||
| -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.
 | ||||
| +built-in openssh default set.
 | ||||
|  The supported algorithms are: | ||||
|  .Pp | ||||
|  .Bl -item -compact -offset indent | ||||
| @@ -1003,15 +992,6 @@ ecdh-sha2-nistp521
 | ||||
|  sntrup761x25519-sha512@openssh.com | ||||
|  .El | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -curve25519-sha256,curve25519-sha256@libssh.org,
 | ||||
| -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
 | ||||
| -diffie-hellman-group-exchange-sha256,
 | ||||
| -diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,
 | ||||
| -diffie-hellman-group14-sha256
 | ||||
| -.Ed
 | ||||
| -.Pp
 | ||||
|  The list of available key exchange algorithms may also be obtained using | ||||
|  .Qq ssh -Q KexAlgorithms . | ||||
|  .It Cm ListenAddress | ||||
| @@ -1097,21 +1077,26 @@ function, and all code in the
 | ||||
|  file. | ||||
|  This option is intended for debugging and no overrides are enabled by default. | ||||
|  .It Cm MACs | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies the available MAC (message authentication code) algorithms. | ||||
|  The MAC algorithm is used for data integrity protection. | ||||
|  Multiple algorithms must be comma-separated. | ||||
|  If the specified list begins with a | ||||
|  .Sq + | ||||
| -character, then the specified algorithms will be appended to the default set
 | ||||
| -instead of replacing them.
 | ||||
| +character, then the specified algorithms will be appended to the built-in
 | ||||
| +openssh default set instead of replacing them.
 | ||||
|  If the specified list begins with a | ||||
|  .Sq - | ||||
|  character, then the specified algorithms (including wildcards) will be removed | ||||
| -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.
 | ||||
| +built-in openssh default set.
 | ||||
|  .Pp | ||||
|  The algorithms that contain | ||||
|  .Qq -etm | ||||
| @@ -1154,15 +1139,6 @@ umac-64-etm@openssh.com
 | ||||
|  umac-128-etm@openssh.com | ||||
|  .El | ||||
|  .Pp | ||||
| -The default is:
 | ||||
| -.Bd -literal -offset indent
 | ||||
| -umac-64-etm@openssh.com,umac-128-etm@openssh.com,
 | ||||
| -hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
 | ||||
| -hmac-sha1-etm@openssh.com,
 | ||||
| -umac-64@openssh.com,umac-128@openssh.com,
 | ||||
| -hmac-sha2-256,hmac-sha2-512,hmac-sha1
 | ||||
| -.Ed
 | ||||
| -.Pp
 | ||||
|  The list of available MAC algorithms may also be obtained using | ||||
|  .Qq ssh -Q mac . | ||||
|  .It Cm Match | ||||
| @@ -1541,37 +1517,25 @@ or equivalent.)
 | ||||
|  The default is | ||||
|  .Cm yes . | ||||
|  .It Cm PubkeyAcceptedAlgorithms | ||||
| +The default is handled system-wide by
 | ||||
| +.Xr crypto-policies 7 .
 | ||||
| +To see the defaults and how to modify this default, see manual page
 | ||||
| +.Xr update-crypto-policies 8 .
 | ||||
| +.Pp
 | ||||
|  Specifies the signature algorithms that will be accepted for public key | ||||
|  authentication as a list of comma-separated patterns. | ||||
|  Alternately if the specified list begins with a | ||||
|  .Sq + | ||||
| -character, then the specified algorithms will be appended to the default set
 | ||||
| -instead of replacing them.
 | ||||
| +character, then the specified algorithms will be appended to the built-in
 | ||||
| +openssh default set instead of replacing them.
 | ||||
|  If the specified list begins with a | ||||
|  .Sq - | ||||
|  character, then the specified algorithms (including wildcards) will be removed | ||||
| -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:
 | ||||
| -.Bd -literal -offset 3n
 | ||||
| -ssh-ed25519-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp256-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp384-cert-v01@openssh.com,
 | ||||
| -ecdsa-sha2-nistp521-cert-v01@openssh.com,
 | ||||
| -sk-ssh-ed25519-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-ed25519,
 | ||||
| -ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,
 | ||||
| -sk-ssh-ed25519@openssh.com,
 | ||||
| -sk-ecdsa-sha2-nistp256@openssh.com,
 | ||||
| -rsa-sha2-512,rsa-sha2-256,ssh-rsa
 | ||||
| -.Ed
 | ||||
| +built-in openssh default set.
 | ||||
|  .Pp | ||||
|  The list of available signature algorithms may also be obtained using | ||||
|  .Qq ssh -Q PubkeyAcceptedAlgorithms . | ||||
							
								
								
									
										3942
									
								
								SOURCES/openssh-8.0p1-gssapi-keyex.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3942
									
								
								SOURCES/openssh-8.0p1-gssapi-keyex.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										12
									
								
								SOURCES/openssh-8.0p1-keygen-strip-doseol.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								SOURCES/openssh-8.0p1-keygen-strip-doseol.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| diff -up openssh-8.0p1/ssh-keygen.c.strip-doseol openssh-8.0p1/ssh-keygen.c
 | ||||
| --- openssh-8.0p1/ssh-keygen.c.strip-doseol	2021-03-18 17:41:34.472404994 +0100
 | ||||
| +++ openssh-8.0p1/ssh-keygen.c	2021-03-18 17:41:55.255538761 +0100
 | ||||
| @@ -901,7 +901,7 @@ do_fingerprint(struct passwd *pw)
 | ||||
|  	while (getline(&line, &linesize, f) != -1) { | ||||
|  		lnum++; | ||||
|  		cp = line; | ||||
| -		cp[strcspn(cp, "\n")] = '\0';
 | ||||
| +		cp[strcspn(cp, "\r\n")] = '\0';
 | ||||
|  		/* Trim leading space and comments */ | ||||
|  		cp = line + strspn(line, " \t"); | ||||
|  		if (*cp == '#' || *cp == '\0') | ||||
							
								
								
									
										720
									
								
								SOURCES/openssh-8.0p1-openssl-evp.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										720
									
								
								SOURCES/openssh-8.0p1-openssl-evp.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,720 @@ | ||||
| From ed7ec0cdf577ffbb0b15145340cf51596ca3eb89 Mon Sep 17 00:00:00 2001 | ||||
| From: Jakub Jelen <jjelen@redhat.com> | ||||
| Date: Tue, 14 May 2019 10:45:45 +0200 | ||||
| Subject: [PATCH] Use high-level OpenSSL API for signatures | ||||
| 
 | ||||
| ---
 | ||||
|  digest-openssl.c |  16 ++++ | ||||
|  digest.h         |   6 ++ | ||||
|  ssh-dss.c        |  65 ++++++++++------ | ||||
|  ssh-ecdsa.c      |  69 ++++++++++------- | ||||
|  ssh-rsa.c        | 193 +++++++++-------------------------------------- | ||||
|  sshkey.c         |  77 +++++++++++++++++++ | ||||
|  sshkey.h         |   4 + | ||||
|  7 files changed, 221 insertions(+), 209 deletions(-) | ||||
| 
 | ||||
| diff --git a/digest-openssl.c b/digest-openssl.c
 | ||||
| index da7ed72bc..6a21d8adb 100644
 | ||||
| --- a/digest-openssl.c
 | ||||
| +++ b/digest-openssl.c
 | ||||
| @@ -63,6 +63,22 @@ const struct ssh_digest digests[] = {
 | ||||
|  	{ -1,			NULL,		0,	NULL }, | ||||
|  }; | ||||
|   | ||||
| +const EVP_MD *
 | ||||
| +ssh_digest_to_md(int digest_type)
 | ||||
| +{
 | ||||
| +	switch (digest_type) {
 | ||||
| +	case SSH_DIGEST_SHA1:
 | ||||
| +		return EVP_sha1();
 | ||||
| +	case SSH_DIGEST_SHA256:
 | ||||
| +		return EVP_sha256();
 | ||||
| +	case SSH_DIGEST_SHA384:
 | ||||
| +		return EVP_sha384();
 | ||||
| +	case SSH_DIGEST_SHA512:
 | ||||
| +		return EVP_sha512();
 | ||||
| +	}
 | ||||
| +	return NULL;
 | ||||
| +}
 | ||||
| +
 | ||||
|  static const struct ssh_digest * | ||||
|  ssh_digest_by_alg(int alg) | ||||
|  { | ||||
| diff --git a/digest.h b/digest.h
 | ||||
| index 274574d0e..c7ceeb36f 100644
 | ||||
| --- a/digest.h
 | ||||
| +++ b/digest.h
 | ||||
| @@ -32,6 +32,12 @@
 | ||||
|  struct sshbuf; | ||||
|  struct ssh_digest_ctx; | ||||
|   | ||||
| +#ifdef WITH_OPENSSL
 | ||||
| +#include <openssl/evp.h>
 | ||||
| +/* Converts internal digest representation to the OpenSSL one */
 | ||||
| +const EVP_MD *ssh_digest_to_md(int digest_type);
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  /* Looks up a digest algorithm by name */ | ||||
|  int ssh_digest_alg_by_name(const char *name); | ||||
|   | ||||
| diff --git a/ssh-dss.c b/ssh-dss.c
 | ||||
| index a23c383dc..ea45e7275 100644
 | ||||
| --- a/ssh-dss.c
 | ||||
| +++ b/ssh-dss.c
 | ||||
| @@ -52,11 +52,15 @@ int
 | ||||
|  ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | ||||
|      const u_char *data, size_t datalen, u_int compat) | ||||
|  { | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|  	DSA_SIG *sig = NULL; | ||||
|  	const BIGNUM *sig_r, *sig_s; | ||||
| -	u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
 | ||||
| -	size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
 | ||||
| +	u_char sigblob[SIGBLOB_LEN];
 | ||||
| +	size_t rlen, slen;
 | ||||
| +	int len;
 | ||||
|  	struct sshbuf *b = NULL; | ||||
| +	u_char *sigb = NULL;
 | ||||
| +	const u_char *psig = NULL;
 | ||||
|  	int ret = SSH_ERR_INVALID_ARGUMENT; | ||||
|   | ||||
|  	if (lenp != NULL) | ||||
| @@ -67,17 +71,24 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  	if (key == NULL || key->dsa == NULL || | ||||
|  	    sshkey_type_plain(key->type) != KEY_DSA) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
| -	if (dlen == 0)
 | ||||
| -		return SSH_ERR_INTERNAL_ERROR;
 | ||||
|   | ||||
| -	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1)
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	ret = sshkey_calculate_signature(pkey, SSH_DIGEST_SHA1, &sigb, &len,
 | ||||
| +	    data, datalen);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
| +	if (ret < 0) {
 | ||||
|  		goto out; | ||||
| +	}
 | ||||
|   | ||||
| -	if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
 | ||||
| +	psig = sigb;
 | ||||
| +	if ((sig = d2i_DSA_SIG(NULL, &psig, len)) == NULL) {
 | ||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| +	free(sigb);
 | ||||
| +	sigb = NULL;
 | ||||
|   | ||||
|  	DSA_SIG_get0(sig, &sig_r, &sig_s); | ||||
|  	rlen = BN_num_bytes(sig_r); | ||||
| @@ -110,7 +121,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		*lenp = len; | ||||
|  	ret = 0; | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	DSA_SIG_free(sig); | ||||
|  	sshbuf_free(b); | ||||
|  	return ret; | ||||
| @@ -121,20 +132,20 @@ ssh_dss_verify(const struct sshkey *key,
 | ||||
|      const u_char *signature, size_t signaturelen, | ||||
|      const u_char *data, size_t datalen, u_int compat) | ||||
|  { | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|  	DSA_SIG *sig = NULL; | ||||
|  	BIGNUM *sig_r = NULL, *sig_s = NULL; | ||||
| -	u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
 | ||||
| -	size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
 | ||||
| +	u_char *sigblob = NULL;
 | ||||
| +	size_t len, slen;
 | ||||
|  	int ret = SSH_ERR_INTERNAL_ERROR; | ||||
|  	struct sshbuf *b = NULL; | ||||
|  	char *ktype = NULL; | ||||
| +	u_char *sigb = NULL, *psig = NULL;
 | ||||
|   | ||||
|  	if (key == NULL || key->dsa == NULL || | ||||
|  	    sshkey_type_plain(key->type) != KEY_DSA || | ||||
|  	    signature == NULL || signaturelen == 0) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
| -	if (dlen == 0)
 | ||||
| -		return SSH_ERR_INTERNAL_ERROR;
 | ||||
|   | ||||
|  	/* fetch signature */ | ||||
|  	if ((b = sshbuf_from(signature, signaturelen)) == NULL) | ||||
| @@ -176,25 +187,31 @@ ssh_dss_verify(const struct sshkey *key,
 | ||||
|  	} | ||||
|  	sig_r = sig_s = NULL; /* transferred */ | ||||
|   | ||||
| -	/* sha1 the data */
 | ||||
| -	if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| +	if ((slen = i2d_DSA_SIG(sig, NULL)) == 0) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
|  		goto out; | ||||
| -
 | ||||
| -	switch (DSA_do_verify(digest, dlen, sig, key->dsa)) {
 | ||||
| -	case 1:
 | ||||
| -		ret = 0;
 | ||||
| -		break;
 | ||||
| -	case 0:
 | ||||
| -		ret = SSH_ERR_SIGNATURE_INVALID;
 | ||||
| +	}
 | ||||
| +	if ((sigb = malloc(slen)) == NULL) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
| -	default:
 | ||||
| +	}
 | ||||
| +	psig = sigb;
 | ||||
| +	if ((slen = i2d_DSA_SIG(sig, &psig)) == 0) {
 | ||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
|   | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_DSA(pkey, key->dsa) != 1) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	ret = sshkey_verify_signature(pkey, SSH_DIGEST_SHA1, data, datalen,
 | ||||
| +	    sigb, slen);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
| +
 | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	DSA_SIG_free(sig); | ||||
|  	BN_clear_free(sig_r); | ||||
|  	BN_clear_free(sig_s); | ||||
| diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
 | ||||
| index 599c7199d..b036796e8 100644
 | ||||
| --- a/ssh-ecdsa.c
 | ||||
| +++ b/ssh-ecdsa.c
 | ||||
| @@ -50,11 +50,13 @@ int
 | ||||
|  ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | ||||
|      const u_char *data, size_t datalen, u_int compat) | ||||
|  { | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|  	ECDSA_SIG *sig = NULL; | ||||
| +	unsigned char *sigb = NULL;
 | ||||
| +	const unsigned char *psig;
 | ||||
|  	const BIGNUM *sig_r, *sig_s; | ||||
|  	int hash_alg; | ||||
| -	u_char digest[SSH_DIGEST_MAX_LENGTH];
 | ||||
| -	size_t len, dlen;
 | ||||
| +	int len;
 | ||||
|  	struct sshbuf *b = NULL, *bb = NULL; | ||||
|  	int ret = SSH_ERR_INTERNAL_ERROR; | ||||
|   | ||||
| @@ -67,18 +69,24 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  	    sshkey_type_plain(key->type) != KEY_ECDSA) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
|   | ||||
| -	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
 | ||||
| -	    (dlen = ssh_digest_bytes(hash_alg)) == 0)
 | ||||
| +	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
 | ||||
|  		return SSH_ERR_INTERNAL_ERROR; | ||||
| -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| +
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1)
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	ret = sshkey_calculate_signature(pkey, hash_alg, &sigb, &len, data,
 | ||||
| +	    datalen);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
| +	if (ret < 0) {
 | ||||
|  		goto out; | ||||
| +	}
 | ||||
|   | ||||
| -	if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {
 | ||||
| +	psig = sigb;
 | ||||
| +	if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) {
 | ||||
|  		ret = SSH_ERR_LIBCRYPTO_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| -
 | ||||
|  	if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { | ||||
|  		ret = SSH_ERR_ALLOC_FAIL; | ||||
|  		goto out; | ||||
| @@ -102,7 +110,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		*lenp = len; | ||||
|  	ret = 0; | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	sshbuf_free(b); | ||||
|  	sshbuf_free(bb); | ||||
|  	ECDSA_SIG_free(sig); | ||||
| @@ -115,22 +123,21 @@ ssh_ecdsa_verify(const struct sshkey *key,
 | ||||
|      const u_char *signature, size_t signaturelen, | ||||
|      const u_char *data, size_t datalen, u_int compat) | ||||
|  { | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|  	ECDSA_SIG *sig = NULL; | ||||
|  	BIGNUM *sig_r = NULL, *sig_s = NULL; | ||||
| -	int hash_alg;
 | ||||
| -	u_char digest[SSH_DIGEST_MAX_LENGTH];
 | ||||
| -	size_t dlen;
 | ||||
| +	int hash_alg, len;
 | ||||
|  	int ret = SSH_ERR_INTERNAL_ERROR; | ||||
|  	struct sshbuf *b = NULL, *sigbuf = NULL; | ||||
|  	char *ktype = NULL; | ||||
| +	unsigned char *sigb = NULL, *psig = NULL;
 | ||||
|   | ||||
|  	if (key == NULL || key->ecdsa == NULL || | ||||
|  	    sshkey_type_plain(key->type) != KEY_ECDSA || | ||||
|  	    signature == NULL || signaturelen == 0) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
|   | ||||
| -	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
 | ||||
| -	    (dlen = ssh_digest_bytes(hash_alg)) == 0)
 | ||||
| +	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
 | ||||
|  		return SSH_ERR_INTERNAL_ERROR; | ||||
|   | ||||
|  	/* fetch signature */ | ||||
| @@ -166,28 +173,36 @@ ssh_ecdsa_verify(const struct sshkey *key,
 | ||||
|  	} | ||||
|  	sig_r = sig_s = NULL; /* transferred */ | ||||
|   | ||||
| -	if (sshbuf_len(sigbuf) != 0) {
 | ||||
| -		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
 | ||||
| +	/* Figure out the length */
 | ||||
| +	if ((len = i2d_ECDSA_SIG(sig, NULL)) == 0) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	if ((sigb = malloc(len)) == NULL) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
|  	} | ||||
| -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| +	psig = sigb;
 | ||||
| +	if ((len = i2d_ECDSA_SIG(sig, &psig)) == 0) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
|  		goto out; | ||||
| +	}
 | ||||
|   | ||||
| -	switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
 | ||||
| -	case 1:
 | ||||
| -		ret = 0;
 | ||||
| -		break;
 | ||||
| -	case 0:
 | ||||
| -		ret = SSH_ERR_SIGNATURE_INVALID;
 | ||||
| +	if (sshbuf_len(sigbuf) != 0) {
 | ||||
| +		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
 | ||||
|  		goto out; | ||||
| -	default:
 | ||||
| -		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa) != 1) {
 | ||||
| +		ret =  SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
|  	} | ||||
| +	ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, sigb, len);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
|   | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
| +	free(sigb);
 | ||||
|  	sshbuf_free(sigbuf); | ||||
|  	sshbuf_free(b); | ||||
|  	ECDSA_SIG_free(sig); | ||||
| diff --git a/ssh-rsa.c b/ssh-rsa.c
 | ||||
| index 9b14f9a9a..8ef3a6aca 100644
 | ||||
| --- a/ssh-rsa.c
 | ||||
| +++ b/ssh-rsa.c
 | ||||
| @@ -37,7 +37,7 @@
 | ||||
|   | ||||
|  #include "openbsd-compat/openssl-compat.h" | ||||
|   | ||||
| -static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
 | ||||
| +static int openssh_RSA_verify(int, const u_char *, size_t, u_char *, size_t, EVP_PKEY *);
 | ||||
|   | ||||
|  static const char * | ||||
|  rsa_hash_alg_ident(int hash_alg) | ||||
| @@ -90,21 +90,6 @@ rsa_hash_id_from_keyname(const char *alg)
 | ||||
|  	return -1; | ||||
|  } | ||||
|   | ||||
| -static int
 | ||||
| -rsa_hash_alg_nid(int type)
 | ||||
| -{
 | ||||
| -	switch (type) {
 | ||||
| -	case SSH_DIGEST_SHA1:
 | ||||
| -		return NID_sha1;
 | ||||
| -	case SSH_DIGEST_SHA256:
 | ||||
| -		return NID_sha256;
 | ||||
| -	case SSH_DIGEST_SHA512:
 | ||||
| -		return NID_sha512;
 | ||||
| -	default:
 | ||||
| -		return -1;
 | ||||
| -	}
 | ||||
| -}
 | ||||
| -
 | ||||
|  int | ||||
|  ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) | ||||
|  { | ||||
| @@ -164,11 +149,10 @@ int
 | ||||
|  ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | ||||
|      const u_char *data, size_t datalen, const char *alg_ident) | ||||
|  { | ||||
| -	const BIGNUM *rsa_n;
 | ||||
| -	u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
 | ||||
| -	size_t slen = 0;
 | ||||
| -	u_int dlen, len;
 | ||||
| -	int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
 | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
| +	u_char *sig = NULL;
 | ||||
| +	int len, slen = 0;
 | ||||
| +	int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
 | ||||
|  	struct sshbuf *b = NULL; | ||||
|   | ||||
|  	if (lenp != NULL) | ||||
| @@ -180,33 +164,24 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		hash_alg = SSH_DIGEST_SHA1; | ||||
|  	else | ||||
|  		hash_alg = rsa_hash_id_from_keyname(alg_ident); | ||||
| +
 | ||||
|  	if (key == NULL || key->rsa == NULL || hash_alg == -1 || | ||||
|  	    sshkey_type_plain(key->type) != KEY_RSA) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
| -	RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
 | ||||
| -	if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 | ||||
| -		return SSH_ERR_KEY_LENGTH;
 | ||||
|  	slen = RSA_size(key->rsa); | ||||
| -	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
 | ||||
| -		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| -
 | ||||
| -	/* hash the data */
 | ||||
| -	nid = rsa_hash_alg_nid(hash_alg);
 | ||||
| -	if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
 | ||||
| -		return SSH_ERR_INTERNAL_ERROR;
 | ||||
| -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| -		goto out;
 | ||||
| +	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 | ||||
| +		return SSH_ERR_KEY_LENGTH;
 | ||||
|   | ||||
| -	if ((sig = malloc(slen)) == NULL) {
 | ||||
| -		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1)
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	ret = sshkey_calculate_signature(pkey, hash_alg, &sig, &len, data,
 | ||||
| +	    datalen);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
| +	if (ret < 0) {
 | ||||
|  		goto out; | ||||
|  	} | ||||
|   | ||||
| -	if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
 | ||||
| -		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| -		goto out;
 | ||||
| -	}
 | ||||
|  	if (len < slen) { | ||||
|  		size_t diff = slen - len; | ||||
|  		memmove(sig + diff, sig, len); | ||||
| @@ -215,6 +190,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		ret = SSH_ERR_INTERNAL_ERROR; | ||||
|  		goto out; | ||||
|  	} | ||||
| +
 | ||||
|  	/* encode signature */ | ||||
|  	if ((b = sshbuf_new()) == NULL) { | ||||
|  		ret = SSH_ERR_ALLOC_FAIL; | ||||
| @@ -235,7 +211,6 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
 | ||||
|  		*lenp = len; | ||||
|  	ret = 0; | ||||
|   out: | ||||
| -	explicit_bzero(digest, sizeof(digest));
 | ||||
|  	freezero(sig, slen); | ||||
|  	sshbuf_free(b); | ||||
|  	return ret; | ||||
| @@ -246,10 +221,10 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|      const u_char *sig, size_t siglen, const u_char *data, size_t datalen, | ||||
|      const char *alg) | ||||
|  { | ||||
| -	const BIGNUM *rsa_n;
 | ||||
| +	EVP_PKEY *pkey = NULL;
 | ||||
|  	char *sigtype = NULL; | ||||
|  	int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; | ||||
| -	size_t len = 0, diff, modlen, dlen;
 | ||||
| +	size_t len = 0, diff, modlen;
 | ||||
|  	struct sshbuf *b = NULL; | ||||
|  	u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; | ||||
|   | ||||
| @@ -257,8 +232,7 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  	    sshkey_type_plain(key->type) != KEY_RSA || | ||||
|  	    sig == NULL || siglen == 0) | ||||
|  		return SSH_ERR_INVALID_ARGUMENT; | ||||
| -	RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
 | ||||
| -	if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 | ||||
| +	if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
 | ||||
|  		return SSH_ERR_KEY_LENGTH; | ||||
|   | ||||
|  	if ((b = sshbuf_from(sig, siglen)) == NULL) | ||||
| @@ -310,16 +284,15 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  		explicit_bzero(sigblob, diff); | ||||
|  		len = modlen; | ||||
|  	} | ||||
| -	if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
 | ||||
| -		ret = SSH_ERR_INTERNAL_ERROR;
 | ||||
| +
 | ||||
| +	if ((pkey = EVP_PKEY_new()) == NULL ||
 | ||||
| +	    EVP_PKEY_set1_RSA(pkey, key->rsa) != 1) {
 | ||||
| +		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
|  		goto out; | ||||
|  	} | ||||
| -	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
 | ||||
| -	    digest, sizeof(digest))) != 0)
 | ||||
| -		goto out;
 | ||||
| +	ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, pkey);
 | ||||
| +	EVP_PKEY_free(pkey);
 | ||||
|   | ||||
| -	ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
 | ||||
| -	    key->rsa);
 | ||||
|   out: | ||||
|  	freezero(sigblob, len); | ||||
|  	free(sigtype); | ||||
| @@ -328,122 +301,26 @@ ssh_rsa_verify(const struct sshkey *key,
 | ||||
|  	return ret; | ||||
|  } | ||||
|   | ||||
| -/*
 | ||||
| - * See:
 | ||||
| - * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
 | ||||
| - * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
 | ||||
| - */
 | ||||
| -
 | ||||
| -/*
 | ||||
| - * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
 | ||||
| - *	oiw(14) secsig(3) algorithms(2) 26 }
 | ||||
| - */
 | ||||
| -static const u_char id_sha1[] = {
 | ||||
| -	0x30, 0x21, /* type Sequence, length 0x21 (33) */
 | ||||
| -	0x30, 0x09, /* type Sequence, length 0x09 */
 | ||||
| -	0x06, 0x05, /* type OID, length 0x05 */
 | ||||
| -	0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
 | ||||
| -	0x05, 0x00, /* NULL */
 | ||||
| -	0x04, 0x14  /* Octet string, length 0x14 (20), followed by sha1 hash */
 | ||||
| -};
 | ||||
| -
 | ||||
| -/*
 | ||||
| - * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
 | ||||
| - * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
 | ||||
| - *      organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
 | ||||
| - *      id-sha256(1) }
 | ||||
| - */
 | ||||
| -static const u_char id_sha256[] = {
 | ||||
| -	0x30, 0x31, /* type Sequence, length 0x31 (49) */
 | ||||
| -	0x30, 0x0d, /* type Sequence, length 0x0d (13) */
 | ||||
| -	0x06, 0x09, /* type OID, length 0x09 */
 | ||||
| -	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
 | ||||
| -	0x05, 0x00, /* NULL */
 | ||||
| -	0x04, 0x20  /* Octet string, length 0x20 (32), followed by sha256 hash */
 | ||||
| -};
 | ||||
| -
 | ||||
| -/*
 | ||||
| - * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
 | ||||
| - * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
 | ||||
| - *      organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
 | ||||
| - *      id-sha256(3) }
 | ||||
| - */
 | ||||
| -static const u_char id_sha512[] = {
 | ||||
| -	0x30, 0x51, /* type Sequence, length 0x51 (81) */
 | ||||
| -	0x30, 0x0d, /* type Sequence, length 0x0d (13) */
 | ||||
| -	0x06, 0x09, /* type OID, length 0x09 */
 | ||||
| -	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
 | ||||
| -	0x05, 0x00, /* NULL */
 | ||||
| -	0x04, 0x40  /* Octet string, length 0x40 (64), followed by sha512 hash */
 | ||||
| -};
 | ||||
| -
 | ||||
|  static int | ||||
| -rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
 | ||||
| +openssh_RSA_verify(int hash_alg, const u_char *data, size_t datalen,
 | ||||
| +    u_char *sigbuf, size_t siglen, EVP_PKEY *pkey)
 | ||||
|  { | ||||
| -	switch (hash_alg) {
 | ||||
| -	case SSH_DIGEST_SHA1:
 | ||||
| -		*oidp = id_sha1;
 | ||||
| -		*oidlenp = sizeof(id_sha1);
 | ||||
| -		break;
 | ||||
| -	case SSH_DIGEST_SHA256:
 | ||||
| -		*oidp = id_sha256;
 | ||||
| -		*oidlenp = sizeof(id_sha256);
 | ||||
| -		break;
 | ||||
| -	case SSH_DIGEST_SHA512:
 | ||||
| -		*oidp = id_sha512;
 | ||||
| -		*oidlenp = sizeof(id_sha512);
 | ||||
| -		break;
 | ||||
| -	default:
 | ||||
| -		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| -	}
 | ||||
| -	return 0;
 | ||||
| -}
 | ||||
| +	size_t rsasize = 0;
 | ||||
| +	const RSA *rsa;
 | ||||
| +	int ret;
 | ||||
|   | ||||
| -static int
 | ||||
| -openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
 | ||||
| -    u_char *sigbuf, size_t siglen, RSA *rsa)
 | ||||
| -{
 | ||||
| -	size_t rsasize = 0, oidlen = 0, hlen = 0;
 | ||||
| -	int ret, len, oidmatch, hashmatch;
 | ||||
| -	const u_char *oid = NULL;
 | ||||
| -	u_char *decrypted = NULL;
 | ||||
| -
 | ||||
| -	if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
 | ||||
| -		return ret;
 | ||||
| -	ret = SSH_ERR_INTERNAL_ERROR;
 | ||||
| -	hlen = ssh_digest_bytes(hash_alg);
 | ||||
| -	if (hashlen != hlen) {
 | ||||
| -		ret = SSH_ERR_INVALID_ARGUMENT;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| +	rsa = EVP_PKEY_get0_RSA(pkey);
 | ||||
|  	rsasize = RSA_size(rsa); | ||||
|  	if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || | ||||
|  	    siglen == 0 || siglen > rsasize) { | ||||
|  		ret = SSH_ERR_INVALID_ARGUMENT; | ||||
|  		goto done; | ||||
|  	} | ||||
| -	if ((decrypted = malloc(rsasize)) == NULL) {
 | ||||
| -		ret = SSH_ERR_ALLOC_FAIL;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| -	if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
 | ||||
| -	    RSA_PKCS1_PADDING)) < 0) {
 | ||||
| -		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| -	if (len < 0 || (size_t)len != hlen + oidlen) {
 | ||||
| -		ret = SSH_ERR_INVALID_FORMAT;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| -	oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
 | ||||
| -	hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
 | ||||
| -	if (!oidmatch || !hashmatch) {
 | ||||
| -		ret = SSH_ERR_SIGNATURE_INVALID;
 | ||||
| -		goto done;
 | ||||
| -	}
 | ||||
| -	ret = 0;
 | ||||
| +
 | ||||
| +	ret = sshkey_verify_signature(pkey, hash_alg, data, datalen,
 | ||||
| +	    sigbuf, siglen);
 | ||||
| +
 | ||||
|  done: | ||||
| -	freezero(decrypted, rsasize);
 | ||||
|  	return ret; | ||||
|  } | ||||
|  #endif /* WITH_OPENSSL */ | ||||
| diff --git a/sshkey.c b/sshkey.c
 | ||||
| index ad1957762..b95ed0b10 100644
 | ||||
| --- a/sshkey.c
 | ||||
| +++ b/sshkey.c
 | ||||
| @@ -358,6 +358,83 @@ sshkey_type_plain(int type)
 | ||||
|  } | ||||
|   | ||||
|  #ifdef WITH_OPENSSL | ||||
| +int
 | ||||
| +sshkey_calculate_signature(EVP_PKEY *pkey, int hash_alg, u_char **sigp,
 | ||||
| +    int *lenp, const u_char *data, size_t datalen)
 | ||||
| +{
 | ||||
| +	EVP_MD_CTX *ctx = NULL;
 | ||||
| +	u_char *sig = NULL;
 | ||||
| +	int ret, slen, len;
 | ||||
| +
 | ||||
| +	if (sigp == NULL || lenp == NULL) {
 | ||||
| +		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	slen = EVP_PKEY_size(pkey);
 | ||||
| +	if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
 | ||||
| +		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +
 | ||||
| +	len = slen;
 | ||||
| +	if ((sig = malloc(slen)) == NULL) {
 | ||||
| +		return SSH_ERR_ALLOC_FAIL;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	if ((ctx = EVP_MD_CTX_new()) == NULL) {
 | ||||
| +		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) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto error;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	*sigp = sig;
 | ||||
| +	*lenp = len;
 | ||||
| +	/* Now owned by the caller */
 | ||||
| +	sig = NULL;
 | ||||
| +	ret = 0;
 | ||||
| +
 | ||||
| +error:
 | ||||
| +	EVP_MD_CTX_free(ctx);
 | ||||
| +	free(sig);
 | ||||
| +	return ret;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
| +sshkey_verify_signature(EVP_PKEY *pkey, int hash_alg, const u_char *data,
 | ||||
| +    size_t datalen, u_char *sigbuf, int siglen)
 | ||||
| +{
 | ||||
| +	EVP_MD_CTX *ctx = NULL;
 | ||||
| +	int ret;
 | ||||
| +
 | ||||
| +	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) {
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto done;
 | ||||
| +	}
 | ||||
| +	ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey);
 | ||||
| +	switch (ret) {
 | ||||
| +	case 1:
 | ||||
| +		ret = 0;
 | ||||
| +		break;
 | ||||
| +	case 0:
 | ||||
| +		ret = SSH_ERR_SIGNATURE_INVALID;
 | ||||
| +		break;
 | ||||
| +	default:
 | ||||
| +		ret = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		break;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +done:
 | ||||
| +	EVP_MD_CTX_free(ctx);
 | ||||
| +	return ret;
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* XXX: these are really begging for a table-driven approach */ | ||||
|  int | ||||
|  sshkey_curve_name_to_nid(const char *name) | ||||
| diff --git a/sshkey.h b/sshkey.h
 | ||||
| index a91e60436..270901a87 100644
 | ||||
| --- a/sshkey.h
 | ||||
| +++ b/sshkey.h
 | ||||
| @@ -179,6 +179,10 @@ const char	*sshkey_ssh_name(const struct sshkey *);
 | ||||
|  const char	*sshkey_ssh_name_plain(const struct sshkey *); | ||||
|  int		 sshkey_names_valid2(const char *, int); | ||||
|  char		*sshkey_alg_list(int, int, int, char); | ||||
| +int		 sshkey_calculate_signature(EVP_PKEY*, int, u_char **,
 | ||||
| +    int *, const u_char *, size_t);
 | ||||
| +int		 sshkey_verify_signature(EVP_PKEY *, int, const u_char *,
 | ||||
| +    size_t, u_char *, int);
 | ||||
|   | ||||
|  int	 sshkey_from_blob(const u_char *, size_t, struct sshkey **); | ||||
|  int	 sshkey_fromb(struct sshbuf *, struct sshkey **); | ||||
| 
 | ||||
							
								
								
									
										137
									
								
								SOURCES/openssh-8.0p1-openssl-kdf.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								SOURCES/openssh-8.0p1-openssl-kdf.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,137 @@ | ||||
| commit 2c3ef499bfffce3cfd315edeebf202850ba4e00a | ||||
| Author: Jakub Jelen <jjelen@redhat.com> | ||||
| Date:   Tue Apr 16 15:35:18 2019 +0200 | ||||
| 
 | ||||
|     Use the new OpenSSL KDF | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 2a455e4e..e01c3d43 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -2712,6 +2712,7 @@ if test "x$openssl" = "xyes" ; then
 | ||||
|  		HMAC_CTX_init \ | ||||
|  		RSA_generate_key_ex \ | ||||
|  		RSA_get_default_method \ | ||||
| +		EVP_KDF_CTX_new_id \
 | ||||
|  	]) | ||||
|   | ||||
|  	# OpenSSL_add_all_algorithms may be a macro. | ||||
| diff --git a/kex.c b/kex.c
 | ||||
| index b6f041f4..1fbce2bb 100644
 | ||||
| --- a/kex.c
 | ||||
| +++ b/kex.c
 | ||||
| @@ -38,6 +38,9 @@
 | ||||
|  #ifdef WITH_OPENSSL | ||||
|  #include <openssl/crypto.h> | ||||
|  #include <openssl/dh.h> | ||||
| +# ifdef HAVE_EVP_KDF_CTX_NEW_ID
 | ||||
| +# include <openssl/kdf.h>
 | ||||
| +# endif
 | ||||
|  #endif | ||||
|   | ||||
|  #include "ssh.h" | ||||
| @@ -942,6 +945,95 @@ kex_choose_conf(struct ssh *ssh)
 | ||||
|  	return r; | ||||
|  } | ||||
|   | ||||
| +#ifdef HAVE_EVP_KDF_CTX_NEW_ID
 | ||||
| +static const EVP_MD *
 | ||||
| +digest_to_md(int digest_type)
 | ||||
| +{
 | ||||
| +	switch (digest_type) {
 | ||||
| +	case SSH_DIGEST_SHA1:
 | ||||
| +		return EVP_sha1();
 | ||||
| +	case SSH_DIGEST_SHA256:
 | ||||
| +		return EVP_sha256();
 | ||||
| +	case SSH_DIGEST_SHA384:
 | ||||
| +		return EVP_sha384();
 | ||||
| +	case SSH_DIGEST_SHA512:
 | ||||
| +		return EVP_sha512();
 | ||||
| +	}
 | ||||
| +	return NULL;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
 | ||||
| +    const struct sshbuf *shared_secret, u_char **keyp)
 | ||||
| +{
 | ||||
| +	struct kex *kex = ssh->kex;
 | ||||
| +	EVP_KDF_CTX *ctx = NULL;
 | ||||
| +	u_char *key = NULL;
 | ||||
| +	int r, key_len;
 | ||||
| +
 | ||||
| +	if ((key_len = ssh_digest_bytes(kex->hash_alg)) == 0)
 | ||||
| +		return SSH_ERR_INVALID_ARGUMENT;
 | ||||
| +	key_len = ROUNDUP(need, key_len);
 | ||||
| +	if ((key = calloc(1, key_len)) == NULL) {
 | ||||
| +		r = SSH_ERR_ALLOC_FAIL;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
 | ||||
| +	if (!ctx) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest_to_md(kex->hash_alg));
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY,
 | ||||
| +	    sshbuf_ptr(shared_secret), sshbuf_len(shared_secret));
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, hash, hashlen);
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, id);
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
 | ||||
| +	    sshbuf_ptr(kex->session_id), sshbuf_len(kex->session_id));
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +	r = EVP_KDF_derive(ctx, key, key_len);
 | ||||
| +	if (r != 1) {
 | ||||
| +		r = SSH_ERR_LIBCRYPTO_ERROR;
 | ||||
| +		goto out;
 | ||||
| +	}
 | ||||
| +#ifdef DEBUG_KEX
 | ||||
| +	fprintf(stderr, "key '%c'== ", id);
 | ||||
| +	dump_digest("key", key, key_len);
 | ||||
| +#endif
 | ||||
| +	*keyp = key;
 | ||||
| +	key = NULL;
 | ||||
| +	r = 0;
 | ||||
| +
 | ||||
| +out:
 | ||||
| +	free (key);
 | ||||
| +	EVP_KDF_CTX_free(ctx);
 | ||||
| +	if (r < 0) {
 | ||||
| +		return r;
 | ||||
| +	}
 | ||||
| +	return 0;
 | ||||
| +}
 | ||||
| +#else
 | ||||
|  static int | ||||
|  derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, | ||||
|      const struct sshbuf *shared_secret, u_char **keyp) | ||||
| @@ -1004,6 +1096,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
 | ||||
|  	ssh_digest_free(hashctx); | ||||
|  	return r; | ||||
|  } | ||||
| +#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */
 | ||||
|   | ||||
|  #define NKEYS	6 | ||||
|  int | ||||
| 
 | ||||
							
								
								
									
										3053
									
								
								SOURCES/openssh-8.0p1-pkcs11-uri.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3053
									
								
								SOURCES/openssh-8.0p1-pkcs11-uri.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										44
									
								
								SOURCES/openssh-8.0p1-preserve-pam-errors.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								SOURCES/openssh-8.0p1-preserve-pam-errors.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| diff -up openssh-8.0p1/auth-pam.c.preserve-pam-errors openssh-8.0p1/auth-pam.c
 | ||||
| --- openssh-8.0p1/auth-pam.c.preserve-pam-errors	2021-03-31 17:03:15.618592347 +0200
 | ||||
| +++ openssh-8.0p1/auth-pam.c	2021-03-31 17:06:58.115220014 +0200
 | ||||
| @@ -511,7 +511,11 @@ sshpam_thread(void *ctxtp)
 | ||||
|  		goto auth_fail; | ||||
|   | ||||
|  	if (!do_pam_account()) { | ||||
| -		sshpam_err = PAM_ACCT_EXPIRED;
 | ||||
| +		/* Preserve PAM_PERM_DENIED and PAM_USER_UNKNOWN.
 | ||||
| +		 * Backward compatibility for other errors. */
 | ||||
| +		if (sshpam_err != PAM_PERM_DENIED
 | ||||
| +			&& sshpam_err != PAM_USER_UNKNOWN)
 | ||||
| +			sshpam_err = PAM_ACCT_EXPIRED;
 | ||||
|  		goto auth_fail; | ||||
|  	} | ||||
|  	if (sshpam_authctxt->force_pwchange) { | ||||
| @@ -568,8 +572,10 @@ sshpam_thread(void *ctxtp)
 | ||||
|  	    pam_strerror(sshpam_handle, sshpam_err))) != 0) | ||||
|  		fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||||
|  	/* XXX - can't do much about an error here */ | ||||
| -	if (sshpam_err == PAM_ACCT_EXPIRED)
 | ||||
| -		ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer);
 | ||||
| +	if (sshpam_err == PAM_PERM_DENIED
 | ||||
| +		|| sshpam_err == PAM_USER_UNKNOWN
 | ||||
| +		|| sshpam_err == PAM_ACCT_EXPIRED)
 | ||||
| +		ssh_msg_send(ctxt->pam_csock, sshpam_err, buffer);
 | ||||
|  	else if (sshpam_maxtries_reached) | ||||
|  		ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer); | ||||
|  	else | ||||
| @@ -856,10 +862,12 @@ sshpam_query(void *ctx, char **name, cha
 | ||||
|  			plen++; | ||||
|  			free(msg); | ||||
|  			break; | ||||
| +		case PAM_USER_UNKNOWN:
 | ||||
| +		case PAM_PERM_DENIED:
 | ||||
|  		case PAM_ACCT_EXPIRED: | ||||
| +			sshpam_account_status = 0;
 | ||||
| +			/* FALLTHROUGH */
 | ||||
|  		case PAM_MAXTRIES: | ||||
| -			if (type == PAM_ACCT_EXPIRED)
 | ||||
| -				sshpam_account_status = 0;
 | ||||
|  			if (type == PAM_MAXTRIES) | ||||
|  				sshpam_set_maxtries_reached(1); | ||||
|  			/* FALLTHROUGH */ | ||||
							
								
								
									
										320
									
								
								SOURCES/openssh-8.0p1-restore-nonblock.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								SOURCES/openssh-8.0p1-restore-nonblock.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,320 @@ | ||||
| diff --git a/channels.c b/channels.c
 | ||||
| index 32d1f617..0024f751 100644
 | ||||
| --- a/channels.c
 | ||||
| +++ b/channels.c
 | ||||
| @@ -333,7 +333,27 @@ channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
 | ||||
|  #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 *sc)
 | ||||
|  } | ||||
|   | ||||
|  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, Channel *c)
 | ||||
|  { | ||||
|  	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 | ||||
| @@ -702,7 +728,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; | ||||
|  			} | ||||
| @@ -1491,7 +1517,8 @@ channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output)
 | ||||
|   | ||||
|  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; | ||||
|   | ||||
| @@ -1499,7 +1526,7 @@ channel_connect_stdio_fwd(struct ssh *ssh,
 | ||||
|   | ||||
|  	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; | ||||
| @@ -1649,7 +1676,7 @@ channel_post_x11_listener(struct ssh *ssh, Channel *c,
 | ||||
|  	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; | ||||
|  	} | ||||
| @@ -2058,7 +2085,7 @@ channel_handle_efd_write(struct ssh *ssh, Channel *c,
 | ||||
|  		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_fr(r, "channel %i: consume", c->self); | ||||
| @@ -2087,7 +2114,7 @@ channel_handle_efd_read(struct ssh *ssh, Channel *c,
 | ||||
|  		return 1; | ||||
|  	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", c->self); | ||||
|  	else if ((r = sshbuf_put(c->extended, buf, len)) != 0) | ||||
| diff --git a/channels.h b/channels.h
 | ||||
| index 378d987c..6bf86b00 100644
 | ||||
| --- a/channels.h
 | ||||
| +++ b/channels.h
 | ||||
| @@ -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) | ||||
| @@ -139,6 +149,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 | ||||
| @@ -266,7 +277,7 @@ void	 channel_register_filter(struct ssh *, int, channel_infilter_fn *,
 | ||||
|  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 */ | ||||
| @@ -313,7 +324,7 @@ Channel	*channel_connect_to_port(struct ssh *, const char *, u_short,
 | ||||
|  	    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 --git a/clientloop.c b/clientloop.c
 | ||||
| index 219f0e90..bdd67686 100644
 | ||||
| --- a/clientloop.c
 | ||||
| +++ b/clientloop.c
 | ||||
| @@ -1405,14 +1405,6 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
 | ||||
|  	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 --git a/mux.c b/mux.c
 | ||||
| index faf4ef1e..9454bfed 100644
 | ||||
| --- a/mux.c
 | ||||
| +++ b/mux.c
 | ||||
| @@ -452,14 +452,6 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid,
 | ||||
|  	if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) | ||||
|  		error_f("tcgetattr: %s", 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) { | ||||
| @@ -469,7 +461,7 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid,
 | ||||
|   | ||||
|  	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 */ | ||||
| @@ -1025,13 +1017,8 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid,
 | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| -	/* 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 --git a/nchan.c b/nchan.c
 | ||||
| index 4a4494b8..7ef3a350 100644
 | ||||
| --- a/nchan.c
 | ||||
| +++ b/nchan.c
 | ||||
| @@ -384,7 +384,7 @@ chan_shutdown_write(struct ssh *ssh, Channel *c)
 | ||||
|  			    c->istate, c->ostate, strerror(errno)); | ||||
|  		} | ||||
|  	} else { | ||||
| -		if (channel_close_fd(ssh, &c->wfd) < 0) {
 | ||||
| +		if (channel_close_fd(ssh, c, &c->wfd) < 0) {
 | ||||
|  			logit_f("channel %d: close() failed for " | ||||
|  			    "fd %d [i%d o%d]: %.100s", c->self, c->wfd, | ||||
|  			    c->istate, c->ostate, strerror(errno)); | ||||
| @@ -412,7 +412,7 @@ chan_shutdown_read(struct ssh *ssh, Channel *c)
 | ||||
|  			    c->istate, c->ostate, strerror(errno)); | ||||
|  		} | ||||
|  	} else { | ||||
| -		if (channel_close_fd(ssh, &c->rfd) < 0) {
 | ||||
| +		if (channel_close_fd(ssh, c, &c->rfd) < 0) {
 | ||||
|  			logit_f("channel %d: close() failed for " | ||||
|  			    "fd %d [i%d o%d]: %.100s", c->self, c->rfd, | ||||
|  			    c->istate, c->ostate, strerror(errno)); | ||||
| @@ -431,7 +431,7 @@ chan_shutdown_extended_read(struct ssh *ssh, Channel *c)
 | ||||
|  	debug_f("channel %d: (i%d o%d sock %d wfd %d efd %d [%s])", | ||||
|  	    c->self, 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_f("channel %d: close() failed for " | ||||
|  		    "extended fd %d [i%d o%d]: %.100s", c->self, c->efd, | ||||
|  		    c->istate, c->ostate, strerror(errno)); | ||||
| diff --git a/ssh.c b/ssh.c
 | ||||
| index 696dc3bc..6243db76 100644
 | ||||
| --- a/ssh.c
 | ||||
| +++ b/ssh.c
 | ||||
| @@ -1876,9 +1876,10 @@ ssh_init_stdio_forwarding(struct ssh *ssh)
 | ||||
|   | ||||
|  	if ((in = dup(STDIN_FILENO)) == -1 || | ||||
|  	    (out = dup(STDOUT_FILENO)) == -1) | ||||
| -		fatal("channel_connect_stdio_fwd: dup() in/out failed");
 | ||||
| +		fatal_f("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_f("channel_connect_stdio_fwd failed"); | ||||
|  	channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0); | ||||
|  	channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL); | ||||
| @@ -2074,14 +2075,6 @@ ssh_session2_open(struct ssh *ssh)
 | ||||
|  	if (in == -1 || out == -1 || err == -1) | ||||
|  		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) { | ||||
| @@ -2091,7 +2084,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_f("channel_new: %d", c->self); | ||||
|   | ||||
							
								
								
									
										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) | ||||
|  { | ||||
							
								
								
									
										30
									
								
								SOURCES/openssh-8.2p1-x11-without-ipv6.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								SOURCES/openssh-8.2p1-x11-without-ipv6.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| diff --git a/channels.c b/channels.c
 | ||||
| --- a/channels.c
 | ||||
| +++ b/channels.c
 | ||||
| @@ -3933,16 +3933,26 @@ x11_create_display_inet(int x11_display_
 | ||||
|  			if (ai->ai_family == AF_INET6) | ||||
|  				sock_set_v6only(sock); | ||||
|  			if (x11_use_localhost) | ||||
|  				set_reuseaddr(sock); | ||||
|  			if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) { | ||||
|  				debug2_f("bind port %d: %.100s", port, | ||||
|  				    strerror(errno)); | ||||
|  				close(sock); | ||||
| +
 | ||||
| +				/* do not remove successfully opened
 | ||||
| +				 * sockets if the request failed because
 | ||||
| +				 * the protocol IPv4/6 is not available
 | ||||
| +				 * (e.g. IPv6 may be disabled while being
 | ||||
| +				 * supported)
 | ||||
| +				 */
 | ||||
| +				if (EADDRNOTAVAIL == errno)
 | ||||
| +    					continue;
 | ||||
| +
 | ||||
|  				for (n = 0; n < num_socks; n++) | ||||
|  					close(socks[n]); | ||||
|  				num_socks = 0; | ||||
|  				break; | ||||
|  			} | ||||
|  			socks[num_socks++] = sock; | ||||
|  			if (num_socks == NUM_SOCKS) | ||||
|  				break; | ||||
							
								
								
									
										57
									
								
								SOURCES/openssh-8.4p1-debian-compat.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								SOURCES/openssh-8.4p1-debian-compat.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| --- compat.h.orig	2020-10-05 10:09:02.953505129 -0700
 | ||||
| +++ compat.h	2020-10-05 10:10:17.587733113 -0700
 | ||||
| @@ -34,7 +34,7 @@
 | ||||
|   | ||||
|  #define SSH_BUG_UTF8TTYMODE	0x00000001 | ||||
|  #define SSH_BUG_SIGTYPE		0x00000002 | ||||
| -/* #define unused		0x00000004 */
 | ||||
| +#define SSH_BUG_SIGTYPE74	0x00000004
 | ||||
|  /* #define unused		0x00000008 */ | ||||
|  #define SSH_OLD_SESSIONID	0x00000010 | ||||
|  /* #define unused		0x00000020 */ | ||||
| --- compat.c.orig	2020-10-05 10:25:02.088720562 -0700
 | ||||
| +++ compat.c	2020-10-05 10:13:11.637282492 -0700
 | ||||
| @@ -65,11 +65,12 @@
 | ||||
|  		{ "OpenSSH_6.5*," | ||||
|  		  "OpenSSH_6.6*",	SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD| | ||||
|  					SSH_BUG_SIGTYPE}, | ||||
| +		{ "OpenSSH_7.4*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE|
 | ||||
| +		  			SSH_BUG_SIGTYPE74},
 | ||||
|  		{ "OpenSSH_7.0*," | ||||
|  		  "OpenSSH_7.1*," | ||||
|  		  "OpenSSH_7.2*," | ||||
|  		  "OpenSSH_7.3*," | ||||
| -		  "OpenSSH_7.4*,"
 | ||||
|  		  "OpenSSH_7.5*," | ||||
|  		  "OpenSSH_7.6*," | ||||
|  		  "OpenSSH_7.7*",	SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE}, | ||||
| --- sshconnect2.c.orig	2020-09-26 07:26:37.618010545 -0700
 | ||||
| +++ sshconnect2.c	2020-10-05 10:47:22.116315148 -0700
 | ||||
| @@ -1305,6 +1305,26 @@
 | ||||
|  			break; | ||||
|  	} | ||||
|  	free(oallowed); | ||||
| +	/*
 | ||||
| +	 * OpenSSH 7.4 supports SHA2 sig types, but fails to indicate its
 | ||||
| +	 * support.  For that release, check the local policy against the
 | ||||
| +	 * SHA2 signature types.
 | ||||
| +	 */
 | ||||
| +	if (alg == NULL &&
 | ||||
| +	    (key->type == KEY_RSA && (ssh->compat & SSH_BUG_SIGTYPE74))) {
 | ||||
| +		oallowed = allowed = xstrdup(options.pubkey_accepted_algos);
 | ||||
| +		while ((cp = strsep(&allowed, ",")) != NULL) {
 | ||||
| +			if (sshkey_type_from_name(cp) != key->type)
 | ||||
| +				continue;
 | ||||
| +			tmp = match_list(sshkey_sigalg_by_name(cp), "rsa-sha2-256,rsa-sha2-512", NULL);
 | ||||
| +			if (tmp != NULL)
 | ||||
| +				alg = xstrdup(cp);
 | ||||
| +			free(tmp);
 | ||||
| +			if (alg != NULL)
 | ||||
| +				break;
 | ||||
| +		}
 | ||||
| +		free(oallowed);
 | ||||
| +	}
 | ||||
|  	return alg; | ||||
|  } | ||||
|   | ||||
| 
 | ||||
							
								
								
									
										16
									
								
								SOURCES/openssh-8.6p1.tar.gz.asc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								SOURCES/openssh-8.6p1.tar.gz.asc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| -----BEGIN PGP SIGNATURE----- | ||||
| 
 | ||||
| iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmB5CwgACgkQKj9BTnNg | ||||
| YLp01RAArXrAALtwTnWDysxBKTxGAUmXsPQOeaBCPd3zND3n0si6iinwwatSbu4d | ||||
| eYj/EOlzXydJkgMImoq6ErZrP2LyApe9RQDHfn/zEr+k5iflOK4su59TK6Dwuy86 | ||||
| SPYsSNSBhABiVyH9HQelRyVLJfHwVU+DP/SaUemHGbeDLcczp5wh+mtXQPG7hMLi | ||||
| yuZ1e9W4pO5HOXwoccS69amO0nhqpLb2qBYhenFjY4lZPmIf7UFkGsqIkYeAqHU4 | ||||
| /uhM0anxo7y+ezc2YD6eZHLrOZcRj1eYxh9IHGZnDcW2+6twks4aVK1kU+HI7xqt | ||||
| m9bhB+RTVKit0hvNjyhZP3XrDksgCQyyiWuXOe323ane42noH1NP6W075lmnC11Q | ||||
| JGueXJ+/vGPq3aYiad2mSZoHS82VfK43cCwXY9psCmZOMuWgARy/rxOWUZa3FBV7 | ||||
| bIS59Mr4hzjyODXArXc+z98Q3Y0qV8jT7xDHCfmsmivBjNcEWH2fX4KvyPHNogJP | ||||
| C+4bA4WbOy9X6s3mKfQFgeLKA4MbeIhGTNFKl3Utyt7bl8dBzPU4nzBx5754e6Q2 | ||||
| 2vRuLsTfAAGWTNwu+XfS5wvhjPMLkXBH4IUxY8acUTxLYY4uPnPFS2ZqCC94Ysrr | ||||
| Af4DzNuqm8lkiglggwRwRLopVCuAHfScyqETdTOA1kLsILWdn8Q= | ||||
| =Jsrn | ||||
| -----END PGP SIGNATURE----- | ||||
							
								
								
									
										36
									
								
								SOURCES/pam_ssh_agent-rmheaders
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								SOURCES/pam_ssh_agent-rmheaders
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| authfd.c | ||||
| authfd.h | ||||
| atomicio.c | ||||
| atomicio.h | ||||
| bufaux.c | ||||
| bufbn.c | ||||
| buffer.h | ||||
| buffer.c | ||||
| cleanup.c | ||||
| cipher.h | ||||
| compat.h | ||||
| entropy.c | ||||
| entropy.h | ||||
| fatal.c | ||||
| includes.h | ||||
| kex.h | ||||
| key.c | ||||
| key.h | ||||
| log.c | ||||
| log.h | ||||
| match.h | ||||
| misc.c | ||||
| misc.h | ||||
| pathnames.h | ||||
| platform.h | ||||
| rsa.h | ||||
| ssh-dss.c | ||||
| ssh-rsa.c | ||||
| ssh.h | ||||
| ssh2.h | ||||
| uidswap.c | ||||
| uidswap.h | ||||
| uuencode.c | ||||
| uuencode.h | ||||
| xmalloc.c | ||||
| xmalloc.h | ||||
							
								
								
									
										992
									
								
								SOURCES/pam_ssh_agent_auth-0.10.2-compat.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										992
									
								
								SOURCES/pam_ssh_agent_auth-0.10.2-compat.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,992 @@ | ||||
| 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-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-pam_ssh_agent_auth-0.10.4/get_command_line.c	2020-09-23 10:52:16.424001475 +0200
 | ||||
| @@ -27,6 +27,7 @@
 | ||||
|   * or implied, of Jamie Beverly. | ||||
|   */ | ||||
|   | ||||
| +#include <stdlib.h>
 | ||||
|  #include <stdio.h> | ||||
|  #include <errno.h> | ||||
|  #include <string.h> | ||||
| @@ -66,8 +67,8 @@ proc_pid_cmdline(char *** inargv)
 | ||||
|                  case EOF: | ||||
|                  case '\0': | ||||
|                      if (len > 0) {  | ||||
| -                        argv = pamsshagentauth_xrealloc(argv, count + 1, sizeof(*argv));
 | ||||
| -                        argv[count] = pamsshagentauth_xcalloc(len + 1, sizeof(*argv[count]));
 | ||||
| +                        argv = xreallocarray(argv, count + 1, sizeof(*argv));
 | ||||
| +                        argv[count] = xcalloc(len + 1, sizeof(*argv[count]));
 | ||||
|                          strncpy(argv[count++], argbuf, len); | ||||
|                          memset(argbuf, '\0', MAX_LEN_PER_CMDLINE_ARG + 1); | ||||
|                          len = 0; | ||||
| @@ -106,9 +107,9 @@ pamsshagentauth_free_command_line(char *
 | ||||
|  { | ||||
|      size_t i; | ||||
|      for (i = 0; i < n_args; i++) | ||||
| -        pamsshagentauth_xfree(argv[i]);
 | ||||
| +        free(argv[i]);
 | ||||
|   | ||||
| -    pamsshagentauth_xfree(argv);
 | ||||
| +    free(argv);
 | ||||
|      return; | ||||
|  } | ||||
|   | ||||
| 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-pam_ssh_agent_auth-0.10.4/identity.h.psaa-compat	2019-07-08 18:36:13.000000000 +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 @@
 | ||||
|  #include "openbsd-compat/sys-queue.h" | ||||
|  #include "xmalloc.h" | ||||
|  #include "log.h" | ||||
| -#include "buffer.h"
 | ||||
| -#include "key.h"
 | ||||
| +#include "sshbuf.h"
 | ||||
| +#include "sshkey.h"
 | ||||
|  #include "authfd.h" | ||||
|  #include <stdio.h> | ||||
|   | ||||
| @@ -41,7 +41,7 @@ typedef struct idlist Idlist;
 | ||||
|  struct identity { | ||||
|      TAILQ_ENTRY(identity) next; | ||||
|      AuthenticationConnection *ac;   /* set if agent supports key */ | ||||
| -    Key *key;           /* public/private key */
 | ||||
| +    struct sshkey *key;           /* public/private key */
 | ||||
|      char    *filename;      /* comment for agent-only keys */ | ||||
|      int tried; | ||||
|      int isprivate;      /* key points to the private key */ | ||||
| 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-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-pam_ssh_agent_auth-0.10.4/iterate_ssh_agent_keys.c	2020-09-23 10:52:16.424001475 +0200
 | ||||
| @@ -36,8 +36,8 @@
 | ||||
|  #include "openbsd-compat/sys-queue.h" | ||||
|  #include "xmalloc.h" | ||||
|  #include "log.h" | ||||
| -#include "buffer.h"
 | ||||
| -#include "key.h"
 | ||||
| +#include "sshbuf.h"
 | ||||
| +#include "sshkey.h"
 | ||||
|  #include "authfd.h" | ||||
|  #include <stdio.h> | ||||
|  #include <openssl/evp.h> | ||||
| @@ -58,6 +58,8 @@
 | ||||
|  #include "get_command_line.h" | ||||
|  extern char **environ; | ||||
|   | ||||
| +#define PAM_SSH_AGENT_AUTH_REQUESTv1 101
 | ||||
| +
 | ||||
|  /*  | ||||
|   * Added by Jamie Beverly, ensure socket fd points to a socket owned by the user  | ||||
|   * A cursory check is done, but to avoid race conditions, it is necessary  | ||||
| @@ -77,7 +79,7 @@ log_action(char ** action, size_t count)
 | ||||
|      if (count == 0) | ||||
|          return NULL; | ||||
|      | ||||
| -    buf = pamsshagentauth_xcalloc((count * MAX_LEN_PER_CMDLINE_ARG) + (count * 3), sizeof(*buf));
 | ||||
| +    buf = xcalloc((count * MAX_LEN_PER_CMDLINE_ARG) + (count * 3), sizeof(*buf));
 | ||||
|      for (i = 0; i < count; i++) { | ||||
|          strcat(buf, (i > 0) ? " '" : "'"); | ||||
|          strncat(buf, action[i], MAX_LEN_PER_CMDLINE_ARG); | ||||
| @@ -87,21 +89,25 @@ log_action(char ** action, size_t count)
 | ||||
|  } | ||||
|   | ||||
|  void | ||||
| -agent_action(Buffer *buf, char ** action, size_t count)
 | ||||
| +agent_action(struct sshbuf **buf, char ** action, size_t count)
 | ||||
|  { | ||||
|      size_t i; | ||||
| -    pamsshagentauth_buffer_init(buf);
 | ||||
| +    int r;
 | ||||
|   | ||||
| -    pamsshagentauth_buffer_put_int(buf, count);
 | ||||
| +    if ((*buf = sshbuf_new()) == NULL)
 | ||||
| +        fatal("%s: sshbuf_new failed", __func__);
 | ||||
| +    if ((r = sshbuf_put_u32(*buf, count)) != 0)
 | ||||
| +        fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
|   | ||||
|      for (i = 0; i < count; i++) { | ||||
| -        pamsshagentauth_buffer_put_cstring(buf, action[i]);
 | ||||
| +        if ((r = sshbuf_put_cstring(*buf, action[i])) != 0)
 | ||||
| +            fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
|      } | ||||
|  } | ||||
|   | ||||
|   | ||||
| -void
 | ||||
| -pamsshagentauth_session_id2_gen(Buffer * session_id2, const char * user,
 | ||||
| +static void
 | ||||
| +pamsshagentauth_session_id2_gen(struct sshbuf ** session_id2, const char * user,
 | ||||
|                                  const char * ruser, const char * servicename) | ||||
|  { | ||||
|      u_char *cookie = NULL; | ||||
| @@ -114,22 +120,23 @@ pamsshagentauth_session_id2_gen(Buffer *
 | ||||
|      char ** reported_argv = NULL; | ||||
|      size_t count = 0; | ||||
|      char * action_logbuf = NULL; | ||||
| -    Buffer action_agentbuf;
 | ||||
| +    struct sshbuf *action_agentbuf = NULL;
 | ||||
|      uint8_t free_logbuf = 0; | ||||
|      char * retc; | ||||
|      int32_t reti; | ||||
| +    int r;
 | ||||
|   | ||||
| -    rnd = pamsshagentauth_arc4random();
 | ||||
| +    rnd = arc4random();
 | ||||
|      cookie_len = ((uint8_t) rnd); | ||||
|      while (cookie_len < 16) {  | ||||
|          cookie_len += 16;                                          /* Add 16 bytes to the size to ensure that while the length is random, the length is always reasonable; ticket #18 */ | ||||
|      } | ||||
|   | ||||
| -    cookie = pamsshagentauth_xcalloc(1,cookie_len);
 | ||||
| +    cookie = xcalloc(1, cookie_len);
 | ||||
|   | ||||
|      for (i = 0; i < cookie_len; i++) { | ||||
|          if (i % 4 == 0) { | ||||
| -            rnd = pamsshagentauth_arc4random();
 | ||||
| +            rnd = arc4random();
 | ||||
|          } | ||||
|          cookie[i] = (u_char) rnd; | ||||
|          rnd >>= 8; | ||||
| @@ -144,7 +151,8 @@ pamsshagentauth_session_id2_gen(Buffer *
 | ||||
|      } | ||||
|      else { | ||||
|          action_logbuf = "unknown on this platform"; | ||||
| -        pamsshagentauth_buffer_init(&action_agentbuf); /* stays empty, means unavailable */
 | ||||
| +        if ((action_agentbuf = sshbuf_new()) == NULL) /* stays empty, means unavailable */
 | ||||
| +            fatal("%s: sshbuf_new failed", __func__);
 | ||||
|      } | ||||
|       | ||||
|      /* | ||||
| @@ -161,35 +169,39 @@ pamsshagentauth_session_id2_gen(Buffer *
 | ||||
|      retc = getcwd(pwd, sizeof(pwd) - 1); | ||||
|      time(&ts); | ||||
|   | ||||
| -    pamsshagentauth_buffer_init(session_id2);
 | ||||
| +    if ((*session_id2 = sshbuf_new()) == NULL)
 | ||||
| +        fatal("%s: sshbuf_new failed", __func__);
 | ||||
|   | ||||
| -    pamsshagentauth_buffer_put_int(session_id2, PAM_SSH_AGENT_AUTH_REQUESTv1);
 | ||||
| -    /* pamsshagentauth_debug3("cookie: %s", pamsshagentauth_tohex(cookie, cookie_len)); */
 | ||||
| -    pamsshagentauth_buffer_put_string(session_id2, cookie, cookie_len);
 | ||||
| -    /* pamsshagentauth_debug3("user: %s", user); */
 | ||||
| -    pamsshagentauth_buffer_put_cstring(session_id2, user);
 | ||||
| -    /* pamsshagentauth_debug3("ruser: %s", ruser); */
 | ||||
| -    pamsshagentauth_buffer_put_cstring(session_id2, ruser);
 | ||||
| -    /* pamsshagentauth_debug3("servicename: %s", servicename); */
 | ||||
| -    pamsshagentauth_buffer_put_cstring(session_id2, servicename);
 | ||||
| -    /* pamsshagentauth_debug3("pwd: %s", pwd); */
 | ||||
| -    if(retc)
 | ||||
| -        pamsshagentauth_buffer_put_cstring(session_id2, pwd);
 | ||||
| -    else
 | ||||
| -        pamsshagentauth_buffer_put_cstring(session_id2, "");
 | ||||
| -    /* pamsshagentauth_debug3("action: %s", action_logbuf); */
 | ||||
| -    pamsshagentauth_buffer_put_string(session_id2, action_agentbuf.buf + action_agentbuf.offset, action_agentbuf.end - action_agentbuf.offset);
 | ||||
| +    if ((r = sshbuf_put_u32(*session_id2, PAM_SSH_AGENT_AUTH_REQUESTv1)) != 0 ||
 | ||||
| +        (r = sshbuf_put_string(*session_id2, cookie, cookie_len)) != 0 ||
 | ||||
| +        (r = sshbuf_put_cstring(*session_id2, user)) != 0 ||
 | ||||
| +        (r = sshbuf_put_cstring(*session_id2, ruser)) != 0 ||
 | ||||
| +        (r = sshbuf_put_cstring(*session_id2, servicename)) != 0)
 | ||||
| +        fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
| +    if (retc) {
 | ||||
| +        if ((r = sshbuf_put_cstring(*session_id2, pwd)) != 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));
 | ||||
| +    }
 | ||||
| +    if ((r = sshbuf_put_stringb(*session_id2, action_agentbuf)) != 0)
 | ||||
| +        fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
|      if (free_logbuf) {  | ||||
| -        pamsshagentauth_xfree(action_logbuf);
 | ||||
| -        pamsshagentauth_buffer_free(&action_agentbuf);
 | ||||
| +        free(action_logbuf);
 | ||||
| +        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); */
 | ||||
| -    if(reti >= 0)
 | ||||
| -        pamsshagentauth_buffer_put_cstring(session_id2, hostname);
 | ||||
| -    else
 | ||||
| -        pamsshagentauth_buffer_put_cstring(session_id2, "");
 | ||||
| -    /* pamsshagentauth_debug3("ts: %ld", ts); */
 | ||||
| -    pamsshagentauth_buffer_put_int64(session_id2, (uint64_t) ts);
 | ||||
| +    /* debug3("ts: %ld", ts); */
 | ||||
| +    if ((r = sshbuf_put_u64(*session_id2, (uint64_t) ts)) != 0)
 | ||||
| +        fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
|   | ||||
|      free(cookie); | ||||
|      return; | ||||
| @@ -278,7 +290,8 @@ ssh_get_authentication_connection_for_ui
 | ||||
|   | ||||
|  	auth = xmalloc(sizeof(*auth)); | ||||
|  	auth->fd = sock; | ||||
| -	buffer_init(&auth->identities);
 | ||||
| +	if ((auth->identities = sshbuf_new()) == NULL)
 | ||||
| +           fatal("%s: sshbuf_new failed", __func__);
 | ||||
|  	auth->howmany = 0; | ||||
|   | ||||
|  	return auth; | ||||
| @@ -287,9 +300,9 @@ ssh_get_authentication_connection_for_ui
 | ||||
|  int | ||||
|  pamsshagentauth_find_authorized_keys(const char * user, const char * ruser, const char * servicename) | ||||
|  { | ||||
| -    Buffer session_id2 = { 0 };
 | ||||
| +    struct sshbuf *session_id2 = NULL;
 | ||||
|      Identity *id; | ||||
| -    Key *key;
 | ||||
| +    struct sshkey *key;
 | ||||
|      AuthenticationConnection *ac; | ||||
|      char *comment; | ||||
|      uint8_t retval = 0; | ||||
| @@ -299,31 +312,30 @@ pamsshagentauth_find_authorized_keys(con
 | ||||
|      pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename); | ||||
|   | ||||
|      if ((ac = ssh_get_authentication_connection_for_uid(uid))) { | ||||
| -        pamsshagentauth_verbose("Contacted ssh-agent of user %s (%u)", ruser, uid);
 | ||||
| +        verbose("Contacted ssh-agent of user %s (%u)", ruser, uid);
 | ||||
|          for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2))  | ||||
|          { | ||||
|              if(key != NULL) { | ||||
| -                id = pamsshagentauth_xcalloc(1, sizeof(*id));
 | ||||
| +                id = xcalloc(1, sizeof(*id));
 | ||||
|                  id->key = key; | ||||
|                  id->filename = comment; | ||||
|                  id->ac = ac; | ||||
| -                if(userauth_pubkey_from_id(ruser, id, &session_id2)) {
 | ||||
| +                if(userauth_pubkey_from_id(ruser, id, session_id2)) {
 | ||||
|                      retval = 1; | ||||
|                  } | ||||
| -                pamsshagentauth_xfree(id->filename);
 | ||||
| -                pamsshagentauth_key_free(id->key);
 | ||||
| -                pamsshagentauth_xfree(id);
 | ||||
| +                free(id->filename);
 | ||||
| +                key_free(id->key);
 | ||||
| +                free(id);
 | ||||
|                  if(retval == 1) | ||||
|                      break; | ||||
|              } | ||||
|          } | ||||
| -        pamsshagentauth_buffer_free(&session_id2);
 | ||||
| +        sshbuf_free(session_id2);
 | ||||
|          ssh_close_authentication_connection(ac); | ||||
|      } | ||||
|      else { | ||||
| -        pamsshagentauth_verbose("No ssh-agent could be contacted");
 | ||||
| +        verbose("No ssh-agent could be contacted");
 | ||||
|      } | ||||
| -    /* pamsshagentauth_xfree(session_id2); */
 | ||||
|      EVP_cleanup(); | ||||
|      return retval; | ||||
|  } | ||||
| 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-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-pam_ssh_agent_auth-0.10.4/pam_ssh_agent_auth.c	2020-09-23 10:53:10.631727657 +0200
 | ||||
| @@ -106,7 +106,7 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||
|   * a patch 8-) | ||||
|   */ | ||||
|  #if ! HAVE___PROGNAME || HAVE_BUNDLE | ||||
| -    __progname = pamsshagentauth_xstrdup(servicename);
 | ||||
| +    __progname = xstrdup(servicename);
 | ||||
|  #endif | ||||
|   | ||||
|      for(i = argc, argv_ptr = (char **) argv; i > 0; ++argv_ptr, i--) { | ||||
| @@ -132,11 +132,11 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||
|  #endif | ||||
|      } | ||||
|   | ||||
| -    pamsshagentauth_log_init(__progname, log_lvl, facility, getenv("PAM_SSH_AGENT_AUTH_DEBUG") ? 1 : 0);
 | ||||
| +    log_init(__progname, log_lvl, facility, getenv("PAM_SSH_AGENT_AUTH_DEBUG") ? 1 : 0);
 | ||||
|      pam_get_item(pamh, PAM_USER, (void *) &user); | ||||
|      pam_get_item(pamh, PAM_RUSER, (void *) &ruser_ptr); | ||||
|   | ||||
| -    pamsshagentauth_verbose("Beginning pam_ssh_agent_auth for user %s", user);
 | ||||
| +    verbose("Beginning pam_ssh_agent_auth for user %s", user);
 | ||||
|   | ||||
|      if(ruser_ptr) { | ||||
|          strncpy(ruser, ruser_ptr, sizeof(ruser) - 1); | ||||
| @@ -151,12 +151,12 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||
|  #ifdef ENABLE_SUDO_HACK | ||||
|          if( (strlen(sudo_service_name) > 0) && strncasecmp(servicename, sudo_service_name, sizeof(sudo_service_name) - 1) == 0 && getenv("SUDO_USER") ) { | ||||
|              strncpy(ruser, getenv("SUDO_USER"), sizeof(ruser) - 1 ); | ||||
| -            pamsshagentauth_verbose( "Using environment variable SUDO_USER (%s)", ruser );
 | ||||
| +            verbose( "Using environment variable SUDO_USER (%s)", ruser );
 | ||||
|          } else | ||||
|  #endif | ||||
|          { | ||||
|              if( ! getpwuid(getuid()) ) { | ||||
| -                pamsshagentauth_verbose("Unable to getpwuid(getuid())");
 | ||||
| +                verbose("Unable to getpwuid(getuid())");
 | ||||
|                  goto cleanexit; | ||||
|              } | ||||
|              strncpy(ruser, getpwuid(getuid())->pw_name, sizeof(ruser) - 1); | ||||
| @@ -165,11 +165,11 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||
|   | ||||
|      /* Might as well explicitely confirm the user exists here */ | ||||
|      if(! getpwnam(ruser) ) { | ||||
| -        pamsshagentauth_verbose("getpwnam(%s) failed, bailing out", ruser);
 | ||||
| +        verbose("getpwnam(%s) failed, bailing out", ruser);
 | ||||
|          goto cleanexit; | ||||
|      } | ||||
|      if( ! getpwnam(user) ) { | ||||
| -        pamsshagentauth_verbose("getpwnam(%s) failed, bailing out", user);
 | ||||
| +        verbose("getpwnam(%s) failed, bailing out", user);
 | ||||
|          goto cleanexit; | ||||
|      } | ||||
|   | ||||
| @@ -179,8 +179,8 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||
|           */ | ||||
|          parse_authorized_key_file(user, authorized_keys_file_input); | ||||
|      } else { | ||||
| -        pamsshagentauth_verbose("Using default file=/etc/security/authorized_keys");
 | ||||
| -        authorized_keys_file = pamsshagentauth_xstrdup("/etc/security/authorized_keys");
 | ||||
| +        verbose("Using default file=/etc/security/authorized_keys");
 | ||||
| +        authorized_keys_file = xstrdup("/etc/security/authorized_keys");
 | ||||
|      } | ||||
|   | ||||
|      /* | ||||
| @@ -189,7 +189,7 @@ pam_sm_authenticate(pam_handle_t * pamh,
 | ||||
|       */ | ||||
|   | ||||
|      if(user && strlen(ruser) > 0) { | ||||
| -        pamsshagentauth_verbose("Attempting authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | ||||
| +        verbose("Attempting authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | ||||
|   | ||||
|          /* | ||||
|           * 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 | ||||
|           */ | ||||
|          if(pamsshagentauth_find_authorized_keys(user, ruser, servicename)) { /* getpwnam(ruser)->pw_uid)) { */ | ||||
| -            pamsshagentauth_logit("Authenticated (agent): `%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; | ||||
|          } else { | ||||
| -            pamsshagentauth_logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | ||||
| +            logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file);
 | ||||
|          } | ||||
|      } else { | ||||
| -        pamsshagentauth_logit("No %s specified, cannot continue with this form of authentication", (user) ? "ruser" : "user" );
 | ||||
| +        logit("No %s specified, cannot continue with this form of authentication", (user) ? "ruser" : "user" );
 | ||||
|      } | ||||
|   | ||||
|  cleanexit: | ||||
| diff -up openssh/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-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-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.c	2020-09-23 10:52:16.424001475 +0200
 | ||||
| @@ -66,8 +66,8 @@
 | ||||
|  #include "xmalloc.h" | ||||
|  #include "match.h" | ||||
|  #include "log.h" | ||||
| -#include "buffer.h"
 | ||||
| -#include "key.h"
 | ||||
| +#include "sshbuf.h"
 | ||||
| +#include "sshkey.h"
 | ||||
|  #include "misc.h" | ||||
|   | ||||
|  #include "xmalloc.h" | ||||
| @@ -77,7 +77,6 @@
 | ||||
|  #include "pathnames.h" | ||||
|  #include "secure_filename.h" | ||||
|   | ||||
| -#include "identity.h"
 | ||||
|  #include "pam_user_key_allowed2.h" | ||||
|   | ||||
|  extern char *authorized_keys_file; | ||||
| @@ -117,12 +116,12 @@ parse_authorized_key_file(const char *us
 | ||||
|          } else { | ||||
|              slash_ptr = strchr(auth_keys_file_buf, '/'); | ||||
|              if(!slash_ptr) | ||||
| -                pamsshagentauth_fatal
 | ||||
| +                fatal
 | ||||
|                      ("cannot expand tilde in path without a `/'"); | ||||
|   | ||||
|              owner_uname_len = slash_ptr - auth_keys_file_buf - 1; | ||||
|              if(owner_uname_len > (sizeof(owner_uname) - 1)) | ||||
| -                pamsshagentauth_fatal("Username too long");
 | ||||
| +                fatal("Username too long");
 | ||||
|   | ||||
|              strncat(owner_uname, auth_keys_file_buf + 1, owner_uname_len); | ||||
|              if(!authorized_keys_file_allowed_owner_uid) | ||||
| @@ -130,11 +129,11 @@ parse_authorized_key_file(const char *us
 | ||||
|                      getpwnam(owner_uname)->pw_uid; | ||||
|          } | ||||
|          authorized_keys_file = | ||||
| -            pamsshagentauth_tilde_expand_filename(auth_keys_file_buf,
 | ||||
| +            tilde_expand_filename(auth_keys_file_buf,
 | ||||
|                                                    authorized_keys_file_allowed_owner_uid); | ||||
|          strncpy(auth_keys_file_buf, authorized_keys_file, | ||||
|                  sizeof(auth_keys_file_buf) - 1); | ||||
| -        pamsshagentauth_xfree(authorized_keys_file)        /* when we
 | ||||
| +        free(authorized_keys_file)        /* when we
 | ||||
|                                                                percent_expand | ||||
|                                                                later, we'd step | ||||
|                                                                on this, so free | ||||
| @@ -150,13 +149,13 @@ parse_authorized_key_file(const char *us
 | ||||
|      strncat(hostname, fqdn, strcspn(fqdn, ".")); | ||||
|  #endif | ||||
|      authorized_keys_file = | ||||
| -        pamsshagentauth_percent_expand(auth_keys_file_buf, "h",
 | ||||
| +        percent_expand(auth_keys_file_buf, "h",
 | ||||
|                                         getpwnam(user)->pw_dir, "H", hostname, | ||||
|                                         "f", fqdn, "u", user, NULL); | ||||
|  } | ||||
|   | ||||
|  int | ||||
| -pam_user_key_allowed(const char *ruser, Key * key)
 | ||||
| +pam_user_key_allowed(const char *ruser, struct sshkey * key)
 | ||||
|  { | ||||
|      return | ||||
|          pamsshagentauth_user_key_allowed2(getpwuid(authorized_keys_file_allowed_owner_uid), | ||||
| 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-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-pam_ssh_agent_auth-0.10.4/pam_user_authorized_keys.h	2020-09-23 10:52:16.424001475 +0200
 | ||||
| @@ -32,7 +32,7 @@
 | ||||
|  #define _PAM_USER_KEY_ALLOWED_H | ||||
|   | ||||
|  #include "identity.h" | ||||
| -int pam_user_key_allowed(const char *, Key *);
 | ||||
| +int pam_user_key_allowed(const char *, struct sshkey *);
 | ||||
|  void parse_authorized_key_file(const char *, const char *); | ||||
|   | ||||
|  #endif | ||||
| 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-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-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.c	2020-09-23 10:52:16.424001475 +0200
 | ||||
| @@ -45,44 +45,46 @@
 | ||||
|  #include "xmalloc.h" | ||||
|  #include "ssh.h" | ||||
|  #include "ssh2.h" | ||||
| -#include "buffer.h"
 | ||||
| +#include "sshbuf.h"
 | ||||
|  #include "log.h" | ||||
|  #include "compat.h" | ||||
| -#include "key.h"
 | ||||
| +#include "digest.h"
 | ||||
| +#include "sshkey.h"
 | ||||
|  #include "pathnames.h" | ||||
|  #include "misc.h" | ||||
|  #include "secure_filename.h" | ||||
|  #include "uidswap.h" | ||||
| -
 | ||||
| -#include "identity.h"
 | ||||
| +#include <unistd.h>
 | ||||
|   | ||||
|  /* return 1 if user allows given key */ | ||||
|  /* Modified slightly from original found in auth2-pubkey.c */ | ||||
|  static int | ||||
| -pamsshagentauth_check_authkeys_file(FILE * f, char *file, Key * key)
 | ||||
| +pamsshagentauth_check_authkeys_file(FILE * f, char *file, struct sshkey * key)
 | ||||
|  { | ||||
| -    char line[SSH_MAX_PUBKEY_BYTES];
 | ||||
| +    char *line = NULL;
 | ||||
|      int found_key = 0; | ||||
|      u_long linenum = 0; | ||||
| -    Key *found;
 | ||||
| +    struct sshkey *found;
 | ||||
|      char *fp; | ||||
| +    size_t linesize = 0;
 | ||||
|   | ||||
|      found_key = 0; | ||||
| -    found = pamsshagentauth_key_new(key->type);
 | ||||
| +    found = sshkey_new(key->type);
 | ||||
|   | ||||
| -    while(read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
 | ||||
| +    while ((getline(&line, &linesize, f)) != -1) {
 | ||||
|          char *cp = NULL; /* *key_options = NULL; */ | ||||
|   | ||||
| +        linenum++;
 | ||||
|          /* Skip leading whitespace, empty and comment lines. */ | ||||
|          for(cp = line; *cp == ' ' || *cp == '\t'; cp++); | ||||
|          if(!*cp || *cp == '\n' || *cp == '#') | ||||
|              continue; | ||||
|   | ||||
| -        if(pamsshagentauth_key_read(found, &cp) != 1) {
 | ||||
| +        if (sshkey_read(found, &cp) != 0) {
 | ||||
|              /* no key? check if there are options for this key */ | ||||
|              int quoted = 0; | ||||
|   | ||||
| -            pamsshagentauth_verbose("user_key_allowed: check options: '%s'", cp);
 | ||||
| +            verbose("user_key_allowed: check options: '%s'", cp);
 | ||||
|              /* key_options = cp; */ | ||||
|              for(; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { | ||||
|                  if(*cp == '\\' && cp[1] == '"') | ||||
| @@ -92,26 +94,27 @@ pamsshagentauth_check_authkeys_file(FILE
 | ||||
|              } | ||||
|              /* Skip remaining whitespace. */ | ||||
|              for(; *cp == ' ' || *cp == '\t'; cp++); | ||||
| -            if(pamsshagentauth_key_read(found, &cp) != 1) {
 | ||||
| -                pamsshagentauth_verbose("user_key_allowed: advance: '%s'", cp);
 | ||||
| +            if(sshkey_read(found, &cp) != 0) {
 | ||||
| +                verbose("user_key_allowed: advance: '%s'", cp);
 | ||||
|                  /* still no key? advance to next line */ | ||||
|                  continue; | ||||
|              } | ||||
|          } | ||||
| -        if(pamsshagentauth_key_equal(found, key)) {
 | ||||
| +        if(sshkey_equal(found, key)) {
 | ||||
|              found_key = 1; | ||||
| -            pamsshagentauth_logit("matching key found: file/command %s, line %lu", file,
 | ||||
| +            logit("matching key found: file/command %s, line %lu", file,
 | ||||
|                                    linenum); | ||||
| -            fp = pamsshagentauth_key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
 | ||||
| -            pamsshagentauth_logit("Found matching %s key: %s",
 | ||||
| -                                  pamsshagentauth_key_type(found), fp);
 | ||||
| -            pamsshagentauth_xfree(fp);
 | ||||
| +            fp = sshkey_fingerprint(found, SSH_DIGEST_SHA256, SSH_FP_BASE64);
 | ||||
| +            logit("Found matching %s key: %s",
 | ||||
| +                                  sshkey_type(found), fp);
 | ||||
| +            free(fp);
 | ||||
|              break; | ||||
|          } | ||||
|      } | ||||
| -    pamsshagentauth_key_free(found);
 | ||||
| +    free(line);
 | ||||
| +    sshkey_free(found);
 | ||||
|      if(!found_key) | ||||
| -        pamsshagentauth_verbose("key not found");
 | ||||
| +        verbose("key not found");
 | ||||
|      return found_key; | ||||
|  } | ||||
|   | ||||
| @@ -120,19 +123,19 @@ pamsshagentauth_check_authkeys_file(FILE
 | ||||
|   * returns 1 if the key is allowed or 0 otherwise. | ||||
|   */ | ||||
|  int | ||||
| -pamsshagentauth_user_key_allowed2(struct passwd *pw, Key * key, char *file)
 | ||||
| +pamsshagentauth_user_key_allowed2(struct passwd *pw, struct sshkey * key, char *file)
 | ||||
|  { | ||||
|      FILE *f; | ||||
|      int found_key = 0; | ||||
|      struct stat st; | ||||
| -    char buf[SSH_MAX_PUBKEY_BYTES];
 | ||||
| +    char buf[256];
 | ||||
|   | ||||
|      /* Temporarily use the user's uid. */ | ||||
| -    pamsshagentauth_verbose("trying public key file %s", file);
 | ||||
| +    verbose("trying public key file %s", file);
 | ||||
|   | ||||
|      /* Fail not so quietly if file does not exist */ | ||||
|      if(stat(file, &st) < 0) { | ||||
| -        pamsshagentauth_verbose("File not found: %s", file);
 | ||||
| +        verbose("File not found: %s", file);
 | ||||
|          return 0; | ||||
|      } | ||||
|   | ||||
| @@ -144,7 +147,7 @@ pamsshagentauth_user_key_allowed2(struct
 | ||||
|   | ||||
|      if(pamsshagentauth_secure_filename(f, file, pw, buf, sizeof(buf)) != 0) { | ||||
|          fclose(f); | ||||
| -        pamsshagentauth_logit("Authentication refused: %s", buf);
 | ||||
| +        logit("Authentication refused: %s", buf);
 | ||||
|          return 0; | ||||
|      } | ||||
|   | ||||
| @@ -160,7 +163,7 @@ pamsshagentauth_user_key_allowed2(struct
 | ||||
|  int | ||||
|  pamsshagentauth_user_key_command_allowed2(char *authorized_keys_command, | ||||
|                            char *authorized_keys_command_user, | ||||
| -                          struct passwd *user_pw, Key * key)
 | ||||
| +                          struct passwd *user_pw, struct sshkey * key)
 | ||||
|  { | ||||
|      FILE *f; | ||||
|      int ok, found_key = 0; | ||||
| @@ -187,44 +190,44 @@ pamsshagentauth_user_key_command_allowed
 | ||||
|      else { | ||||
|          pw = getpwnam(authorized_keys_command_user); | ||||
|          if(pw == NULL) { | ||||
| -            pamsshagentauth_logerror("authorized_keys_command_user \"%s\" not found: %s",
 | ||||
| +            error("authorized_keys_command_user \"%s\" not found: %s",
 | ||||
|                   authorized_keys_command_user, strerror(errno)); | ||||
|              return 0; | ||||
|          } | ||||
|      } | ||||
|   | ||||
| -    pamsshagentauth_temporarily_use_uid(pw);
 | ||||
| +    temporarily_use_uid(pw);
 | ||||
|   | ||||
|      if(stat(authorized_keys_command, &st) < 0) { | ||||
| -        pamsshagentauth_logerror
 | ||||
| +        error
 | ||||
|              ("Could not stat AuthorizedKeysCommand \"%s\": %s", | ||||
|               authorized_keys_command, strerror(errno)); | ||||
|          goto out; | ||||
|      } | ||||
|      if(pamsshagentauth_auth_secure_path | ||||
|         (authorized_keys_command, &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) { | ||||
| -        pamsshagentauth_logerror("Unsafe AuthorizedKeysCommand: %s", errmsg);
 | ||||
| +        error("Unsafe AuthorizedKeysCommand: %s", errmsg);
 | ||||
|          goto out; | ||||
|      } | ||||
|   | ||||
|      /* open the pipe and read the keys */ | ||||
|      if(pipe(p) != 0) { | ||||
| -        pamsshagentauth_logerror("%s: pipe: %s", __func__, strerror(errno));
 | ||||
| +        error("%s: pipe: %s", __func__, strerror(errno));
 | ||||
|          goto out; | ||||
|      } | ||||
|   | ||||
| -    pamsshagentauth_debug("Running AuthorizedKeysCommand: \"%s\" as \"%s\" with argument: \"%s\"",
 | ||||
| +    debug("Running AuthorizedKeysCommand: \"%s\" as \"%s\" with argument: \"%s\"",
 | ||||
|                            authorized_keys_command, pw->pw_name, username); | ||||
|   | ||||
|      /*  | ||||
|       * Don't want to call this in the child, where it can fatal() and | ||||
|       * run cleanup_exit() code. | ||||
|       */ | ||||
| -    pamsshagentauth_restore_uid();
 | ||||
| +    restore_uid();
 | ||||
|   | ||||
|      switch ((pid = fork())) { | ||||
|      case -1:                                              /* error */ | ||||
| -        pamsshagentauth_logerror("%s: fork: %s", __func__, strerror(errno));
 | ||||
| +        error("%s: fork: %s", __func__, strerror(errno));
 | ||||
|          close(p[0]); | ||||
|          close(p[1]); | ||||
|          return 0; | ||||
| @@ -234,13 +237,13 @@ pamsshagentauth_user_key_command_allowed
 | ||||
|   | ||||
|          /* do this before the setresuid so thta they can be logged */ | ||||
|          if((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { | ||||
| -            pamsshagentauth_logerror("%s: open %s: %s", __func__, _PATH_DEVNULL,
 | ||||
| +            error("%s: open %s: %s", __func__, _PATH_DEVNULL,
 | ||||
|                                       strerror(errno)); | ||||
|              _exit(1); | ||||
|          } | ||||
|          if(dup2(devnull, STDIN_FILENO) == -1 || dup2(p[1], STDOUT_FILENO) == -1 | ||||
|             || dup2(devnull, STDERR_FILENO) == -1) { | ||||
| -            pamsshagentauth_logerror("%s: dup2: %s", __func__, strerror(errno));
 | ||||
| +            error("%s: dup2: %s", __func__, strerror(errno));
 | ||||
|              _exit(1); | ||||
|          } | ||||
|  #if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID) | ||||
| @@ -248,7 +251,7 @@ pamsshagentauth_user_key_command_allowed
 | ||||
|  #else | ||||
|          if (setgid(pw->pw_gid) != 0 || setegid(pw->pw_gid) != 0) { | ||||
|  #endif | ||||
| -            pamsshagentauth_logerror("setresgid %u: %s", (u_int) pw->pw_gid,
 | ||||
| +            error("setresgid %u: %s", (u_int) pw->pw_gid,
 | ||||
|                                       strerror(errno)); | ||||
|              _exit(1); | ||||
|          } | ||||
| @@ -258,7 +261,7 @@ pamsshagentauth_user_key_command_allowed
 | ||||
|  #else | ||||
|          if (setuid(pw->pw_uid) != 0 || seteuid(pw->pw_uid) != 0) { | ||||
|  #endif | ||||
| -            pamsshagentauth_logerror("setresuid %u: %s", (u_int) pw->pw_uid,
 | ||||
| +            error("setresuid %u: %s", (u_int) pw->pw_uid,
 | ||||
|                                       strerror(errno)); | ||||
|              _exit(1); | ||||
|          } | ||||
| @@ -270,18 +273,18 @@ pamsshagentauth_user_key_command_allowed
 | ||||
|   | ||||
|          /* pretty sure this will barf because we are now suid, but since we | ||||
|             should't reach this anyway, I'll leave it here */ | ||||
| -        pamsshagentauth_logerror("AuthorizedKeysCommand %s exec failed: %s",
 | ||||
| +        error("AuthorizedKeysCommand %s exec failed: %s",
 | ||||
|                                   authorized_keys_command, strerror(errno)); | ||||
|          _exit(127); | ||||
|      default:                                              /* parent */ | ||||
|          break; | ||||
|      } | ||||
|   | ||||
| -    pamsshagentauth_temporarily_use_uid(pw);
 | ||||
| +    temporarily_use_uid(pw);
 | ||||
|   | ||||
|      close(p[1]); | ||||
|      if((f = fdopen(p[0], "r")) == NULL) { | ||||
| -        pamsshagentauth_logerror("%s: fdopen: %s", __func__, strerror(errno));
 | ||||
| +        error("%s: fdopen: %s", __func__, strerror(errno));
 | ||||
|          close(p[0]); | ||||
|          /* Don't leave zombie child */ | ||||
|          while(waitpid(pid, NULL, 0) == -1 && errno == EINTR); | ||||
| @@ -292,22 +295,22 @@ pamsshagentauth_user_key_command_allowed
 | ||||
|   | ||||
|      while(waitpid(pid, &status, 0) == -1) { | ||||
|          if(errno != EINTR) { | ||||
| -            pamsshagentauth_logerror("%s: waitpid: %s", __func__,
 | ||||
| +            error("%s: waitpid: %s", __func__,
 | ||||
|                                       strerror(errno)); | ||||
|              goto out; | ||||
|          } | ||||
|      } | ||||
|      if(WIFSIGNALED(status)) { | ||||
| -        pamsshagentauth_logerror("AuthorizedKeysCommand %s exited on signal %d",
 | ||||
| +        error("AuthorizedKeysCommand %s exited on signal %d",
 | ||||
|                                   authorized_keys_command, WTERMSIG(status)); | ||||
|          goto out; | ||||
|      } else if(WEXITSTATUS(status) != 0) { | ||||
| -        pamsshagentauth_logerror("AuthorizedKeysCommand %s returned status %d",
 | ||||
| +        error("AuthorizedKeysCommand %s returned status %d",
 | ||||
|                                   authorized_keys_command, WEXITSTATUS(status)); | ||||
|          goto out; | ||||
|      } | ||||
|      found_key = ok; | ||||
|    out: | ||||
| -    pamsshagentauth_restore_uid();
 | ||||
| +    restore_uid();
 | ||||
|      return found_key; | ||||
|  } | ||||
| diff -up openssh/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-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-pam_ssh_agent_auth-0.10.4/pam_user_key_allowed2.h	2020-09-23 10:52:16.424001475 +0200
 | ||||
| @@ -32,7 +32,7 @@
 | ||||
|  #define _PAM_USER_KEY_ALLOWED_H | ||||
|   | ||||
|  #include "identity.h" | ||||
| -int pamsshagentauth_user_key_allowed2(struct passwd *, Key *, char *);
 | ||||
| -int pamsshagentauth_user_key_command_allowed2(char *, char *, struct passwd *, Key *);
 | ||||
| +int pamsshagentauth_user_key_allowed2(struct passwd *, struct sshkey *, char *);
 | ||||
| +int pamsshagentauth_user_key_command_allowed2(char *, char *, struct passwd *, struct sshkey *);
 | ||||
|   | ||||
|  #endif | ||||
| 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-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-pam_ssh_agent_auth-0.10.4/secure_filename.c	2020-09-23 10:52:16.424001475 +0200
 | ||||
| @@ -53,8 +53,8 @@
 | ||||
|  #include "xmalloc.h" | ||||
|  #include "match.h" | ||||
|  #include "log.h" | ||||
| -#include "buffer.h"
 | ||||
| -#include "key.h"
 | ||||
| +#include "sshbuf.h"
 | ||||
| +#include "sshkey.h"
 | ||||
|  #include "misc.h" | ||||
|   | ||||
|   | ||||
| @@ -80,7 +80,7 @@ pamsshagentauth_auth_secure_path(const c
 | ||||
|  	int comparehome = 0; | ||||
|  	struct stat st; | ||||
|   | ||||
| -    pamsshagentauth_verbose("auth_secure_filename: checking for uid: %u", uid);
 | ||||
| +    verbose("auth_secure_filename: checking for uid: %u", uid);
 | ||||
|   | ||||
|  	if (realpath(name, buf) == NULL) { | ||||
|  		snprintf(err, errlen, "realpath %s failed: %s", name, | ||||
| @@ -115,9 +115,9 @@ pamsshagentauth_auth_secure_path(const c
 | ||||
|  			snprintf(err, errlen, "dirname() failed"); | ||||
|  			return -1; | ||||
|  		} | ||||
| -		pamsshagentauth_strlcpy(buf, cp, sizeof(buf));
 | ||||
| +		strlcpy(buf, cp, sizeof(buf));
 | ||||
|   | ||||
| -		pamsshagentauth_verbose("secure_filename: checking '%s'", buf);
 | ||||
| +		verbose("secure_filename: checking '%s'", buf);
 | ||||
|  		if (stat(buf, &st) < 0 || | ||||
|  		    (st.st_uid != 0 && st.st_uid != uid) || | ||||
|  		    (st.st_mode & 022) != 0) { | ||||
| @@ -128,7 +128,7 @@ pamsshagentauth_auth_secure_path(const c
 | ||||
|   | ||||
|  		/* If are passed the homedir then we can stop */ | ||||
|  		if (comparehome && strcmp(homedir, buf) == 0) { | ||||
| -			pamsshagentauth_verbose("secure_filename: terminating check at '%s'",
 | ||||
| +			verbose("secure_filename: terminating check at '%s'",
 | ||||
|  			    buf); | ||||
|  			break; | ||||
|  		} | ||||
| diff -up openssh/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-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-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.c	2020-09-23 10:52:16.424001475 +0200
 | ||||
| @@ -37,10 +37,11 @@
 | ||||
|  #include "xmalloc.h" | ||||
|  #include "ssh.h" | ||||
|  #include "ssh2.h" | ||||
| -#include "buffer.h"
 | ||||
| +#include "sshbuf.h"
 | ||||
|  #include "log.h" | ||||
|  #include "compat.h" | ||||
| -#include "key.h"
 | ||||
| +#include "sshkey.h"
 | ||||
| +#include "ssherr.h"
 | ||||
|  #include "pathnames.h" | ||||
|  #include "misc.h" | ||||
|  #include "secure_filename.h" | ||||
| @@ -48,54 +49,59 @@
 | ||||
|  #include "identity.h" | ||||
|  #include "pam_user_authorized_keys.h" | ||||
|   | ||||
| +#define SSH2_MSG_USERAUTH_TRUST_REQUEST          54
 | ||||
| +
 | ||||
|  /* extern u_char  *session_id2; | ||||
|  extern uint8_t  session_id_len; | ||||
|   */ | ||||
|   | ||||
|  int | ||||
| -userauth_pubkey_from_id(const char *ruser, Identity * id, Buffer * session_id2)
 | ||||
| +userauth_pubkey_from_id(const char *ruser, Identity * id, struct sshbuf * session_id2)
 | ||||
|  { | ||||
| -    Buffer          b = { 0 };
 | ||||
| +    struct sshbuf  *b = NULL;
 | ||||
|      char           *pkalg = NULL; | ||||
|      u_char         *pkblob = NULL, *sig = NULL; | ||||
| -    u_int           blen = 0, slen = 0;
 | ||||
| -    int             authenticated = 0;
 | ||||
| +    size_t          blen = 0, slen = 0;
 | ||||
| +    int             r, authenticated = 0;
 | ||||
|   | ||||
| -    pkalg = (char *) key_ssh_name(id->key);
 | ||||
| +    pkalg = (char *) sshkey_ssh_name(id->key);
 | ||||
|   | ||||
|      /* first test if this key is even allowed */ | ||||
|      if(! pam_user_key_allowed(ruser, id->key)) | ||||
| -        goto user_auth_clean_exit;
 | ||||
| +        goto user_auth_clean_exit_without_buffer;
 | ||||
|   | ||||
| -    if(pamsshagentauth_key_to_blob(id->key, &pkblob, &blen) == 0)
 | ||||
| -        goto user_auth_clean_exit;
 | ||||
| +    if(sshkey_to_blob(id->key, &pkblob, &blen) != 0)
 | ||||
| +        goto user_auth_clean_exit_without_buffer;
 | ||||
|   | ||||
|      /* construct packet to sign and test */ | ||||
| -    pamsshagentauth_buffer_init(&b);
 | ||||
| +    if ((b = sshbuf_new()) == NULL)
 | ||||
| +        fatal("%s: sshbuf_new failed", __func__);
 | ||||
|   | ||||
| -    pamsshagentauth_buffer_put_string(&b, session_id2->buf + session_id2->offset, session_id2->end - session_id2->offset);
 | ||||
| -    pamsshagentauth_buffer_put_char(&b, SSH2_MSG_USERAUTH_TRUST_REQUEST); 
 | ||||
| -    pamsshagentauth_buffer_put_cstring(&b, ruser);
 | ||||
| -    pamsshagentauth_buffer_put_cstring(&b, "pam_ssh_agent_auth");
 | ||||
| -    pamsshagentauth_buffer_put_cstring(&b, "publickey");
 | ||||
| -    pamsshagentauth_buffer_put_char(&b, 1);
 | ||||
| -    pamsshagentauth_buffer_put_cstring(&b, pkalg);
 | ||||
| -    pamsshagentauth_buffer_put_string(&b, pkblob, blen);
 | ||||
| +    if ((r = sshbuf_put_string(b, sshbuf_ptr(session_id2), sshbuf_len(session_id2))) != 0 ||
 | ||||
| +        (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_TRUST_REQUEST)) != 0 ||
 | ||||
| +        (r = sshbuf_put_cstring(b, ruser)) != 0 ||
 | ||||
| +        (r = sshbuf_put_cstring(b, "pam_ssh_agent_auth")) != 0 ||
 | ||||
| +        (r = sshbuf_put_cstring(b, "publickey")) != 0 ||
 | ||||
| +        (r = sshbuf_put_u8(b, 1)) != 0 ||
 | ||||
| +        (r = sshbuf_put_cstring(b, pkalg)) != 0 ||
 | ||||
| +        (r = sshbuf_put_string(b, pkblob, blen)) != 0)
 | ||||
| +        fatal("%s: buffer error: %s", __func__, ssh_err(r));
 | ||||
|   | ||||
| -    if(ssh_agent_sign(id->ac, id->key, &sig, &slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) != 0)
 | ||||
| +    if (ssh_agent_sign(id->ac, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b)) != 0)
 | ||||
|          goto user_auth_clean_exit; | ||||
|   | ||||
|      /* test for correct signature */ | ||||
| -    if(pamsshagentauth_key_verify(id->key, sig, slen, pamsshagentauth_buffer_ptr(&b), pamsshagentauth_buffer_len(&b)) == 1)
 | ||||
| +    if (sshkey_verify(id->key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), NULL, 0, NULL) == 0)
 | ||||
|          authenticated = 1; | ||||
|   | ||||
|    user_auth_clean_exit: | ||||
|      /* if(&b != NULL) */ | ||||
| -    pamsshagentauth_buffer_free(&b);
 | ||||
| +    sshbuf_free(b);
 | ||||
| +  user_auth_clean_exit_without_buffer:
 | ||||
|      if(sig != NULL) | ||||
| -        pamsshagentauth_xfree(sig);
 | ||||
| +        free(sig);
 | ||||
|      if(pkblob != NULL) | ||||
| -        pamsshagentauth_xfree(pkblob);
 | ||||
| +        free(pkblob);
 | ||||
|      CRYPTO_cleanup_all_ex_data(); | ||||
|      return authenticated; | ||||
|  } | ||||
| 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-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-pam_ssh_agent_auth-0.10.4/userauth_pubkey_from_id.h	2020-09-23 10:52:16.424001475 +0200
 | ||||
| @@ -31,7 +31,7 @@
 | ||||
|  #ifndef _USERAUTH_PUBKEY_FROM_ID_H | ||||
|  #define _USERAUTH_PUBKEY_FROM_ID_H | ||||
|   | ||||
| -#include <identity.h>
 | ||||
| -int userauth_pubkey_from_id(const char *, Identity *, Buffer *);
 | ||||
| +#include "identity.h"
 | ||||
| +int userauth_pubkey_from_id(const char *, Identity *, struct sshbuf *);
 | ||||
|   | ||||
|  #endif | ||||
| 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-pam_ssh_agent_auth-0.10.4/uuencode.c.psaa-compat	2019-07-08 18:36:13.000000000 +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
 | ||||
|  	/* and remove trailing whitespace because __b64_pton needs this */ | ||||
|  	*p = '\0'; | ||||
|  	len = pamsshagentauth___b64_pton(encoded, target, targsize); | ||||
| -	pamsshagentauth_xfree(encoded);
 | ||||
| +	xfree(encoded);
 | ||||
|  	return len; | ||||
|  } | ||||
|   | ||||
| @@ -70,7 +70,7 @@ pamsshagentauth_dump_base64(FILE *fp, co
 | ||||
|  		fprintf(fp, "dump_base64: len > 65536\n"); | ||||
|  		return; | ||||
|  	} | ||||
| -	buf = pamsshagentauth_xmalloc(2*len);
 | ||||
| +	buf = malloc(2*len);
 | ||||
|  	n = pamsshagentauth_uuencode(data, len, buf, 2*len); | ||||
|  	for (i = 0; i < n; i++) { | ||||
|  		fprintf(fp, "%c", buf[i]); | ||||
| @@ -79,5 +79,5 @@ pamsshagentauth_dump_base64(FILE *fp, co
 | ||||
|  	} | ||||
|  	if (i % 70 != 69) | ||||
|  		fprintf(fp, "\n"); | ||||
| -	pamsshagentauth_xfree(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); | ||||
|      } | ||||
							
								
								
									
										20
									
								
								SOURCES/pam_ssh_agent_auth-0.10.2-dereference.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								SOURCES/pam_ssh_agent_auth-0.10.2-dereference.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| diff --git a/pam_ssh_agent_auth-0.10.2/pam_user_authorized_keys.c b/pam_ssh_agent_auth-0.10.2/pam_user_authorized_keys.c
 | ||||
| --- a/pam_ssh_agent_auth-0.10.2/pam_user_authorized_keys.c
 | ||||
| +++ b/pam_ssh_agent_auth-0.10.2/pam_user_authorized_keys.c
 | ||||
| @@ -158,11 +158,12 @@ parse_authorized_key_file(const char *user,
 | ||||
|  int | ||||
|  pam_user_key_allowed(const char *ruser, struct sshkey * key) | ||||
|  { | ||||
| +    struct passwd *pw;
 | ||||
|      return | ||||
| -        pamsshagentauth_user_key_allowed2(getpwuid(authorized_keys_file_allowed_owner_uid),
 | ||||
| -                                          key, authorized_keys_file)
 | ||||
| -        || pamsshagentauth_user_key_allowed2(getpwuid(0), key,
 | ||||
| -                                             authorized_keys_file)
 | ||||
| +        ( (pw = getpwuid(authorized_keys_file_allowed_owner_uid)) &&
 | ||||
| +            pamsshagentauth_user_key_allowed2(pw, key, authorized_keys_file))
 | ||||
| +        || ((pw = getpwuid(0)) &&
 | ||||
| +            pamsshagentauth_user_key_allowed2(pw, key, authorized_keys_file))
 | ||||
|          || pamsshagentauth_user_key_command_allowed2(authorized_keys_command, | ||||
|                                                       authorized_keys_command_user, | ||||
|                                                       getpwnam(ruser), key); | ||||
							
								
								
									
										37
									
								
								SOURCES/pam_ssh_agent_auth-0.10.3-seteuid.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								SOURCES/pam_ssh_agent_auth-0.10.3-seteuid.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-seteuid openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c
 | ||||
| --- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-seteuid	2017-02-07 15:41:53.172334151 +0100
 | ||||
| +++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c	2017-02-07 15:41:53.174334149 +0100
 | ||||
| @@ -238,17 +238,26 @@ ssh_get_authentication_socket_for_uid(ui
 | ||||
|  	} | ||||
|   | ||||
|  	errno = 0;  | ||||
| -	seteuid(uid); /* To ensure a race condition is not used to circumvent the stat
 | ||||
| -	             above, we will temporarily drop UID to the caller */
 | ||||
| -	if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) {
 | ||||
| +	/* To ensure a race condition is not used to circumvent the stat
 | ||||
| +	   above, we will temporarily drop UID to the caller */
 | ||||
| +	if (seteuid(uid) == -1) {
 | ||||
|  		close(sock); | ||||
| -        if(errno == EACCES)
 | ||||
| -		fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid);
 | ||||
| +		error("seteuid(%lu) failed with error: %s",
 | ||||
| +		    (unsigned long) uid, strerror(errno));
 | ||||
|  		return -1; | ||||
|  	} | ||||
| +	if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) {
 | ||||
| +		close(sock);
 | ||||
| +		sock = -1;
 | ||||
| +		if(errno == EACCES)
 | ||||
| +			fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid);
 | ||||
| +	}
 | ||||
|   | ||||
| -	seteuid(0); /* we now continue the regularly scheduled programming */
 | ||||
| -
 | ||||
| +	/* we now continue the regularly scheduled programming */
 | ||||
| +	if (0 != seteuid(0)) {
 | ||||
| +		fatal("setuid(0) failed with error: %s", strerror(errno));
 | ||||
| +		return -1;
 | ||||
| +	}
 | ||||
|  	return sock; | ||||
|  } | ||||
|   | ||||
							
								
								
									
										21
									
								
								SOURCES/pam_ssh_agent_auth-0.9.2-visibility.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								SOURCES/pam_ssh_agent_auth-0.9.2-visibility.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| diff -up openssh-7.1p2/pam_ssh_agent_auth-0.10.2/pam_ssh_agent_auth.c.psaa-visibility openssh-7.1p2/pam_ssh_agent_auth-0.10.2/pam_ssh_agent_auth.c
 | ||||
| --- openssh-7.1p2/pam_ssh_agent_auth-0.10.2/pam_ssh_agent_auth.c.psaa-visibility	2014-03-31 19:35:17.000000000 +0200
 | ||||
| +++ openssh-7.1p2/pam_ssh_agent_auth-0.10.2/pam_ssh_agent_auth.c	2016-01-22 15:22:40.984469774 +0100
 | ||||
| @@ -72,7 +72,7 @@ char           *__progname;
 | ||||
|  extern char    *__progname; | ||||
|  #endif | ||||
|   | ||||
| -PAM_EXTERN int
 | ||||
| +PAM_EXTERN int __attribute__ ((visibility ("default")))
 | ||||
|  pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv) | ||||
|  { | ||||
|      char          **argv_ptr; | ||||
| @@ -214,7 +214,7 @@ cleanexit:
 | ||||
|  } | ||||
|   | ||||
|   | ||||
| -PAM_EXTERN int
 | ||||
| +PAM_EXTERN int __attribute__ ((visibility ("default")))
 | ||||
|  pam_sm_setcred(pam_handle_t * pamh, int flags, int argc, const char **argv) | ||||
|  { | ||||
|      UNUSED(pamh); | ||||
							
								
								
									
										96
									
								
								SOURCES/pam_ssh_agent_auth-0.9.3-agent_structure.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								SOURCES/pam_ssh_agent_auth-0.9.3-agent_structure.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | ||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/identity.h
 | ||||
| --- openssh/pam_ssh_agent_auth-0.10.3/identity.h.psaa-agent	2016-11-13 04:24:32.000000000 +0100
 | ||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/identity.h	2017-09-27 14:25:49.421739027 +0200
 | ||||
| @@ -38,6 +38,12 @@
 | ||||
|  typedef struct identity Identity; | ||||
|  typedef struct idlist Idlist; | ||||
|   | ||||
| +typedef struct {
 | ||||
| +       int     fd;
 | ||||
| +       struct sshbuf *identities;
 | ||||
| +       int     howmany;
 | ||||
| +}      AuthenticationConnection;
 | ||||
| +
 | ||||
|  struct identity { | ||||
|      TAILQ_ENTRY(identity) next; | ||||
|      AuthenticationConnection *ac;   /* set if agent supports key */ | ||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c
 | ||||
| --- openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-agent	2017-09-27 14:25:49.420739021 +0200
 | ||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c	2017-09-27 14:25:49.421739027 +0200
 | ||||
| @@ -39,6 +39,7 @@
 | ||||
|  #include "sshbuf.h" | ||||
|  #include "sshkey.h" | ||||
|  #include "authfd.h" | ||||
| +#include "ssherr.h"
 | ||||
|  #include <stdio.h> | ||||
|  #include <openssl/evp.h> | ||||
|  #include "ssh2.h" | ||||
| @@ -291,36 +292,43 @@ pamsshagentauth_find_authorized_keys(con
 | ||||
|  { | ||||
|      struct sshbuf *session_id2 = NULL; | ||||
|      Identity *id; | ||||
| -    struct sshkey *key;
 | ||||
|      AuthenticationConnection *ac; | ||||
| -    char *comment;
 | ||||
|      uint8_t retval = 0; | ||||
|      uid_t uid = getpwnam(ruser)->pw_uid; | ||||
| +    struct ssh_identitylist *idlist;
 | ||||
| +    int r;
 | ||||
| +    unsigned int i;
 | ||||
|   | ||||
|      OpenSSL_add_all_digests(); | ||||
|      pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename); | ||||
|   | ||||
|      if ((ac = ssh_get_authentication_connection_for_uid(uid))) { | ||||
|          verbose("Contacted ssh-agent of user %s (%u)", ruser, uid); | ||||
| -        for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2)) 
 | ||||
| -        {
 | ||||
| -            if(key != NULL) {
 | ||||
| +        if ((r = ssh_fetch_identitylist(ac->fd, &idlist)) != 0) {
 | ||||
| +            if (r != SSH_ERR_AGENT_NO_IDENTITIES)
 | ||||
| +               fprintf(stderr, "error fetching identities for "
 | ||||
| +                               "protocol %d: %s\n", 2, ssh_err(r));
 | ||||
| +        } else {
 | ||||
| +            for (i = 0; i < idlist->nkeys; i++)
 | ||||
| +            {
 | ||||
| +              if (idlist->keys[i] != NULL) {
 | ||||
|                  id = xcalloc(1, sizeof(*id)); | ||||
| -                id->key = key;
 | ||||
| -                id->filename = comment;
 | ||||
| +                id->key = idlist->keys[i];
 | ||||
| +                id->filename = idlist->comments[i];
 | ||||
|                  id->ac = ac; | ||||
|                  if(userauth_pubkey_from_id(ruser, id, session_id2)) { | ||||
|                      retval = 1; | ||||
|                  } | ||||
| -                free(id->filename);
 | ||||
| -                key_free(id->key);
 | ||||
|                  free(id); | ||||
|                  if(retval == 1) | ||||
|                      break; | ||||
| -            }
 | ||||
| -        }
 | ||||
| +              }
 | ||||
| +            }
 | ||||
| -        sshbuf_free(session_id2);
 | ||||
| -        ssh_close_authentication_connection(ac);
 | ||||
| +            sshbuf_free(session_id2);
 | ||||
| +            ssh_free_identitylist(idlist);
 | ||||
| +        }
 | ||||
| +        ssh_close_authentication_socket(ac->fd);
 | ||||
| +        free(ac);
 | ||||
|      } | ||||
|      else { | ||||
|          verbose("No ssh-agent could be contacted"); | ||||
| diff -up openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-agent openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c
 | ||||
| --- openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c.psaa-agent	2017-09-27 14:25:49.420739021 +0200
 | ||||
| +++ openssh/pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c	2017-09-27 14:25:49.422739032 +0200
 | ||||
| @@ -84,7 +85,7 @@ 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, id->key, &sig, &slen, sshbuf_ptr(b), sshbuf_len(b)) != 0)
 | ||||
| +    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 */ | ||||
							
								
								
									
										198
									
								
								SOURCES/pam_ssh_agent_auth-0.9.3-build.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								SOURCES/pam_ssh_agent_auth-0.9.3-build.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,198 @@ | ||||
| diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-build openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c
 | ||||
| --- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c.psaa-build	2016-11-13 04:24:32.000000000 +0100
 | ||||
| +++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c	2017-02-07 14:29:41.626116675 +0100
 | ||||
| @@ -43,12 +43,31 @@
 | ||||
|  #include <openssl/evp.h> | ||||
|  #include "ssh2.h" | ||||
|  #include "misc.h" | ||||
| +#include "ssh.h"
 | ||||
| +#include <sys/types.h>
 | ||||
| +#include <sys/stat.h>
 | ||||
| +#include <sys/socket.h>
 | ||||
| +#include <sys/un.h>
 | ||||
| +#include <unistd.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <errno.h>
 | ||||
| +#include <fcntl.h>
 | ||||
|   | ||||
|  #include "userauth_pubkey_from_id.h" | ||||
|  #include "identity.h" | ||||
|  #include "get_command_line.h" | ||||
|  extern char **environ; | ||||
|   | ||||
| +/* 
 | ||||
| + * Added by Jamie Beverly, ensure socket fd points to a socket owned by the user 
 | ||||
| + * A cursory check is done, but to avoid race conditions, it is necessary 
 | ||||
| + * to drop effective UID when connecting to the socket. 
 | ||||
| + *
 | ||||
| + * If the cause of error is EACCES, because we verified we would not have that 
 | ||||
| + * problem initially, we can safely assume that somebody is attempting to find a 
 | ||||
| + * race condition; so a more "direct" log message is generated.
 | ||||
| + */
 | ||||
| +
 | ||||
|  static char * | ||||
|  log_action(char ** action, size_t count) | ||||
|  { | ||||
| @@ -85,7 +104,7 @@ void
 | ||||
|  pamsshagentauth_session_id2_gen(Buffer * session_id2, const char * user, | ||||
|                                  const char * ruser, const char * servicename) | ||||
|  { | ||||
| -    char *cookie = NULL;
 | ||||
| +    u_char *cookie = NULL;
 | ||||
|      uint8_t i = 0; | ||||
|      uint32_t rnd = 0; | ||||
|      uint8_t cookie_len; | ||||
| @@ -112,7 +131,7 @@ pamsshagentauth_session_id2_gen(Buffer *
 | ||||
|          if (i % 4 == 0) { | ||||
|              rnd = pamsshagentauth_arc4random(); | ||||
|          } | ||||
| -        cookie[i] = (char) rnd;
 | ||||
| +        cookie[i] = (u_char) rnd;
 | ||||
|          rnd >>= 8; | ||||
|      } | ||||
|   | ||||
| @@ -177,6 +196,86 @@ pamsshagentauth_session_id2_gen(Buffer *
 | ||||
|  } | ||||
|   | ||||
|  int | ||||
| +ssh_get_authentication_socket_for_uid(uid_t uid)
 | ||||
| +{
 | ||||
| +	const char *authsocket;
 | ||||
| +	int sock;
 | ||||
| +	struct sockaddr_un sunaddr;
 | ||||
| +	struct stat sock_st;
 | ||||
| +
 | ||||
| +	authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
 | ||||
| +	if (!authsocket)
 | ||||
| +		return -1;
 | ||||
| +
 | ||||
| +	/* Advisory only; seteuid ensures no race condition; but will only log if we see EACCES */
 | ||||
| +	if( stat(authsocket,&sock_st) == 0) {
 | ||||
| +		if(uid != 0 && sock_st.st_uid != uid) {
 | ||||
| +			fatal("uid %lu attempted to open an agent socket owned by uid %lu", (unsigned long) uid, (unsigned long) sock_st.st_uid);
 | ||||
| +			return -1;
 | ||||
| +		}
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	/* 
 | ||||
| +	 * Ensures that the EACCES tested for below can _only_ happen if somebody 
 | ||||
| +	 * is attempting to race the stat above to bypass authentication.
 | ||||
| +	 */
 | ||||
| +	if( (sock_st.st_mode & S_IWUSR) != S_IWUSR || (sock_st.st_mode & S_IRUSR) != S_IRUSR) {
 | ||||
| +		error("ssh-agent socket has incorrect permissions for owner");
 | ||||
| +		return -1;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	sunaddr.sun_family = AF_UNIX;
 | ||||
| +	strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
 | ||||
| +
 | ||||
| +	sock = socket(AF_UNIX, SOCK_STREAM, 0);
 | ||||
| +	if (sock < 0)
 | ||||
| +		return -1;
 | ||||
| +
 | ||||
| +	/* close on exec */
 | ||||
| +	if (fcntl(sock, F_SETFD, 1) == -1) {
 | ||||
| +		close(sock);
 | ||||
| +		return -1;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	errno = 0; 
 | ||||
| +	seteuid(uid); /* To ensure a race condition is not used to circumvent the stat
 | ||||
| +	             above, we will temporarily drop UID to the caller */
 | ||||
| +	if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) {
 | ||||
| +		close(sock);
 | ||||
| +        if(errno == EACCES)
 | ||||
| +		fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid);
 | ||||
| +		return -1;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	seteuid(0); /* we now continue the regularly scheduled programming */
 | ||||
| +
 | ||||
| +	return sock;
 | ||||
| +}
 | ||||
| +
 | ||||
| +AuthenticationConnection *
 | ||||
| +ssh_get_authentication_connection_for_uid(uid_t uid)
 | ||||
| +{
 | ||||
| +	AuthenticationConnection *auth;
 | ||||
| +	int sock;
 | ||||
| +
 | ||||
| +	sock = ssh_get_authentication_socket_for_uid(uid);
 | ||||
| +
 | ||||
| +	/*
 | ||||
| +	 * Fail if we couldn't obtain a connection.  This happens if we
 | ||||
| +	 * exited due to a timeout.
 | ||||
| +	 */
 | ||||
| +	if (sock < 0)
 | ||||
| +		return NULL;
 | ||||
| +
 | ||||
| +	auth = xmalloc(sizeof(*auth));
 | ||||
| +	auth->fd = sock;
 | ||||
| +	buffer_init(&auth->identities);
 | ||||
| +	auth->howmany = 0;
 | ||||
| +
 | ||||
| +	return auth;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
|  pamsshagentauth_find_authorized_keys(const char * user, const char * ruser, const char * servicename) | ||||
|  { | ||||
|      Buffer session_id2 = { 0 }; | ||||
| @@ -190,7 +289,7 @@ pamsshagentauth_find_authorized_keys(con
 | ||||
|      OpenSSL_add_all_digests(); | ||||
|      pamsshagentauth_session_id2_gen(&session_id2, user, ruser, servicename); | ||||
|   | ||||
| -    if ((ac = ssh_get_authentication_connection(uid))) {
 | ||||
| +    if ((ac = ssh_get_authentication_connection_for_uid(uid))) {
 | ||||
|          pamsshagentauth_verbose("Contacted ssh-agent of user %s (%u)", ruser, uid); | ||||
|          for (key = ssh_get_first_identity(ac, &comment, 2); key != NULL; key = ssh_get_next_identity(ac, &comment, 2))  | ||||
|          { | ||||
| diff -up openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in.psaa-build openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in
 | ||||
| --- openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in.psaa-build	2016-11-13 04:24:32.000000000 +0100
 | ||||
| +++ openssh-7.4p1/pam_ssh_agent_auth-0.10.3/Makefile.in	2017-02-07 14:40:14.407566921 +0100
 | ||||
| @@ -52,7 +52,7 @@ PATHS=
 | ||||
|  CC=@CC@ | ||||
|  LD=@LD@ | ||||
|  CFLAGS=@CFLAGS@ | ||||
| -CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
 | ||||
| +CPPFLAGS=-I.. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
 | ||||
|  LIBS=@LIBS@ | ||||
|  AR=@AR@ | ||||
|  AWK=@AWK@ | ||||
| @@ -61,8 +61,8 @@ INSTALL=@INSTALL@
 | ||||
|  PERL=@PERL@ | ||||
|  SED=@SED@ | ||||
|  ENT=@ENT@ | ||||
| -LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
 | ||||
| -LDFLAGS_SHARED = @LDFLAGS_SHARED@
 | ||||
| +LDFLAGS=-L.. -L../openbsd-compat/ @LDFLAGS@
 | ||||
| +LDFLAGS_SHARED =-Wl,-z,defs @LDFLAGS_SHARED@
 | ||||
|  EXEEXT=@EXEEXT@ | ||||
|   | ||||
|  INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ | ||||
| @@ -74,7 +74,7 @@ SSHOBJS=xmalloc.o atomicio.o authfd.o bu
 | ||||
|   | ||||
|  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 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 userauth_pubkey_from_pam.o secure_filename.o
 | ||||
|   | ||||
|   | ||||
|  MANPAGES_IN	= pam_ssh_agent_auth.pod | ||||
| @@ -94,13 +94,13 @@ $(PAM_MODULES): Makefile.in config.h
 | ||||
|  .c.o: | ||||
|  	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ | ||||
|   | ||||
| -LIBCOMPAT=openbsd-compat/libopenbsd-compat.a
 | ||||
| +LIBCOMPAT=../openbsd-compat/libopenbsd-compat.a
 | ||||
|  $(LIBCOMPAT): always | ||||
|  	(cd openbsd-compat && $(MAKE)) | ||||
|  always: | ||||
|   | ||||
| -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
 | ||||
| +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) ../ssh-sk-client.o $(LDFLAGS) -lssh -lopenbsd-compat pam_ssh_agent_auth.o ../uidswap.o $(LIBS) -lpam
 | ||||
|   | ||||
|  $(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 | ||||
							
								
								
									
										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 | ||||
							
								
								
									
										8
									
								
								SOURCES/ssh-keycat.pam
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								SOURCES/ssh-keycat.pam
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| #%PAM-1.0 | ||||
| # pam_selinux.so close should be the first session rule | ||||
| session    required     pam_selinux.so close | ||||
| session    required     pam_loginuid.so | ||||
| # pam_selinux.so open should only be followed by sessions to be executed in the user context | ||||
| session    required     pam_selinux.so open env_params | ||||
| session    required     pam_namespace.so | ||||
| 
 | ||||
							
								
								
									
										40
									
								
								SOURCES/sshd-keygen
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								SOURCES/sshd-keygen
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| #!/bin/bash | ||||
| 
 | ||||
| # Create the host keys for the OpenSSH server. | ||||
| KEYTYPE=$1 | ||||
| case $KEYTYPE in | ||||
| 	"dsa") ;& # disabled in FIPS | ||||
| 	"ed25519") | ||||
| 		FIPS=/proc/sys/crypto/fips_enabled | ||||
| 		if [[ -r "$FIPS" && $(cat $FIPS) == "1" ]]; then | ||||
| 			exit 0 | ||||
| 		fi ;; | ||||
| 	"rsa") ;; # always ok | ||||
| 	"ecdsa") ;; | ||||
| 	*) # wrong argument | ||||
| 		exit 12 ;; | ||||
| esac | ||||
| KEY=/etc/ssh/ssh_host_${KEYTYPE}_key | ||||
| 
 | ||||
| KEYGEN=/usr/bin/ssh-keygen | ||||
| if [[ ! -x $KEYGEN ]]; then | ||||
| 	exit 13 | ||||
| fi | ||||
| 
 | ||||
| # remove old keys | ||||
| rm -f $KEY{,.pub} | ||||
| 
 | ||||
| # create new keys | ||||
| if ! $KEYGEN -q -t $KEYTYPE -f $KEY -C '' -N '' >&/dev/null; then | ||||
| 	exit 1 | ||||
| fi | ||||
| 
 | ||||
| # sanitize permissions | ||||
| /usr/bin/chgrp ssh_keys $KEY | ||||
| /usr/bin/chmod 640 $KEY | ||||
| /usr/bin/chmod 644 $KEY.pub | ||||
| if [[ -x /usr/sbin/restorecon ]]; then | ||||
| 	/usr/sbin/restorecon $KEY{,.pub} | ||||
| fi | ||||
| 
 | ||||
| exit 0 | ||||
							
								
								
									
										5
									
								
								SOURCES/sshd-keygen.target
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								SOURCES/sshd-keygen.target
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| [Unit] | ||||
| Wants=sshd-keygen@rsa.service | ||||
| Wants=sshd-keygen@ecdsa.service | ||||
| Wants=sshd-keygen@ed25519.service | ||||
| PartOf=sshd.service | ||||
							
								
								
									
										11
									
								
								SOURCES/sshd-keygen@.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								SOURCES/sshd-keygen@.service
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| [Unit] | ||||
| Description=OpenSSH %i Server Key Generation | ||||
| ConditionFileNotEmpty=|!/etc/ssh/ssh_host_%i_key | ||||
| 
 | ||||
| [Service] | ||||
| Type=oneshot | ||||
| EnvironmentFile=-/etc/sysconfig/sshd | ||||
| ExecStart=/usr/libexec/openssh/sshd-keygen %i | ||||
| 
 | ||||
| [Install] | ||||
| WantedBy=sshd-keygen.target | ||||
							
								
								
									
										17
									
								
								SOURCES/sshd.pam
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								SOURCES/sshd.pam
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| #%PAM-1.0 | ||||
| auth       substack     password-auth | ||||
| auth       include      postlogin | ||||
| account    required     pam_sepermit.so | ||||
| account    required     pam_nologin.so | ||||
| account    include      password-auth | ||||
| password   include      password-auth | ||||
| # pam_selinux.so close should be the first session rule | ||||
| session    required     pam_selinux.so close | ||||
| session    required     pam_loginuid.so | ||||
| # pam_selinux.so open should only be followed by sessions to be executed in the user context | ||||
| session    required     pam_selinux.so open env_params | ||||
| session    required     pam_namespace.so | ||||
| session    optional     pam_keyinit.so force revoke | ||||
| session    optional     pam_motd.so | ||||
| session    include      password-auth | ||||
| session    include      postlogin | ||||
							
								
								
									
										17
									
								
								SOURCES/sshd.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								SOURCES/sshd.service
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| [Unit] | ||||
| Description=OpenSSH server daemon | ||||
| Documentation=man:sshd(8) man:sshd_config(5) | ||||
| After=network.target sshd-keygen.target | ||||
| Wants=sshd-keygen.target | ||||
| 
 | ||||
| [Service] | ||||
| Type=notify | ||||
| EnvironmentFile=-/etc/sysconfig/sshd | ||||
| ExecStart=/usr/sbin/sshd -D $OPTIONS | ||||
| ExecReload=/bin/kill -HUP $MAINPID | ||||
| KillMode=process | ||||
| Restart=on-failure | ||||
| RestartSec=42s | ||||
| 
 | ||||
| [Install] | ||||
| WantedBy=multi-user.target | ||||
							
								
								
									
										11
									
								
								SOURCES/sshd.socket
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								SOURCES/sshd.socket
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| [Unit] | ||||
| Description=OpenSSH Server Socket | ||||
| Documentation=man:sshd(8) man:sshd_config(5) | ||||
| Conflicts=sshd.service | ||||
| 
 | ||||
| [Socket] | ||||
| ListenStream=22 | ||||
| Accept=yes | ||||
| 
 | ||||
| [Install] | ||||
| WantedBy=sockets.target | ||||
							
								
								
									
										7
									
								
								SOURCES/sshd.sysconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								SOURCES/sshd.sysconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| # Configuration file for the sshd service. | ||||
| 
 | ||||
| # The server keys are automatically generated if they are missing. | ||||
| # To change the automatic creation, adjust sshd.service options for | ||||
| # 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 | ||||
| # creation. | ||||
							
								
								
									
										10
									
								
								SOURCES/sshd@.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								SOURCES/sshd@.service
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| [Unit] | ||||
| Description=OpenSSH per-connection server daemon | ||||
| Documentation=man:sshd(8) man:sshd_config(5) | ||||
| Wants=sshd-keygen.target | ||||
| After=sshd-keygen.target | ||||
| 
 | ||||
| [Service] | ||||
| EnvironmentFile=-/etc/sysconfig/sshd | ||||
| ExecStart=-/usr/sbin/sshd -i $OPTIONS | ||||
| StandardInput=socket | ||||
							
								
								
									
										2920
									
								
								SPECS/openssh.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2920
									
								
								SPECS/openssh.spec
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user