Hello community, here is the log from the commit of package hiawatha for openSUSE:Factory checked in at 2015-01-12 09:50:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hiawatha (Old) and /work/SRC/openSUSE:Factory/.hiawatha.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hiawatha" Changes: -------- --- /work/SRC/openSUSE:Factory/hiawatha/hiawatha.changes 2014-12-16 14:48:36.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.hiawatha.new/hiawatha.changes 2015-01-12 09:50:22.000000000 +0100 @@ -1,0 +2,12 @@ +Sun Jan 11 22:23:28 UTC 2015 - [email protected] + +- Update to 9.10: + * Support for banning bad clients who connect via a proxy. + * UrlToolkit option Do added. Changed how Call and Skip should be called. + * General UrlToolkit improvements. See config/toolkit.conf for syntax. + * Hiawatha now prefers reverse proxies with a scheme matching the one of the + client connection. See config/toolkit.conf for syntax. + * Hiawatha will now first process UrlToolkit rules before using ReverseProxy. + * Small bugfixes and improvements. + +------------------------------------------------------------------- Old: ---- hiawatha-9.9.tar.gz New: ---- hiawatha-9.10.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hiawatha.spec ++++++ --- /var/tmp/diff_new_pack.Loi9z4/_old 2015-01-12 09:50:23.000000000 +0100 +++ /var/tmp/diff_new_pack.Loi9z4/_new 2015-01-12 09:50:23.000000000 +0100 @@ -1,8 +1,8 @@ # # spec file for package hiawatha # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. -# Copyright (c) 2013-2014 Mariusz Fik <[email protected]>. +# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2013-2015 Mariusz Fik <[email protected]>. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,7 +20,7 @@ %define webroot /srv/www Name: hiawatha -Version: 9.9 +Version: 9.10 Release: 0 Summary: A secure and advanced webserver License: GPL-2.0 @@ -54,16 +54,11 @@ %prep %setup -q +# Remove bundled source for polarssl, we use system version +rm -rv polarssl %build -mkdir build -cd build -cmake .. \ - -DCMAKE_C_FLAGS="%{optflags} -pie -fPIC" \ - -DCMAKE_INSTALL_PREFIX="%{_prefix}" \ - -DCMAKE_INSTALL_BINDIR="%{_bindir}" \ - -DCMAKE_INSTALL_SBINDIR="%{_sbindir}" \ - -DCMAKE_INSTALL_LIBDIR=%{_libdir} \ +%cmake \ -DCONFIG_DIR="%{_sysconfdir}/hiawatha" \ -DLOG_DIR="%{_localstatedir}/log/hiawatha" \ -DPID_DIR="%{_localstatedir}/run" \ @@ -83,8 +78,7 @@ make %{?_smp_mflags} %install -cd build -%make_install +%cmake_install install -D -m0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/logrotate.d/%{name} install -D -m0644 %{SOURCE2} %{buildroot}%{_unitdir}/%{name}.service @@ -97,9 +91,6 @@ install -D -m 0644 %{S:101} \ %{buildroot}%{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/%{name}-ssl -# temp fix -rm -vf %{buildroot}%{_libdir}/%{name}/libpolarssl.so - %pre %service_add_pre %{name}.service ++++++ hiawatha-9.9.tar.gz -> hiawatha-9.10.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/CMakeLists.txt new/hiawatha-9.10/CMakeLists.txt --- old/hiawatha-9.9/CMakeLists.txt 2014-11-30 19:50:43.000000000 +0100 +++ new/hiawatha-9.10/CMakeLists.txt 2015-01-01 20:53:39.000000000 +0100 @@ -35,13 +35,16 @@ # Settings set(HIAWATHA_VERSION_MAJOR 9) -set(HIAWATHA_VERSION_MINOR 9) +set(HIAWATHA_VERSION_MINOR 10) set(HIAWATHA_VERSION_PATCH 0) +set(HIAWATHA_VERSION_TWEAK 0) string(TOLOWER ${CMAKE_PROJECT_NAME} PROJECT_NAME) -if(${HIAWATHA_VERSION_PATCH} EQUAL 0) - set(HIAWATHA_VERSION "${HIAWATHA_VERSION_MAJOR}.${HIAWATHA_VERSION_MINOR}") -else() - set(HIAWATHA_VERSION "${HIAWATHA_VERSION_MAJOR}.${HIAWATHA_VERSION_MINOR}.${HIAWATHA_VERSION_PATCH}") +set(HIAWATHA_VERSION "${HIAWATHA_VERSION_MAJOR}.${HIAWATHA_VERSION_MINOR}") +if(NOT ${HIAWATHA_VERSION_PATCH} EQUAL 0) + set(HIAWATHA_VERSION "${HIAWATHA_VERSION}.${HIAWATHA_VERSION_PATCH}") +endif() +if(NOT ${HIAWATHA_VERSION_TWEAK} EQUAL 0) + set(HIAWATHA_VERSION "${HIAWATHA_VERSION}-${HIAWATHA_VERSION_TWEAK}") endif() if(EXISTS "/proc/loadavg") option(ENABLE_LOADCHECK "Enable the ability to check for server load." on) @@ -172,6 +175,6 @@ install(FILES extra/index.html DESTINATION ${WEBROOT_DIR}) # Create directories -install(DIRECTORY empty DESTINATION ${LOG_DIR} PATTERN "empty" EXCLUDE) -install(DIRECTORY empty DESTINATION ${PID_DIR} PATTERN "empty" EXCLUDE) -install(DIRECTORY empty DESTINATION ${WORK_DIR} PATTERN "empty" EXCLUDE) +install(DIRECTORY DESTINATION ${LOG_DIR}) +install(DIRECTORY DESTINATION ${PID_DIR}) +install(DIRECTORY DESTINATION ${WORK_DIR}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/ChangeLog new/hiawatha-9.10/ChangeLog --- old/hiawatha-9.9/ChangeLog 2014-12-07 12:15:15.000000000 +0100 +++ new/hiawatha-9.10/ChangeLog 2015-01-03 19:09:50.000000000 +0100 @@ -1,3 +1,15 @@ +hiawatha (9.10) stable; urgency=low + + * Support for banning bad clients who connect via a proxy. + * UrlToolkit option Do added. Changed how Call and Skip should be called. + * General UrlToolkit improvements. See config/toolkit.conf for syntax. + * Hiawatha now prefers reverse proxies with a scheme matching the one of + the client connection. See config/toolkit.conf for syntax. + * Hiawatha will now first process UrlToolkit rules before using ReverseProxy. + * Small bugfixes and improvements. + + -- Hugo Leisink <[email protected]> Sat, 3 Jan 2015 19:09:11 +0100 + hiawatha (9.9) stable; urgency=low * HTTPAuthToCGI option added. @@ -8,7 +20,7 @@ * Dropped support for SSL3.0. * Small bugfixes and improvements. - -- Hugo Leisink <[email protected]> Sun, 7 Dec 2014 12:15:57 +0100 + -- Hugo Leisink <[email protected]> Sun, 7 Dec 2014 12:15:57 +0100 hiawatha (9.8) stable; urgency=low diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/config/toolkit.conf new/hiawatha-9.10/config/toolkit.conf --- old/hiawatha-9.9/config/toolkit.conf 2014-12-08 13:38:23.000000000 +0100 +++ new/hiawatha-9.10/config/toolkit.conf 2014-12-29 09:45:24.000000000 +0100 @@ -1,12 +1,19 @@ +# This file does nothing but to give you an overview of the UrlToolkit syntax. + +VirtualHost { + ... + UseToolkit = <toolkit_id> +} + + UrlToolkit { ToolkitID = <toolkit_id> - Call <rewrite_id> - Header <key> [!]<value> Call|DenyAccess|Exit|Goto|Return|Skip|Use - Match [!]<url> Ban|Call|DenyAccess|Exit|Expire|Goto|Return|Rewrite|Redirect|Skip|UseFastCGI - Method [!]<request method> Call|DenyAccess|Exit|Goto|Redirect|Return|Skip|Use - RequestURI exists|isfile|isdir Return|Exit - Skip <lines> + Do Ban|Call|DenyAccess|Exit|Goto|Return|Skip|Use + Header <key> [!]<value> Ban|Call|DenyAccess|Exit|Goto|Return|Skip|Use + Match [!]<url> Ban|Call|DenyAccess|Exit|Expire|Goto|Redirect|Return|Rewrite|Skip|UseFastCGI + Method [!]<request method> Call|DenyAccess|Exit|Goto|Return|Skip|Use + RequestURI exists|isfile|isdir Call|Return|Exit|Skip UseSSL Call|Exit|Goto|Return|Skip } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/man/hiawatha.1.in new/hiawatha-9.10/man/hiawatha.1.in --- old/hiawatha-9.9/man/hiawatha.1.in 2014-12-06 10:13:38.000000000 +0100 +++ new/hiawatha-9.10/man/hiawatha.1.in 2015-01-03 16:31:30.000000000 +0100 @@ -599,7 +599,7 @@ (requires that Hiawatha was not compiled with -DENABLE_SSL=off) .TP .B ReverseProxy [!]<pattern> http[s]://<hostname>[:<port>][/<path>] [<timeout>] [keep-alive] -Forward the request with URLs that match the regular expression <pattern> to another webserver, where <path> is placed before the original URL. Note that the reverse proxy selection comes before the URL toolkit handling. When <hostname> is an IP address, the value of the Host HTTP header is unchanged. Otherwise, it is replaced with the value of <hostname>. The connection is closed after <timeout> seconds, which is set to 5 seconds by default. By default, Hiawatha doesn't use keep-alive connections to the final webserver. You can enable this by adding 'keep-alive' to the configuration line. See also CAcertificates. +Forward the request with URLs that match the regular expression <pattern> to another webserver, where <path> is placed before the original URL. Note that the reverse proxy selection comes before the URL toolkit handling. When <hostname> is an IP address, the value of the Host HTTP header is unchanged. Otherwise, it is replaced with the value of <hostname>. The connection is closed after <timeout> seconds, which is set to 5 seconds by default. By default, Hiawatha doesn't use keep-alive connections to the final webserver. You can enable this by adding 'keep-alive' to the configuration line. When specifying multiple reverse proxies for one (virtual) host, Hiawatha prefers reverse proxies with a scheme (HTTP/HTTPS) matching the one of the client connection. See also CAcertificates. .br Example: ReverseProxy ^/icons http://resources.lan/images .TP @@ -795,16 +795,18 @@ .SH URL TOOLKIT How to use the URL toolkit is explained in this chapter. To use URL toolkits, Hiawatha should not have been compiled with -DENABLE_TOOLKIT=off. The main toolkit commands are: .TP -.B Call <toolkit_id> -Execute toolkit section <toolkit_id> and continue in the current section. +.B Do <action> +Perform an action, where <action> can be one of the following: +.br +Ban, Call, DenyAccess, Exit, Goto, Return, Skip or Use. .br -Example: Call other_rule_set +Example: Do Call other_rule_set .TP .B Header <key> [!]<pattern> <action> .br Perform an action when the HTTP header <key> matches the regular expresion <pattern>, where <action> can be one of the following: .br -Call, DenyAccess, Exit, Goto, Redirect, Return, Skip and Use. +Ban, Call, DenyAccess, Exit, Goto, Return, Skip or Use. .br A negative pattern (leading exclamation mark) can't be used with the redirect action. The <key> can be * to test every HTTP header. .TP @@ -820,12 +822,14 @@ .br Perform an action when the request method equals <request method>, where <action> can be one of the following: .br -Call, DenyAccess, Exit, Goto, Redirect, Return, Skip or Use +Call, DenyAccess, Exit, Goto, Return, Skip or Use .br Example: Method POST Return .TP -.B RequestURI exists|isfile|isdir Return|Exit -If the requested URL exists on disk, don't continue with the URL toolkit. +.B RequestURI exists|isfile|isdir <action> +Perform an action if the requested URL exists on disk, where <action> can be one of the following: +.br +Call, Return Exit or Skip. .br Example: RequestURI isfile Return .TP @@ -834,11 +838,6 @@ .br Example: ToolkitId = my_toolkit .TP -.B Skip <number> -Skip the next following <number> lines (ToolkitId excluded). -.br -Example: Skip 2 -.TP .B UseSSL <action> .br Perform an action when the client is connection via a SSL secured connection, where <action> can be one of the following: @@ -854,7 +853,7 @@ .TP .B Call <toolkit_id> .br -Execute toolkit section <toolkit_id> and continue in the current section. +Execute toolkit section <toolkit_id> and continue in the current section afterwards. .TP .B DenyAccess .br diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/client.c new/hiawatha-9.10/src/client.c --- old/hiawatha-9.9/src/client.c 2014-08-16 22:06:58.000000000 +0200 +++ new/hiawatha-9.10/src/client.c 2014-12-21 13:40:23.000000000 +0100 @@ -255,7 +255,7 @@ /* Check whether to allow or deny a new connection. */ -int connection_allowed(t_ip_addr *ip, int maxperip, int maxtotal) { +int connection_allowed(t_ip_addr *ip, bool ip_of_proxy, int max_per_ip, int max_total) { t_banned *ban; int perip = 1, total = 1, i; t_client *client; @@ -263,29 +263,31 @@ now = time(NULL); - /* Check bans - */ - pthread_mutex_lock(&ban_mutex); + if (ip_of_proxy == false) { + /* Check for ban + */ + pthread_mutex_lock(&ban_mutex); + + ban = banlist; + while (ban != NULL) { + if (same_ip(&(ban->ip), ip)) { + /* Ban expired? + */ + if (now >= ban->deadline) { + break; + } - ban = banlist; - while (ban != NULL) { - if (same_ip(&(ban->ip), ip)) { - /* Ban expired? - */ - if (now >= ban->deadline) { - break; + ban->connect_attempts++; + pthread_mutex_unlock(&ban_mutex); + return ca_BANNED; } - - ban->connect_attempts++; - pthread_mutex_unlock(&ban_mutex); - return ca_BANNED; + ban = ban->next; } - ban = ban->next; - } - pthread_mutex_unlock(&ban_mutex); + pthread_mutex_unlock(&ban_mutex); + } - /* Check max connections + /* Check maximum connections */ for (i = 0; i < 256; i++) { pthread_mutex_lock(&client_mutex[i]); @@ -306,9 +308,9 @@ pthread_mutex_unlock(&client_mutex[i]); } - if (perip > maxperip) { + if ((perip > max_per_ip) && (ip_of_proxy == false)) { return ca_TOOMUCH_PERIP; - } else if (total > maxtotal) { + } else if (total > max_total) { return ca_TOOMUCH_TOTAL; } else { return total; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/client.h new/hiawatha-9.10/src/client.h --- old/hiawatha-9.9/src/client.h 2013-06-17 20:36:40.000000000 +0200 +++ new/hiawatha-9.10/src/client.h 2014-12-21 13:39:57.000000000 +0100 @@ -29,7 +29,7 @@ int mark_client_for_removal(t_session *session, int delay); void check_remove_deadlines(t_config *config, time_t now); int remove_client(t_session *session, bool free_session); -int connection_allowed(t_ip_addr *ip, int maxperip, int maxtotal); +int connection_allowed(t_ip_addr *ip, bool ip_of_proxy, int max_per_ip, int max_total); int disconnect_clients(t_config *config); bool client_is_flooding(t_session *session); void check_flooding(t_config *config); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/filehashes.c new/hiawatha-9.10/src/filehashes.c --- old/hiawatha-9.9/src/filehashes.c 2014-11-07 08:40:11.000000000 +0100 +++ new/hiawatha-9.10/src/filehashes.c 2014-12-23 13:20:35.000000000 +0100 @@ -25,7 +25,7 @@ #include "polarssl/sha256.h" #include "memdbg.h" -void sha2_bin2hex(unsigned char bin[SHA_HASH_SIZE], char hex[FILE_HASH_SIZE + 1]) { +static void sha2_bin2hex(unsigned char bin[SHA_HASH_SIZE], char hex[FILE_HASH_SIZE + 1]) { int i; for (i = 0; i < SHA_HASH_SIZE; i++) { @@ -144,7 +144,7 @@ DIR *dp; struct dirent *fileinfo; unsigned char bin_hash[SHA_HASH_SIZE]; - char hex_hash[FILE_HASH_SIZE + 1], *file; + char hex_hash[FILE_HASH_SIZE + 1], *file = NULL; int result = -1; if ((dp = opendir(directory)) == NULL) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/hiawatha.c new/hiawatha-9.10/src/hiawatha.c --- old/hiawatha-9.9/src/hiawatha.c 2014-12-06 08:50:23.000000000 +0100 +++ new/hiawatha-9.10/src/hiawatha.c 2014-12-21 19:14:25.000000000 +0100 @@ -466,17 +466,19 @@ } #endif + if (in_iplist(config->hide_proxy, &(session->ip_address))) { + session->via_trusted_proxy = true; + } + if (session->request_limit == false) { conns_per_ip = config->total_connections; - } else if (in_iplist(config->hide_proxy, &(session->ip_address))) { - conns_per_ip = config->total_connections; } else { conns_per_ip = config->connections_per_ip; } kick_client = true; - if ((total_conns = connection_allowed(&(session->ip_address), conns_per_ip, config->total_connections)) >= 0) { + if ((total_conns = connection_allowed(&(session->ip_address), session->via_trusted_proxy, conns_per_ip, config->total_connections)) >= 0) { if (total_conns < (config->total_connections >> 2)) { optval = 1; if (setsockopt(session->client_socket, IPPROTO_TCP, TCP_NODELAY, (void*)&optval, sizeof(int)) == -1) { @@ -503,30 +505,8 @@ if (start_worker(session) == 0) { kick_client = false; } - } else switch (total_conns) { - case ca_TOOMUCH_PERIP: - log_system(session, "Maximum number of connections for IP address reached"); - if ((config->ban_on_max_per_ip > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { - log_system(session, "Client banned because of too many simultaneous connections"); - ban_ip(&(session->ip_address), config->ban_on_max_per_ip, config->kick_on_ban); -#ifdef ENABLE_MONITOR - if (config->monitor_enabled) { - monitor_count_ban(session); - } -#endif - } - break; - case ca_TOOMUCH_TOTAL: - log_system(session, "Maximum number of total connections reached"); - break; - case ca_BANNED: - if (config->reban_during_ban && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { - reban_ip(&(session->ip_address)); - } -#ifdef ENABLE_TOMAHAWK - increment_counter(COUNTER_DENY); -#endif - break; + } else { + handle_connection_not_allowed(session, total_conns); } if (kick_client) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/http.c new/hiawatha-9.10/src/http.c --- old/hiawatha-9.9/src/http.c 2014-10-26 12:35:08.000000000 +0100 +++ new/hiawatha-9.10/src/http.c 2014-12-21 18:52:39.000000000 +0100 @@ -777,6 +777,7 @@ {441, "SQL Injection Detected"}, {442, "Cross-Site Scripting Detected"}, {443, "Cross-Site Request Forgery Detected"}, + {444, "Banned Due To Misconduct"}, /* Server error */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/libstr.c new/hiawatha-9.10/src/libstr.c --- old/hiawatha-9.9/src/libstr.c 2014-11-30 15:00:42.000000000 +0100 +++ new/hiawatha-9.10/src/libstr.c 2015-01-02 21:58:01.000000000 +0100 @@ -374,74 +374,6 @@ *dest = '\0'; } -/* Encode string to UTF-8 -int utf8_encode(char *str, char **encoded) { - int len = 0, extra = 0; - unsigned char *r, *w; - - if (str == NULL) { - return -1; - } - - r = (unsigned char*)str; - while (*r != '\0') { - len++; - if (*r >= 0x80) { - extra++; - } - r++; - } - - if (extra == 0) { - *encoded = NULL; - return 0; - } else if ((*encoded = (char*)malloc(len + extra + 1)) == NULL) { - return -1; - } - - r = (unsigned char*)str; - w = (unsigned char*)*encoded; - while (*r != '\0') { - if (*r >= 0xC0) { - *(w++) = 0xC3; - *(w++) = *(r++) - 0x40; - continue; - } else if (*r >= 0x80) { - *(w++) = 0xC2; - } - *(w++) = *(r++); - } - *w = '\0'; - - return extra; -} -*/ - -/* Decode UTF-8 string - */ -void utf8_decode(char *str) { - unsigned char *r, *w; - - if (str == NULL) { - return; - } - - r = (unsigned char*)str; - w = (unsigned char*)str; - while (*r != '\0') { - if ((*r == 0xC2) && (*(r+1) >= 0x80) && (*(r+1) < 0xC0)) { - r++; - *(w++) = *(r++); - } else if ((*r == 0xC3) && (*(r+1) >= 0x80) && (*(r+1) < 0xC0)) { - r++; - *(w++) = *(r++) + 0x40; - } else { - *(w++) = *(r++); - } - } - *w = '\0'; -} - /* Scan for characters with ASCII value < 32. */ bool forbidden_chars_present(char *str) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/libstr.h new/hiawatha-9.10/src/libstr.h --- old/hiawatha-9.9/src/libstr.h 2014-08-12 10:24:09.000000000 +0200 +++ new/hiawatha-9.10/src/libstr.h 2015-01-02 21:58:05.000000000 +0100 @@ -34,7 +34,6 @@ bool valid_uri(char *uri, bool allow_dot_files); int url_encode(char *str, char **encoded); void url_decode(char *str); -void utf8_decode(char *str); bool forbidden_chars_present(char *str); int str_replace(char *src, char *from, char *to, char **dst); bool min_strlen(char *str, int n); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/rproxy.c new/hiawatha-9.10/src/rproxy.c --- old/hiawatha-9.9/src/rproxy.c 2014-12-06 10:33:54.000000000 +0100 +++ new/hiawatha-9.10/src/rproxy.c 2014-12-26 16:13:19.000000000 +0100 @@ -251,12 +251,40 @@ /* Does URL match with proxy match pattern? */ -bool rproxy_match(t_rproxy *rproxy, char *uri) { - if ((rproxy == NULL) || (uri == NULL)) { +t_rproxy *find_rproxy(t_rproxy *rproxy_list, char *uri +#ifdef ENABLE_SSL + , bool use_ssl +#endif + ) { + t_rproxy *rproxy; + + if ((rproxy_list == NULL) || (uri == NULL)) { return false; } - return (regexec(&(rproxy->pattern), uri, 0, NULL, 0) != REG_NOMATCH) != rproxy->neg_match; +#ifdef ENABLE_SSL + rproxy = rproxy_list; + while (rproxy != NULL) { + if (rproxy->use_ssl == use_ssl) { + if ((regexec(&(rproxy->pattern), uri, 0, NULL, 0) != REG_NOMATCH) != rproxy->neg_match) { + return rproxy; + } + } + + rproxy = rproxy->next; + } +#endif + + rproxy = rproxy_list; + while (rproxy != NULL) { + if ((regexec(&(rproxy->pattern), uri, 0, NULL, 0) != REG_NOMATCH) != rproxy->neg_match) { + return rproxy; + } + + rproxy = rproxy->next; + } + + return NULL; } /* Detect reverse proxy loop diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/rproxy.h new/hiawatha-9.10/src/rproxy.h --- old/hiawatha-9.9/src/rproxy.h 2014-12-05 13:47:45.000000000 +0100 +++ new/hiawatha-9.10/src/rproxy.h 2014-12-23 09:21:34.000000000 +0100 @@ -78,7 +78,11 @@ int init_rproxy_module(void); t_rproxy *rproxy_setting(char *line); -bool rproxy_match(t_rproxy *rproxy, char *uri); +t_rproxy *find_rproxy(t_rproxy *rproxy_list, char *uri +#ifdef ENABLE_SSL + , bool use_ssl +#endif + ); bool rproxy_loop_detected(t_http_header *http_headers); void init_rproxy_result(t_rproxy_result *result); int send_request_to_webserver(t_rproxy_webserver *webserver, t_rproxy_options *options, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/serverconfig.c new/hiawatha-9.10/src/serverconfig.c --- old/hiawatha-9.9/src/serverconfig.c 2014-12-08 19:53:20.000000000 +0100 +++ new/hiawatha-9.10/src/serverconfig.c 2014-12-11 20:33:59.000000000 +0100 @@ -103,7 +103,7 @@ host->script_alias = NULL; #ifdef ENABLE_SSL host->require_ssl = false; - host->hsts_time = "31536000"; /* A year in seconds */ + host->hsts_time = NULL; host->key_cert_file = NULL; host->ca_cert_file = NULL; host->ca_crl_file = NULL; @@ -1224,10 +1224,10 @@ if ((time = str_to_int(rest)) < 0) { return false; } - if (time == 0) { - host->hsts_time = NULL; - } else if ((host->hsts_time = strdup(rest)) == NULL) { - return false; + if (time > 0) { + if ((host->hsts_time = strdup(rest)) == NULL) { + return false; + } } } return true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/session.c new/hiawatha-9.10/src/session.c --- old/hiawatha-9.9/src/session.c 2014-11-01 11:18:45.000000000 +0100 +++ new/hiawatha-9.10/src/session.c 2014-12-21 19:13:39.000000000 +0100 @@ -21,6 +21,7 @@ #include <sys/socket.h> #include "global.h" #include "alternative.h" +#include "client.h" #include "libstr.h" #include "liblist.h" #include "session.h" @@ -139,6 +140,7 @@ clear_session(session); session->socket_open = false; + session->via_trusted_proxy = false; session->flooding_timer = session->time; #ifdef ENABLE_RPROXY @@ -806,3 +808,33 @@ session->socket_open = false; } } + +int handle_connection_not_allowed(t_session *session, int connections) { + switch (connections) { + case ca_TOOMUCH_PERIP: + log_system(session, "Maximum number of connections for IP address reached"); + if ((session->config->ban_on_max_per_ip > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { + log_system(session, "Client banned because of too many simultaneous connections"); + ban_ip(&(session->ip_address), session->config->ban_on_max_per_ip, session->config->kick_on_ban); +#ifdef ENABLE_MONITOR + if (session->config->monitor_enabled) { + monitor_count_ban(session); + } +#endif + } + return 444; + case ca_TOOMUCH_TOTAL: + log_system(session, "Maximum number of total connections reached"); + return 503; + case ca_BANNED: + if (session->config->reban_during_ban && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { + reban_ip(&(session->ip_address)); + } +#ifdef ENABLE_TOMAHAWK + increment_counter(COUNTER_DENY); +#endif + return 444; + } + + return 500; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/session.h new/hiawatha-9.10/src/session.h --- old/hiawatha-9.9/src/session.h 2014-07-13 22:07:07.000000000 +0200 +++ new/hiawatha-9.10/src/session.h 2014-12-21 19:12:19.000000000 +0100 @@ -48,6 +48,7 @@ int client_socket; t_binding *binding; bool socket_open; + bool via_trusted_proxy; bool parsing_oke; bool keep_alive; int kept_alive; @@ -161,5 +162,6 @@ int prevent_sqli(t_session *session); int prevent_csrf(t_session *session); void close_socket(t_session *session); +int handle_connection_not_allowed(t_session *session, int connections); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/toolkit.c new/hiawatha-9.10/src/toolkit.c --- old/hiawatha-9.9/src/toolkit.c 2014-11-30 14:41:13.000000000 +0100 +++ new/hiawatha-9.10/src/toolkit.c 2014-12-30 01:20:59.000000000 +0100 @@ -242,7 +242,7 @@ } else if (strcasecmp(value, "use") == 0) { /* Use */ - new_rule->operation = to_replace; + new_rule->operation = to_use; new_rule->flow = tf_exit; if (valid_uri(rest, false) == false) { @@ -275,12 +275,20 @@ char *rest; int cflags; size_t len; - char *header_operations[] = {"call", "denyaccess", "exit", "goto", "redirect", "return", "skip", "use", NULL}; - char *match_operations[] = {"ban", "call", "denyaccess", "exit", "expire", "goto", "redirect", "return", "rewrite", "skip", "usefastcgi", NULL}; - char *method_operations[] = {"call", "denyaccess", "exit", "goto", "redirect", "return", "skip", "use", NULL}; - char *requesturi_operations[] = {"exit", "return", NULL}; + char *do_operations[] = { + "ban", "call", "denyaccess", "exit", "goto", "return", "skip", "use", NULL}; + char *header_operations[] = { + "ban", "call", "denyaccess", "exit", "goto", "return", "skip", "use", NULL}; + char *match_operations[] = { + "ban", "call", "denyaccess", "exit", "expire", "goto", "redirect", "return", + "rewrite", "skip", "usefastcgi", NULL}; + char *method_operations[] = { + "call", "denyaccess", "exit", "goto", "return", "skip", "use", NULL}; + char *requesturi_operations[] = { + "call", "exit", "return", "skip", NULL}; #ifdef ENABLE_SSL - char *usessl_operations[] = {"call", "exit", "goto", "return", "skip", NULL}; + char *usessl_operations[] = { + "call", "exit", "goto", "return", "skip", NULL}; #endif if ((key == NULL) || (value == NULL) || (toolkit == NULL)) { @@ -320,12 +328,10 @@ key = "match"; } - if (strcmp(key, "call") == 0) { - /* Call + if (strcmp(key, "do") == 0) { + /* Do */ - new_rule->operation = to_sub; - - if ((new_rule->parameter = strdup(value)) == NULL) { + if (parse_parameters(new_rule, value, do_operations) == false) { return false; } } else if (strcmp(key, "header") == 0) { @@ -436,14 +442,6 @@ if (parse_parameters(new_rule, rest, requesturi_operations) == false) { return false; } - } else if (strcmp(key, "skip") == 0) { - /* Skip - */ - new_rule->operation = to_skip; - - if ((new_rule->value = str_to_int(value)) < 1) { - return false; - } #ifdef ENABLE_SSL } else if (strcmp(key, "usessl") == 0) { /* UseSSL @@ -737,8 +735,28 @@ /* None */ break; - case to_rewrite: - /* Rewrite + case to_ban: + /* Ban client + */ + options->ban = rule->value; + break; + case to_deny_access: + /* Deny access + */ + return UT_DENY_ACCESS; + case to_expire: + /* Send Expire HTTP header + */ + options->expire = rule->value; + options->caco_private = rule->caco_private; + break; + case to_fastcgi: + /* Use FastCGI server + */ + options->fastcgi_server = rule->parameter; + break; + case to_redirect: + /* Redirect client */ if (rule->neg_match) { if ((options->new_url = strdup(rule->parameter)) == NULL) { @@ -755,28 +773,25 @@ if (url_replaced) { free(url); } - url = options->new_url; - url_replaced = true; + return UT_REDIRECT; } else if (url_replaced) { options->new_url = url; } break; - case to_sub: - /* Subroutine + case to_rewrite: + /* Rewrite */ - if (++(options->sub_depth) > MAX_SUB_DEPTH) { - return UT_ERROR; - } - - if ((result = use_toolkit(url, rule->parameter, options)) == UT_ERROR) { + if (rule->neg_match) { + if ((options->new_url = strdup(rule->parameter)) == NULL) { + return UT_ERROR; + } + } else if (do_rewrite(url, &(rule->pattern), pmatch, rule->parameter, &(options->new_url), rule->match_loop) == -1) { if (options->new_url != NULL) { free(options->new_url); options->new_url = NULL; } return UT_ERROR; } - options->sub_depth--; - if (options->new_url != NULL) { if (url_replaced) { free(url); @@ -786,60 +801,43 @@ } else if (url_replaced) { options->new_url = url; } - - if (result != UT_RETURN) { - return result; - } - break; - case to_expire: - /* Send Expire HTTP header - */ - options->expire = rule->value; - options->caco_private = rule->caco_private; break; case to_skip: /* Skip */ skip = rule->value; break; - case to_deny_access: - /* Deny access - */ - return UT_DENY_ACCESS; - case to_redirect: - /* Redirect client + case to_sub: + /* Subroutine */ - if (rule->neg_match) { - if ((options->new_url = strdup(rule->parameter)) == NULL) { - return UT_ERROR; - } - } else if (do_rewrite(url, &(rule->pattern), pmatch, rule->parameter, &(options->new_url), rule->match_loop) == -1) { + if (++(options->sub_depth) > MAX_SUB_DEPTH) { + return UT_ERROR; + } + + if ((result = use_toolkit(url, rule->parameter, options)) == UT_ERROR) { if (options->new_url != NULL) { free(options->new_url); options->new_url = NULL; } return UT_ERROR; } + options->sub_depth--; + if (options->new_url != NULL) { if (url_replaced) { free(url); } - return UT_REDIRECT; + url = options->new_url; + url_replaced = true; } else if (url_replaced) { options->new_url = url; } + + if (result != UT_RETURN) { + return result; + } break; - case to_fastcgi: - /* Use FastCGI server - */ - options->fastcgi_server = rule->parameter; - break; - case to_ban: - /* Ban client - */ - options->ban = rule->value; - break; - case to_replace: + case to_use: /* Replace URL */ if (url_replaced) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/toolkit.h new/hiawatha-9.10/src/toolkit.h --- old/hiawatha-9.9/src/toolkit.h 2014-07-31 09:35:28.000000000 +0200 +++ new/hiawatha-9.10/src/toolkit.h 2014-12-29 10:15:37.000000000 +0100 @@ -30,14 +30,14 @@ #define IU_ISFILE 1 #define IU_ISDIR 2 -typedef enum { tc_none, tc_match, tc_header, tc_request_uri, tc_method +typedef enum { tc_none, tc_header, tc_match, tc_method, tc_request_uri #ifdef ENABLE_SSL , tc_use_ssl #endif } t_toolkit_condition; -typedef enum { to_none, to_rewrite, to_sub, to_expire, to_skip, to_deny_access, - to_redirect, to_fastcgi, to_ban, to_replace } t_toolkit_operation; -typedef enum { tf_continue, tf_return, tf_exit } t_toolkit_flow; +typedef enum { to_none, to_ban, to_deny_access, to_expire, to_fastcgi, to_redirect, + to_rewrite, to_skip, to_sub, to_use } t_toolkit_operation; +typedef enum { tf_continue, tf_exit, tf_return } t_toolkit_flow; typedef struct type_toolkit_rule { t_toolkit_condition condition; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/wigwam.c new/hiawatha-9.10/src/wigwam.c --- old/hiawatha-9.9/src/wigwam.c 2014-11-30 19:53:32.000000000 +0100 +++ new/hiawatha-9.10/src/wigwam.c 2014-12-23 09:24:47.000000000 +0100 @@ -643,12 +643,15 @@ void check_url_toolkit(char *config_dir, char **toolkit_id) { t_line *config = NULL; - char input[MAX_INPUT_SIZE + 1], **id, *url, current_dir[MAX_PATH], *scheme; + char input[MAX_INPUT_SIZE + 1], **id, *url, current_dir[MAX_PATH]; t_url_toolkit *url_toolkit, *toolkit = NULL, *new_toolkit; t_toolkit_options options; t_http_header *http_headers; bool in_rule_section = false; int result = 0; +#ifdef ENABLE_SSL + char *scheme; +#endif if (quiet == false) { printf("Using %s\n", config_dir); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/workers.c new/hiawatha-9.10/src/workers.c --- old/hiawatha-9.9/src/workers.c 2014-09-23 13:51:08.000000000 +0200 +++ new/hiawatha-9.10/src/workers.c 2015-01-03 11:38:24.000000000 +0100 @@ -307,7 +307,7 @@ /* Serve the client that connected to the webserver */ static int serve_client(t_session *session) { - int result, length, auth_result; + int result, length, auth_result, conns_per_ip, total_conns; char *qmark, chr, *header; t_host *host_record; t_access access; @@ -345,10 +345,21 @@ /* Hide reverse proxies */ - if (in_iplist(session->config->hide_proxy, &(session->ip_address))) { + if (session->via_trusted_proxy) { if (last_forwarded_ip(session->http_headers, &ip_addr) == 0) { if (reposition_client(session, &ip_addr) != -1) { copy_ip(&(session->ip_address), &ip_addr); + + if (session->request_limit == false) { + conns_per_ip = session->config->total_connections; + } else { + conns_per_ip = session->config->connections_per_ip; + } + + if ((total_conns = connection_allowed(&ip_addr, false, conns_per_ip, session->config->total_connections)) < 0) { + session->keep_alive = false; + return handle_connection_not_allowed(session, total_conns); + } } } } @@ -513,105 +524,6 @@ } } -#ifdef ENABLE_RPROXY - /* Reverse proxy - */ - rproxy = session->host->rproxy; - while (rproxy != NULL) { - if (rproxy_match(rproxy, session->request_uri)) { - if (rproxy_loop_detected(session->http_headers)) { - return 508; - } - - if ((qmark = strchr(session->uri, '?')) != NULL) { - *qmark = '\0'; - session->vars = qmark + 1; - } - - if (validate_url(session) == false) { - return -1; - } - - if ((session->vars != NULL) && (session->host->secure_url)) { - if (forbidden_chars_present(session->vars)) { - log_error(session, "URL contains forbidden characters"); - return 403; - } - } - - if (duplicate_host(session) == false) { - log_error(session, "duplicate_host() error"); - return 500; - } - - if ((result = uri_to_path(session)) != 200) { - return result; - } - - if (session->host->ignore_dot_hiawatha == false) { - if (load_user_config(session) == -1) { - return 500; - } - } - - if ((result = copy_directory_settings(session)) != 200) { - return result; - } - - switch (access = allow_client(session)) { - case deny: - log_error(session, fb_accesslist); - return 403; - case allow: - break; - case pwd: - case unspecified: - if ((auth_result = http_authentication_result(session, access == unspecified)) != 200) { - return auth_result; - } - } - - /* Prevent SQL injection - */ - if (session->host->prevent_sqli) { - result = prevent_sqli(session); - if (result == 1) { - session->error_cause = ec_SQL_INJECTION; - } - if (result != 0) { - return -1; - } - } - - /* Prevent Cross-site Scripting - */ - if (session->host->prevent_xss != p_no) { - if (prevent_xss(session) > 0) { - if (session->host->prevent_xss == p_block) { - session->error_cause = ec_XSS; - return -1; - } - } - } - - /* Prevent Cross-site Request Forgery - */ - if (session->host->prevent_csrf != p_no) { - if (prevent_csrf(session) > 0) { - if (session->host->prevent_csrf == p_block) { - session->error_cause = ec_CSRF; - return -1; - } - } - } - - return proxy_request(session, rproxy); - } - - rproxy = rproxy->next; - } -#endif - /* Actions based on request method */ switch (session->request_method) { @@ -679,6 +591,7 @@ } session->toolkit_fastcgi = toolkit_options.fastcgi_server; + if (toolkit_options.new_url != NULL) { if (register_tempdata(&(session->tempdata), toolkit_options.new_url, tc_data) == -1) { free(toolkit_options.new_url); @@ -746,6 +659,69 @@ return result; } +#ifdef ENABLE_RPROXY + /* Reverse proxy + */ + if ((rproxy = find_rproxy(session->host->rproxy, session->request_uri +#ifdef ENABLE_SSL + , session->binding->use_ssl +#endif + )) != NULL) { + if (rproxy_loop_detected(session->http_headers)) { + return 508; + } + + switch (access = allow_client(session)) { + case deny: + log_error(session, fb_accesslist); + return 403; + case allow: + break; + case pwd: + case unspecified: + if ((auth_result = http_authentication_result(session, access == unspecified)) != 200) { + return auth_result; + } + } + + /* Prevent SQL injection + */ + if (session->host->prevent_sqli) { + result = prevent_sqli(session); + if (result == 1) { + session->error_cause = ec_SQL_INJECTION; + } + if (result != 0) { + return -1; + } + } + + /* Prevent Cross-site Scripting + */ + if (session->host->prevent_xss != p_no) { + if (prevent_xss(session) > 0) { + if (session->host->prevent_xss == p_block) { + session->error_cause = ec_XSS; + return -1; + } + } + } + + /* Prevent Cross-site Request Forgery + */ + if (session->host->prevent_csrf != p_no) { + if (prevent_csrf(session) > 0) { + if (session->host->prevent_csrf == p_block) { + session->error_cause = ec_CSRF; + return -1; + } + } + } + + return proxy_request(session, rproxy); + } +#endif + switch (access = allow_client(session)) { case deny: log_error(session, fb_accesslist); @@ -955,7 +931,8 @@ } #endif } - session->return_code = 441; + //session->return_code = 441; + session->return_code = 404; send_code(session); log_request(session); break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiawatha-9.9/src/xslt.c new/hiawatha-9.10/src/xslt.c --- old/hiawatha-9.9/src/xslt.c 2014-09-17 14:57:21.000000000 +0200 +++ new/hiawatha-9.10/src/xslt.c 2015-01-02 21:57:24.000000000 +0100 @@ -612,7 +612,7 @@ /* Start XML */ - if (add_str(&text_xml, &text_max, XML_CHUNK_LEN, &text_size, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<index>") == -1) { + if (add_str(&text_xml, &text_max, XML_CHUNK_LEN, &text_size, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<index>") == -1) { free(text_xml); remove_filelist(filelist); return -1; @@ -647,8 +647,6 @@ /* Loop through files */ while (file != NULL) { - utf8_decode(file->name); - if (file->is_dir && root_dir) { if (strcmp(file->name, "..") == 0) { file = file->next; @@ -895,7 +893,7 @@ /* Start XML */ - if (add_str(&text_xml, &text_max, XML_CHUNK_LEN, &text_size, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<error>") == -1) { + if (add_str(&text_xml, &text_max, XML_CHUNK_LEN, &text_size, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<error>") == -1) { free(text_xml); return -1; } -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
