You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by W G Stoddard <wg...@us.ibm.com> on 1998/07/07 14:44:12 UTC

[PATCH] PR2356 - SSI exec

Ref PR2356...

This is an update of a patch I sent in earlier.  There are 13 new
lines of code to detect and handle shellcmd.  COMMAND.COM is used
to exec the script on Win95, CMD.EXE on NT.

Intentionally left out a performance improvement that saves the result
of GetVersionEx in a global and uses the saved value (rather than calling
GetVersionEx again) on all calls after the first.  Will gladly post it if you
think it is
worthwhile.

Bill Stoddard
wgstodda@us.ibm.com


*** util_script.c.orig Sat Jun 27 21:05:45 1998
--- util_script.c Mon Jul 06 18:40:23 1998
***************
*** 792,862 ****
   interpreter[0] = 0;
   pid = -1;

!  exename = strrchr(r->filename, '/');
!  if (!exename) {
!      exename = strrchr(r->filename, '\\');
!  }
!  if (!exename) {
!      exename = r->filename;
!  }
!  else {
!      exename++;
!  }
!  dot = strrchr(exename, '.');
!  if (dot) {
!      if (!strcasecmp(dot, ".BAT")
!   || !strcasecmp(dot, ".CMD")
!   || !strcasecmp(dot, ".EXE")
!   ||  !strcasecmp(dot, ".COM")) {
!   is_exe = 1;
!      }
!  }
!
!  if (!is_exe) {
!      program = fopen(r->filename, "rb");
!      if (!program) {
!   ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
!         "fopen(%s) failed", r->filename);
!   return (pid);
!      }
!      sz = fread(interpreter, 1, sizeof(interpreter) - 1, program);
!      if (sz < 0) {
!   ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
!         "fread of %s failed", r->filename);
!   fclose(program);
!   return (pid);
!      }
!      interpreter[sz] = 0;
!      fclose(program);
!      if (!strncmp(interpreter, "#!", 2)) {
!   is_script = 1;
!   for (i = 2; i < sizeof(interpreter); i++) {
!       if ((interpreter[i] == '\r')
!    || (interpreter[i] == '\n')) {
!    break;
!       }
!   }
!   interpreter[i] = 0;
!   for (i = 2; interpreter[i] == ' '; ++i)
!       ;
!   memmove(interpreter+2,interpreter+i,strlen(interpreter+i)+1);
!      }
!      else {
!          /* Check to see if it's a executable */
!                 IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)interpreter;
!                 if (hdr->e_magic == IMAGE_DOS_SIGNATURE && hdr->e_cblp < 512)
{
!                     is_binary = 1;
!   }
!      }
!  }
!         /* Bail out if we haven't figured out what kind of
!          * file this is by now..
!          */
!         if (!is_exe && !is_script && !is_binary) {
!             ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
!     "%s is not executable", r->filename);
!             return (pid);
!  }

   /*
    * Make child process use hPipeOutputWrite as standard out,
--- 792,864 ----
   interpreter[0] = 0;
   pid = -1;

!         if (!shellcmd) {
!             exename = strrchr(r->filename, '/');
!             if (!exename) {
!                 exename = strrchr(r->filename, '\\');
!             }
!             if (!exename) {
!                 exename = r->filename;
!             }
!             else {
!                 exename++;
!             }
!             dot = strrchr(exename, '.');
!             if (dot) {
!                 if (!strcasecmp(dot, ".BAT")
!                     || !strcasecmp(dot, ".CMD")
!                     || !strcasecmp(dot, ".EXE")
!                     ||  !strcasecmp(dot, ".COM")) {
!                     is_exe = 1;
!                 }
!             }
!
!             if (!is_exe) {
!                 program = fopen(r->filename, "rb");
!                 if (!program) {
!                     ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
!                                  "fopen(%s) failed", r->filename);
!                     return (pid);
!                 }
!                 sz = fread(interpreter, 1, sizeof(interpreter) - 1, program);
!                 if (sz < 0) {
!                     ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
!                                  "fread of %s failed", r->filename);
!                     fclose(program);
!                     return (pid);
!                 }
!                 interpreter[sz] = 0;
!                 fclose(program);
!                 if (!strncmp(interpreter, "#!", 2)) {
!                     is_script = 1;
!                     for (i = 2; i < sizeof(interpreter); i++) {
!                         if ((interpreter[i] == '\r')
!                             || (interpreter[i] == '\n')) {
!                             break;
!                         }
!                     }
!                     interpreter[i] = 0;
!                     for (i = 2; interpreter[i] == ' '; ++i)
!                         ;
!
memmove(interpreter+2,interpreter+i,strlen(interpreter+i)+1);
!                 }
!                 else {
!                     /* Check to see if it's a executable */
!                     IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)interpreter;
!                     if (hdr->e_magic == IMAGE_DOS_SIGNATURE && hdr->e_cblp <
512) {
!                         is_binary = 1;
!                     }
!                 }
!             }
!             /* Bail out if we haven't figured out what kind of
!              * file this is by now..
!              */
!             if (!is_exe && !is_script && !is_binary) {
!                 ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
!                          "%s is not executable", r->filename);
!                 return (pid);
!             }
!         }

   /*
    * Make child process use hPipeOutputWrite as standard out,
***************
*** 869,875 ****
   si.hStdOutput  = pinfo->hPipeOutputWrite;
   si.hStdError   = pinfo->hPipeErrorWrite;

!  if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) {
       if (is_exe || is_binary) {
           /*
            * When the CGI is a straight binary executable,
--- 871,892 ----
   si.hStdOutput  = pinfo->hPipeOutputWrite;
   si.hStdError   = pinfo->hPipeErrorWrite;

!         if (shellcmd) {
!             char *shell_cmd = "CMD.EXE /C ";
!             OSVERSIONINFO osver;
!             osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
!
!             /*
!              * Use CMD.EXE for NT, COMMAND.COM for WIN95
!              */
!             if (GetVersionEx(&osver)) {
!                 if (osver.dwPlatformId != VER_PLATFORM_WIN32_NT) {
!                     shell_cmd = "COMMAND.COM /C ";
!                 }
!             }
!             pCommand = ap_pstrcat(r->pool, shell_cmd, argv0, NULL);
!         }
!  else if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) {
       if (is_exe || is_binary) {
           /*
            * When the CGI is a straight binary executable,



Users of the Apache webserver are hereby granted a non-exclusive, irrevocable,
world-wide, royalty-free, non-transferable license to use, execute, prepare
derivative works of, and distribute (internally and externally, and including
derivative works) the code accompanying this license as part of, and integrated
into the Apache webserver.

This code is provided "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTY OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK ARISING OUT OF THE USE
OR PERFORMANCE OF THIS CODE REMAINS WITH USERS OF THE APACHE WEBSERVER.

I represent and warrant that I am legally entitled to grant the above license.