New (correct) PAM code

Tgetpass now takes an echo flag for use with PAM_PROMPT_ECHO_ON
Block SIGINT and SIGTSTP during auth
remove a useless umask setting
Change error from BAD_ALLOCATION -> BAD_AUTH_INIT (for use with sia/PAM)
Some cosmetic changes to auth.c for consistency
This commit is contained in:
Todd C. Miller
1999-07-05 20:14:21 +00:00
parent 20002b5fe2
commit 69a00325ec
6 changed files with 175 additions and 184 deletions

233
auth.c
View File

@@ -92,8 +92,7 @@ static int sudo_krb5_validate_user __P((struct passwd *, char *));
static int verify_krb_v5_tgt __P((krb5_ccache)); static int verify_krb_v5_tgt __P((krb5_ccache));
#endif /* HAVE_KERB5 */ #endif /* HAVE_KERB5 */
#ifdef HAVE_PAM #ifdef HAVE_PAM
static int pam_auth __P((char *, char *)); static int sudo_conv __P((int,
static int PAM_conv __P((int,
PAM_CONST struct pam_message **, PAM_CONST struct pam_message **,
struct pam_response **, void *)); struct pam_response **, void *));
#endif /* HAVE_PAM */ #endif /* HAVE_PAM */
@@ -150,9 +149,7 @@ check_passwd()
exit(1); exit(1);
} }
/* /* You get TRIES_FOR_PASSWORD times to guess your password */
* you get TRIES_FOR_PASSWORD times to guess your password
*/
while (counter > 0) { while (counter > 0) {
if (sd_auth(sd) == ACM_OK) { if (sd_auth(sd) == ACM_OK) {
set_perms(PERM_USER, 0); set_perms(PERM_USER, 0);
@@ -164,14 +161,8 @@ check_passwd()
} }
set_perms(PERM_USER, 0); set_perms(PERM_USER, 0);
if (counter > 0) { log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
log_error(PASSWORD_NOT_CORRECT); inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
inform_user(PASSWORD_NOT_CORRECT);
} else {
log_error(PASSWORDS_NOT_CORRECT);
inform_user(PASSWORDS_NOT_CORRECT);
}
exit(1); exit(1);
} }
#else /* !HAVE_SECURID */ #else /* !HAVE_SECURID */
@@ -207,9 +198,7 @@ check_passwd()
exit(1); exit(1);
} }
/* /* You get TRIES_FOR_PASSWORD times to guess your password */
* you get TRIES_FOR_PASSWORD times to guess your password
*/
while (counter > 0) { while (counter > 0) {
sprintf(cbuf,"authorize %s sudo",user_name); sprintf(cbuf,"authorize %s sudo",user_name);
@@ -219,9 +208,9 @@ check_passwd()
if (!strncmp(cbuf, "challenge ", 10)) { if (!strncmp(cbuf, "challenge ", 10)) {
sprintf(buf, "Challenge \"%s\": ", &cbuf[10]); sprintf(buf, "Challenge \"%s\": ", &cbuf[10]);
pass = GETPASS(buf, PASSWORD_TIMEOUT * 60); pass = GETPASS(buf, PASSWORD_TIMEOUT * 60, 1);
} else if (!strncmp(cbuf, "password", 8)) { } else if (!strncmp(cbuf, "password", 8)) {
pass = GETPASS(buf, PASSWORD_TIMEOUT * 60); pass = GETPASS(buf, PASSWORD_TIMEOUT * 60, 1);
} else { } else {
fprintf(stderr, "Server sent %s\n", cbuf); fprintf(stderr, "Server sent %s\n", cbuf);
auth_close(); auth_close();
@@ -249,13 +238,8 @@ check_passwd()
auth_close(); auth_close();
if (counter > 0) { log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
log_error(PASSWORD_NOT_CORRECT); inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
inform_user(PASSWORD_NOT_CORRECT);
} else {
log_error(PASSWORDS_NOT_CORRECT);
inform_user(PASSWORDS_NOT_CORRECT);
}
exit(1); exit(1);
} }
@@ -281,14 +265,12 @@ check_passwd()
(void) memset((VOID *)&opie, 0, sizeof(opie)); (void) memset((VOID *)&opie, 0, sizeof(opie));
#endif /* HAVE_OPIE */ #endif /* HAVE_OPIE */
/* /* You get TRIES_FOR_PASSWORD times to guess your password */
* you get TRIES_FOR_PASSWORD times to guess your password
*/
while (counter > 0) { while (counter > 0) {
#ifdef HAVE_AUTHENTICATE #ifdef HAVE_AUTHENTICATE
/* use AIX authenticate() function */ /* use AIX authenticate() function */
pass = GETPASS(prompt, PASSWORD_TIMEOUT * 60); pass = GETPASS(prompt, PASSWORD_TIMEOUT * 60, 1);
reenter = 1; reenter = 1;
if (authenticate(user_name, pass, &reenter, &message) == 0) if (authenticate(user_name, pass, &reenter, &message) == 0)
return; /* valid password */ return; /* valid password */
@@ -311,7 +293,7 @@ check_passwd()
(void) des_read_pw_string(kpass, sizeof(kpass) - 1, prompt, 0); (void) des_read_pw_string(kpass, sizeof(kpass) - 1, prompt, 0);
pass = kpass; pass = kpass;
# else # else
pass = (char *) GETPASS(prompt, PASSWORD_TIMEOUT * 60); pass = (char *) GETPASS(prompt, PASSWORD_TIMEOUT * 60, 1);
# endif /* HAVE_KERB4 */ # endif /* HAVE_KERB4 */
# ifdef HAVE_SKEY # ifdef HAVE_SKEY
@@ -399,14 +381,8 @@ check_passwd()
pass_warn(stderr); pass_warn(stderr);
} }
if (counter > 0) { log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
log_error(PASSWORD_NOT_CORRECT); inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
inform_user(PASSWORD_NOT_CORRECT);
} else {
log_error(PASSWORDS_NOT_CORRECT);
inform_user(PASSWORDS_NOT_CORRECT);
}
exit(1); exit(1);
} }
#endif /* HAVE_AUTHSRV */ #endif /* HAVE_AUTHSRV */
@@ -496,7 +472,7 @@ sudo_krb5_validate_user(pw, pass)
princ_name = emalloc(strlen(pw->pw_name) + strlen(realm) + 2); princ_name = emalloc(strlen(pw->pw_name) + strlen(realm) + 2);
sprintf(princ_name, "%s@%s", pw->pw_name, realm); (void) sprintf(princ_name, "%s@%s", pw->pw_name, realm);
if (retval = krb5_parse_name(sudo_context, princ_name, &princ)) if (retval = krb5_parse_name(sudo_context, princ_name, &princ))
return retval; return retval;
@@ -613,118 +589,109 @@ cleanup:
* pam_attempt_auth() * pam_attempt_auth()
* *
* Try to authenticate the user using Pluggable Authentication * Try to authenticate the user using Pluggable Authentication
* Modules (PAM). Added 9/11/98 by Gary J. Calvin * Modules (PAM).
* Reworked for stock PAM by Amos Elberg and Todd Miller
*/ */
static char *PAM_username;
static char *PAM_password;
static int
PAM_conv(num_msg, msg, resp, appdata_ptr)
int num_msg;
PAM_CONST struct pam_message **msg;
struct pam_response **resp;
void *appdata_ptr;
{
int replies = 0;
struct pam_response *reply = NULL;
if ((reply = malloc(sizeof(struct pam_response) * num_msg)) == NULL)
return(PAM_CONV_ERR);
for (replies = 0; replies < num_msg; replies++) {
switch (msg[replies]->msg_style) {
case PAM_PROMPT_ECHO_ON:
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = estrdup(PAM_username);
/* PAM frees resp */
break;
case PAM_PROMPT_ECHO_OFF:
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = estrdup(PAM_password);
/* PAM frees resp */
break;
case PAM_TEXT_INFO:
/* fall through */
case PAM_ERROR_MSG:
/* ignore it... */
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = NULL;
break;
default:
/* Must be an error of some sort... */
free(reply);
return(PAM_CONV_ERR);
}
}
if (reply)
*resp = reply;
return(PAM_SUCCESS);
}
static int
pam_auth(user, password)
char *user;
char *password;
{
struct pam_conv PAM_conversation;
pam_handle_t *pamh;
/* Initialize our variables for PAM */
PAM_conversation.conv = PAM_conv;
PAM_conversation.appdata_ptr = NULL;
PAM_password = password;
PAM_username = user;
/*
* Setting PAM_SILENT stops generation of error messages to syslog
* to enable debugging on Red Hat Linux set:
* /etc/pam.d/sudo:
* auth required /lib/security/pam_pwdb.so shadow nullok audit
* _OR_ change PAM_SILENT to 0 to force detailed reporting (logging)
*/
if (pam_start("sudo", user, &PAM_conversation, &pamh) != PAM_SUCCESS ||
pam_authenticate(pamh, PAM_SILENT) != PAM_SUCCESS) {
pam_end(pamh, 0);
return(0);
}
/* User authenticated successfully */
pam_end(pamh, PAM_SUCCESS);
return(1);
}
void void
pam_attempt_auth() pam_attempt_auth()
{ {
int i = TRIES_FOR_PASSWORD; int counter = TRIES_FOR_PASSWORD;
int null_pw = 0;
static struct pam_conv pam_conv;
static pam_handle_t *pamh;
set_perms(PERM_ROOT, 0); set_perms(PERM_ROOT, 0);
while (i > 0) {
char *pamPass = (char *) GETPASS(prompt, PASSWORD_TIMEOUT * 60);
if (pam_auth(user_name, pamPass)) { /* Initial PAM setup + use our default prompt */
pam_conv.conv = sudo_conv;
pam_conv.appdata_ptr = &null_pw;
if (pam_start("sudo", user_name, &pam_conv, &pamh) != PAM_SUCCESS ||
pam_set_item(pamh, PAM_USER_PROMPT, (void *) prompt) != PAM_SUCCESS) {
set_perms(PERM_USER, 0);
log_error(BAD_AUTH_INIT);
inform_user(BAD_AUTH_INIT);
exit(1);
}
/* You get TRIES_FOR_PASSWORD times to guess your password */
while (counter > 0) {
/* PAM_SILENT prevents error messages from going to syslog(3) */
if (pam_authenticate(pamh, PAM_SILENT) == PAM_SUCCESS) {
pam_end(pamh, PAM_SUCCESS);
set_perms(PERM_USER, 0); set_perms(PERM_USER, 0);
return; return;
} }
--i; if (null_pw)
break;
--counter; /* otherwise, try again */
pass_warn(stderr); pass_warn(stderr);
} }
pam_end(pamh, 0);
set_perms(PERM_USER, 0); set_perms(PERM_USER, 0);
if (i == 0) { log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
log_error(PASSWORD_NOT_CORRECT); inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
inform_user(PASSWORD_NOT_CORRECT);
} else {
log_error(PASSWORDS_NOT_CORRECT);
inform_user(PASSWORDS_NOT_CORRECT);
}
exit(1); exit(1);
} }
/********************************************************************
* sudo_conv()
*
* ``Conversation function'' for PAM.
*/
static int
sudo_conv(num_msg, msg, response, appdata_ptr)
int num_msg;
PAM_CONST struct pam_message **msg;
struct pam_response **response;
void *appdata_ptr;
{
struct pam_response *pr;
struct pam_message *pm;
int echo = 0;
if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL)
return(PAM_CONV_ERR);
(void) memset((VOID *)*response, 0, num_msg * sizeof(struct pam_response));
for (pr = *response, pm = *msg; num_msg--; pr++, pm++) {
switch (pm->msg_style) {
case PAM_PROMPT_ECHO_ON:
echo = 1;
case PAM_PROMPT_ECHO_OFF:
pr->resp = estrdup((char *) GETPASS(pm->msg,
PASSWORD_TIMEOUT * 60, !echo));
/* Solaris PAM does not pass through appdata_ptr! */
if (pr->resp[0] == '\0' && appdata_ptr != NULL)
*((int *) appdata_ptr) = 1; /* indicate an empty password */
break;
case PAM_TEXT_INFO:
if (pm->msg)
(void) puts(pm->msg);
break;
case PAM_ERROR_MSG:
if (pm->msg) {
(void) fputs(pm->msg, stderr);
(void) fputc('\n', stderr);
}
break;
default:
/* Something odd happened */
/* XXX - should free non-NULL response members */
free(*response);
*response = NULL;
return(PAM_CONV_ERR);
break;
}
}
return(PAM_SUCCESS);
}
#endif /* HAVE_PAM */ #endif /* HAVE_PAM */
#ifdef HAVE_SKEY #ifdef HAVE_SKEY
/******************************************************************** /********************************************************************
* *

31
check.c
View File

@@ -45,6 +45,7 @@
#include <strings.h> #include <strings.h>
#endif /* HAVE_STRINGS_H */ #endif /* HAVE_STRINGS_H */
#include <fcntl.h> #include <fcntl.h>
#include <signal.h>
#include <time.h> #include <time.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/types.h> #include <sys/types.h>
@@ -96,13 +97,28 @@ static char timestampfile[MAXPATHLEN];
void void
check_user() check_user()
{ {
register int rtn; int rtn;
mode_t oldmask; #ifdef POSIX_SIGNALS
sigset_t set, oset;
#else
int omask;
#endif /* POSIX_SIGNALS */
if (user_is_exempt()) /* some users don't need to enter a passwd */ if (user_is_exempt()) /* some users don't need to enter a passwd */
return; return;
oldmask = umask(077); /* make sure the timestamp files are private */ /*
* Block SIGINT and SIGTSTP during authentication so the user
* can't abort the logging.
*/
#ifdef POSIX_SIGNALS
(void) sigemptyset(&set);
(void) sigaddset(&set, SIGINT);
(void) sigaddset(&set, SIGTSTP);
(void) sigprocmask(SIG_BLOCK, &set, &oset);
#else
omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));
#endif /* POSIX_SIGNALS */
rtn = check_timestamp(); rtn = check_timestamp();
if (rtn && user_uid) { /* if timestamp is not current... */ if (rtn && user_uid) { /* if timestamp is not current... */
@@ -123,9 +139,14 @@ check_user()
#endif /* HAVE_SIA */ #endif /* HAVE_SIA */
} }
update_timestamp(); /* Unblock signals */
(void) umask(oldmask); /* want a real umask to exec() the command */ #ifdef POSIX_SIGNALS
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
#else
(void) sigsetmask(omask);
#endif /* POSIX_SIGNALS */
update_timestamp();
} }

View File

@@ -113,8 +113,8 @@ sia_attempt_auth()
1, NULL); 1, NULL);
if (retval != SIASUCCESS) { if (retval != SIASUCCESS) {
set_perms(PERM_USER, 0); set_perms(PERM_USER, 0);
log_error(BAD_ALLOCATION); log_error(BAD_AUTH_INIT);
inform_user(BAD_ALLOCATION); inform_user(BAD_AUTH_INIT);
exit(1); exit(1);
} }
/* XXX - need a way to detect user hitting return or EOF at prompt */ /* XXX - need a way to detect user hitting return or EOF at prompt */

View File

@@ -264,9 +264,9 @@ log_error(code)
tty, cwd, runas_user); tty, cwd, runas_user);
break; break;
case BAD_ALLOCATION: case BAD_AUTH_INIT:
(void) sprintf(p, (void) sprintf(p,
"allocation failure; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=", "unable to initialize authentication scheme; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=",
tty, cwd, runas_user); tty, cwd, runas_user);
break; break;
@@ -668,9 +668,9 @@ inform_user(code)
"Your timestamp file has a preposterous date, ignoring.\n"); "Your timestamp file has a preposterous date, ignoring.\n");
break; break;
case BAD_ALLOCATION: case BAD_AUTH_INIT:
(void) fprintf(stderr, (void) fprintf(stderr,
"Resource allocation failure.\n"); "Unable to initialize authentication scheme.\n");
break; break;
case NO_CMND_SAFE: case NO_CMND_SAFE:
@@ -736,7 +736,7 @@ appropriate(code)
case NO_SUDOERS_FILE: case NO_SUDOERS_FILE:
case BAD_STAMPDIR: case BAD_STAMPDIR:
case BAD_STAMPFILE: case BAD_STAMPFILE:
case BAD_ALLOCATION: case BAD_AUTH_INIT:
case NO_CMND_SAFE: case NO_CMND_SAFE:
default: default:
return (1); return (1);

8
sudo.h
View File

@@ -152,7 +152,7 @@ struct generic_alias {
#define SUDOERS_NOT_FILE ( 0x0B | GLOBAL_PROBLEM ) #define SUDOERS_NOT_FILE ( 0x0B | GLOBAL_PROBLEM )
#define BAD_STAMPDIR 0x0C #define BAD_STAMPDIR 0x0C
#define BAD_STAMPFILE 0x0D #define BAD_STAMPFILE 0x0D
#define BAD_ALLOCATION 0x0E #define BAD_AUTH_INIT 0x0E
#define NO_CMND_SAFE 0x0F #define NO_CMND_SAFE 0x0F
#ifdef HAVE_KERB5 #ifdef HAVE_KERB5
#define GLOBAL_KRB5_INIT_ERR ( 0x10 | GLOBAL_PROBLEM ) #define GLOBAL_KRB5_INIT_ERR ( 0x10 | GLOBAL_PROBLEM )
@@ -209,9 +209,9 @@ struct generic_alias {
* Use either tgetpass() or system getpass() * Use either tgetpass() or system getpass()
*/ */
#ifdef USE_GETPASS #ifdef USE_GETPASS
#define GETPASS(p, t) getpass(p) #define GETPASS(p, t, e) getpass(p)
#else #else
#define GETPASS(p, t) tgetpass(p, t) #define GETPASS(p, t, e) tgetpass(p, t, e)
#endif #endif
/* /*
@@ -235,7 +235,7 @@ int putenv __P((const char *));
#endif #endif
char *sudo_goodpath __P((const char *)); char *sudo_goodpath __P((const char *));
int sudo_setenv __P((char *, char *)); int sudo_setenv __P((char *, char *));
char *tgetpass __P((const char *, int)); char *tgetpass __P((const char *, int, int));
int find_path __P((char *, char **)); int find_path __P((char *, char **));
void log_error __P((int)); void log_error __P((int));
void inform_user __P((int)); void inform_user __P((int));

View File

@@ -88,9 +88,10 @@ static const char rcsid[] = "$Sudo$";
*/ */
char * char *
tgetpass(prompt, timeout) tgetpass(prompt, timeout, echo_off)
const char *prompt; const char *prompt;
int timeout; int timeout;
int echo_off;
{ {
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
struct termios term; struct termios term;
@@ -102,12 +103,11 @@ tgetpass(prompt, timeout)
#endif /* HAVE_TERMIO_H */ #endif /* HAVE_TERMIO_H */
#endif /* HAVE_TERMIOS_H */ #endif /* HAVE_TERMIOS_H */
#ifdef POSIX_SIGNALS #ifdef POSIX_SIGNALS
sigset_t oldmask; sigset_t set, oset;
sigset_t mask;
#else #else
int oldmask; int omask;
#endif /* POSIX_SIGNALS */ #endif /* POSIX_SIGNALS */
int n, echo, input, output; int n, input, output;
static char buf[SUDO_PASS_MAX + 1]; static char buf[SUDO_PASS_MAX + 1];
fd_set *readfds; fd_set *readfds;
struct timeval tv; struct timeval tv;
@@ -116,13 +116,13 @@ tgetpass(prompt, timeout)
* mask out SIGINT and SIGTSTP, should probably just catch and deal. * mask out SIGINT and SIGTSTP, should probably just catch and deal.
*/ */
#ifdef POSIX_SIGNALS #ifdef POSIX_SIGNALS
(void) sigemptyset(&mask); (void) sigemptyset(&set);
(void) sigaddset(&mask, SIGINT); (void) sigaddset(&set, SIGINT);
(void) sigaddset(&mask, SIGTSTP); (void) sigaddset(&set, SIGTSTP);
(void) sigprocmask(SIG_BLOCK, &mask, &oldmask); (void) sigprocmask(SIG_BLOCK, &set, &oset);
#else #else
oldmask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP)); omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));
#endif #endif /* POSIX_SIGNALS */
/* /*
* open /dev/tty for reading/writing if possible or use * open /dev/tty for reading/writing if possible or use
@@ -138,29 +138,31 @@ tgetpass(prompt, timeout)
(void) write(output, prompt, strlen(prompt) + 1); (void) write(output, prompt, strlen(prompt) + 1);
/* /*
* turn off echo * turn off echo unless asked to keep it on
*/ */
if (echo_off) {
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
(void) tcgetattr(input, &term); (void) tcgetattr(input, &term);
if ((echo = (term.c_lflag & ECHO))) { if ((echo_off = (term.c_lflag & ECHO))) {
term.c_lflag &= ~ECHO; term.c_lflag &= ~ECHO;
(void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); (void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
} }
#else #else
#ifdef HAVE_TERMIO_H #ifdef HAVE_TERMIO_H
(void) ioctl(input, TCGETA, &term); (void) ioctl(input, TCGETA, &term);
if ((echo = (term.c_lflag & ECHO))) { if ((echo_off = (term.c_lflag & ECHO))) {
term.c_lflag &= ~ECHO; term.c_lflag &= ~ECHO;
(void) ioctl(input, TCSETA, &term); (void) ioctl(input, TCSETA, &term);
} }
#else #else
(void) ioctl(input, TIOCGETP, &ttyb); (void) ioctl(input, TIOCGETP, &ttyb);
if ((echo = (ttyb.sg_flags & ECHO))) { if ((echo_off = (ttyb.sg_flags & ECHO))) {
ttyb.sg_flags &= ~ECHO; ttyb.sg_flags &= ~ECHO;
(void) ioctl(input, TIOCSETP, &ttyb); (void) ioctl(input, TIOCSETP, &ttyb);
} }
#endif /* HAVE_TERMIO_H */ #endif /* HAVE_TERMIO_H */
#endif /* HAVE_TERMIOS_H */ #endif /* HAVE_TERMIOS_H */
}
/* /*
* Timeout of <= 0 means no timeout * Timeout of <= 0 means no timeout
@@ -198,20 +200,20 @@ tgetpass(prompt, timeout)
} }
} }
/* turn on echo */ /* turn on echo if we turned it off above */
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
if (echo) { if (echo_off) {
term.c_lflag |= ECHO; term.c_lflag |= ECHO;
(void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); (void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
} }
#else #else
#ifdef HAVE_TERMIO_H #ifdef HAVE_TERMIO_H
if (echo) { if (echo_off) {
term.c_lflag |= ECHO; term.c_lflag |= ECHO;
(void) ioctl(input, TCSETA, &term); (void) ioctl(input, TCSETA, &term);
} }
#else #else
if (echo) { if (echo_off) {
ttyb.sg_flags |= ECHO; ttyb.sg_flags |= ECHO;
(void) ioctl(input, TIOCSETP, &ttyb); (void) ioctl(input, TIOCSETP, &ttyb);
} }
@@ -219,14 +221,15 @@ tgetpass(prompt, timeout)
#endif /* HAVE_TERMIOS_H */ #endif /* HAVE_TERMIOS_H */
/* print a newline since echo is turned off */ /* print a newline since echo is turned off */
if (echo_off)
(void) write(output, "\n", 1); (void) write(output, "\n", 1);
/* restore old signal mask */ /* restore old signal mask */
#ifdef POSIX_SIGNALS #ifdef POSIX_SIGNALS
(void) sigprocmask(SIG_SETMASK, &oldmask, NULL); (void) sigprocmask(SIG_SETMASK, &oset, NULL);
#else #else
(void) sigsetmask(oldmask); (void) sigsetmask(omask);
#endif #endif /* POSIX_SIGNALS */
/* close /dev/tty if that's what we opened */ /* close /dev/tty if that's what we opened */
if (input != STDIN_FILENO) if (input != STDIN_FILENO)