]> granicus.if.org Git - sudo/commitdiff
Add SUDO_CONV_PREFER_TTY flag for conversation function to tell
authorTodd C. Miller <Todd.Miller@sudo.ws>
Wed, 13 Jun 2018 17:19:33 +0000 (11:19 -0600)
committerTodd C. Miller <Todd.Miller@sudo.ws>
Wed, 13 Jun 2018 17:19:33 +0000 (11:19 -0600)
sudo to try writing to /dev/tty first.  Can be used in conjunction
with SUDO_CONV_INFO_MSG and SUDO_CONV_ERROR_MSG.

doc/sudo_plugin.cat
doc/sudo_plugin.man.in
doc/sudo_plugin.mdoc.in
include/sudo_plugin.h
src/conversation.c

index aab7b6bb719d0b1463420bc0874445eb44e8a75b..ad1ff85d7a4dee73b753c1ebfd8fb274e9fcc572 100644 (file)
@@ -1336,6 +1336,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
      #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
      #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
      #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
+     #define SUDO_CONV_PREFER_TTY       0x2000 /* flag: use tty if possible */
          int msg_type;
          int timeout;
          const char *msg;
@@ -1382,6 +1383,49 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
      them when the process is resumed.  Note that the functions are not
      actually invoked from within a signal handler.
 
+     The _\bm_\bs_\bg_\b__\bt_\by_\bp_\be must be set to one of the following values:
+
+     SUDO_CONV_PROMPT_ECHO_OFF
+           Prompt the user for input with echo disabled; this is generally
+           used for passwords.  The reply will be stored in the _\br_\be_\bp_\bl_\bi_\be_\bs array.
+
+     SUDO_CONV_PROMPT_ECHO_ON
+           Prompt the user for input with echo enabled.  The reply will be
+           stored in the _\br_\be_\bp_\bl_\bi_\be_\bs array.
+
+     SUDO_CONV_ERROR_MSG
+           Display an error message.  The message is written to the standard
+           error unless the SUDO_CONV_PREFER_TTY flag is set, in which case it
+           is written to the user's terminal if possible.
+
+     SUDO_CONV_INFO_MSG
+           Display a message.  The message is written to the standard output
+           unless the SUDO_CONV_PREFER_TTY flag is set, in which case it is
+           written to the user's terminal if possible.
+
+     SUDO_CONV_PROMPT_MASK
+           Prompt the user for input but echo an asterisk character for each
+           character read.  The reply will be stored in the _\br_\be_\bp_\bl_\bi_\be_\bs This can
+           be used to provide visual feedback to the user while reading
+           sensitive information that should not be displayed.
+
+     In addition to the above values, the following flag bits may also be set:
+
+     SUDO_CONV_PROMPT_ECHO_OK
+           Allow input to be read when echo cannot be disabled when the
+           message type is SUDO_CONV_PROMPT_ECHO_OFF or SUDO_CONV_PROMPT_MASK.
+           By default, s\bsu\bud\bdo\bo will refuse to read input if the echo cannot be
+           disabled for those message types.
+
+     SUDO_CONV_PREFER_TTY
+           When displaying a message via SUDO_CONV_ERROR_MSG or
+           SUDO_CONV_INFO_MSG, try to write the message to the user's
+           terminal.  If the terminal is unavailable, the standard error or
+           standard output will be used, depending upon whether The user's
+           terminal is always used when possible for input, this flag is only
+           used for output.  SUDO_CONV_ERROR_MSG or SUDO_CONV_INFO_MSG was
+           used.
+
      The plugin is responsible for freeing the reply buffer located in each
      struct sudo_conv_reply, if it is not NULL.  SUDO_CONV_REPL_MAX represents
      the maximum length of the reply buffer (not including the trailing NUL
@@ -1604,4 +1648,4 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
      file distributed with s\bsu\bud\bdo\bo or https://www.sudo.ws/license.html for
      complete details.
 
-Sudo 1.8.23                     March 21, 2018                     Sudo 1.8.23
+Sudo 1.8.24                      June 1, 2018                      Sudo 1.8.24
index 06f10409cf3263d352cd70a4a001d52c3154cc82..73419b5581790c9299e7d48b67c051148e1ecb2c 100644 (file)
@@ -15,7 +15,7 @@
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.TH "SUDO_PLUGIN" "5" "March 21, 2018" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.TH "SUDO_PLUGIN" "5" "June 1, 2018" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
 .nh
 .if n .ad l
 .SH "NAME"
@@ -2354,6 +2354,7 @@ struct sudo_conv_message {
 #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
 #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
 #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
+#define SUDO_CONV_PREFER_TTY       0x2000 /* flag: use tty if possible */
     int msg_type;
     int timeout;
     const char *msg;
@@ -2436,6 +2437,71 @@ that should not be held indefinitely while suspended and then reacquire them
 when the process is resumed.
 Note that the functions are not actually invoked from within a signal handler.
 .PP
+The
+\fImsg_type\fR
+must be set to one of the following values:
+.TP 6n
+SUDO_CONV_PROMPT_ECHO_OFF
+Prompt the user for input with echo disabled;
+this is generally used for passwords.
+The reply will be stored in the
+\fIreplies\fR
+array.
+.TP 6n
+SUDO_CONV_PROMPT_ECHO_ON
+Prompt the user for input with echo enabled.
+The reply will be stored in the
+\fIreplies\fR
+array.
+.TP 6n
+SUDO_CONV_ERROR_MSG
+Display an error message.
+The message is written to the standard error unless the
+\fRSUDO_CONV_PREFER_TTY\fR
+flag is set, in which case it is written to the user's terminal if possible.
+.TP 6n
+SUDO_CONV_INFO_MSG
+Display a message.
+The message is written to the standard output unless the
+\fRSUDO_CONV_PREFER_TTY\fR
+flag is set, in which case it is written to the user's terminal if possible.
+.TP 6n
+SUDO_CONV_PROMPT_MASK
+Prompt the user for input but echo an asterisk character for each
+character read.
+The reply will be stored in the
+\fIreplies\fR
+This can be used to provide visual feedback to the user while reading
+sensitive information that should not be displayed.
+.PP
+In addition to the above values, the following flag bits may also be set:
+.TP 6n
+SUDO_CONV_PROMPT_ECHO_OK
+Allow input to be read when echo cannot be disabled
+when the message type is
+\fRSUDO_CONV_PROMPT_ECHO_OFF\fR
+or
+\fRSUDO_CONV_PROMPT_MASK\fR.
+By default,
+\fBsudo\fR
+will refuse to read input if the echo cannot be disabled for those
+message types.
+.TP 6n
+SUDO_CONV_PREFER_TTY
+When displaying a message via
+\fRSUDO_CONV_ERROR_MSG\fR
+or
+\fRSUDO_CONV_INFO_MSG\fR,
+try to write the message to the user's terminal.
+If the terminal is unavailable, the standard error or standard output
+will be used, depending upon whether
+The user's terminal is always used when possible for input,
+this flag is only used for output.
+\fRSUDO_CONV_ERROR_MSG\fR
+or
+\fRSUDO_CONV_INFO_MSG\fR
+was used.
+.PP
 The plugin is responsible for freeing the reply buffer located in each
 \fRstruct sudo_conv_reply\fR,
 if it is not
index d38bbd0926e0b6495a83fb00ec31a99a01725d87..5150e23c14db011d6d66699b7c545bff62382f3f 100644 (file)
@@ -14,7 +14,7 @@
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd March 21, 2018
+.Dd June 1, 2018
 .Dt SUDO_PLUGIN @mansectform@
 .Os Sudo @PACKAGE_VERSION@
 .Sh NAME
@@ -2048,6 +2048,7 @@ struct sudo_conv_message {
 #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
 #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
 #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
+#define SUDO_CONV_PREFER_TTY       0x2000 /* flag: use tty if possible */
     int msg_type;
     int timeout;
     const char *msg;
@@ -2126,6 +2127,68 @@ that should not be held indefinitely while suspended and then reacquire them
 when the process is resumed.
 Note that the functions are not actually invoked from within a signal handler.
 .Pp
+The
+.Em msg_type
+must be set to one of the following values:
+.Bl -tag -width 4n
+.It SUDO_CONV_PROMPT_ECHO_OFF
+Prompt the user for input with echo disabled;
+this is generally used for passwords.
+The reply will be stored in the
+.Em replies
+array.
+.It SUDO_CONV_PROMPT_ECHO_ON
+Prompt the user for input with echo enabled.
+The reply will be stored in the
+.Em replies
+array.
+.It SUDO_CONV_ERROR_MSG
+Display an error message.
+The message is written to the standard error unless the
+.Dv SUDO_CONV_PREFER_TTY
+flag is set, in which case it is written to the user's terminal if possible.
+.It SUDO_CONV_INFO_MSG
+Display a message.
+The message is written to the standard output unless the
+.Dv SUDO_CONV_PREFER_TTY
+flag is set, in which case it is written to the user's terminal if possible.
+.It SUDO_CONV_PROMPT_MASK
+Prompt the user for input but echo an asterisk character for each
+character read.
+The reply will be stored in the
+.Em replies
+This can be used to provide visual feedback to the user while reading
+sensitive information that should not be displayed.
+.El
+.Pp
+In addition to the above values, the following flag bits may also be set:
+.Bl -tag -width 4n
+.It SUDO_CONV_PROMPT_ECHO_OK
+Allow input to be read when echo cannot be disabled
+when the message type is
+.Dv SUDO_CONV_PROMPT_ECHO_OFF
+or
+.Dv SUDO_CONV_PROMPT_MASK .
+By default,
+.Nm sudo
+will refuse to read input if the echo cannot be disabled for those
+message types.
+.It SUDO_CONV_PREFER_TTY
+When displaying a message via
+.Dv SUDO_CONV_ERROR_MSG
+or
+.Dv SUDO_CONV_INFO_MSG ,
+try to write the message to the user's terminal.
+If the terminal is unavailable, the standard error or standard output
+will be used, depending upon whether
+The user's terminal is always used when possible for input,
+this flag is only used for output.
+.Dv SUDO_CONV_ERROR_MSG
+or
+.Dv SUDO_CONV_INFO_MSG
+was used.
+.El
+.Pp
 The plugin is responsible for freeing the reply buffer located in each
 .Li struct sudo_conv_reply ,
 if it is not
index efe82df667b4cda2e09d31a822382fc8ef3dfa94..bd22076ea8823a752ab71329fc31e5cc2067841b 100644 (file)
@@ -41,6 +41,7 @@ struct sudo_conv_message {
 #define SUDO_CONV_INFO_MSG         0x0004  /* informational message */
 #define SUDO_CONV_PROMPT_MASK      0x0005  /* mask user input */
 #define SUDO_CONV_PROMPT_ECHO_OK    0x1000  /* flag: allow echo if no tty */
+#define SUDO_CONV_PREFER_TTY       0x2000  /* flag: use tty if possible */
     int msg_type;
     int timeout;
     const char *msg;
index 7c7b3c3ad003126a9869d22351789be750a3cd81..a7b5091bff3e63f69dd16b0af2629259258c08e2 100644 (file)
@@ -29,8 +29,9 @@
 #ifdef HAVE_STRINGS_H
 # include <strings.h>
 #endif /* HAVE_STRINGS_H */
-#include <unistd.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 #include "sudo.h"
 #include "sudo_plugin.h"
@@ -46,7 +47,7 @@ sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
     struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
 {
     char *pass;
-    int n;
+    int fd, n;
     const int conv_debug_instance = sudo_debug_get_active_instance();
 
     sudo_debug_set_active_instance(sudo_debug_instance);
@@ -54,6 +55,7 @@ sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
     for (n = 0; n < num_msgs; n++) {
        const struct sudo_conv_message *msg = &msgs[n];
        int flags = tgetpass_flags;
+       FILE *fp = stdout;
 
        switch (msg->msg_type & 0xff) {
            case SUDO_CONV_PROMPT_ECHO_ON:
@@ -77,13 +79,22 @@ sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
                }
                memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
                break;
-           case SUDO_CONV_INFO_MSG:
-               if (msg->msg != NULL && fputs(msg->msg, stdout) == EOF)
-                   goto err;
-               break;
            case SUDO_CONV_ERROR_MSG:
-               if (msg->msg != NULL && fputs(msg->msg, stderr) == EOF)
-                   goto err;
+               fp = stderr;
+               /* FALLTHROUGH */
+           case SUDO_CONV_INFO_MSG:
+               if (msg->msg != NULL) {
+                   if (ISSET(msg->msg_type, SUDO_CONV_PREFER_TTY)) {
+                       /* Try writing to /dev/tty first. */
+                       if ((fd = open(_PATH_TTY, O_WRONLY)) != -1) {
+                           if (write(fd, msg->msg, strlen(msg->msg)) != -1)
+                               break;
+                           close(fd);
+                       }
+                   }
+                   if (fputs(msg->msg, fp) == EOF)
+                       goto err;
+               }
                break;
            default:
                goto err;