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)); int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version, void (*deregister_hooks)(int version,
int (*deregister_hook)(struct sudo_hook *hook)); 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. 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 See the _P_o_l_i_c_y _p_l_u_g_i_n _A_P_I section for a description of
deregister_hooks. 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 _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. 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) Version 1.11 (sudo 1.8.20)
The _t_i_m_e_o_u_t entry was added to the settings list. 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 SSEEEE AALLSSOO
sudo.conf(4), sudoers(4), sudo(1m) sudo.conf(4), sudoers(4), sudo(1m)
@@ -1592,4 +1604,4 @@ DDIISSCCLLAAIIMMEERR
file distributed with ssuuddoo or https://www.sudo.ws/license.html for file distributed with ssuuddoo or https://www.sudo.ws/license.html for
complete details. 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. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" 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 .nh
.if n .ad l .if n .ad l
.SH "NAME" .SH "NAME"
@@ -1470,6 +1470,7 @@ struct io_plugin {
int (*register_hook)(struct sudo_hook *hook)); int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version, void (*deregister_hooks)(int version,
int (*deregister_hook)(struct sudo_hook *hook)); int (*deregister_hook)(struct sudo_hook *hook));
int (*change_winsize)(unsigned int lines, unsigned int cols);
}; };
.RE .RE
.fi .fi
@@ -1976,6 +1977,24 @@ See the
\fIPolicy plugin API\fR \fIPolicy plugin API\fR
section for a description of section for a description of
\fRderegister_hooks.\fR \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 .PP
\fII/O Plugin Version Macros\fR \fII/O Plugin Version Macros\fR
.PP .PP
@@ -2794,6 +2813,11 @@ The
entry was added to the entry was added to the
\fRsettings\fR \fRsettings\fR
list. 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" .SH "SEE ALSO"
sudo.conf(@mansectform@), sudo.conf(@mansectform@),
sudoers(@mansectform@), sudoers(@mansectform@),

View File

@@ -14,7 +14,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd June 2, 2017 .Dd July 11, 2017
.Dt SUDO_PLUGIN @mansectform@ .Dt SUDO_PLUGIN @mansectform@
.Os Sudo @PACKAGE_VERSION@ .Os Sudo @PACKAGE_VERSION@
.Sh NAME .Sh NAME
@@ -1298,6 +1298,7 @@ struct io_plugin {
int (*register_hook)(struct sudo_hook *hook)); int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version, void (*deregister_hooks)(int version,
int (*deregister_hook)(struct sudo_hook *hook)); int (*deregister_hook)(struct sudo_hook *hook));
int (*change_winsize)(unsigned int lines, unsigned int cols);
}; };
.Ed .Ed
.Pp .Pp
@@ -1730,6 +1731,19 @@ See the
.Sx Policy plugin API .Sx Policy plugin API
section for a description of section for a description of
.Li deregister_hooks. .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 .El
.Pp .Pp
.Em I/O Plugin Version Macros .Em I/O Plugin Version Macros
@@ -2447,6 +2461,10 @@ The
entry was added to the entry was added to the
.Li settings .Li settings
list. list.
.It Version 1.12 (sudo 1.8.21)
The
.Li change_winsize
field was added to the io_plugin struct.
.El .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr sudo.conf @mansectform@ , .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 * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -19,7 +19,7 @@
/* API version major/minor */ /* API version major/minor */
#define SUDO_API_VERSION_MAJOR 1 #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_MKVERSION(x, y) (((x) << 16) | (y))
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR) #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); int (*log_stderr)(const char *buf, unsigned int len);
void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook)); void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version, int (*deregister_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 */ /* 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); 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. * Check whether we are running in the foregroup.
* Updates the foreground global and does lazy init of the * 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; foreground = tcgetpgrp(io_fds[SFD_USERTTY]) == ppgrp;
if (foreground && !tty_initialized) { if (foreground && !tty_initialized) {
if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_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]); 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) { if (foreground) {
/* Copy terminal attrs from user tty -> pty slave. */ /* Copy terminal attrs from user tty -> pty slave. */
if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_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]); 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. */ /* 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 static void
sync_ttysize(int src, int dst) sync_ttysize(int src, int dst)
@@ -1526,9 +1559,12 @@ sync_ttysize(int src, int dst)
debug_decl(sync_ttysize, SUDO_DEBUG_EXEC); debug_decl(sync_ttysize, SUDO_DEBUG_EXEC);
if (ioctl(src, TIOCGWINSZ, &wsize) == 0) { if (ioctl(src, TIOCGWINSZ, &wsize) == 0) {
ioctl(dst, TIOCSWINSZ, &wsize); (void)ioctl(dst, TIOCSWINSZ, &wsize);
if ((pgrp = tcgetpgrp(dst)) != -1) if ((pgrp = tcgetpgrp(dst)) != -1)
killpg(pgrp, SIGWINCH); killpg(pgrp, SIGWINCH);
if (tty_initialized)
log_winchange(wsize.ws_row, wsize.ws_col);
} }
debug_return; debug_return;