Fri, 30 Dec 2016 18:47:26 +0100
adds new a pathcheck saf and improves content type matchin and improves content type matching
--- 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; +}