]> Git repositories of Nishi - tewi.git/commitdiff
patch for windows xp
authorNishi <nishi@nishi.boats>
Thu, 19 Sep 2024 09:23:45 +0000 (09:23 +0000)
committerNishi <nishi@nishi.boats>
Thu, 19 Sep 2024 09:23:45 +0000 (09:23 +0000)
git-svn-id: file:///raid/svn-personal/tewi/trunk@70 8739d7e6-ffea-ec47-b151-bdff447c6205

Common/cm_string.h
Common/string.c
Server/http.c
Server/main.c
Server/server.c
Server/tw_version.h

index 945ba748506a762ac557612bcd86825ff11dd328..0132139f149391b03a8e8c9f370e562b240f0b0c 100644 (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);
index 6b7af53d0c9c15c91ff3e607f537496b20ef2341..ebb780523790ee8e414aaa0c6f331b4bcab22b52 100644 (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++) {
index fbbbf8d0d9cf7a7c3f153f5941139c948e81ab15..5b7fc8d37b7163a4499209ebc16681e3aaadae9e 100644 (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);
index 6105f9c6cccb6dae9f3c6263b6a6ffff74250bfc..3f36e0990b37db8e7d962aca01b01962c6bd05bb 100644 (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;
                                        }
index 4618e65c86d0cff2ee55ab3251790fcbd8e18c1d..1c78386a8ede39e32297ef05a35040ddacc5976d 100644 (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;
index 568ed38b1c7f3ced2f942bc2808c3c6fbdd4efc4..24beee15b4b976ad04050f292259dda3f49639c2 100644 (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);