]> git.pond.sub.org Git - empserver/commitdiff
client: Delay additional input processing until after send
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 25 Jun 2017 09:13:00 +0000 (11:13 +0200)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 6 Aug 2017 09:22:29 +0000 (11:22 +0200)
We need to copy input to @auxfp to implement command line option -2,
and pass it to save_input() to enable protection against a rogue
server exploiting redirection and execute.  We currently do this right
when input enters the ring buffer, in recv_input().

Calling save_input() before sending input to the server is sloppy: it
can make the client accept "future" redirections and executes.

Delay save_input() until after input is sent.  For simplicity, delay
copying to @auxfp as well.

This is actually pretty close to how things worked before commit
8b7d0b9 (v4.3.11).

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
src/client/play.c

index 2e0742336fd9971d272bdafd0017bb3dad84feac..210ff733f682a9a85736a3d42831a03f8172b791 100644 (file)
@@ -421,7 +421,7 @@ recv_output(int sock)
 static int
 recv_input(int fd, struct ring *inbuf)
 {
 static int
 recv_input(int fd, struct ring *inbuf)
 {
-    int n, i, ch;
+    int n;
     int res = 1;
 
     n = ring_from_file(inbuf, fd);
     int res = 1;
 
     n = ring_from_file(inbuf, fd);
@@ -435,16 +435,6 @@ recv_input(int fd, struct ring *inbuf)
        res = 0;
     }
 
        res = 0;
     }
 
-    /* copy input to AUXFP etc. */
-    for (i = -n; i < 0; i++) {
-       ch = ring_peek(inbuf, i);
-       assert(ch != EOF);
-       if (ch != '\r')
-           save_input(ch);
-       if (auxfp)
-           putc(ch, auxfp);
-    }
-
     return res;
 }
 
     return res;
 }
 
@@ -452,14 +442,24 @@ static int
 send_input(int fd, struct ring *inbuf)
 {
     struct iovec iov[2];
 send_input(int fd, struct ring *inbuf)
 {
     struct iovec iov[2];
-    int cnt;
+    int cnt, i, ch;
     ssize_t res;
 
     cnt = ring_to_iovec(inbuf, iov);
     res = writev(fd, iov, cnt);
     if (res < 0)
        return res;
     ssize_t res;
 
     cnt = ring_to_iovec(inbuf, iov);
     res = writev(fd, iov, cnt);
     if (res < 0)
        return res;
-    ring_discard(inbuf, res);
+
+    /* Copy input to @auxfp etc. */
+    for (i = 0; i < res; i++) {
+       ch = ring_getc(inbuf);
+       assert(ch != EOF);
+       if (ch != '\r')
+           save_input(ch);
+       if (auxfp)
+           putc(ch, auxfp);
+    }
+
     return res;
 }
 
     return res;
 }