* add SSH_ASKPASS support (based on patch from Paul Whittaker

* don't exit if setnonblocking() fails with "not supported by device"
  (allows redirection from /dev/null)

--HG--
extra : convert_revision : 02fb18acdb680a868b2bfbd6452b2ccdb4cdde99
This commit is contained in:
Matt Johnston
2005-02-28 13:01:00 +00:00
parent 03d78bbb31
commit 4127be0a95
3 changed files with 111 additions and 4 deletions

View File

@@ -30,13 +30,105 @@
#include "runopts.h"
#ifdef ENABLE_CLI_PASSWORD_AUTH
#ifdef ENABLE_CLI_ASKPASS_HELPER
/* Returns 1 if we want to use the askpass program, 0 otherwise */
static int want_askpass()
{
char* askpass_prog = NULL;
askpass_prog = getenv("SSH_ASKPASS");
return askpass_prog && !isatty(STDIN_FILENO) && getenv("DISPLAY");
}
/* returns a statically allocated password from a helper app, or NULL
* on failure */
static char *gui_getpass(const char *prompt) {
pid_t pid;
int p[2], maxlen, len, status;
static char buf[DROPBEAR_MAX_CLI_PASS + 1];
char* helper = NULL;
TRACE(("enter gui_getpass"))
helper = getenv("SSH_ASKPASS");
if (!helper)
{
TRACE(("leave gui_getpass: no askpass program"))
return NULL;
}
if (pipe(p) < 0) {
TRACE(("error creating child pipe"))
return NULL;
}
pid = fork();
if (pid < 0) {
TRACE(("fork error"))
return NULL;
}
if (!pid) {
/* child */
close(p[0]);
if (dup2(p[1], STDOUT_FILENO) < 0) {
TRACE(("error redirecting stdout"))
exit(1);
}
close(p[1]);
execlp(helper, helper, prompt, (char *)0);
TRACE(("execlp error"))
exit(1);
}
close(p[1]);
maxlen = sizeof(buf);
while (maxlen > 0) {
len = read(p[0], buf + sizeof(buf) - maxlen, maxlen);
if (len > 0) {
maxlen -= len;
} else {
if (errno != EINTR)
break;
}
}
close(p[0]);
while (waitpid(pid, &status, 0) < 0 && errno == EINTR)
;
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
return(NULL);
len = sizeof(buf) - maxlen;
buf[len] = '\0';
if (len > 0 && buf[len - 1] == '\n')
buf[len - 1] = '\0';
TRACE(("leave gui_getpass"))
return(buf);
}
#endif /* ENABLE_CLI_ASKPASS_HELPER */
int cli_auth_password() {
char* password = NULL;
TRACE(("enter cli_auth_password"))
TRACE(("enter cli_auth_password"))
CHECKCLEARTOWRITE();
password = getpass("Password: ");
#ifdef ENABLE_CLI_ASKPASS_HELPER
if (want_askpass())
password = gui_getpass("Password: ");
else
#endif
password = getpass("Password: ");
if (password == NULL)
return 0;
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
@@ -60,4 +152,4 @@ int cli_auth_password() {
return 1; /* Password auth can always be tried */
}
#endif
#endif /* ENABLE_CLI_PASSWORD_AUTH */