httpd-win32-msi-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject cvs commit: httpd-win32-msi/src real_features.c
Date Tue, 20 May 2003 20:17:40 GMT
wrowe       2003/05/20 13:17:40

  Modified:    src      real_features.c
  Log:
    Fix a bug identified by Ryan Bloom - we may have a null p->name here,
    so the strlen which was meant to test q->name overflow could segfault.
  
  Revision  Changes    Path
  1.8       +137 -11   httpd-win32-msi/src/real_features.c
  
  Index: real_features.c
  ===================================================================
  RCS file: /home/cvs/httpd-win32-msi/src/real_features.c,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- real_features.c	2 Mar 2001 23:39:40 -0000	1.7
  +++ real_features.c	20 May 2003 20:17:40 -0000	1.8
  @@ -109,7 +109,7 @@
   	    char *str2 = inet_ntoa(*((struct in_addr *) p->h_addr_list[x]));
   	    struct hostent *q = gethostbyaddr(p->h_addr_list[x], p->h_length, p->h_addrtype);
               if (q->h_name && strchr(q->h_name, '.') 
  -                          && strlen(p->h_name) <= MAXHOSTNAMELEN)
  +                          && strlen(q->h_name) <= MAXHOSTNAMELEN)
                   strcpy(hostname, q->h_name);
   	    for (y = 0; q->h_aliases && !*hostname && q->h_aliases[y]; ++y)
{
                   if (strchr(q->h_aliases[y], '.')
  @@ -131,21 +131,30 @@
       return ERROR_SUCCESS;
   }
   
  +typedef int (isfn)(int);
  +
  +int issafe(int ch) {
  +  return isprint(ch) && !strchr(" |*()[]:;<>?$%&#'`\"", ch);
  +}
  +
  +int issafelisten(int ch) {
  +  return isprint(ch) && !strchr(" |*();<>?$%&#'`\"", ch);
  +}
   
   /* Return the first unrecognized character and truncate the
    * string after the last good character. 
    */
  -static char test_bad_ch(char *str)
  +static char test_bad_ch(char *str, isfn* goodch)
   {
       while (*str) {
  -        if (!isprint(*str) || strchr(" |*()[]:;<>?$%&#'`\"", *str)) {
  +        if (!(goodch)(*str)) {
               char ch = *str;
               while (*str) {
                   if (!isprint(*str))
                       *str = '?';
                   ++str;
               }
  -            return ch;
  +            return isprint(ch) ? ch : '?';
           }
           ++str;
       }
  @@ -180,6 +189,104 @@
                   "fill in the " fld " entry, and you can then proceed " \
                   "with installation.") 
   
  +#define BADLISTEN(fld, badch) \
  +    badch ? ("The " fld " entry cannot contain anything but digits\n\n" \
  +                "are all reserved and could cause problems for installation " \
  +                "or for the installed server.  Please click OK, correct " \
  +                "the " fld " entry, and then proceed with installation.") \
  +          : ("The " fld " entry cannot be left blank.  Please click OK, " \
  +                "fill in the " fld " entry, and you can then proceed " \
  +                "with installation.") 
  +
  +/* Stubs, to work with listen.c */
  +#include "apr_errno.h"
  +#include "apr_strings.h"
  +#include "httpd.h"
  +#include "ap_config.h"
  +#include "ap_listen.h"
  +void __stdcall ap_log_assert(const char *szExp, const char *szFile, int nLine) 
  +{
  +    DebugBreak();
  +}
  +const char* __stdcall ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden) 
  +{
  +    return NULL;
  +}
  +
  +static char *ap_log_perror_res;
  +
  +#define ERRBUF_LEN 1024
  +
  +void __cdecl ap_log_perror(const char *file, int line, int level, 
  +                           apr_status_t status, apr_pool_t *pool, 
  +                           const char *fmt, ...)
  +{
  +    char *msg = apr_palloc(pool, ERRBUF_LEN);
  +    va_list ap;
  +    va_start(ap, fmt);
  +
  +    apr_strerror(status, msg, ERRBUF_LEN);
  +    ap_log_perror_res = apr_pstrcat(pool, "(", msg, ") ",
  +                                    apr_pvsprintf(pool, fmt, ap), 
  +                                    NULL);
  +    va_end(ap);
  +}
  +
  +#define LISTEN_ERROR    "The Server Listener must be an unused tcp/ip " \
  +                        "port, or full ipaddress:port.  The given port " \
  +                        "could not be used, perhaps because of firewall, " \
  +                        "antivirus or vpn socket filtering, or perhaps " \
  +                        "because other software such as IIS is already " \
  +                        "running on this port.  The exact error was: " \
  +
  +char *test_listener(char *str)
  +{
  +    char *msg;
  +    cmd_parms *cmd;
  +    apr_pool_t *pool;
  +    apr_status_t rv;
  +    int n = ERRBUF_LEN;
  +
  +    rv = apr_initialize();
  +    if (rv) {
  +        msg = malloc(ERRBUF_LEN);
  +        strcpy (msg, LISTEN_ERROR);
  +        n = strlen(msg);
  +        return apr_strerror(rv, msg + n, ERRBUF_LEN - n);
  +    }
  +    rv = apr_pool_create(&pool, NULL);
  +    if (rv) {
  +        apr_terminate();
  +        msg = malloc(ERRBUF_LEN);
  +        strcpy (msg, LISTEN_ERROR);
  +        n = strlen(msg);
  +        return apr_strerror(rv, msg + n, ERRBUF_LEN - n);
  +    }
  +    
  +    cmd = apr_pcalloc(pool, sizeof(cmd_parms));
  +    cmd->pool = pool;
  +    cmd->server = apr_pcalloc(pool, sizeof(server_rec));
  +    cmd->server->process = apr_pcalloc(pool, sizeof(process_rec));
  +    cmd->server->process->pool = pool;
  +
  +    ap_listen_pre_config();
  +    if ((msg = (char*)ap_set_listener(cmd, NULL, str)) != NULL)
  +        msg = ap_log_perror_res;
  +    else {
  +        if (!ap_setup_listeners(cmd->server) && !msg) {
  +            msg = "Internal Fatal Error: Failed to recover listeners.";
  +        }
  +    }
  +
  +    if (msg)
  +        msg = apr_pstrcat(pool, LISTEN_ERROR, msg, NULL);
  +    
  +    apr_pool_destroy(pool);
  +    apr_terminate();
  +    return msg;
  +}
  +
  +
   UINT __declspec(dllexport) __stdcall ValidateServerName(MSIHANDLE hInstall) 
   {
       char dstr[MAXHOSTNAMELEN + 1];
  @@ -192,12 +299,10 @@
        */
       *str = '\0';  len = sizeof(str) - 1;
       MsiGetPropertyA(hInstall, "SERVERDOMAIN", str, &len);
  -    ch[0] = test_bad_ch(pch = trim_white_space(dstr, str));
  +    ch[0] = test_bad_ch(pch = trim_white_space(dstr, str), issafe);
       if (strcmp(dstr, str))
           MsiSetPropertyA(hInstall, "SERVERDOMAIN", dstr);
       if (ch[0] || !strlen(dstr)) {
  -        if (ch[0] && !isprint(ch[0]))
  -            ch[0] = '?';
           MsiSetPropertyA(hInstall, "INVALIDFIELD", "Domain Name");
           MsiSetPropertyA(hInstall, "INVALIDMESSAGE", 
                           BADFIELD("Domain Name", ch[0]));
  @@ -208,7 +313,7 @@
        */
       *str = '\0';  len = sizeof(str) - 1;
       MsiGetPropertyA(hInstall, "SERVERNAME",   str, &len);
  -    ch[0] = test_bad_ch(pch = trim_white_space(dstr, str));
  +    ch[0] = test_bad_ch(pch = trim_white_space(dstr, str), issafe);
       if (strcmp(dstr, str))
           MsiSetPropertyA(hInstall, "SERVERNAME", dstr);
       if (ch[0] || !strlen(dstr)) {
  @@ -224,12 +329,10 @@
        */
       *str = '\0';  len = sizeof(str) - 1;
       MsiGetPropertyA(hInstall, "SERVERADMIN",  str, &len);
  -    ch[0] = test_bad_ch(pch = trim_white_space(dstr, str));
  +    ch[0] = test_bad_ch(pch = trim_white_space(dstr, str), issafe);
       if (strcmp(dstr, str))
           MsiSetPropertyA(hInstall, "SERVERADMIN", dstr);
       if (ch[0] || !strlen(dstr)) {
  -        if (ch[0] && !isprint(ch[0]))
  -            ch[0] = '?';
           MsiSetPropertyA(hInstall, "INVALIDFIELD", "Administrator's Email Address");
           MsiSetPropertyA(hInstall, "INVALIDMESSAGE", 
                           BADFIELD("Administrator's Email Address", ch[0]));
  @@ -246,6 +349,29 @@
                           "correct the Administrator's Email Address entry, "
                           "including a single '@' symbol between the "
                           "mail account and mail server names,");
  +        return ERROR_SUCCESS;
  +    }
  +
  +    /* Validate the Port is not blank, is numeric
  +     */
  +    *str = '\0';  len = sizeof(str) - 1;
  +    MsiGetPropertyA(hInstall, "SERVERPORT",  str, &len);
  +    ch[0] = test_bad_ch(pch = trim_white_space(dstr, str), isdigit);
  +    if (strcmp(dstr, str))
  +        MsiSetPropertyA(hInstall, "SERVERPORT", dstr);
  +    if (ch[0] || !strlen(dstr)) {
  +        MsiSetPropertyA(hInstall, "INVALIDFIELD", "Server Port");
  +        MsiSetPropertyA(hInstall, "INVALIDMESSAGE", 
  +                        BADLISTEN("Server Port", ch[0]));
  +        return ERROR_SUCCESS;
  +    }
  +    /* Validate that the Port creates a valid listener
  +     */
  +    pch = test_listener(dstr);
  +    if (pch) {
  +        MsiSetPropertyA(hInstall, "INVALIDFIELD", "Server Port");
  +        MsiSetPropertyA(hInstall, "INVALIDMESSAGE", pch);
  +        free (pch);
           return ERROR_SUCCESS;
       }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: win32-msi-cvs-unsubscribe@httpd.apache.org
For additional commands, e-mail: win32-msi-cvs-help@httpd.apache.org


Mime
View raw message