readpass.c revision 76259
157429Smarkm/* 257429Smarkm * Copyright (c) 1988, 1993 357429Smarkm * The Regents of the University of California. All rights reserved. 457429Smarkm * 557429Smarkm * Redistribution and use in source and binary forms, with or without 657429Smarkm * modification, are permitted provided that the following conditions 757429Smarkm * are met: 857429Smarkm * 1. Redistributions of source code must retain the above copyright 957429Smarkm * notice, this list of conditions and the following disclaimer. 1057429Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1157429Smarkm * notice, this list of conditions and the following disclaimer in the 1257429Smarkm * documentation and/or other materials provided with the distribution. 1357429Smarkm * 3. All advertising materials mentioning features or use of this software 1457429Smarkm * must display the following acknowledgement: 1557429Smarkm * This product includes software developed by the University of 1657429Smarkm * California, Berkeley and its contributors. 1757429Smarkm * 4. Neither the name of the University nor the names of its contributors 1857429Smarkm * may be used to endorse or promote products derived from this software 1957429Smarkm * without specific prior written permission. 2057429Smarkm * 2157429Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2257429Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2357429Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2457429Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2557429Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2657429Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2757429Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2857429Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2957429Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3057429Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3157429Smarkm * SUCH DAMAGE. 3257429Smarkm */ 3357429Smarkm 3457429Smarkm#include "includes.h" 3576259SgreenRCSID("$OpenBSD: readpass.c,v 1.15 2001/04/18 21:57:41 markus Exp $"); 3657429Smarkm 3757429Smarkm#include "xmalloc.h" 3876259Sgreen#include "cli.h" 3976259Sgreen#include "readpass.h" 4076259Sgreen#include "pathnames.h" 4176259Sgreen#include "log.h" 4276259Sgreen#include "atomicio.h" 4357429Smarkm#include "ssh.h" 4457429Smarkm 4576259Sgreenchar * 4676259Sgreenssh_askpass(char *askpass, char *msg) 4776259Sgreen{ 4876259Sgreen pid_t pid; 4976259Sgreen size_t len; 5076259Sgreen char *nl, *pass; 5176259Sgreen int p[2], status; 5276259Sgreen char buf[1024]; 5376259Sgreen 5476259Sgreen if (fflush(stdout) != 0) 5576259Sgreen error("ssh_askpass: fflush: %s", strerror(errno)); 5676259Sgreen if (askpass == NULL) 5776259Sgreen fatal("internal error: askpass undefined"); 5876259Sgreen if (pipe(p) < 0) 5976259Sgreen fatal("ssh_askpass: pipe: %s", strerror(errno)); 6076259Sgreen if ((pid = fork()) < 0) 6176259Sgreen fatal("ssh_askpass: fork: %s", strerror(errno)); 6276259Sgreen if (pid == 0) { 6376259Sgreen seteuid(getuid()); 6476259Sgreen setuid(getuid()); 6576259Sgreen close(p[0]); 6676259Sgreen if (dup2(p[1], STDOUT_FILENO) < 0) 6776259Sgreen fatal("ssh_askpass: dup2: %s", strerror(errno)); 6876259Sgreen execlp(askpass, askpass, msg, (char *) 0); 6976259Sgreen fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno)); 7076259Sgreen } 7176259Sgreen close(p[1]); 7276259Sgreen len = read(p[0], buf, sizeof buf); 7376259Sgreen close(p[0]); 7476259Sgreen while (waitpid(pid, &status, 0) < 0) 7576259Sgreen if (errno != EINTR) 7676259Sgreen break; 7776259Sgreen if (len <= 1) 7876259Sgreen return xstrdup(""); 7976259Sgreen nl = strchr(buf, '\n'); 8076259Sgreen if (nl) 8176259Sgreen *nl = '\0'; 8276259Sgreen pass = xstrdup(buf); 8376259Sgreen memset(buf, 0, sizeof(buf)); 8476259Sgreen return pass; 8576259Sgreen} 8676259Sgreen 8776259Sgreen 8857429Smarkm/* 8957429Smarkm * Reads a passphrase from /dev/tty with echo turned off. Returns the 9057429Smarkm * passphrase (allocated with xmalloc), being very careful to ensure that 9157429Smarkm * no other userland buffer is storing the password. 9257429Smarkm */ 9369587Sgreen/* 9469587Sgreen * Note: the funcationallity of this routing has been moved to 9569587Sgreen * cli_read_passphrase(). This routing remains to maintain 9669587Sgreen * compatibility with existing code. 9769587Sgreen */ 9857429Smarkmchar * 9969587Sgreenread_passphrase(char *prompt, int from_stdin) 10057429Smarkm{ 10176259Sgreen char *askpass = NULL; 10276259Sgreen int use_askpass = 0, ttyfd; 10376259Sgreen 10476259Sgreen if (from_stdin) { 10576259Sgreen if (!isatty(STDIN_FILENO)) 10676259Sgreen use_askpass = 1; 10776259Sgreen } else { 10876259Sgreen ttyfd = open("/dev/tty", O_RDWR); 10976259Sgreen if (ttyfd >= 0) 11076259Sgreen close(ttyfd); 11176259Sgreen else 11276259Sgreen use_askpass = 1; 11376259Sgreen } 11476259Sgreen 11576259Sgreen if (use_askpass && getenv("DISPLAY")) { 11676259Sgreen if (getenv(SSH_ASKPASS_ENV)) 11776259Sgreen askpass = getenv(SSH_ASKPASS_ENV); 11876259Sgreen else 11976259Sgreen askpass = _PATH_SSH_ASKPASS_DEFAULT; 12076259Sgreen return ssh_askpass(askpass, prompt); 12176259Sgreen } 12276259Sgreen 12369587Sgreen return cli_read_passphrase(prompt, from_stdin, 0); 12457429Smarkm} 125