patch for windows xp

git-svn-id: file:///raid/svn-personal/tewi/trunk@70 8739d7e6-ffea-ec47-b151-bdff447c6205
This commit is contained in:
Nishi 2024-09-19 09:23:45 +00:00
parent fb8fbec980
commit 8d8e81e210
6 changed files with 86 additions and 34 deletions

View File

@ -6,6 +6,8 @@
#include <stdbool.h>
int cm_hex(const char* str, int len);
bool cm_nocase_endswith(const char* str, const char* end);
bool cm_endswith(const char* str, const char* end);
char* cm_html_escape(const char* str);
char* cm_url_escape(const char* str);
char* cm_strcat(const char* a, const char* b);

View File

@ -7,6 +7,8 @@
#include <ctype.h>
char* cm_strcat(const char* a, const char* b) {
if(a == NULL) a = "";
if(b == NULL) b = "";
char* str = malloc(strlen(a) + strlen(b) + 1);
memcpy(str, a, strlen(a));
memcpy(str + strlen(a), b, strlen(b));
@ -23,6 +25,24 @@ char* cm_strcat3(const char* a, const char* b, const char* c) {
char* cm_strdup(const char* str) { return cm_strcat(str, ""); }
bool cm_endswith(const char* str, const char* end) {
if(strlen(str) < strlen(end)) return false;
int i;
for(i = strlen(str) - strlen(end); i < strlen(str); i++) {
if(str[i] != end[i - strlen(str) + strlen(end)]) return false;
}
return true;
}
bool cm_nocase_endswith(const char* str, const char* end) {
if(strlen(str) < strlen(end)) return false;
int i;
for(i = strlen(str) - strlen(end); i < strlen(str); i++) {
if(tolower(str[i]) != tolower(end[i - strlen(str) + strlen(end)])) return false;
}
return true;
}
char* cm_trimstart(const char* str) {
int i;
for(i = 0; str[i] != 0; i++) {

View File

@ -82,7 +82,7 @@ int tw_http_parse(SSL* ssl, int sock, struct tw_http_request* req) {
}
#endif
int len = tw_read(ssl, sock, buffer, 512);
if(len <= 0){
if(len <= 0) {
bad = true;
break;
}
@ -284,11 +284,13 @@ getout:
if(req->path[i] == '%') {
if(req->path[i + 1] == 0) continue;
cbuf[0] = cm_hex(req->path + i + 1, 2);
char* tmp = result;
result = cm_strcat(tmp, cbuf);
free(tmp);
if(cbuf[0] != '\\') {
char* tmp = result;
result = cm_strcat(tmp, cbuf);
free(tmp);
}
i += 2;
} else {
} else if(req->path[i] != '\\') {
cbuf[0] = req->path[i];
char* tmp = result;
result = cm_strcat(tmp, cbuf);
@ -324,7 +326,7 @@ getout:
p = cm_strdup("/");
}
} else if(strcmp(pth, ".") == 0) {
} else if(oldc != '\\') {
} else {
char* tmp = p;
p = cm_strcat3(tmp, pth, cbuf);
free(tmp);

View File

@ -36,17 +36,17 @@ int startup(int argc, char** argv);
SERVICE_STATUS status;
SERVICE_STATUS_HANDLE status_handle;
void WINAPI servhandler(DWORD control){
switch(control){
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
status.dwCurrentState = SERVICE_STOP_PENDING;
break;
void WINAPI servhandler(DWORD control) {
switch(control) {
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
status.dwCurrentState = SERVICE_STOP_PENDING;
break;
}
SetServiceStatus(status_handle, &status);
}
void WINAPI servmain(DWORD argc, LPSTR* argv){
void WINAPI servmain(DWORD argc, LPSTR* argv) {
logfile = fopen(PREFIX "/logs/tewi.log", "a");
if(logfile == NULL) logfile = stderr;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
@ -60,7 +60,7 @@ void WINAPI servmain(DWORD argc, LPSTR* argv){
if(status_handle == NULL) return;
if(SetServiceStatus(status_handle, &status) == 0) return;
int st = startup(argc, argv);
if(st != -1){
if(st != -1) {
status.dwWin32ExitCode = NO_ERROR;
status.dwServiceSpecificExitCode = st;
status.dwCurrentState = SERVICE_STOPPED;
@ -87,20 +87,20 @@ int main(int argc, char** argv) {
#endif
}
int startup(int argc, char** argv){
int startup(int argc, char** argv) {
int i;
const char* confpath = PREFIX "/etc/tewi.conf";
if(argv != NULL){
if(argv != NULL) {
for(i = 1; i < argc; i++) {
if(argv[i][0] == '-') {
if(strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
if(!cm_do_log) {
cm_do_log = true;
#ifndef NO_SSL
#ifndef NO_SSL
cm_log("", "This is Tewi HTTPd, version %s, using %s", tw_get_version(), OPENSSL_VERSION_TEXT);
#else
#else
cm_log("", "This is Tewi HTTPd, version %s", tw_get_version());
#endif
#endif
} else {
cm_do_log = true;
}

View File

@ -51,6 +51,10 @@ int sockcount = 0;
SOCKADDR addresses[MAX_PORTS];
int sockets[MAX_PORTS];
#ifdef __MINGW32__
const char* reserved_names[] = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"};
#endif
/* https://qiita.com/gyu-don/items/5a640c6d2252a860c8cd */
int tw_wildcard_match(const char* wildcard, const char* target) {
const char *pw = wildcard, *pt = target;
@ -428,7 +432,7 @@ void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
char* vhost = cm_strdup(config.hostname);
int i;
time_t cmtime = 0;
if(req.headers != NULL){
if(req.headers != NULL) {
for(i = 0; req.headers[i] != NULL; i += 2) {
if(cm_strcaseequ(req.headers[i], "Host")) {
free(vhost);
@ -479,8 +483,31 @@ void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
cm_log("Server", "Document root is %s", vhost_entry->root == NULL ? "not set" : vhost_entry->root);
char* path = cm_strcat(vhost_entry->root == NULL ? "" : vhost_entry->root, req.path);
cm_log("Server", "Filesystem path is %s", path);
bool rej = false;
#ifdef __MINGW32__
for(i = 0; i < sizeof(reserved_names) / sizeof(reserved_names[0]); i++) {
char* n = cm_strcat("/", reserved_names[i]);
if(cm_nocase_endswith(path, n)) {
tw_http_error(s, sock, 403, name, port);
free(n);
rej = true;
cm_log("Server", "XP Patch ; rejecting access to device");
break;
}
free(n);
char* y = cm_strcat3("/", reserved_names[i], ":");
if(cm_nocase_endswith(path, y)) {
tw_http_error(s, sock, 403, name, port);
free(y);
rej = true;
cm_log("Server", "XP Patch ; rejecting access to device");
break;
}
free(y);
}
#endif
struct stat st;
if(stat(path, &st) == 0) {
if(!rej && stat(path, &st) == 0) {
if(!tw_permission_allowed(path, addr, req, vhost_entry)) {
tw_http_error(s, sock, 403, name, port);
} else if(S_ISDIR(st.st_mode)) {
@ -647,6 +674,7 @@ void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
fread(rmbuf, s.st_size, 1, fr);
addstring(&str, "<pre><code>%h</code></pre>\n", rmbuf);
fclose(fr);
free(rmbuf);
}
free(fpth);
}
@ -681,11 +709,11 @@ void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
}
free(vhost);
free(host);
tw_free_request(&req);
} else if(ret == -1) {
} else {
tw_http_error(s, sock, 400, name, port);
}
tw_free_request(&req);
cleanup:
#ifndef NO_SSL
if(sslworks) {
@ -717,7 +745,7 @@ void tw_server_loop(void) {
int i;
#ifdef __MINGW32__
struct thread_entry threads[2048];
for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++){
for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++) {
threads[i].used = false;
}
#endif
@ -731,13 +759,13 @@ void tw_server_loop(void) {
int ret = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
if(ret == -1) {
break;
}else if(ret == 0){
} else if(ret == 0) {
#ifdef __MINGW32__
for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++){
if(threads[i].used){
for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++) {
if(threads[i].used) {
DWORD ex;
GetExitCodeThread(threads[i].handle, &ex);
if(ex != STILL_ACTIVE){
if(ex != STILL_ACTIVE) {
CloseHandle(threads[i].handle);
threads[i].used = false;
}
@ -745,7 +773,7 @@ void tw_server_loop(void) {
}
#endif
#ifdef SERVICE
if(status.dwCurrentState == SERVICE_STOP_PENDING){
if(status.dwCurrentState == SERVICE_STOP_PENDING) {
break;
}
#endif
@ -765,18 +793,18 @@ void tw_server_loop(void) {
e->port = config.ports[i];
e->addr = claddr;
int j;
for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++){
if(threads[j].used){
for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) {
if(threads[j].used) {
DWORD ex;
GetExitCodeThread(threads[j].handle, &ex);
if(ex != STILL_ACTIVE){
if(ex != STILL_ACTIVE) {
CloseHandle(threads[j].handle);
threads[j].used = false;
}
}
}
for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++){
if(!threads[j].used){
for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) {
if(!threads[j].used) {
threads[j].handle = (HANDLE)_beginthreadex(NULL, 0, tw_server_pass, e, 0, NULL);
threads[j].used = true;
break;

View File

@ -3,7 +3,7 @@
#ifndef __TW_VERSION_H__
#define __TW_VERSION_H__
#define TW_VERSION "1.00\0"
#define TW_VERSION "1.01\0"
const char* tw_get_version(void);
const char* tw_get_platform(void);