Add SUDO_CONV_PREFER_TTY flag for conversation function to tell

sudo to try writing to /dev/tty first.  Can be used in conjunction
with SUDO_CONV_INFO_MSG and SUDO_CONV_ERROR_MSG.
This commit is contained in:
Todd C. Miller
2018-06-13 11:19:33 -06:00
parent 89c83f0321
commit 6eadaddc99
5 changed files with 196 additions and 11 deletions

View File

@@ -1336,6 +1336,7 @@ DDEESSCCRRIIPPTTIIOONN
#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 @@ DDEESSCCRRIIPPTTIIOONN
them when the process is resumed. Note that the functions are not
actually invoked from within a signal handler.
The _m_s_g___t_y_p_e 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 _r_e_p_l_i_e_s array.
SUDO_CONV_PROMPT_ECHO_ON
Prompt the user for input with echo enabled. The reply will be
stored in the _r_e_p_l_i_e_s 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 _r_e_p_l_i_e_s 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, ssuuddoo 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 @@ DDIISSCCLLAAIIMMEERR
file distributed with ssuuddoo 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

View 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

View 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

View 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;

View 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;