You are viewing a plain text version of this content. The canonical link for it is here.
Posted to win32-msi-cvs@httpd.apache.org by wr...@apache.org on 2003/05/20 22:17:40 UTC
cvs commit: httpd-win32-msi/src real_features.c
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