]> granicus.if.org Git - sudo/commitdiff
Pass window size change events to the plugin.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 12 Jul 2017 11:47:28 +0000 (05:47 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 12 Jul 2017 11:47:28 +0000 (05:47 -0600)
doc/sudo_plugin.cat
doc/sudo_plugin.man.in
doc/sudo_plugin.mdoc.in
include/sudo_plugin.h
src/exec_pty.c

index 0bb30f2ec460d3f2e6f82e07232ba9226f0d5d95..2187ecf2196f1d8c8cdaf80b3aa322adb5daebbf 100644 (file)
@@ -867,6 +867,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
             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, s\bsu\bud\bdo\bo runs the command in a pseudo-tty.
@@ -1124,6 +1125,14 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
            See the _\bP_\bo_\bl_\bi_\bc_\by _\bp_\bl_\bu_\bg_\bi_\bn _\bA_\bP_\bI section for a description of
            deregister_hooks.
 
+     change_winsize
+           int (*change_winsize)(unsigned int lines, unsigned int cols);
+
+           The c\bch\bha\ban\bng\bge\be_\b_w\bwi\bin\bns\bsi\biz\bze\be() 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).
+
      _\bI_\b/_\bO _\bP_\bl_\bu_\bg_\bi_\bn _\bV_\be_\br_\bs_\bi_\bo_\bn _\bM_\ba_\bc_\br_\bo_\bs
 
      Same as for the _\bP_\bo_\bl_\bi_\bc_\by _\bp_\bl_\bu_\bg_\bi_\bn _\bA_\bP_\bI.
@@ -1563,6 +1572,9 @@ P\bPL\bLU\bUG\bGI\bIN\bN A\bAP\bPI\bI C\bCH\bHA\bAN\bNG\bGE\bEL\bLO\bOG\bG
      Version 1.11 (sudo 1.8.20)
            The _\bt_\bi_\bm_\be_\bo_\bu_\bt 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.
+
 S\bSE\bEE\bE A\bAL\bLS\bSO\bO
      sudo.conf(4), sudoers(4), sudo(1m)
 
@@ -1592,4 +1604,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.21                      June 2, 2017                      Sudo 1.8.21
+Sudo 1.8.21                      July 11, 2017                     Sudo 1.8.21
index 4e169fcccba6e1ba27e2365c40cd26b2b82c4d05..c4f03810361af2b44119d6d8c1bab6a118e3c503 100644 (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@),
index 285ca6e556e1d9ac97ad734f8777c98f383eee9c..d8bc3b910456b5a89b6ed228738682e7270c09d4 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 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@ ,
index 309e2963be6028d1d8bd751d940fcf3948fe19c3..a15ce18827d42d4bbbc242cf217788dd9cd17afe 100644 (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 */
index d8efb2979a2b128a1399348e763f49eabb7f66d4..c7cb6430357aeeb7946726b722103f540db858ca 100644 (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;