adds new a pathcheck saf and improves content type matchin and improves content type matching

Fri, 30 Dec 2016 18:47:26 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 30 Dec 2016 18:47:26 +0100
changeset 142
55298bc9ed28
parent 141
ff311b63c3af
child 143
6bf5d2f37425

adds new a pathcheck saf and improves content type matchin and improves content type matching

src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.h file | annotate | diff | comparison | revisions
src/server/daemon/main.c file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.c file | annotate | diff | comparison | revisions
src/server/daemon/ws-fn.c file | annotate | diff | comparison | revisions
src/server/safs/pathcheck.c file | annotate | diff | comparison | revisions
src/server/safs/pathcheck.h file | annotate | diff | comparison | revisions
src/server/util/io.c file | annotate | diff | comparison | revisions
--- a/src/server/daemon/httprequest.c	Fri Dec 30 14:15:52 2016 +0100
+++ b/src/server/daemon/httprequest.c	Fri Dec 30 18:47:26 2016 +0100
@@ -799,7 +799,7 @@
                                 rq->rq.srvhdrs);
                     }
                     // compare types
-                    if(strcmp(dtp, content_type) != 0) {
+                    if(!contenttype_match(sstr(dtp), sstr(content_type))) {
                         continue;
                     }
                 }
@@ -1060,7 +1060,10 @@
             return 1;
         }
     } else if(cmp[0] == 0) {
-        /* empty string */
+        // empty string
+        log_ereport(
+                LOG_WARN,
+                "Skipped service saf with empty method parameter");
         return 0;
     }
 
@@ -1085,6 +1088,43 @@
 }
 
 /*
+ * checks if the content type matches the cmp string
+ * the format of cmp is a single string with wildcards or a list
+ * of types (also with wildcard support)
+ * (type1|type2*)
+ */
+int contenttype_match(sstr_t cmp, sstr_t ctype) {
+    if(cmp.ptr[0] != '(') {
+        if(cmp.ptr[0] == '*') {
+            cmp.ptr++;
+            cmp.length--;
+            return sstrsuffix(ctype, cmp);
+        } else if(cmp.ptr[cmp.length-1] == '*') {
+            cmp.length--;
+            return sstrprefix(ctype, cmp);
+        } else {
+            return !sstrcmp(cmp, ctype);
+        }
+    } else if(cmp.ptr[0] == 0) {
+        log_ereport(LOG_WARN, "Skipped service saf with empty type parameter");
+        return 0;
+    }
+    
+    cmp = sstrsubsl(cmp, 1, cmp.length - 2);
+    
+    int begin = 0;
+    for(int i=0;i<cmp.length;i++) {
+        if(cmp.ptr[i] == '|') {
+            if(contenttype_match(sstrsubsl(cmp, begin, i-begin), ctype)) {
+                return 1;
+            }
+            begin = i + 1;
+        }
+    }
+    return contenttype_match(sstrsubs(cmp, begin), ctype);
+}
+
+/*
  * adds objects with specific name or path to the httpd_objset
  */
 int add_objects(
--- a/src/server/daemon/httprequest.h	Fri Dec 30 14:15:52 2016 +0100
+++ b/src/server/daemon/httprequest.h	Fri Dec 30 18:47:26 2016 +0100
@@ -126,6 +126,7 @@
         char *path);
 
 int method_match(char *cmp, char *method);
+int contenttype_match(sstr_t cmp, sstr_t ctype);
 
 /* request.h functions */
 int request_initialize(
--- a/src/server/daemon/main.c	Fri Dec 30 14:15:52 2016 +0100
+++ b/src/server/daemon/main.c	Fri Dec 30 18:47:26 2016 +0100
@@ -163,13 +163,13 @@
     int status;
     status = webserver_init();
     if(status != 0) {
-        fprintf(stderr, "Cannot initialize server!\n");
+        log_ereport(LOG_FAILURE, "Cannot initialize server.");
         return EXIT_FAILURE;
     }
 
     status = webserver_run();
     if(status != 0) {
-        fprintf(stderr, "Cannot run server!\n");
+        log_ereport(LOG_FAILURE, "Cannot run server.");
         return EXIT_FAILURE;
     }
      
--- a/src/server/daemon/sessionhandler.c	Fri Dec 30 14:15:52 2016 +0100
+++ b/src/server/daemon/sessionhandler.c	Fri Dec 30 18:47:26 2016 +0100
@@ -61,13 +61,6 @@
     int ret = SSL_read(conn->ssl, buf, len);
     if(ret <= 0) {
         conn->ssl_error = SSL_get_error(conn->ssl, ret);
-        if(conn->ssl_error == SSL_ERROR_SYSCALL) {
-            log_ereport(
-                    LOG_VERBOSE,
-                    "Connection: %d: SSL_read failed: %s",
-                    (int)conn,
-                    strerror(errno));
-        }
     }
     return ret;
 }
@@ -76,22 +69,17 @@
     int ret = SSL_write(conn->ssl, buf, len);
     if(ret <= 0) {
         conn->ssl_error = SSL_get_error(conn->ssl, ret);
-        if(conn->ssl_error == SSL_ERROR_SYSCALL) {
-            log_ereport(
-                    LOG_VERBOSE,
-                    "Connection: %d: SSL_write failed: %s",
-                    (int)conn,
-                    strerror(errno));
-        }
     }
     return ret;
 }
 
 void connection_ssl_close(Connection *conn) {
-    int ret = SSL_shutdown(conn->ssl);
-    if(ret != 1) {
-        conn->ssl_error = SSL_get_error(conn->ssl, ret);
-        log_ereport(LOG_VERBOSE, "SSL_shutdown failed: %d", conn->ssl_error);
+    if(!conn->ssl_error) {
+        int ret = SSL_shutdown(conn->ssl);
+        if(ret != 1) {
+            conn->ssl_error = SSL_get_error(conn->ssl, ret);
+            log_ereport(LOG_VERBOSE, "SSL_shutdown failed: %d", conn->ssl_error);
+        }
     }
     close(conn->fd);
 }
--- a/src/server/daemon/ws-fn.c	Fri Dec 30 14:15:52 2016 +0100
+++ b/src/server/daemon/ws-fn.c	Fri Dec 30 18:47:26 2016 +0100
@@ -65,6 +65,7 @@
     { "append-acl", append_acl, NULL, NULL, 0},
     { "check-acl", check_acl, NULL, NULL, 0},
     { "find-index", find_index, NULL, NULL, 0},
+    { "dir-redirect", dir_redirect, NULL, NULL, 0},
     { "print-message", print_message, NULL, NULL, 0},
     { "common-log", common_log, NULL, NULL, 0},
     { "send-cgi", send_cgi, NULL, NULL, 0},
--- a/src/server/safs/pathcheck.c	Fri Dec 30 14:15:52 2016 +0100
+++ b/src/server/safs/pathcheck.c	Fri Dec 30 18:47:26 2016 +0100
@@ -37,6 +37,8 @@
 #include "../daemon/session.h"
 #include "../daemon/vserver.h"
 
+#include "../daemon/vfs.h"
+
 #include "../config/acl.h"
 
 int require_auth(pblock *pb, Session *sn, Request *rq) {
@@ -157,3 +159,32 @@
     
     return ret;
 }
+
+int dir_redirect(pblock *pb, Session *sn, Request *rq) {
+    char *path = pblock_findkeyval(pb_key_path, rq->vars);
+    
+    // TODO: VFS support
+    
+    struct stat s;
+    if(stat(path, &s) != 0) {
+        return REQ_NOACTION;
+    }
+    
+    // TODO: remove code duplication (service.c)
+    if(S_ISDIR(s.st_mode) && path[strlen(path)-1] != '/') {
+        pblock_nvinsert("content-length", "0", rq->srvhdrs);
+        pblock_removekey(pb_key_content_type, rq->srvhdrs);
+        char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
+        size_t urilen = strlen(uri);
+        char *location = pool_malloc(sn->pool, urilen + 2);
+        memcpy(location, uri, urilen);
+        location[urilen] = '/';
+        location[urilen+1] = '\0';
+        pblock_kvinsert(pb_key_location, location, urilen + 1, rq->srvhdrs);
+        protocol_status(sn, rq, 302, NULL);
+        http_start_response(sn, rq);
+        return REQ_ABORTED;
+    }
+    
+    return REQ_PROCEED;
+}
--- a/src/server/safs/pathcheck.h	Fri Dec 30 14:15:52 2016 +0100
+++ b/src/server/safs/pathcheck.h	Fri Dec 30 18:47:26 2016 +0100
@@ -45,6 +45,8 @@
 
 int find_index(pblock *pb, Session *sn, Request *rq);
 
+int dir_redirect(pblock *pb, Session *sn, Request *rq);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/src/server/util/io.c	Fri Dec 30 14:15:52 2016 +0100
+++ b/src/server/util/io.c	Fri Dec 30 18:47:26 2016 +0100
@@ -361,6 +361,7 @@
     sstr_t buf = ucx_vasprintf(ucx_default_allocator(), format, arg);
     ssize_t r = net_write(fd, buf.ptr, buf.length);
     free(buf.ptr);
+    va_end(arg);
     return r;
 }
 

mercurial