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