mirror of git://anongit.mindrot.org/openssh.git
upstream: dd API for performing one-shot notifications via tty or
SSH_ASKPASS OpenBSD-Commit-ID: 9484aea33aff5b62ce3642bf259546c7639f23f3
This commit is contained in:
parent
166927fd41
commit
5d1c1590d7
7
misc.h
7
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@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))
|
||||
|
|
86
readpass.c
86
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue