[openssh-commits] [openssh] 02/05: upstream: dd API for performing one-shot notifications via tty or

git+noreply at mindrot.org git+noreply at mindrot.org
Wed Nov 13 10:15:53 AEDT 2019


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

djm pushed a commit to branch master
in repository openssh.

commit 5d1c1590d736694f41b03e686045f08fcae20d62
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Tue Nov 12 22:34:20 2019 +0000

    upstream: dd API for performing one-shot notifications via tty or
    
    SSH_ASKPASS
    
    OpenBSD-Commit-ID: 9484aea33aff5b62ce3642bf259546c7639f23f3
---
 misc.h     |  7 ++++-
 readpass.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 91 insertions(+), 2 deletions(-)

diff --git a/misc.h b/misc.h
index bcc34f98..7421fbdf 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.81 2019/09/03 08:32:11 djm Exp $ */
+/* $OpenBSD: misc.h,v 1.82 2019/11/12 22:34:20 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
@@ -178,8 +178,13 @@ int	opt_match(const char **opts, const char *term);
 #define RP_ALLOW_EOF		0x0004
 #define RP_USE_ASKPASS		0x0008
 
+struct notifier_ctx;
+
 char	*read_passphrase(const char *, int);
 int	 ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
+struct notifier_ctx *notify_start(int, const char *, ...)
+	__attribute__((format(printf, 2, 3)));
+void	notify_complete(struct notifier_ctx *);
 
 #define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
 #define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
diff --git a/readpass.c b/readpass.c
index 7e52cae9..33fc03bb 100644
--- a/readpass.c
+++ b/readpass.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readpass.c,v 1.54 2019/06/28 13:35:04 deraadt Exp $ */
+/* $OpenBSD: readpass.c,v 1.55 2019/11/12 22:34:20 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
@@ -197,3 +197,87 @@ ask_permission(const char *fmt, ...)
 
 	return (allowed);
 }
+
+struct notifier_ctx {
+	pid_t pid;
+	void (*osigchld)(int);
+};
+
+struct notifier_ctx *
+notify_start(int force_askpass, const char *fmt, ...)
+{
+	va_list args;
+	char *prompt = NULL;
+	int devnull;
+	pid_t pid;
+	void (*osigchld)(int);
+	const char *askpass;
+	struct notifier_ctx *ret;
+
+	va_start(args, fmt);
+	xvasprintf(&prompt, fmt, args);
+	va_end(args);
+
+	if (fflush(NULL) != 0)
+		error("%s: fflush: %s", __func__, strerror(errno));
+	if (!force_askpass && isatty(STDERR_FILENO)) {
+		(void)write(STDERR_FILENO, "\r", 1);
+		(void)write(STDERR_FILENO, prompt, strlen(prompt));
+		(void)write(STDERR_FILENO, "\r\n", 2);
+		free(prompt);
+		return NULL;
+	}
+	if (getenv("DISPLAY") == NULL ||
+	    (askpass = getenv("SSH_ASKPASS")) == NULL || *askpass == '\0') {
+		debug3("%s: cannot notify", __func__);
+		free(prompt);
+		return NULL;
+	}
+	osigchld = signal(SIGCHLD, SIG_DFL);
+	if ((pid = fork()) == -1) {
+		error("%s: fork: %s", __func__, strerror(errno));
+		signal(SIGCHLD, osigchld);
+		free(prompt);
+		return NULL;
+	}
+	if (pid == 0) {
+		if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
+			fatal("%s: open %s", __func__, strerror(errno));
+		if (dup2(devnull, STDIN_FILENO) == -1 ||
+		    dup2(devnull, STDOUT_FILENO) == -1)
+			fatal("%s: dup2: %s", __func__, strerror(errno));
+		closefrom(STDERR_FILENO + 1);
+		setenv("SSH_ASKPASS_PROMPT", "none", 1); /* hint to UI */
+		execlp(askpass, askpass, prompt, (char *)NULL);
+		fatal("%s: exec(%s): %s", __func__, askpass, strerror(errno));
+		/* NOTREACHED */
+	}
+	if ((ret = calloc(1, sizeof(*ret))) == NULL) {
+		kill(pid, SIGTERM);
+		fatal("%s: calloc failed", __func__);
+	}
+	ret->pid = pid;
+	ret->osigchld = osigchld;
+	free(prompt);
+	return ret;
+}
+
+void
+notify_complete(struct notifier_ctx *ctx)
+{
+	int ret;
+
+	if (ctx == NULL || ctx->pid <= 0) {
+		free(ctx);
+		return;
+	}
+	kill(ctx->pid, SIGTERM);
+	while ((ret = waitpid(ctx->pid, NULL, 0)) == -1) {
+		if (errno != EINTR)
+			break;
+	}
+	if (ret == -1)
+		fatal("%s: waitpid: %s", __func__, strerror(errno));
+	signal(SIGCHLD, ctx->osigchld);
+	free(ctx);
+}

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


More information about the openssh-commits mailing list