[openssh-commits] [openssh] 01/01: upstream: Add server support for signalling sessions via the SSH

git+noreply at mindrot.org git+noreply at mindrot.org
Tue Oct 2 22:41:10 AEST 2018


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit cd98925c6405e972dc9f211afc7e75e838abe81c
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Tue Oct 2 12:40:07 2018 +0000

    upstream: Add server support for signalling sessions via the SSH
    
    channel/ session protocol. Signalling is only supported to sesssions that are
    not subsystems and were not started with a forced command.
    
    Long requested in bz#1424
    
    Based on a patch from markus@ and reworked by dtucker@;
    ok markus@ dtucker@
    
    OpenBSD-Commit-ID: 4bea826f575862eaac569c4bedd1056a268be1c3
---
 session.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 session.h |  3 ++-
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/session.c b/session.c
index f2cf5200..63adc68c 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.305 2018/07/25 13:56:23 deraadt Exp $ */
+/* $OpenBSD: session.c,v 1.306 2018/10/02 12:40:07 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -705,7 +705,9 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
 		command = auth_opts->force_command;
 		forced = "(key-option)";
 	}
+	s->forced = 0;
 	if (forced != NULL) {
+		s->forced = 1;
 		if (IS_INTERNAL_SFTP(command)) {
 			s->is_subsystem = s->is_subsystem ?
 			    SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
@@ -2101,6 +2103,76 @@ session_env_req(struct ssh *ssh, Session *s)
 	return (0);
 }
 
+/*
+ * Conversion of signals from ssh channel request names.
+ * Subset of signals from RFC 4254 section 6.10C, with SIGINFO as
+ * local extension.
+ */
+static int
+name2sig(char *name)
+{
+#define SSH_SIG(x) if (strcmp(name, #x) == 0) return SIG ## x
+	SSH_SIG(HUP);
+	SSH_SIG(INT);
+	SSH_SIG(KILL);
+	SSH_SIG(QUIT);
+	SSH_SIG(TERM);
+	SSH_SIG(USR1);
+	SSH_SIG(USR2);
+#undef	SSH_SIG
+	if (strcmp(name, "INFO at openssh.com") == 0)
+		return SIGINFO;
+	return -1;
+}
+
+static int
+session_signal_req(struct ssh *ssh, Session *s)
+{
+	char *signame = NULL;
+	int r, sig, success = 0;
+
+	if ((r = sshpkt_get_cstring(ssh, &signame, NULL)) != 0 ||
+	    (r = sshpkt_get_end(ssh)) != 0) {
+		error("%s: parse packet: %s", __func__, ssh_err(r));
+		goto out;
+	}
+	if ((sig = name2sig(signame)) == -1) {
+		error("%s: unsupported signal \"%s\"", __func__, signame);
+		goto out;
+	}
+	if (s->pid <= 0) {
+		error("%s: no pid for session %d", __func__, s->self);
+		goto out;
+	}
+	if (s->forced || s->is_subsystem) {
+		error("%s: refusing to send signal %s to %s session", __func__,
+		    signame, s->forced ? "forced-command" : "subsystem");
+		goto out;
+	}
+	if (!use_privsep || mm_is_monitor()) {
+		error("%s: session signalling requires privilege separation",
+		    __func__);
+		goto out;
+	}
+
+	debug("%s: signal %s, killpg(%ld, %d)", __func__, signame,
+	    (long)s->pid, sig);
+	temporarily_use_uid(s->pw);
+	r = killpg(s->pid, sig);
+	restore_uid();
+	if (r != 0) {
+		error("%s: killpg(%ld, %d): %s", __func__, (long)s->pid,
+		    sig, strerror(errno));
+		goto out;
+	}
+
+	/* success */
+	success = 1;
+ out:
+	free(signame);
+	return success;
+}
+
 static int
 session_auth_agent_req(struct ssh *ssh, Session *s)
 {
@@ -2157,6 +2229,8 @@ session_input_channel_req(struct ssh *ssh, Channel *c, const char *rtype)
 		success = session_window_change_req(ssh, s);
 	} else if (strcmp(rtype, "break") == 0) {
 		success = session_break_req(ssh, s);
+	} else if (strcmp(rtype, "signal") == 0) {
+		success = session_signal_req(ssh, s);
 	}
 
 	return success;
diff --git a/session.h b/session.h
index 54dd1f0c..ce59dabd 100644
--- a/session.h
+++ b/session.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.h,v 1.35 2017/09/12 06:32:07 djm Exp $ */
+/* $OpenBSD: session.h,v 1.36 2018/10/02 12:40:07 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -35,6 +35,7 @@ struct Session {
 	struct passwd *pw;
 	Authctxt *authctxt;
 	pid_t	pid;
+	int	forced;
 
 	/* tty */
 	char	*term;

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list