From: Todd C. Miller Date: Tue, 27 Aug 2019 01:30:11 +0000 (-0600) Subject: Use the SUDO_CONV_PREFER_TTY flag during authentication. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=972670bfca64423488928bc7e482645d9c440080;p=sudo Use the SUDO_CONV_PREFER_TTY flag during authentication. This prevents the password and PAM prompts from being redirected. Bug #895 --- diff --git a/plugins/sudoers/auth/aix_auth.c b/plugins/sudoers/auth/aix_auth.c index b40382c52..bb62612e2 100644 --- a/plugins/sudoers/auth/aix_auth.c +++ b/plugins/sudoers/auth/aix_auth.c @@ -256,7 +256,8 @@ sudo_aix_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_co if (result != 0) { /* Display error message, if any. */ if (sudo_aix_valid_message(message)) - sudo_printf(SUDO_CONV_ERROR_MSG, "%s", message); + sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, + "%s", message); ret = pass ? AUTH_FAILURE : AUTH_INTR; } free(message); @@ -266,8 +267,9 @@ sudo_aix_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_co if (ret == AUTH_SUCCESS) { result = passwdexpired(pw->pw_name, &message); if (message != NULL && message[0] != '\0') { - sudo_printf(result ? SUDO_CONV_ERROR_MSG : SUDO_CONV_INFO_MSG, - "%s", message); + int msg_type = SUDO_CONV_PREFER_TTY; + msg_type |= result ? SUDO_CONV_ERROR_MSG : SUDO_CONV_INFO_MSG, + sudo_printf(msg_type, "%s", message); free(message); message = NULL; } diff --git a/plugins/sudoers/auth/dce.c b/plugins/sudoers/auth/dce.c index 2f88b4b1c..27bd059fc 100644 --- a/plugins/sudoers/auth/dce.c +++ b/plugins/sudoers/auth/dce.c @@ -103,7 +103,7 @@ sudo_dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth, struct sudo_ * sure that we didn't get spoofed by another DCE server. */ if (!sec_login_certify_identity(login_context, &status)) { - sudo_printf(SUDO_CONV_ERROR_MSG, + sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, "Whoa! Bogus authentication server!\n"); (void) check_dce_status(status,"sec_login_certify_identity(1):"); debug_return_int(AUTH_FAILURE); @@ -125,13 +125,13 @@ sudo_dce_verify(struct passwd *pw, char *plain_pw, sudo_auth *auth, struct sudo_ * DCE client and DCE security server... */ if (auth_src != sec_login_auth_src_network) { - sudo_printf(SUDO_CONV_ERROR_MSG, + sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, "You have no network credentials.\n"); debug_return_int(AUTH_FAILURE); } /* Check if the password has aged and is thus no good */ if (reset_passwd) { - sudo_printf(SUDO_CONV_ERROR_MSG, + sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, "Your DCE password needs resetting.\n"); debug_return_int(AUTH_FAILURE); } @@ -191,7 +191,8 @@ check_dce_status(error_status_t input_status, char *comment) if (input_status == rpc_s_ok) debug_return_int(0); dce_error_inq_text(input_status, error_string, &error_stat); - sudo_printf(SUDO_CONV_ERROR_MSG, "%s %s\n", comment, error_string); + sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, + "%s %s\n", comment, error_string); debug_return_int(1); } diff --git a/plugins/sudoers/auth/fwtk.c b/plugins/sudoers/auth/fwtk.c index 2291ff921..c1784b3e3 100644 --- a/plugins/sudoers/auth/fwtk.c +++ b/plugins/sudoers/auth/fwtk.c @@ -109,7 +109,7 @@ restart: } else if (strncmp(resp, "password", 8) == 0) { pass = auth_getpass(prompt, SUDO_CONV_PROMPT_ECHO_OFF, callback); } else if (strncmp(resp, "display ", 8) == 0) { - sudo_printf(SUDO_CONV_INFO_MSG, "%s\n", &resp[8]); + sudo_printf(SUDO_CONV_INFO_MSG|SUDO_CONV_PREFER_TTY, "%s\n", &resp[8]); strlcpy(buf, "response dummy", sizeof(buf)); goto restart; } else { diff --git a/plugins/sudoers/auth/pam.c b/plugins/sudoers/auth/pam.c index 03bdfeaeb..db342b0f6 100644 --- a/plugins/sudoers/auth/pam.c +++ b/plugins/sudoers/auth/pam.c @@ -696,11 +696,13 @@ converse(int num_msg, PAM_CONST struct pam_message **msg, break; case PAM_TEXT_INFO: if (pm->msg != NULL && !is_filtered(pm->msg)) - sudo_printf(SUDO_CONV_INFO_MSG, "%s\n", pm->msg); + sudo_printf(SUDO_CONV_INFO_MSG|SUDO_CONV_PREFER_TTY, + "%s\n", pm->msg); break; case PAM_ERROR_MSG: if (pm->msg != NULL) - sudo_printf(SUDO_CONV_ERROR_MSG, "%s\n", pm->msg); + sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, + "%s\n", pm->msg); break; default: sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, diff --git a/plugins/sudoers/auth/securid5.c b/plugins/sudoers/auth/securid5.c index 64fd978bf..9f1ab3b16 100644 --- a/plugins/sudoers/auth/securid5.c +++ b/plugins/sudoers/auth/securid5.c @@ -206,9 +206,9 @@ then enter the new token code.\n", \ */ /* XXX - Is setting up a new PIN within sudo's scope? */ SD_Pin(*sd, ""); - sudo_printf(SUDO_CONV_ERROR_MSG, + sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, "Your SecurID access has not yet been set up.\n"); - sudo_printf(SUDO_CONV_ERROR_MSG, + sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, "Please set up a PIN before you try to authenticate.\n"); ret = AUTH_FATAL; break; diff --git a/plugins/sudoers/auth/sudo_auth.c b/plugins/sudoers/auth/sudo_auth.c index 0d8d99341..bae41a20d 100644 --- a/plugins/sudoers/auth/sudo_auth.c +++ b/plugins/sudoers/auth/sudo_auth.c @@ -227,7 +227,7 @@ pass_warn(void) if (def_insults) warning = INSULT; #endif - sudo_printf(SUDO_CONV_ERROR_MSG, "%s\n", warning); + sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, "%s\n", warning); debug_return; } diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c index 74c8f2f43..db8e05161 100644 --- a/plugins/sudoers/check.c +++ b/plugins/sudoers/check.c @@ -259,13 +259,13 @@ display_lecture(int status) if (def_lecture_file && (fp = fopen(def_lecture_file, "r")) != NULL) { while ((nread = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) != 0) { buf[nread] = '\0'; - msg.msg_type = SUDO_CONV_ERROR_MSG; + msg.msg_type = SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY; msg.msg = buf; sudo_conv(1, &msg, &repl, NULL); } fclose(fp); } else { - msg.msg_type = SUDO_CONV_ERROR_MSG; + msg.msg_type = SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY; msg.msg = _("\n" "We trust you have received the usual lecture from the local System\n" "Administrator. It usually boils down to these three things:\n\n" diff --git a/plugins/sudoers/sudo_printf.c b/plugins/sudoers/sudo_printf.c index 9e6a3d9b1..fd21e4b9e 100644 --- a/plugins/sudoers/sudo_printf.c +++ b/plugins/sudoers/sudo_printf.c @@ -32,22 +32,28 @@ #include "sudo_compat.h" #include "sudo_plugin.h" #include "sudo_debug.h" +#include "pathnames.h" static int sudo_printf_int(int msg_type, const char *fmt, ...) { + FILE *fp = stdout; + FILE *ttyfp = NULL; va_list ap; int len; - switch (msg_type) { - case SUDO_CONV_INFO_MSG: - va_start(ap, fmt); - len = vfprintf(stdout, fmt, ap); - va_end(ap); - break; + if (ISSET(msg_type, SUDO_CONV_PREFER_TTY)) { + /* Try writing to /dev/tty first. */ + ttyfp = fopen(_PATH_TTY, "w"); + } + + switch (msg_type & 0xff) { case SUDO_CONV_ERROR_MSG: + fp = stderr; + /* FALLTHROUGH */ + case SUDO_CONV_INFO_MSG: va_start(ap, fmt); - len = vfprintf(stderr, fmt, ap); + len = vfprintf(ttyfp ? ttyfp : fp, fmt, ap); va_end(ap); break; default: @@ -56,6 +62,9 @@ sudo_printf_int(int msg_type, const char *fmt, ...) break; } + if (ttyfp != NULL) + fclose(ttyfp); + return len; } diff --git a/src/conversation.c b/src/conversation.c index d78e1b89f..1e20215d0 100644 --- a/src/conversation.c +++ b/src/conversation.c @@ -140,21 +140,26 @@ sudo_conversation_1_7(int num_msgs, const struct sudo_conv_message msgs[], int sudo_conversation_printf(int msg_type, const char *fmt, ...) { + FILE *fp = stdout; + FILE *ttyfp = NULL; va_list ap; int len; const int conv_debug_instance = sudo_debug_get_active_instance(); sudo_debug_set_active_instance(sudo_debug_instance); - switch (msg_type) { - case SUDO_CONV_INFO_MSG: - va_start(ap, fmt); - len = vfprintf(stdout, fmt, ap); - va_end(ap); - break; + if (ISSET(msg_type, SUDO_CONV_PREFER_TTY)) { + /* Try writing to /dev/tty first. */ + ttyfp = fopen(_PATH_TTY, "w"); + } + + switch (msg_type & 0xff) { case SUDO_CONV_ERROR_MSG: + fp = stderr; + /* FALLTHROUGH */ + case SUDO_CONV_INFO_MSG: va_start(ap, fmt); - len = vfprintf(stderr, fmt, ap); + len = vfprintf(ttyfp ? ttyfp : fp, fmt, ap); va_end(ap); break; default: @@ -163,6 +168,9 @@ sudo_conversation_printf(int msg_type, const char *fmt, ...) break; } + if (ttyfp != NULL) + fclose(ttyfp); + sudo_debug_set_active_instance(conv_debug_instance); return len; }