Pass window size change events to the plugin.

This commit is contained in:
Todd C. Miller
2017-07-12 05:47:28 -06:00
parent 6505d05803
commit 8898ec1f9c
5 changed files with 100 additions and 9 deletions

View File

@@ -867,6 +867,7 @@ DDEESSCCRRIIPPTTIIOONN
int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version,
int (*deregister_hook)(struct sudo_hook *hook));
int (*change_winsize)(unsigned int lines, unsigned int cols);
};
When an I/O plugin is loaded, ssuuddoo runs the command in a pseudo-tty.
@@ -1124,6 +1125,14 @@ DDEESSCCRRIIPPTTIIOONN
See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a description of
deregister_hooks.
change_winsize
int (*change_winsize)(unsigned int lines, unsigned int cols);
The cchhaannggee__wwiinnssiizzee() function is called whenever the window size of
the terminal changes from the initial values specified in the
user_info list. It returns 1 on success, 0 on failure, -1 if an
error occurred (which will terminate the running command).
_I_/_O _P_l_u_g_i_n _V_e_r_s_i_o_n _M_a_c_r_o_s
Same as for the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I.
@@ -1563,6 +1572,9 @@ PPLLUUGGIINN AAPPII CCHHAANNGGEELLOOGG
Version 1.11 (sudo 1.8.20)
The _t_i_m_e_o_u_t entry was added to the settings list.
Version 1.12 (sudo 1.8.21)
The change_winsize field was added to the io_plugin struct.
SSEEEE AALLSSOO
sudo.conf(4), sudoers(4), sudo(1m)
@@ -1592,4 +1604,4 @@ DDIISSCCLLAAIIMMEERR
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
complete details.
Sudo 1.8.21 June 2, 2017 Sudo 1.8.21
Sudo 1.8.21 July 11, 2017 Sudo 1.8.21

View File

@@ -16,7 +16,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.TH "SUDO_PLUGIN" "5" "June 2, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.TH "SUDO_PLUGIN" "5" "July 11, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.nh
.if n .ad l
.SH "NAME"
@@ -1470,6 +1470,7 @@ struct io_plugin {
int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version,
int (*deregister_hook)(struct sudo_hook *hook));
int (*change_winsize)(unsigned int lines, unsigned int cols);
};
.RE
.fi
@@ -1976,6 +1977,24 @@ See the
\fIPolicy plugin API\fR
section for a description of
\fRderegister_hooks.\fR
.TP 6n
change_winsize
.nf
.RS 6n
int (*change_winsize)(unsigned int lines, unsigned int cols);
.RE
.fi
.RS 6n
.sp
The
\fBchange_winsize\fR()
function is called whenever the window size of the terminal changes from
the initial values specified in the
\fRuser_info\fR
list.
It returns 1 on success, 0 on failure, \-1 if an error occurred (which
will terminate the running command).
.RE
.PP
\fII/O Plugin Version Macros\fR
.PP
@@ -2794,6 +2813,11 @@ The
entry was added to the
\fRsettings\fR
list.
.TP 6n
Version 1.12 (sudo 1.8.21)
The
\fRchange_winsize\fR
field was added to the io_plugin struct.
.SH "SEE ALSO"
sudo.conf(@mansectform@),
sudoers(@mansectform@),

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 June 2, 2017
.Dd July 11, 2017
.Dt SUDO_PLUGIN @mansectform@
.Os Sudo @PACKAGE_VERSION@
.Sh NAME
@@ -1298,6 +1298,7 @@ struct io_plugin {
int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version,
int (*deregister_hook)(struct sudo_hook *hook));
int (*change_winsize)(unsigned int lines, unsigned int cols);
};
.Ed
.Pp
@@ -1730,6 +1731,19 @@ See the
.Sx Policy plugin API
section for a description of
.Li deregister_hooks.
.It change_winsize
.Bd -literal -compact
int (*change_winsize)(unsigned int lines, unsigned int cols);
.Ed
.Pp
The
.Fn change_winsize
function is called whenever the window size of the terminal changes from
the initial values specified in the
.Li user_info
list.
It returns 1 on success, 0 on failure, \-1 if an error occurred (which
will terminate the running command).
.El
.Pp
.Em I/O Plugin Version Macros
@@ -2447,6 +2461,10 @@ The
entry was added to the
.Li settings
list.
.It Version 1.12 (sudo 1.8.21)
The
.Li change_winsize
field was added to the io_plugin struct.
.El
.Sh SEE ALSO
.Xr sudo.conf @mansectform@ ,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2016 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 2009-2017 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -19,7 +19,7 @@
/* API version major/minor */
#define SUDO_API_VERSION_MAJOR 1
#define SUDO_API_VERSION_MINOR 11
#define SUDO_API_VERSION_MINOR 12
#define SUDO_API_MKVERSION(x, y) (((x) << 16) | (y))
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
@@ -168,6 +168,7 @@ struct io_plugin {
int (*log_stderr)(const char *buf, unsigned int len);
void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version, int (*deregister_hook)(struct sudo_hook *hook));
int (*change_winsize)(unsigned int rows, unsigned int cols);
};
/* Sudoers group plugin version major/minor */

View File

@@ -362,6 +362,38 @@ log_stderr(const char *buf, unsigned int n, struct io_buffer *iob)
debug_return_bool(ret);
}
/* Call I/O plugin stderr log method. */
static void
log_winchange(unsigned int rows, unsigned int cols)
{
struct plugin_container *plugin;
sigset_t omask;
debug_decl(log_winchange, SUDO_DEBUG_EXEC);
sigprocmask(SIG_BLOCK, &ttyblock, &omask);
TAILQ_FOREACH(plugin, &io_plugins, entries) {
if (plugin->u.io->version < SUDO_API_MKVERSION(1, 12))
continue;
if (plugin->u.io->change_winsize) {
int rc;
sudo_debug_set_active_instance(plugin->debug_instance);
rc = plugin->u.io->change_winsize(rows, cols);
if (rc <= 0) {
if (rc < 0) {
/* Error: disable plugin's I/O function. */
plugin->u.io->change_winsize = NULL;
}
break;
}
}
}
sudo_debug_set_active_instance(sudo_debug_instance);
sigprocmask(SIG_SETMASK, &omask, NULL);
debug_return;
}
/*
* Check whether we are running in the foregroup.
* Updates the foreground global and does lazy init of the
@@ -376,8 +408,8 @@ check_foreground(pid_t ppgrp)
foreground = tcgetpgrp(io_fds[SFD_USERTTY]) == ppgrp;
if (foreground && !tty_initialized) {
if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
tty_initialized = true;
sync_ttysize(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE]);
tty_initialized = true;
}
}
}
@@ -1266,8 +1298,8 @@ exec_pty(struct command_details *details, struct command_status *cstat)
if (foreground) {
/* Copy terminal attrs from user tty -> pty slave. */
if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
tty_initialized = true;
sync_ttysize(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE]);
tty_initialized = true;
}
/* Start out in raw mode unless part of a pipeline or backgrounded. */
@@ -1516,7 +1548,8 @@ del_io_events(bool nonblocking)
}
/*
* Propagates tty size change signals to pty being used by the command.
* Propagates tty size change signals to pty being used by the command
* and passes new window size to the I/O plugin.
*/
static void
sync_ttysize(int src, int dst)
@@ -1526,9 +1559,12 @@ sync_ttysize(int src, int dst)
debug_decl(sync_ttysize, SUDO_DEBUG_EXEC);
if (ioctl(src, TIOCGWINSZ, &wsize) == 0) {
ioctl(dst, TIOCSWINSZ, &wsize);
(void)ioctl(dst, TIOCSWINSZ, &wsize);
if ((pgrp = tcgetpgrp(dst)) != -1)
killpg(pgrp, SIGWINCH);
if (tty_initialized)
log_winchange(wsize.ws_row, wsize.ws_col);
}
debug_return;