Mercurial > dropbear
diff cli-authpasswd.c @ 173:257f09a63dab
* 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)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 28 Feb 2005 13:01:00 +0000 |
parents | 0cfba3034be5 |
children | efbaf6b03837 |
line wrap: on
line diff
--- a/cli-authpasswd.c Mon Feb 28 10:15:16 2005 +0000 +++ b/cli-authpasswd.c Mon Feb 28 13:01:00 2005 +0000 @@ -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")) + CHECKCLEARTOWRITE(); - 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 @@ return 1; /* Password auth can always be tried */ } -#endif +#endif /* ENABLE_CLI_PASSWORD_AUTH */