]> git.pond.sub.org Git - empserver/commitdiff
Flaws in the Empire protocol make redirections within execute next to
authorMarkus Armbruster <armbru@pond.sub.org>
Wed, 28 Nov 2007 07:10:27 +0000 (07:10 +0000)
committerMarkus Armbruster <armbru@pond.sub.org>
Wed, 28 Nov 2007 07:10:27 +0000 (07:10 +0000)
impossible to implement correctly, and nested execute practically
useless (#116377).  Catch and refuse those:
(executing): New.
(doexecute, prompt): Set and clear it.
(redir_authorized): Reject if set.
(doexecute, play): Don't signal doexecute() failure through input_fd,
because that screws up up when we're executing already.  Increment
send_eof in doexecute() instead.
(send_eof): External linkage.

src/client/misc.h
src/client/play.c
src/client/servcmd.c

index ee9c9e064851cf6cc2891a7bd3f0dd6bc88e7648..8cb8acd39278363f5edb2907638cba300acb5b35 100644 (file)
@@ -45,6 +45,7 @@ extern char empirehost[];
 extern char empireport[];
 extern int eight_bit_clean;
 extern int input_fd;
+extern int send_eof;
 extern FILE *auxfp;
 extern char *SO;
 extern char *SE;
index 956ca410a9440e5c084dc3d9c95ba2f78b5bb587..ff465e5fb3abb0fb1e36e4bf8fd72381c8c0011c 100644 (file)
@@ -51,6 +51,7 @@
 #define INTR_COOKIE "\naborted\n"
 
 int input_fd;
+int send_eof;                          /* need to send EOF_COOKIE */
 static volatile sig_atomic_t send_intr; /* need to send INTR_COOKIE */
 
 /*
@@ -218,7 +219,6 @@ play(int sock)
     struct sigaction sa;
     struct ring inbuf;         /* input buffer, draining to SOCK */
     int eof_fd0;               /* read fd 0 hit EOF? */
-    int send_eof;              /* need to send EOF_COOKIE */
     fd_set rdfd, wrfd;
     int n;
 
@@ -229,7 +229,8 @@ play(int sock)
     sigaction(SIGPIPE, &sa, NULL);
 
     ring_init(&inbuf);
-    eof_fd0 = send_eof = 0;
+    eof_fd0 = send_eof = send_intr = 0;
+    input_fd = 0;
 
     for (;;) {
        FD_ZERO(&rdfd);
@@ -278,8 +279,7 @@ play(int sock)
                send_eof++;
                if (input_fd) {
                    /* execute done, switch back to fd 0 */
-                   if (input_fd > 0)
-                       close(input_fd);
+                   close(input_fd);
                    input_fd = 0;
                } else {
                    /* stop reading input, drain socket ring buffers */
@@ -308,11 +308,6 @@ play(int sock)
            }
            if (n == 0)
                return 0;
-           if (input_fd < 0) {
-               /* execute failed */
-               input_fd = 0;
-               send_eof++;
-           }
        }
     }
 }
index 0b837f3ebd464927fc43099addce610f8e63f82c..aaab478a1f05177e9ca7ab1e511f9241c109f656 100644 (file)
@@ -51,6 +51,7 @@ FILE *auxfp;
 
 static FILE *redir_fp;
 static FILE *pipe_fp;
+static int executing;
 static size_t input_to_forget;
 
 static void prompt(int, char *, char *);
@@ -126,6 +127,7 @@ prompt(int code, char *prompt, char *teles)
            (void)pclose(pipe_fp);
            pipe_fp = NULL;
        }
+       executing = 0;
        if (input_to_forget) {
            forget_input(input_to_forget);
            input_to_forget = 0;
@@ -157,6 +159,11 @@ redir_authorized(char *arg, char *attempt)
 {
     size_t seen = seen_input(arg);
 
+    if (executing) {
+       fprintf(stderr, "Can't %s in a script\n", attempt);
+       return 0;
+    }
+
     if (!seen || (input_to_forget && input_to_forget != seen)) {
        fprintf(stderr, "WARNING!  Server attempted to %s %s\n",
                attempt, arg);
@@ -217,7 +224,7 @@ doredir(char *p)
 static void
 dopipe(char *p)
 {
-    if (!redir_authorized(p, "pipe to command"))
+    if (!redir_authorized(p, "pipe to shell command"))
        return;
     if (*p++ != '|') {
        fprintf(stderr, "WARNING!  Weird pipe %s", p);
@@ -239,22 +246,29 @@ dopipe(char *p)
 static void
 doexecute(char *p)
 {
-    input_fd = -1;             /* make sure play() terminates exec */
+    int fd;
 
-    if (!redir_authorized(p, "read file"))
+    if (!redir_authorized(p, "execute script file")) {
+       send_eof++;
        return;
+    }
 
     p = fname(p);
     if (*p == 0) {
        fprintf(stderr, "Need a file to execute\n");
+       send_eof++;
        return;
     }
 
-    if ((input_fd = open(p, O_RDONLY)) < 0) {
+    if ((fd = open(p, O_RDONLY)) < 0) {
        fprintf(stderr, "Can't open execute file %s: %s\n",
                p, strerror(errno));
+       send_eof++;
        return;
     }
+
+    input_fd = fd;
+    executing = 1;
 }
 
 void