1 /* 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "includes.h" 35 RCSID("$OpenBSD: readpass.c,v 1.15 2001/04/18 21:57:41 markus Exp $"); 36 37 #include "xmalloc.h" 38 #include "cli.h" 39 #include "readpass.h" 40 #include "pathnames.h" 41 #include "log.h" 42 #include "atomicio.h" 43 #include "ssh.h" 44 45 char * 46 ssh_askpass(char *askpass, char *msg) 47 { 48 pid_t pid; 49 size_t len; 50 char *nl, *pass; 51 int p[2], status; 52 char buf[1024]; 53 54 if (fflush(stdout) != 0) 55 error("ssh_askpass: fflush: %s", strerror(errno)); 56 if (askpass == NULL) 57 fatal("internal error: askpass undefined"); 58 if (pipe(p) < 0) 59 fatal("ssh_askpass: pipe: %s", strerror(errno)); 60 if ((pid = fork()) < 0) 61 fatal("ssh_askpass: fork: %s", strerror(errno)); 62 if (pid == 0) { 63 seteuid(getuid()); 64 setuid(getuid()); 65 close(p[0]); 66 if (dup2(p[1], STDOUT_FILENO) < 0) 67 fatal("ssh_askpass: dup2: %s", strerror(errno)); 68 execlp(askpass, askpass, msg, (char *) 0); 69 fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno)); 70 } 71 close(p[1]); 72 len = read(p[0], buf, sizeof buf); 73 close(p[0]); 74 while (waitpid(pid, &status, 0) < 0) 75 if (errno != EINTR) 76 break; 77 if (len <= 1) 78 return xstrdup(""); 79 nl = strchr(buf, '\n'); 80 if (nl) 81 *nl = '\0'; 82 pass = xstrdup(buf); 83 memset(buf, 0, sizeof(buf)); 84 return pass; 85 } 86 87 88 /* 89 * Reads a passphrase from /dev/tty with echo turned off. Returns the 90 * passphrase (allocated with xmalloc), being very careful to ensure that 91 * no other userland buffer is storing the password. 92 */ 93 /* 94 * Note: the funcationallity of this routing has been moved to 95 * cli_read_passphrase(). This routing remains to maintain 96 * compatibility with existing code. 97 */ 98 char * 99 read_passphrase(char *prompt, int from_stdin) 100 { 101 char *askpass = NULL; 102 int use_askpass = 0, ttyfd; 103 104 if (from_stdin) { 105 if (!isatty(STDIN_FILENO)) 106 use_askpass = 1; 107 } else { 108 ttyfd = open("/dev/tty", O_RDWR); 109 if (ttyfd >= 0) 110 close(ttyfd); 111 else 112 use_askpass = 1; 113 } 114 115 if (use_askpass && getenv("DISPLAY")) { 116 if (getenv(SSH_ASKPASS_ENV)) 117 askpass = getenv(SSH_ASKPASS_ENV); 118 else 119 askpass = _PATH_SSH_ASKPASS_DEFAULT; 120 return ssh_askpass(askpass, prompt); 121 } 122 123 return cli_read_passphrase(prompt, from_stdin, 0); 124 } 125