summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorArno Töll <arno@debian.org>2012-10-20 02:58:14 +0200
committerArno Töll <arno@debian.org>2012-10-20 02:58:14 +0200
commit5c4fba3ffbe778bdffe10a93d04821579601a020 (patch)
tree91be9a7f99d3988ba48b0a619479aa46a3234191 /modules
parent8f9c15530d0bc387af114619b3ff3f930eb23d3c (diff)
downloadapache2-upstream/2.4.3.tar.gz
Imported Upstream version 2.4.3upstream/2.4.3
Diffstat (limited to 'modules')
-rw-r--r--modules/NWGNUmakefile4
-rw-r--r--modules/aaa/mod_auth_digest.c13
-rw-r--r--modules/aaa/mod_authn_dbd.c17
-rw-r--r--modules/aaa/mod_authnz_ldap.c111
-rw-r--r--modules/aaa/mod_authz_core.c105
-rw-r--r--modules/aaa/mod_authz_dbd.c4
-rw-r--r--modules/arch/win32/mod_isapi.c2
-rw-r--r--modules/cache/cache_util.c2
-rw-r--r--modules/cache/mod_cache.c3
-rw-r--r--modules/cache/mod_socache_dbm.c4
-rw-r--r--modules/cache/mod_socache_dc.c3
-rw-r--r--modules/cache/mod_socache_shmcb.c40
-rw-r--r--modules/core/mod_so.c77
-rw-r--r--modules/filters/NWGNUdeflate1
-rw-r--r--modules/filters/config.m48
-rw-r--r--modules/filters/mod_deflate.c31
-rw-r--r--modules/filters/mod_deflate.dsp4
-rw-r--r--modules/filters/mod_ext_filter.c11
-rw-r--r--modules/filters/mod_filter.c13
-rw-r--r--modules/filters/sed1.c7
-rw-r--r--modules/generators/mod_asis.c2
-rw-r--r--modules/generators/mod_cgi.c2
-rw-r--r--modules/generators/mod_cgid.c9
-rw-r--r--modules/generators/mod_info.c64
-rw-r--r--modules/generators/mod_status.c2
-rw-r--r--modules/http/http_protocol.c107
-rw-r--r--modules/http/http_request.c2
-rw-r--r--modules/ldap/util_ldap.c2
-rw-r--r--modules/loggers/mod_log_config.c4
-rw-r--r--modules/loggers/mod_log_debug.c4
-rw-r--r--modules/lua/README7
-rw-r--r--modules/lua/lua_config.c58
-rw-r--r--modules/lua/lua_request.c87
-rw-r--r--modules/lua/lua_vmprep.c218
-rw-r--r--modules/lua/lua_vmprep.h6
-rw-r--r--modules/lua/mod_lua.c331
-rw-r--r--modules/lua/mod_lua.h9
-rw-r--r--modules/mappers/mod_negotiation.c4
-rw-r--r--modules/mappers/mod_rewrite.c118
-rw-r--r--modules/metadata/mod_setenvif.c12
-rw-r--r--modules/proxy/NWGNUproxy1
-rw-r--r--modules/proxy/NWGNUproxylbm_busy1
-rw-r--r--modules/proxy/NWGNUproxylbm_hb1
-rw-r--r--modules/proxy/NWGNUproxylbm_req1
-rw-r--r--modules/proxy/NWGNUproxylbm_traf1
-rw-r--r--modules/proxy/ajp_header.c2
-rw-r--r--modules/proxy/mod_proxy.c1
-rw-r--r--modules/proxy/mod_proxy.h12
-rw-r--r--modules/proxy/mod_proxy_ajp.c48
-rw-r--r--modules/proxy/mod_proxy_balancer.c20
-rw-r--r--modules/proxy/mod_proxy_connect.c58
-rw-r--r--modules/proxy/mod_proxy_fcgi.c2
-rw-r--r--modules/proxy/mod_proxy_ftp.c4
-rw-r--r--modules/proxy/mod_proxy_http.c44
-rw-r--r--modules/proxy/proxy_util.c66
-rw-r--r--modules/session/config.m42
-rw-r--r--modules/session/mod_session.c2
-rw-r--r--modules/ssl/mod_ssl.c3
-rw-r--r--modules/ssl/ssl_engine_config.c23
-rw-r--r--modules/ssl/ssl_engine_init.c62
-rw-r--r--modules/ssl/ssl_engine_io.c26
-rw-r--r--modules/ssl/ssl_engine_kernel.c33
-rw-r--r--modules/ssl/ssl_engine_log.c13
-rw-r--r--modules/ssl/ssl_engine_pphrase.c18
-rw-r--r--modules/ssl/ssl_private.h17
-rw-r--r--modules/ssl/ssl_scache.c4
-rw-r--r--modules/ssl/ssl_util.c26
-rw-r--r--modules/ssl/ssl_util_ocsp.c8
-rw-r--r--modules/ssl/ssl_util_stapling.c4
69 files changed, 1230 insertions, 781 deletions
diff --git a/modules/NWGNUmakefile b/modules/NWGNUmakefile
index b929d01a..0ec061ef 100644
--- a/modules/NWGNUmakefile
+++ b/modules/NWGNUmakefile
@@ -13,8 +13,12 @@ include $(AP_WORK)/build/NWGNUenvironment.inc
ifeq "$(wildcard $(APRUTIL)/include/apr_ldap.h)" "$(APRUTIL)/include/apr_ldap.h"
WITH_LDAP = $(shell $(AWK) '/^\#define APR_HAS_LDAP /{print $$3}' $(APRUTIL)/include/apr_ldap.h)
else
+ifeq "$(MAKECMDGOALS)" "clean"
+WITH_LDAP = 1
+else
WITH_LDAP = 0
endif
+endif
# If USE_STDSOCKETS is defined we allways build mod_ssl
ifdef USE_STDSOCKETS
diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c
index 460619b0..65183160 100644
--- a/modules/aaa/mod_auth_digest.c
+++ b/modules/aaa/mod_auth_digest.c
@@ -267,26 +267,17 @@ static int initialize_tables(server_rec *s, apr_pool_t *ctx)
{
unsigned long idx;
apr_status_t sts;
- const char *tempdir;
/* set up client list */
- sts = apr_temp_dir_get(&tempdir, ctx);
- if (APR_SUCCESS != sts) {
- ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, APLOGNO(01761)
- "Failed to find temporary directory");
- log_error_and_cleanup("failed to find temp dir", sts, s);
- return HTTP_INTERNAL_SERVER_ERROR;
- }
-
/* Create the shared memory segment */
/*
* Create a unique filename using our pid. This information is
* stashed in the global variable so the children inherit it.
*/
- client_shm_filename = apr_psprintf(ctx, "%s/authdigest_shm.%"APR_PID_T_FMT, tempdir,
- getpid());
+ client_shm_filename = ap_runtime_dir_relative(ctx, "authdigest_shm");
+ client_shm_filename = ap_append_pid(ctx, client_shm_filename, ".");
/* Now create that segment */
sts = apr_shm_create(&client_shm, shmem_size,
diff --git a/modules/aaa/mod_authn_dbd.c b/modules/aaa/mod_authn_dbd.c
index 5819abd4..db5b05f6 100644
--- a/modules/aaa/mod_authn_dbd.c
+++ b/modules/aaa/mod_authn_dbd.c
@@ -100,6 +100,7 @@ static authn_status authn_dbd_password(request_rec *r, const char *user,
apr_dbd_prepared_t *statement;
apr_dbd_results_t *res = NULL;
apr_dbd_row_t *row = NULL;
+ int ret;
authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
&authn_dbd_module);
@@ -124,11 +125,12 @@ static authn_status authn_dbd_password(request_rec *r, const char *user,
"AuthDBDUserPWQuery with the key '%s'", conf->user);
return AUTH_GENERAL_ERROR;
}
- if (apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, statement,
- 0, user, NULL) != 0) {
+ if ((ret = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
+ statement, 0, user, NULL) != 0)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01656)
"Query execution error looking up '%s' "
- "in database", user);
+ "in database [%s]",
+ user, apr_dbd_error(dbd->driver, dbd->handle, ret));
return AUTH_GENERAL_ERROR;
}
for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
@@ -193,6 +195,7 @@ static authn_status authn_dbd_realm(request_rec *r, const char *user,
apr_dbd_prepared_t *statement;
apr_dbd_results_t *res = NULL;
apr_dbd_row_t *row = NULL;
+ int ret;
authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
&authn_dbd_module);
@@ -215,11 +218,13 @@ static authn_status authn_dbd_realm(request_rec *r, const char *user,
"AuthDBDUserRealmQuery with the key '%s'", conf->realm);
return AUTH_GENERAL_ERROR;
}
- if (apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, statement,
- 0, user, realm, NULL) != 0) {
+ if ((ret = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
+ statement, 0, user, realm, NULL) != 0)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01661)
"Query execution error looking up '%s:%s' "
- "in database", user, realm);
+ "in database [%s]",
+ user, realm,
+ apr_dbd_error(dbd->driver, dbd->handle, ret));
return AUTH_GENERAL_ERROR;
}
for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
diff --git a/modules/aaa/mod_authnz_ldap.c b/modules/aaa/mod_authnz_ldap.c
index 689d5b76..d55b57f5 100644
--- a/modules/aaa/mod_authnz_ldap.c
+++ b/modules/aaa/mod_authnz_ldap.c
@@ -870,6 +870,7 @@ static authz_status ldapgroup_check_authorization(request_rec *r,
"membership in \"%s\"",
t);
+ /* PR52464 exhaust attrs in base group before checking subgroups */
for (i = 0; i < sec->groupattr->nelts; i++) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01714)
"auth_ldap authorize: require group: testing for %s: "
@@ -879,64 +880,62 @@ static authz_status ldapgroup_check_authorization(request_rec *r,
result = util_ldap_cache_compare(r, ldc, sec->url, t, ent[i].name,
sec->group_attrib_is_dn ? req->dn : req->user);
- switch(result) {
- case LDAP_COMPARE_TRUE: {
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01715)
- "auth_ldap authorize: require group: "
- "authorization successful (attribute %s) "
- "[%s][%d - %s]",
- ent[i].name, ldc->reason, result,
- ldap_err2string(result));
- set_request_vars(r, LDAP_AUTHZ);
- return AUTHZ_GRANTED;
- }
- case LDAP_NO_SUCH_ATTRIBUTE:
- case LDAP_COMPARE_FALSE: {
- /* nested groups need searches and compares, so grab a new handle */
- authnz_ldap_cleanup_connection_close(ldc);
- apr_pool_cleanup_kill(r->pool, ldc,authnz_ldap_cleanup_connection_close);
-
- ldc = get_connection_for_authz(r, LDAP_COMPARE_AND_SEARCH);
- apr_pool_cleanup_register(r->pool, ldc,
- authnz_ldap_cleanup_connection_close,
- apr_pool_cleanup_null);
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01716)
- "auth_ldap authorise: require group \"%s\": "
- "failed [%s][%d - %s], checking sub-groups",
- t, ldc->reason, result, ldap_err2string(result));
-
- result = util_ldap_cache_check_subgroups(r, ldc, sec->url, t, ent[i].name,
- sec->group_attrib_is_dn ? req->dn : req->user,
- sec->sgAttributes[0] ? sec->sgAttributes : default_attributes,
- sec->subgroupclasses,
- 0, sec->maxNestingDepth);
- if(result == LDAP_COMPARE_TRUE) {
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01717)
- "auth_ldap authorise: require group "
- "(sub-group): authorisation successful "
- "(attribute %s) [%s][%d - %s]",
- ent[i].name, ldc->reason, result,
- ldap_err2string(result));
- set_request_vars(r, LDAP_AUTHZ);
- return AUTHZ_GRANTED;
- }
- else {
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01718)
- "auth_ldap authorise: require group "
- "(sub-group) \"%s\": authorisation failed "
- "[%s][%d - %s]",
- t, ldc->reason, result,
- ldap_err2string(result));
- }
- break;
- }
- default: {
+ if (result == LDAP_COMPARE_TRUE) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01715)
+ "auth_ldap authorize: require group: "
+ "authorization successful (attribute %s) "
+ "[%s][%d - %s]",
+ ent[i].name, ldc->reason, result,
+ ldap_err2string(result));
+ set_request_vars(r, LDAP_AUTHZ);
+ return AUTHZ_GRANTED;
+ }
+ else {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01719)
"auth_ldap authorize: require group \"%s\": "
- "authorization failed [%s][%d - %s]",
- t, ldc->reason, result, ldap_err2string(result));
- }
+ "didn't match with attr %s [%s][%d - %s]",
+ t, ldc->reason, ent[i].name, result,
+ ldap_err2string(result));
+ }
+ }
+
+ for (i = 0; i < sec->groupattr->nelts; i++) {
+ /* nested groups need searches and compares, so grab a new handle */
+ authnz_ldap_cleanup_connection_close(ldc);
+ apr_pool_cleanup_kill(r->pool, ldc,authnz_ldap_cleanup_connection_close);
+
+ ldc = get_connection_for_authz(r, LDAP_COMPARE_AND_SEARCH);
+ apr_pool_cleanup_register(r->pool, ldc,
+ authnz_ldap_cleanup_connection_close,
+ apr_pool_cleanup_null);
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01716)
+ "auth_ldap authorise: require group \"%s\": "
+ "failed [%s][%d - %s], checking sub-groups",
+ t, ldc->reason, result, ldap_err2string(result));
+
+ result = util_ldap_cache_check_subgroups(r, ldc, sec->url, t, ent[i].name,
+ sec->group_attrib_is_dn ? req->dn : req->user,
+ sec->sgAttributes[0] ? sec->sgAttributes : default_attributes,
+ sec->subgroupclasses,
+ 0, sec->maxNestingDepth);
+ if (result == LDAP_COMPARE_TRUE) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01717)
+ "auth_ldap authorise: require group "
+ "(sub-group): authorisation successful "
+ "(attribute %s) [%s][%d - %s]",
+ ent[i].name, ldc->reason, result,
+ ldap_err2string(result));
+ set_request_vars(r, LDAP_AUTHZ);
+ return AUTHZ_GRANTED;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01718)
+ "auth_ldap authorise: require group "
+ "(sub-group) \"%s\": didn't match with attr %s "
+ "[%s][%d - %s]",
+ t, ldc->reason, ent[i].name, result,
+ ldap_err2string(result));
}
}
diff --git a/modules/aaa/mod_authz_core.c b/modules/aaa/mod_authz_core.c
index fb286e20..9b7173c8 100644
--- a/modules/aaa/mod_authz_core.c
+++ b/modules/aaa/mod_authz_core.c
@@ -221,6 +221,14 @@ static authz_status authz_alias_check_authorization(request_rec *r,
r->per_dir_config = orig_dir_config;
}
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02305)
+ "no alias provider found for '%s' (BUG?)",
+ provider_name);
+ }
+ }
+ else {
+ ap_assert(provider_name != NULL);
}
return ret;
@@ -305,6 +313,14 @@ static const char *authz_require_alias_section(cmd_parms *cmd, void *mconfig,
"Unknown Authz provider: %s",
provider_name);
}
+ if (prvdraliasrec->provider->parse_require_line) {
+ const char *err = prvdraliasrec->provider->parse_require_line(cmd,
+ provider_args, &prvdraliasrec->provider_parsed_args);
+ if (err)
+ return apr_psprintf(cmd->pool,
+ "Can't parse 'Require %s %s': %s",
+ provider_name, provider_args, err);
+ }
authcfg = ap_get_module_config(cmd->server->module_config,
&authz_core_module);
@@ -397,8 +413,14 @@ static const char *add_authz_provider(cmd_parms *cmd, void *config,
section->limited = cmd->limited;
if (section->provider->parse_require_line) {
- const char *err = section->provider->parse_require_line(cmd, args,
- &section->provider_parsed_args);
+ const char *err;
+ apr_pool_userdata_setn(section->provider_name,
+ AUTHZ_PROVIDER_NAME_NOTE,
+ apr_pool_cleanup_null,
+ cmd->temp_pool);
+ err = section->provider->parse_require_line(cmd, args,
+ &section->provider_parsed_args);
+
if (err)
return err;
}
@@ -607,12 +629,9 @@ static int authz_core_check_section(apr_pool_t *p, server_rec *s,
if (ret != OK) {
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, APR_SUCCESS, s, APLOGNO(01624)
- "%s",
- apr_pstrcat(p, (is_conf
- ? "<Directory>, <Location>, or similar"
- : format_authz_command(p, section)),
- " directive contains only negative "
- "authorization directives", NULL));
+ "%s directive contains only negative authorization directives",
+ is_conf ? "<Directory>, <Location>, or similar"
+ : format_authz_command(p, section));
}
return ret;
@@ -1015,36 +1034,74 @@ static const authz_provider authz_method_provider =
&method_parse_config,
};
-static authz_status expr_check_authorization(request_rec *r,
- const char *require_line,
- const void *parsed_require_line)
-{
- const char *err = NULL;
- const ap_expr_info_t *expr = parsed_require_line;
- int rc = ap_expr_exec(r, expr, &err);
+/*
+ * expr authz provider
+ */
- if (rc <= 0)
- /* XXX: real error handling? */
- return AUTHZ_DENIED;
- else
- return AUTHZ_GRANTED;
+#define REQUIRE_EXPR_NOTE "Require_expr_info"
+struct require_expr_info {
+ ap_expr_info_t *expr;
+ int want_user;
+};
+
+static int expr_lookup_fn(ap_expr_lookup_parms *parms)
+{
+ if (parms->type == AP_EXPR_FUNC_VAR
+ && strcasecmp(parms->name, "REMOTE_USER") == 0) {
+ struct require_expr_info *info;
+ apr_pool_userdata_get((void**)&info, REQUIRE_EXPR_NOTE, parms->ptemp);
+ AP_DEBUG_ASSERT(info != NULL);
+ info->want_user = 1;
+ }
+ return ap_expr_lookup_default(parms);
}
static const char *expr_parse_config(cmd_parms *cmd, const char *require_line,
const void **parsed_require_line)
{
const char *expr_err = NULL;
- ap_expr_info_t *expr = ap_expr_parse_cmd(cmd, require_line, 0, &expr_err,
- NULL);
+ struct require_expr_info *info = apr_pcalloc(cmd->pool, sizeof(*info));
+
+ apr_pool_userdata_setn(info, REQUIRE_EXPR_NOTE, apr_pool_cleanup_null,
+ cmd->temp_pool);
+ info->expr = ap_expr_parse_cmd(cmd, require_line, 0, &expr_err,
+ expr_lookup_fn);
if (expr_err)
- return "Cannot parse expression in require line";
+ return apr_pstrcat(cmd->temp_pool,
+ "Cannot parse expression in require line: ",
+ expr_err, NULL);
- *parsed_require_line = expr;
+ *parsed_require_line = info;
return NULL;
}
+static authz_status expr_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ const char *err = NULL;
+ const struct require_expr_info *info = parsed_require_line;
+ int rc = ap_expr_exec(r, info->expr, &err);
+
+ if (rc < 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02320)
+ "Error evaluating expression in 'Require expr': %s",
+ err);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ else if (rc == 0) {
+ if (info->want_user)
+ return AUTHZ_DENIED_NO_USER;
+ else
+ return AUTHZ_DENIED;
+ }
+ else {
+ return AUTHZ_GRANTED;
+ }
+}
+
static const authz_provider authz_expr_provider =
{
&expr_check_authorization,
diff --git a/modules/aaa/mod_authz_dbd.c b/modules/aaa/mod_authz_dbd.c
index 59ca2b34..86d3b561 100644
--- a/modules/aaa/mod_authz_dbd.c
+++ b/modules/aaa/mod_authz_dbd.c
@@ -162,8 +162,8 @@ static int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg,
"authz_dbd: no redirect query!");
/* OK, this is non-critical; we can just not-redirect */
}
- else if (apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
- query, 0, r->user, NULL) == 0) {
+ else if ((rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle,
+ &res, query, 0, r->user, NULL) == 0)) {
for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
rv != -1;
rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
diff --git a/modules/arch/win32/mod_isapi.c b/modules/arch/win32/mod_isapi.c
index d77ff688..f6cb99a2 100644
--- a/modules/arch/win32/mod_isapi.c
+++ b/modules/arch/win32/mod_isapi.c
@@ -894,7 +894,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
}
/* Reset the method to GET */
- r->method = apr_pstrdup(r->pool, "GET");
+ r->method = "GET";
r->method_number = M_GET;
/* Don't let anyone think there's still data */
diff --git a/modules/cache/cache_util.c b/modules/cache/cache_util.c
index bad438ac..1e5098d5 100644
--- a/modules/cache/cache_util.c
+++ b/modules/cache/cache_util.c
@@ -172,7 +172,7 @@ cache_provider_list *cache_get_providers(request_rec *r,
cache_server_conf *conf,
apr_uri_t uri)
{
- cache_dir_conf *dconf = dconf = ap_get_module_config(r->per_dir_config, &cache_module);
+ cache_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &cache_module);
cache_provider_list *providers = NULL;
int i;
diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c
index 720d81a5..e75f01d3 100644
--- a/modules/cache/mod_cache.c
+++ b/modules/cache/mod_cache.c
@@ -1655,6 +1655,9 @@ static void cache_insert_error_filter(request_rec *r)
r->err_headers_out = cache->stale_handle->resp_hdrs;
+ ap_set_content_type(r, apr_table_get(
+ cache->stale_handle->resp_hdrs, "Content-Type"));
+
/* add a revalidation warning */
warn_head = apr_table_get(r->err_headers_out, "Warning");
if ((warn_head == NULL) || ((warn_head != NULL)
diff --git a/modules/cache/mod_socache_dbm.c b/modules/cache/mod_socache_dbm.c
index 70fe28bf..0d7c302b 100644
--- a/modules/cache/mod_socache_dbm.c
+++ b/modules/cache/mod_socache_dbm.c
@@ -53,7 +53,7 @@ struct ap_socache_instance_t {
*/
#define DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
-#define DEFAULT_DBM_PREFIX DEFAULT_REL_RUNTIMEDIR "/socache-dbm-"
+#define DEFAULT_DBM_PREFIX "socache-dbm-"
/* ### this should use apr_dbm_usednames. */
#if !defined(DBM_FILE_SUFFIX_DIR) && !defined(DBM_FILE_SUFFIX_PAG)
@@ -127,7 +127,7 @@ static apr_status_t socache_dbm_init(ap_socache_instance_t *ctx,
const char *path = apr_pstrcat(p, DEFAULT_DBM_PREFIX, namespace,
NULL);
- ctx->data_file = ap_server_root_relative(p, path);
+ ctx->data_file = ap_runtime_dir_relative(p, path);
if (ctx->data_file == NULL) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00803)
diff --git a/modules/cache/mod_socache_dc.c b/modules/cache/mod_socache_dc.c
index 9739a97b..7d09408d 100644
--- a/modules/cache/mod_socache_dc.c
+++ b/modules/cache/mod_socache_dc.c
@@ -140,7 +140,8 @@ static apr_status_t socache_dc_remove(ap_socache_instance_t *ctx,
if (!DC_CTX_remove_session(ctx->dc, id, idlen)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00745) "distributed scache 'remove' MISS");
return APR_NOTFOUND;
- } else {
+ }
+ else {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00746) "distributed scache 'remove' HIT");
return APR_SUCCESS;
}
diff --git a/modules/cache/mod_socache_shmcb.c b/modules/cache/mod_socache_shmcb.c
index ff4defd3..4d4246b3 100644
--- a/modules/cache/mod_socache_shmcb.c
+++ b/modules/cache/mod_socache_shmcb.c
@@ -32,10 +32,14 @@
#define SHMCB_MAX_SIZE (64 * 1024 * 1024)
-#define DEFAULT_SHMCB_PREFIX DEFAULT_REL_RUNTIMEDIR "/socache-shmcb-"
+#define DEFAULT_SHMCB_PREFIX "socache-shmcb-"
#define DEFAULT_SHMCB_SUFFIX ".cache"
+#define ALIGNED_HEADER_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBHeader))
+#define ALIGNED_SUBCACHE_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBSubcache))
+#define ALIGNED_INDEX_SIZE APR_ALIGN_DEFAULT(sizeof(SHMCBIndex))
+
/*
* Header structure - the start of the shared-mem segment
*/
@@ -141,7 +145,7 @@ struct ap_socache_instance_t {
* a pointer to the corresponding subcache. */
#define SHMCB_SUBCACHE(pHeader, num) \
(SHMCBSubcache *)(((unsigned char *)(pHeader)) + \
- sizeof(SHMCBHeader) + \
+ ALIGNED_HEADER_SIZE + \
(num) * ((pHeader)->subcache_size))
/* This macro takes a pointer to the header and an id and returns a
@@ -157,8 +161,9 @@ struct ap_socache_instance_t {
/* This macro takes a pointer to a subcache and a zero-based index and returns
* a pointer to the corresponding SHMCBIndex. */
#define SHMCB_INDEX(pSubcache, num) \
- ((SHMCBIndex *)(((unsigned char *)pSubcache) + \
- sizeof(SHMCBSubcache)) + num)
+ (SHMCBIndex *)(((unsigned char *)pSubcache) + \
+ ALIGNED_SUBCACHE_SIZE + \
+ (num) * ALIGNED_INDEX_SIZE)
/* This macro takes a pointer to the header and a subcache and returns a
* pointer to the corresponding data area. */
@@ -194,7 +199,8 @@ static void shmcb_cyclic_ntoc_memcpy(unsigned int buf_size, unsigned char *data,
}
}
-/* A "cyclic-to-normal" memcpy. */static void shmcb_cyclic_cton_memcpy(unsigned int buf_size, unsigned char *dest,
+/* A "cyclic-to-normal" memcpy. */
+static void shmcb_cyclic_cton_memcpy(unsigned int buf_size, unsigned char *dest,
const unsigned char *data, unsigned int src_offset,
unsigned int src_len)
{
@@ -341,7 +347,7 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx,
const char *path = apr_pstrcat(p, DEFAULT_SHMCB_PREFIX, namespace,
DEFAULT_SHMCB_SUFFIX, NULL);
- ctx->data_file = ap_server_root_relative(p, path);
+ ctx->data_file = ap_runtime_dir_relative(p, path);
}
/* Use anonymous shm by default, fall back on name-based. */
@@ -373,7 +379,7 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx,
shm_segment = apr_shm_baseaddr_get(ctx->shm);
shm_segsize = apr_shm_size_get(ctx->shm);
- if (shm_segsize < (5 * sizeof(SHMCBHeader))) {
+ if (shm_segsize < (5 * ALIGNED_HEADER_SIZE)) {
/* the segment is ridiculously small, bail out */
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00820)
"shared memory segment too small");
@@ -384,7 +390,7 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx,
" bytes of shared memory",
shm_segsize);
/* Discount the header */
- shm_segsize -= sizeof(SHMCBHeader);
+ shm_segsize -= ALIGNED_HEADER_SIZE;
/* Select index size based on average object size hints, if given. */
avg_obj_size = hints && hints->avg_obj_size ? hints->avg_obj_size : 150;
avg_id_len = hints && hints->avg_id_len ? hints->avg_id_len : 30;
@@ -397,7 +403,8 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx,
"for %" APR_SIZE_T_FMT " bytes (%" APR_SIZE_T_FMT
" including header), recommending %u subcaches, "
"%u indexes each", shm_segsize,
- shm_segsize + sizeof(SHMCBHeader), num_subcache, num_idx);
+ shm_segsize + ALIGNED_HEADER_SIZE,
+ num_subcache, num_idx);
if (num_idx < 5) {
/* we're still too small, bail out */
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00823)
@@ -416,13 +423,14 @@ static apr_status_t socache_shmcb_init(ap_socache_instance_t *ctx,
header->stat_removes_miss = 0;
header->subcache_num = num_subcache;
/* Convert the subcache size (in bytes) to a value that is suitable for
- * structure alignment on the host platform, by rounding down if necessary.
- * This assumes that sizeof(unsigned long) provides an appropriate
- * alignment unit. */
- header->subcache_size = ((size_t)(shm_segsize / num_subcache) &
- ~(size_t)(sizeof(unsigned long) - 1));
- header->subcache_data_offset = sizeof(SHMCBSubcache) +
- num_idx * sizeof(SHMCBIndex);
+ * structure alignment on the host platform, by rounding down if necessary. */
+ header->subcache_size = (size_t)(shm_segsize / num_subcache);
+ if (header->subcache_size != APR_ALIGN_DEFAULT(header->subcache_size)) {
+ header->subcache_size = APR_ALIGN_DEFAULT(header->subcache_size) -
+ APR_ALIGN_DEFAULT(1);
+ }
+ header->subcache_data_offset = ALIGNED_SUBCACHE_SIZE +
+ num_idx * ALIGNED_INDEX_SIZE;
header->subcache_data_size = header->subcache_size -
header->subcache_data_offset;
header->index_num = num_idx;
diff --git a/modules/core/mod_so.c b/modules/core/mod_so.c
index 13ecd963..6df596a9 100644
--- a/modules/core/mod_so.c
+++ b/modules/core/mod_so.c
@@ -143,6 +143,37 @@ static apr_status_t unload_module(void *data)
return APR_SUCCESS;
}
+static const char *dso_load(cmd_parms *cmd, apr_dso_handle_t **modhandlep,
+ const char *filename, const char **used_filename)
+{
+ int retry = 0;
+ const char *fullname = ap_server_root_relative(cmd->temp_pool, filename);
+ char my_error[256];
+ if (filename != NULL && ap_strchr_c(filename, '/') == NULL) {
+ /* retry on error without path to use dlopen()'s search path */
+ retry = 1;
+ }
+
+ if (fullname == NULL && !retry) {
+ return apr_psprintf(cmd->temp_pool, "Invalid %s path %s",
+ cmd->cmd->name, filename);
+ }
+ *used_filename = fullname;
+ if (apr_dso_load(modhandlep, fullname, cmd->pool) == APR_SUCCESS) {
+ return NULL;
+ }
+ if (retry) {
+ *used_filename = filename;
+ if (apr_dso_load(modhandlep, filename, cmd->pool) == APR_SUCCESS)
+ return NULL;
+ }
+
+ return apr_pstrcat(cmd->temp_pool, "Cannot load ", filename,
+ " into server: ",
+ apr_dso_error(*modhandlep, my_error, sizeof(my_error)),
+ NULL);
+}
+
/*
* This is called for the directive LoadModule and actually loads
* a shared object file into the address space of the server process.
@@ -154,7 +185,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
apr_dso_handle_t *modhandle;
apr_dso_handle_sym_t modsym;
module *modp;
- const char *szModuleFile = ap_server_root_relative(cmd->pool, filename);
+ const char *module_file;
so_server_conf *sconf;
ap_module_symbol_t *modi;
ap_module_symbol_t *modie;
@@ -167,11 +198,6 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
*/
*(ap_directive_t **)dummy = NULL;
- if (!szModuleFile) {
- return apr_pstrcat(cmd->pool, "Invalid LoadModule path ",
- filename, NULL);
- }
-
/*
* check for already existing module
* If it already exists, we have nothing to do
@@ -234,16 +260,11 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
/*
* Load the file into the Apache address space
*/
- if (apr_dso_load(&modhandle, szModuleFile, cmd->pool) != APR_SUCCESS) {
- char my_error[256];
-
- return apr_pstrcat(cmd->pool, "Cannot load ", szModuleFile,
- " into server: ",
- apr_dso_error(modhandle, my_error, sizeof(my_error)),
- NULL);
- }
+ error = dso_load(cmd, &modhandle, filename, &module_file);
+ if (error)
+ return error;
ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, cmd->pool, APLOGNO(01575)
- "loaded module %s", modname);
+ "loaded module %s from %s", modname, module_file);
/*
* Retrieve the pointer to the module structure through the module name:
@@ -254,7 +275,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
char my_error[256];
return apr_pstrcat(cmd->pool, "Can't locate API module structure `",
- modname, "' in file ", szModuleFile, ": ",
+ modname, "' in file ", module_file, ": ",
apr_dso_error(modhandle, my_error, sizeof(my_error)),
NULL);
}
@@ -271,7 +292,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
"is garbled - expected signature %08lx but saw "
"%08lx - perhaps this is not an Apache module DSO, "
"or was compiled for a different Apache version?",
- modname, szModuleFile,
+ modname, module_file,
MODULE_MAGIC_COOKIE, modp->magic);
}
@@ -306,26 +327,14 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
static const char *load_file(cmd_parms *cmd, void *dummy, const char *filename)
{
apr_dso_handle_t *handle;
- const char *file;
-
- file = ap_server_root_relative(cmd->pool, filename);
+ const char *used_file, *error;
- if (!file) {
- return apr_pstrcat(cmd->pool, "Invalid LoadFile path ",
- filename, NULL);
- }
-
- if (apr_dso_load(&handle, file, cmd->pool) != APR_SUCCESS) {
- char my_error[256];
-
- return apr_pstrcat(cmd->pool, "Cannot load ", filename,
- " into server: ",
- apr_dso_error(handle, my_error, sizeof(my_error)),
- NULL);
- }
+ error = dso_load(cmd, &handle, filename, &used_file);
+ if (error)
+ return error;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(01576)
- "loaded file %s", filename);
+ "loaded file %s", used_file);
return NULL;
}
diff --git a/modules/filters/NWGNUdeflate b/modules/filters/NWGNUdeflate
index 579d1386..7f7204d1 100644
--- a/modules/filters/NWGNUdeflate
+++ b/modules/filters/NWGNUdeflate
@@ -30,6 +30,7 @@ XINCDIRS += \
$(APR)/include \
$(APRUTIL)/include \
$(AP_WORK)/include \
+ $(STDMOD)/ssl \
$(NWOS) \
$(EOLIST)
diff --git a/modules/filters/config.m4 b/modules/filters/config.m4
index 4ef2d3a5..966f77a5 100644
--- a/modules/filters/config.m4
+++ b/modules/filters/config.m4
@@ -16,7 +16,13 @@ APACHE_MODULE(reflector, Reflect request through the output filter stack, , , )
APACHE_MODULE(substitute, response content rewrite-like filtering, , , most)
sed_obj="mod_sed.lo sed0.lo sed1.lo regexp.lo"
-APACHE_MODULE(sed, filter request and/or response bodies through sed, $sed_obj, , most)
+APACHE_MODULE(sed, filter request and/or response bodies through sed, $sed_obj, , most, [
+ if test "x$enable_sed" = "xshared"; then
+ # The only symbol which needs to be exported is the module
+ # structure, so ask libtool to hide libsed internals:
+ APR_ADDTO(MOD_SED_LDADD, [-export-symbols-regex sed_module])
+ fi
+])
if test "$ac_cv_ebcdic" = "yes"; then
# mod_charset_lite can be very useful on an ebcdic system,
diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c
index 0876cb4e..48d37b13 100644
--- a/modules/filters/mod_deflate.c
+++ b/modules/filters/mod_deflate.c
@@ -45,6 +45,7 @@
#include "http_request.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"
+#include "mod_ssl.h"
#include "zlib.h"
@@ -83,6 +84,7 @@ static const char deflate_magic[2] = { '\037', '\213' };
#define DEFAULT_MEMLEVEL 9
#define DEFAULT_BUFFERSIZE 8096
+static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *mod_deflate_ssl_var = NULL;
/* Check whether a request is gzipped, so we can un-gzip it.
* If a request has multiple encodings, we need the gzip
@@ -419,6 +421,18 @@ static void deflate_check_etag(request_rec *r, const char *transform)
}
}
+static int have_ssl_compression(request_rec *r)
+{
+ const char *comp;
+ if (mod_deflate_ssl_var == NULL)
+ return 0;
+ comp = mod_deflate_ssl_var(r->pool, r->server, r->connection, r,
+ "SSL_COMPRESS_METHOD");
+ if (comp == NULL || *comp == '\0' || strcmp(comp, "NULL") == 0)
+ return 0;
+ return 1;
+}
+
static apr_status_t deflate_out_filter(ap_filter_t *f,
apr_bucket_brigade *bb)
{
@@ -448,6 +462,14 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
char *token;
const char *encoding;
+ if (have_ssl_compression(r)) {
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+ "Compression enabled at SSL level; not compressing "
+ "at HTTP level.");
+ ap_remove_output_filter(f);
+ return ap_pass_brigade(f->next, bb);
+ }
+
/* We have checked above that bb is not empty */
e = APR_BRIGADE_LAST(bb);
if (APR_BUCKET_IS_EOS(e)) {
@@ -1474,6 +1496,14 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
return APR_SUCCESS;
}
+static int mod_deflate_post_config(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ mod_deflate_ssl_var = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
+ return OK;
+}
+
+
#define PROTO_FLAGS AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH
static void register_hooks(apr_pool_t *p)
{
@@ -1483,6 +1513,7 @@ static void register_hooks(apr_pool_t *p)
AP_FTYPE_RESOURCE-1);
ap_register_input_filter(deflateFilterName, deflate_in_filter, NULL,
AP_FTYPE_CONTENT_SET);
+ ap_hook_post_config(mod_deflate_post_config, NULL, NULL, APR_HOOK_MIDDLE);
}
static const command_rec deflate_filter_cmds[] = {
diff --git a/modules/filters/mod_deflate.dsp b/modules/filters/mod_deflate.dsp
index 06ce9683..f990c976 100644
--- a/modules/filters/mod_deflate.dsp
+++ b/modules/filters/mod_deflate.dsp
@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "NDEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_deflate_src" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "NDEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_deflate_src" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -75,7 +75,7 @@ PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).ma
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "_DEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_deflate_src" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "_DEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_deflate_src" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
diff --git a/modules/filters/mod_ext_filter.c b/modules/filters/mod_ext_filter.c
index 76ddbc8a..fc1ed2ce 100644
--- a/modules/filters/mod_ext_filter.c
+++ b/modules/filters/mod_ext_filter.c
@@ -66,7 +66,7 @@ typedef struct ef_ctx_t {
apr_procattr_t *procattr;
ef_dir_t *dc;
ef_filter_t *filter;
- int noop;
+ int noop, hit_eos;
#if APR_FILES_AS_SOCKETS
apr_pollset_t *pollset;
#endif
@@ -827,6 +827,7 @@ static int ef_unified_filter(ap_filter_t *f, apr_bucket_brigade *bb)
if (eos) {
b = apr_bucket_eos_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
+ ctx->hit_eos = 1;
}
return APR_SUCCESS;
@@ -910,6 +911,14 @@ static apr_status_t ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb,
ctx = f->ctx;
}
+ if (ctx->hit_eos) {
+ /* Match behaviour of HTTP_IN if filter is re-invoked after
+ * hitting EOS: give back another EOS. */
+ apr_bucket *e = apr_bucket_eos_create(f->c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, e);
+ return APR_SUCCESS;
+ }
+
if (ctx->noop) {
ap_remove_input_filter(f);
return ap_get_brigade(f->next, bb, mode, block, readbytes);
diff --git a/modules/filters/mod_filter.c b/modules/filters/mod_filter.c
index 7dd7db1a..67cfd6bb 100644
--- a/modules/filters/mod_filter.c
+++ b/modules/filters/mod_filter.c
@@ -165,13 +165,21 @@ static int filter_lookup(ap_filter_t *f, ap_filter_rec_t *filter)
const char **type = provider->types;
size_t len = strcspn(r->content_type, "; \t");
AP_DEBUG_ASSERT(type != NULL);
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
+ "Content-Type '%s' ...", r->content_type);
while (*type) {
/* Handle 'content-type;charset=...' correctly */
if (strncmp(*type, r->content_type, len) == 0
&& (*type)[len] == '\0') {
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
+ "... matched '%s'", *type);
match = 1;
break;
}
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
+ "... did not match '%s'", *type);
+ }
type++;
}
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
@@ -179,6 +187,11 @@ static int filter_lookup(ap_filter_t *f, ap_filter_rec_t *filter)
provider->frec->name,
match ? "matched" : "did not match");
}
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+ "Content-Type condition for '%s' did not match: "
+ "no Content-Type", provider->frec->name);
+ }
if (match) {
/* condition matches this provider */
diff --git a/modules/filters/sed1.c b/modules/filters/sed1.c
index ddca3bdb..739e1ce9 100644
--- a/modules/filters/sed1.c
+++ b/modules/filters/sed1.c
@@ -25,7 +25,7 @@
#include "apr_strings.h"
#include "regexp.h"
-char *trans[040] = {
+static const char *const trans[040] = {
"\\01",
"\\02",
"\\03",
@@ -58,7 +58,7 @@ char *trans[040] = {
"\\36",
"\\37"
};
-char rub[] = {"\\177"};
+static const char rub[] = {"\\177"};
extern int sed_step(char *p1, char *p2, int circf, step_vars_storage *vars);
static int substitute(sed_eval_t *eval, sed_reptr_t *ipc,
@@ -692,7 +692,8 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
step_vars_storage *step_vars)
{
int i;
- char *p1, *p2, *p3;
+ char *p1, *p2;
+ const char *p3;
int length;
char sz[32]; /* 32 bytes enough to store 64 bit integer in decimal */
apr_status_t rv = APR_SUCCESS;
diff --git a/modules/generators/mod_asis.c b/modules/generators/mod_asis.c
index 1fc14389..c947e303 100644
--- a/modules/generators/mod_asis.c
+++ b/modules/generators/mod_asis.c
@@ -70,7 +70,7 @@ static int asis_handler(request_rec *r)
/* This redirect needs to be a GET no matter what the original
* method was.
*/
- r->method = apr_pstrdup(r->pool, "GET");
+ r->method = "GET";
r->method_number = M_GET;
ap_internal_redirect_handler(location, r);
diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c
index 385bb364..a6096545 100644
--- a/modules/generators/mod_cgi.c
+++ b/modules/generators/mod_cgi.c
@@ -993,7 +993,7 @@ static int cgi_handler(request_rec *r)
/* This redirect needs to be a GET no matter what the original
* method was.
*/
- r->method = apr_pstrdup(r->pool, "GET");
+ r->method = "GET";
r->method_number = M_GET;
/* We already read the message body (if any), so don't allow
diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c
index 1e4aaf67..1155bd75 100644
--- a/modules/generators/mod_cgid.c
+++ b/modules/generators/mod_cgid.c
@@ -135,7 +135,7 @@ static int is_scriptaliased(request_rec *r)
#define DEFAULT_LOGBYTES 10385760
#define DEFAULT_BUFBYTES 1024
-#define DEFAULT_SOCKET DEFAULT_REL_RUNTIMEDIR "/cgisock"
+#define DEFAULT_SOCKET "cgisock"
#define CGI_REQ 1
#define SSI_REQ 2
@@ -910,6 +910,7 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
procnew->err = procnew->in = procnew->out = NULL;
apr_pool_userdata_set((const void *)procnew, userdata_key,
apr_pool_cleanup_null, main_server->process->pool);
+ return ret;
}
else {
procnew = data;
@@ -922,7 +923,7 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
total_modules++;
parent_pid = getpid();
- tmp_sockname = ap_server_root_relative(p, sockname);
+ tmp_sockname = ap_runtime_dir_relative(p, sockname);
if (strlen(tmp_sockname) > sizeof(server_addr->sun_path) - 1) {
tmp_sockname[sizeof(server_addr->sun_path)] = '\0';
ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, APLOGNO(01254)
@@ -1016,7 +1017,7 @@ static const char *set_script_socket(cmd_parms *cmd, void *dummy, const char *ar
/* Make sure the pid is appended to the sockname */
sockname = ap_append_pid(cmd->pool, arg, ".");
- sockname = ap_server_root_relative(cmd->pool, sockname);
+ sockname = ap_runtime_dir_relative(cmd->pool, sockname);
if (!sockname) {
return apr_pstrcat(cmd->pool, "Invalid ScriptSock path",
@@ -1593,7 +1594,7 @@ static int cgid_handler(request_rec *r)
/* This redirect needs to be a GET no matter what the original
* method was.
*/
- r->method = apr_pstrdup(r->pool, "GET");
+ r->method = "GET";
r->method_number = M_GET;
/* We already read the message body (if any), so don't allow
diff --git a/modules/generators/mod_info.c b/modules/generators/mod_info.c
index 360290c7..75c37782 100644
--- a/modules/generators/mod_info.c
+++ b/modules/generators/mod_info.c
@@ -62,6 +62,7 @@
#include "util_script.h"
#include "ap_mpm.h"
#include "mpm_common.h"
+#include "ap_provider.h"
#include <stdio.h>
#include <stdlib.h>
@@ -688,6 +689,57 @@ static int show_active_hooks(request_rec * r)
return 0;
}
+static int cmp_provider_groups(const void *a_, const void *b_)
+{
+ const ap_list_provider_groups_t *a = a_, *b = b_;
+ int ret = strcmp(a->provider_group, b->provider_group);
+ if (!ret)
+ ret = strcmp(a->provider_version, b->provider_version);
+ return ret;
+}
+
+static int cmp_provider_names(const void *a_, const void *b_)
+{
+ const ap_list_provider_names_t *a = a_, *b = b_;
+ return strcmp(a->provider_name, b->provider_name);
+}
+
+static void show_providers(request_rec *r)
+{
+ apr_array_header_t *groups = ap_list_provider_groups(r->pool);
+ ap_list_provider_groups_t *group;
+ apr_array_header_t *names;
+ ap_list_provider_names_t *name;
+ int i,j;
+ const char *cur_group = NULL;
+
+ qsort(groups->elts, groups->nelts, sizeof(ap_list_provider_groups_t),
+ cmp_provider_groups);
+ ap_rputs("<h2><a name=\"providers\">Providers</a></h2>\n<dl>", r);
+
+ for (i = 0; i < groups->nelts; i++) {
+ group = &APR_ARRAY_IDX(groups, i, ap_list_provider_groups_t);
+ if (!cur_group || strcmp(cur_group, group->provider_group) != 0) {
+ if (cur_group)
+ ap_rputs("\n</dt>\n", r);
+ cur_group = group->provider_group;
+ ap_rprintf(r, "<dt><strong>%s</strong> (version <tt>%s</tt>):"
+ "\n <br />\n", cur_group, group->provider_version);
+ }
+ names = ap_list_provider_names(r->pool, group->provider_group,
+ group->provider_version);
+ qsort(names->elts, names->nelts, sizeof(ap_list_provider_names_t),
+ cmp_provider_names);
+ for (j = 0; j < names->nelts; j++) {
+ name = &APR_ARRAY_IDX(names, j, ap_list_provider_names_t);
+ ap_rprintf(r, "<tt>&nbsp;&nbsp;%s</tt><br/>", name->provider_name);
+ }
+ }
+ if (cur_group)
+ ap_rputs("\n</dt>\n", r);
+ ap_rputs("</dl>\n<hr />\n", r);
+}
+
static int cmp_module_name(const void *a_, const void *b_)
{
const module * const *a = a_;
@@ -737,8 +789,9 @@ static int display_info(request_rec * r)
ap_rputs("<dl><dt><tt>Subpages:<br />", r);
ap_rputs("<a href=\"?config\">Configuration Files</a>, "
"<a href=\"?server\">Server Settings</a>, "
- "<a href=\"?list\">Module List</a>, "
- "<a href=\"?hooks\">Active Hooks</a>", r);
+ "<a href=\"?list\">Module List</a>, "
+ "<a href=\"?hooks\">Active Hooks</a>, "
+ "<a href=\"?providers\">Available Providers</a>", r);
ap_rputs("</tt></dt></dl><hr />", r);
ap_rputs("<dl><dt><tt>Sections:<br />", r);
@@ -746,7 +799,8 @@ static int display_info(request_rec * r)
"<a href=\"#server\">Server Settings</a>, "
"<a href=\"#startup_hooks\">Startup Hooks</a>, "
"<a href=\"#request_hooks\">Request Hooks</a>, "
- "<a href=\"#other_hooks\">Other Hooks</a>", r);
+ "<a href=\"#other_hooks\">Other Hooks</a>, "
+ "<a href=\"#providers\">Providers</a>", r);
ap_rputs("</tt></dt></dl><hr />", r);
ap_rputs("<h2><a name=\"modules\">Loaded Modules</a></h2>"
@@ -772,6 +826,10 @@ static int display_info(request_rec * r)
show_active_hooks(r);
}
+ if (!r->args || !strcasecmp(r->args, "providers")) {
+ show_providers(r);
+ }
+
if (r->args && 0 == strcasecmp(r->args, "config")) {
ap_rputs("<dl><dt><strong>Configuration:</strong>\n", r);
mod_info_module_cmds(r, NULL, ap_conftree, 0, 0);
diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c
index ced19edb..50bcb272 100644
--- a/modules/generators/mod_status.c
+++ b/modules/generators/mod_status.c
@@ -582,7 +582,7 @@ static int status_handler(request_rec *r)
"\"<b><code>L</code></b>\" Logging, \n"
"\"<b><code>G</code></b>\" Gracefully finishing,<br /> \n"
"\"<b><code>I</code></b>\" Idle cleanup of worker, \n"
- "\"<b><code>.</code></b>\" Open slot with no current process,<br />\n"
+ "\"<b><code>.</code></b>\" Open slot with no current process<br />\n"
"<p />\n", r);
if (!ap_extended_status) {
int j;
diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c
index 10165478..2f786123 100644
--- a/modules/http/http_protocol.c
+++ b/modules/http/http_protocol.c
@@ -62,8 +62,12 @@ APLOG_USE_MODULE(http);
/* New Apache routine to map status codes into array indicies
* e.g. 100 -> 0, 101 -> 1, 200 -> 2 ...
- * The number of status lines must equal the value of RESPONSE_CODES (httpd.h)
- * and must be listed in order.
+ * The number of status lines must equal the value of
+ * RESPONSE_CODES (httpd.h) and must be listed in order.
+ * No gaps are allowed between X00 and the largest Xnn
+ * for any X (see ap_index_of_response).
+ * When adding a new code here, add a define to httpd.h
+ * as well.
*/
static const char * const status_lines[RESPONSE_CODES] =
@@ -80,58 +84,81 @@ static const char * const status_lines[RESPONSE_CODES] =
"205 Reset Content",
"206 Partial Content",
"207 Multi-Status",
-#define LEVEL_300 11
+ "208 Already Reported",
+ NULL, /* 209 */
+ NULL, /* 210 */
+ NULL, /* 211 */
+ NULL, /* 212 */
+ NULL, /* 213 */
+ NULL, /* 214 */
+ NULL, /* 215 */
+ NULL, /* 216 */
+ NULL, /* 217 */
+ NULL, /* 218 */
+ NULL, /* 219 */
+ NULL, /* 220 */
+ NULL, /* 221 */
+ NULL, /* 222 */
+ NULL, /* 223 */
+ NULL, /* 224 */
+ NULL, /* 225 */
+ "226 IM Used",
+#define LEVEL_300 30
"300 Multiple Choices",
"301 Moved Permanently",
"302 Found",
"303 See Other",
"304 Not Modified",
"305 Use Proxy",
- "306 unused",
+ NULL, /* 306 */
"307 Temporary Redirect",
-#define LEVEL_400 19
+ "308 Permanent Redirect",
+#define LEVEL_400 39
"400 Bad Request",
- "401 Authorization Required",
+ "401 Unauthorized",
"402 Payment Required",
"403 Forbidden",
"404 Not Found",
"405 Method Not Allowed",
"406 Not Acceptable",
"407 Proxy Authentication Required",
- "408 Request Time-out",
+ "408 Request Timeout",
"409 Conflict",
"410 Gone",
"411 Length Required",
"412 Precondition Failed",
"413 Request Entity Too Large",
- "414 Request-URI Too Large",
+ "414 Request-URI Too Long",
"415 Unsupported Media Type",
"416 Requested Range Not Satisfiable",
"417 Expectation Failed",
- "418 unused",
- "419 unused",
- "420 unused",
- "421 unused",
+ NULL, /* 418 */
+ NULL, /* 419 */
+ NULL, /* 420 */
+ NULL, /* 421 */
"422 Unprocessable Entity",
"423 Locked",
"424 Failed Dependency",
- /* This is a hack, but it is required for ap_index_of_response
- * to work with 426.
- */
- "425 No code",
+ NULL, /* 425 */
"426 Upgrade Required",
-#define LEVEL_500 46
+ NULL, /* 427 */
+ "428 Precondition Required",
+ "429 Too Many Requests",
+ NULL, /* 430 */
+ "431 Request Header Fields Too Large",
+#define LEVEL_500 71
"500 Internal Server Error",
- "501 Method Not Implemented",
+ "501 Not Implemented",
"502 Bad Gateway",
- "503 Service Temporarily Unavailable",
- "504 Gateway Time-out",
+ "503 Service Unavailable",
+ "504 Gateway Timeout",
"505 HTTP Version Not Supported",
"506 Variant Also Negotiates",
"507 Insufficient Storage",
- "508 unused",
- "509 unused",
- "510 Not Extended"
+ "508 Loop Detected",
+ NULL, /* 509 */
+ "510 Not Extended",
+ "511 Network Authentication Required"
};
APR_HOOK_STRUCT(
@@ -739,6 +766,7 @@ AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum)
* decides to define a high-numbered code before the lower numbers.
* If that sad event occurs, replace the code below with a linear search
* from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1];
+ * or use NULL to fill the gaps.
*/
AP_DECLARE(int) ap_index_of_response(int status)
{
@@ -754,7 +782,7 @@ AP_DECLARE(int) ap_index_of_response(int status)
status -= 100;
if (status < 100) {
pos = (status + shortcut[i]);
- if (pos < shortcut[i + 1]) {
+ if (pos < shortcut[i + 1] && status_lines[pos] != NULL) {
return pos;
}
else {
@@ -771,11 +799,9 @@ AP_DECLARE(const char *) ap_get_status_line(int status)
}
/* Build the Allow field-value from the request handler method mask.
- * Note that we always allow TRACE, since it is handled below.
*/
static char *make_allow(request_rec *r)
{
- char *list;
apr_int64_t mask;
apr_array_header_t *allow = apr_array_make(r->pool, 10, sizeof(char *));
apr_hash_index_t *hi = apr_hash_first(r->pool, methods_registry);
@@ -803,25 +829,15 @@ static char *make_allow(request_rec *r)
if (conf->trace_enable != AP_TRACE_DISABLE)
*(const char **)apr_array_push(allow) = "TRACE";
- list = apr_array_pstrcat(r->pool, allow, ',');
-
/* ### this is rather annoying. we should enforce registration of
### these methods */
if ((mask & (AP_METHOD_BIT << M_INVALID))
&& (r->allowed_methods->method_list != NULL)
&& (r->allowed_methods->method_list->nelts != 0)) {
- int i;
- char **xmethod = (char **) r->allowed_methods->method_list->elts;
-
- /*
- * Append all of the elements of r->allowed_methods->method_list
- */
- for (i = 0; i < r->allowed_methods->method_list->nelts; ++i) {
- list = apr_pstrcat(r->pool, list, ",", xmethod[i], NULL);
- }
+ apr_array_cat(allow, r->allowed_methods->method_list);
}
- return list;
+ return apr_array_pstrcat(r->pool, allow, ',');
}
AP_DECLARE(int) ap_send_http_options(request_rec *r)
@@ -887,6 +903,7 @@ static const char *get_canned_error_string(int status,
case HTTP_MOVED_PERMANENTLY:
case HTTP_MOVED_TEMPORARILY:
case HTTP_TEMPORARY_REDIRECT:
+ case HTTP_PERMANENT_REDIRECT:
return(apr_pstrcat(p,
"<p>The document has moved <a href=\"",
ap_escape_html(r->pool, location),
@@ -1048,6 +1065,14 @@ static const char *get_canned_error_string(int status,
"connection to SSL, but your client doesn't support it.\n"
"Either upgrade your client, or try requesting the page\n"
"using https://\n");
+ case HTTP_PRECONDITION_REQUIRED:
+ return("<p>The request is required to be conditional.</p>\n");
+ case HTTP_TOO_MANY_REQUESTS:
+ return("<p>The user has sent too many requests\n"
+ "in a given amount of time.</p>\n");
+ case HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE:
+ return("<p>The server refused this request because\n"
+ "the request header fields are too large.</p>\n");
case HTTP_INSUFFICIENT_STORAGE:
return("<p>The method could not be performed on the resource\n"
"because the server is unable to store the\n"
@@ -1061,9 +1086,15 @@ static const char *get_canned_error_string(int status,
case HTTP_GATEWAY_TIME_OUT:
return("<p>The gateway did not receive a timely response\n"
"from the upstream server or application.</p>\n");
+ case HTTP_LOOP_DETECTED:
+ return("<p>The server terminated an operation because\n"
+ "it encountered an infinite loop.</p>\n");
case HTTP_NOT_EXTENDED:
return("<p>A mandatory extension policy in the request is not\n"
"accepted by the server for this resource.</p>\n");
+ case HTTP_NETWORK_AUTHENTICATION_REQUIRED:
+ return("<p>The client needs to authenticate to gain\n"
+ "network access.</p>\n");
default: /* HTTP_INTERNAL_SERVER_ERROR */
/*
* This comparison to expose error-notes could be modified to
diff --git a/modules/http/http_request.c b/modules/http/http_request.c
index ce16de92..21c6debd 100644
--- a/modules/http/http_request.c
+++ b/modules/http/http_request.c
@@ -197,7 +197,7 @@ AP_DECLARE(void) ap_die(int type, request_rec *r)
"error-notes")) != NULL) {
apr_table_setn(r->subprocess_env, "ERROR_NOTES", error_notes);
}
- r->method = apr_pstrdup(r->pool, "GET");
+ r->method = "GET";
r->method_number = M_GET;
ap_internal_redirect(custom_response, r);
return;
diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c
index 46840ad6..c7f7b93d 100644
--- a/modules/ldap/util_ldap.c
+++ b/modules/ldap/util_ldap.c
@@ -2110,7 +2110,7 @@ static const char *util_ldap_set_cache_file(cmd_parms *cmd, void *dummy,
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01298)
- "LDAP cache: Setting shared memory cache file to %s bytes.",
+ "LDAP cache: Setting shared memory cache file to %s.",
st->cache_file);
return NULL;
diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c
index 026a6cf6..bc225cee 100644
--- a/modules/loggers/mod_log_config.c
+++ b/modules/loggers/mod_log_config.c
@@ -544,10 +544,10 @@ static const char *log_cookie(request_rec *r, char *a)
while ((cookie = apr_strtok(cookies, ";", &last1))) {
char *name = apr_strtok(cookie, "=", &last2);
if (name) {
- char *value;
+ char *value = name + strlen(name) + 1;
apr_collapse_spaces(name, name);
- if (!strcasecmp(name, a) && (value = apr_strtok(NULL, "=", &last2))) {
+ if (!strcasecmp(name, a)) {
char *last;
value += strspn(value, " \t"); /* Move past leading WS */
last = value + strlen(value) - 1;
diff --git a/modules/loggers/mod_log_debug.c b/modules/loggers/mod_log_debug.c
index 0361cba7..9111b119 100644
--- a/modules/loggers/mod_log_debug.c
+++ b/modules/loggers/mod_log_debug.c
@@ -35,8 +35,8 @@ typedef struct {
apr_array_header_t *entries;
} log_debug_dirconf;
-const char *allhooks = "all";
-const char * const hooks[] = {
+static const char *allhooks = "all";
+static const char * const hooks[] = {
"log_transaction", /* 0 */
"quick_handler", /* 1 */
"handler", /* 2 */
diff --git a/modules/lua/README b/modules/lua/README
index 4efa9cd6..c614b3e2 100644
--- a/modules/lua/README
+++ b/modules/lua/README
@@ -54,6 +54,13 @@
** TODO apw_rgetvm needs to handle connection scoped vms
** TODO options in server scoped vms (ie, min and max vm counts)
** TODO provide means to implement authn and authz providers
+** TODO: Flatten LuaHook* to LuaHook phase file fn ?
+** TODO: Lua and ap_expr integration in one or both directions
+** TODO: document or remove block sections
+** TODO: test per-dir behavior of block sections
+** TODO: Catch-up documentation on r: methods
+** TODO: 500 errors instead of 404 with AddHandler lua-script
+** TODO: Suppress internal details (fs path to scripts, etc) in error responses
* License
Apache License, Version 2.0,
diff --git a/modules/lua/lua_config.c b/modules/lua/lua_config.c
index 0e675652..07dd932b 100644
--- a/modules/lua/lua_config.c
+++ b/modules/lua/lua_config.c
@@ -154,14 +154,6 @@ static const struct luaL_Reg cfg_methods[] = {
{NULL, NULL}
};
-
-static int cmd_foo(lua_State *L)
-{
- cmd_parms *cmd = check_cmd_parms(L, 1);
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server, APLOGNO(01479) "FOO!");
- return 0;
-}
-
/* helper function for the logging functions below */
static int cmd_log_at(lua_State *L, int level)
{
@@ -181,88 +173,70 @@ static int cmd_log_at(lua_State *L, int level)
/* r:debug(String) and friends which use apache logging */
static int cmd_emerg(lua_State *L)
{
- cmd_log_at(L, APLOG_EMERG);
- return 0;
+ return cmd_log_at(L, APLOG_EMERG);
}
static int cmd_alert(lua_State *L)
{
- cmd_log_at(L, APLOG_ALERT);
- return 0;
+ return cmd_log_at(L, APLOG_ALERT);
}
static int cmd_crit(lua_State *L)
{
- cmd_log_at(L, APLOG_CRIT);
- return 0;
+ return cmd_log_at(L, APLOG_CRIT);
}
static int cmd_err(lua_State *L)
{
- cmd_log_at(L, APLOG_ERR);
- return 0;
+ return cmd_log_at(L, APLOG_ERR);
}
static int cmd_warn(lua_State *L)
{
- cmd_log_at(L, APLOG_WARNING);
- return 0;
+ return cmd_log_at(L, APLOG_WARNING);
}
static int cmd_notice(lua_State *L)
{
- cmd_log_at(L, APLOG_NOTICE);
- return 0;
+ return cmd_log_at(L, APLOG_NOTICE);
}
static int cmd_info(lua_State *L)
{
- cmd_log_at(L, APLOG_INFO);
- return 0;
+ return cmd_log_at(L, APLOG_INFO);
}
static int cmd_debug(lua_State *L)
{
- cmd_log_at(L, APLOG_DEBUG);
- return 0;
+ return cmd_log_at(L, APLOG_DEBUG);
}
static int cmd_trace1(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE1);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE1);
}
static int cmd_trace2(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE2);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE2);
}
static int cmd_trace3(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE3);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE3);
}
static int cmd_trace4(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE4);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE4);
}
static int cmd_trace5(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE5);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE5);
}
static int cmd_trace6(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE6);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE6);
}
static int cmd_trace7(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE7);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE7);
}
static int cmd_trace8(lua_State *L)
{
- cmd_log_at(L, APLOG_TRACE8);
- return 0;
+ return cmd_log_at(L, APLOG_TRACE8);
}
static const struct luaL_Reg cmd_methods[] = {
- {"foo", cmd_foo},
-
{"trace8", cmd_trace8},
{"trace7", cmd_trace7},
{"trace6", cmd_trace6},
diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
index 91bd3b75..9a1cdf8c 100644
--- a/modules/lua/lua_request.c
+++ b/modules/lua/lua_request.c
@@ -164,6 +164,34 @@ static int req_parseargs(lua_State *L)
return 2; /* [table<string, string>, table<string, array<string>>] */
}
+/* r:parsebody() returning a lua table */
+static int req_parsebody(lua_State *L)
+{
+ apr_array_header_t *pairs;
+ apr_off_t len;
+ int res;
+ apr_size_t size;
+ apr_size_t max_post_size;
+ char *buffer;
+ request_rec *r = ap_lua_check_request_rec(L, 1);
+ max_post_size = (apr_size_t) luaL_optint(L, 2, MAX_STRING_LEN);
+ lua_newtable(L);
+ lua_newtable(L); /* [table, table] */
+ res = ap_parse_form_data(r, NULL, &pairs, -1, max_post_size);
+ if (res == OK) {
+ while(pairs && !apr_is_empty_array(pairs)) {
+ ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
+ apr_brigade_length(pair->value, 1, &len);
+ size = (apr_size_t) len;
+ buffer = apr_palloc(r->pool, size + 1);
+ apr_brigade_flatten(pair->value, buffer, &size);
+ buffer[len] = 0;
+ req_aprtable2luatable_cb(L, pair->name, buffer);
+ }
+ }
+ return 2; /* [table<string, string>, table<string, array<string>>] */
+}
+
/* wrap ap_rputs as r:puts(String) */
static int req_puts(lua_State *L)
{
@@ -235,6 +263,16 @@ static const char *req_document_root(request_rec *r)
return ap_document_root(r);
}
+static const char *req_context_prefix(request_rec *r)
+{
+ return ap_context_prefix(r);
+}
+
+static const char *req_context_document_root(request_rec *r)
+{
+ return ap_context_document_root(r);
+}
+
static char *req_uri_field(request_rec *r)
{
return r->uri;
@@ -323,6 +361,16 @@ static const char *req_the_request_field(request_rec *r)
return r->the_request;
}
+static const char *req_log_id_field(request_rec *r)
+{
+ return r->log_id;
+}
+
+static const char *req_useragent_ip_field(request_rec *r)
+{
+ return r->useragent_ip;
+}
+
static int req_status_field(request_rec *r)
{
return r->status;
@@ -452,49 +500,40 @@ static int req_log_at(lua_State *L, int level)
/* r:debug(String) and friends which use apache logging */
static int req_emerg(lua_State *L)
{
- req_log_at(L, APLOG_EMERG);
- return 0;
+ return req_log_at(L, APLOG_EMERG);
}
static int req_alert(lua_State *L)
{
- req_log_at(L, APLOG_ALERT);
- return 0;
+ return req_log_at(L, APLOG_ALERT);
}
static int req_crit(lua_State *L)
{
- req_log_at(L, APLOG_CRIT);
- return 0;
+ return req_log_at(L, APLOG_CRIT);
}
static int req_err(lua_State *L)
{
- req_log_at(L, APLOG_ERR);
- return 0;
+ return req_log_at(L, APLOG_ERR);
}
static int req_warn(lua_State *L)
{
- req_log_at(L, APLOG_WARNING);
- return 0;
+ return req_log_at(L, APLOG_WARNING);
}
static int req_notice(lua_State *L)
{
- req_log_at(L, APLOG_NOTICE);
- return 0;
+ return req_log_at(L, APLOG_NOTICE);
}
static int req_info(lua_State *L)
{
- req_log_at(L, APLOG_INFO);
- return 0;
+ return req_log_at(L, APLOG_INFO);
}
static int req_debug(lua_State *L)
{
- req_log_at(L, APLOG_DEBUG);
- return 0;
+ return req_log_at(L, APLOG_DEBUG);
}
#define APLUA_REQ_TRACE(lev) static int req_trace##lev(lua_State *L) \
{ \
- req_log_at(L, APLOG_TRACE##lev); \
- return 0; \
+ return req_log_at(L, APLOG_TRACE##lev); \
}
APLUA_REQ_TRACE(1)
@@ -608,8 +647,14 @@ AP_LUA_DECLARE(void) ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
makefun(&req_write, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "document_root", APR_HASH_KEY_STRING,
makefun(&req_document_root, APL_REQ_FUNTYPE_STRING, p));
+ apr_hash_set(dispatch, "context_prefix", APR_HASH_KEY_STRING,
+ makefun(&req_context_prefix, APL_REQ_FUNTYPE_STRING, p));
+ apr_hash_set(dispatch, "context_document_root", APR_HASH_KEY_STRING,
+ makefun(&req_context_document_root, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "parseargs", APR_HASH_KEY_STRING,
makefun(&req_parseargs, APL_REQ_FUNTYPE_LUACFUN, p));
+ apr_hash_set(dispatch, "parsebody", APR_HASH_KEY_STRING,
+ makefun(&req_parsebody, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "debug", APR_HASH_KEY_STRING,
makefun(&req_debug, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "info", APR_HASH_KEY_STRING,
@@ -688,6 +733,10 @@ AP_LUA_DECLARE(void) ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
makefun(&req_uri_field, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "the_request", APR_HASH_KEY_STRING,
makefun(&req_the_request_field, APL_REQ_FUNTYPE_STRING, p));
+ apr_hash_set(dispatch, "log_id", APR_HASH_KEY_STRING,
+ makefun(&req_log_id_field, APL_REQ_FUNTYPE_STRING, p));
+ apr_hash_set(dispatch, "useragent_ip", APR_HASH_KEY_STRING,
+ makefun(&req_useragent_ip_field, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "method", APR_HASH_KEY_STRING,
makefun(&req_method_field, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "proxyreq", APR_HASH_KEY_STRING,
@@ -744,7 +793,7 @@ AP_LUA_DECLARE(void) ap_lua_push_connection(lua_State *L, conn_rec *c)
lua_setfield(L, -2, "notes");
lua_pushstring(L, c->client_ip);
- lua_setfield(L, -2, "remote_ip");
+ lua_setfield(L, -2, "client_ip");
lua_pop(L, 1);
}
diff --git a/modules/lua/lua_vmprep.c b/modules/lua/lua_vmprep.c
index 7c383ca9..e821fee3 100644
--- a/modules/lua/lua_vmprep.c
+++ b/modules/lua/lua_vmprep.c
@@ -19,6 +19,7 @@
#include "apr_uuid.h"
#include "lua_config.h"
#include "apr_file_info.h"
+#include "mod_auth.h"
APLOG_USE_MODULE(lua);
@@ -96,6 +97,8 @@ static void pstack_dump(lua_State *L, apr_pool_t *r, int level,
/* BEGIN apache lmodule */
+#define makeintegerfield(L, n) lua_pushinteger(L, n); lua_setfield(L, -2, #n)
+
AP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L)
{
lua_getglobal(L, "package");
@@ -106,130 +109,83 @@ AP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L)
lua_pop(L, 1); /* empty stack */
lua_getglobal(L, "apache2");
- lua_pushinteger(L, OK);
- lua_setfield(L, -2, "OK");
-
- lua_pushinteger(L, DECLINED);
- lua_setfield(L, -2, "DECLINED");
-
- lua_pushinteger(L, DONE);
- lua_setfield(L, -2, "DONE");
lua_pushstring(L, ap_get_server_banner());
lua_setfield(L, -2, "version");
- lua_pushinteger(L, HTTP_MOVED_TEMPORARILY);
- lua_setfield(L, -2, "HTTP_MOVED_TEMPORARILY");
-
- lua_pushinteger(L, PROXYREQ_NONE);
- lua_setfield(L, -2, "PROXYREQ_NONE");
-
- lua_pushinteger(L, PROXYREQ_PROXY);
- lua_setfield(L, -2, "PROXYREQ_PROXY");
-
- lua_pushinteger(L, PROXYREQ_REVERSE);
- lua_setfield(L, -2, "PROXYREQ_REVERSE");
-
- lua_pushinteger(L, PROXYREQ_RESPONSE);
- lua_setfield(L, -2, "PROXYREQ_RESPONSE");
+ makeintegerfield(L, OK);
+ makeintegerfield(L, DECLINED);
+ makeintegerfield(L, DONE);
+ makeintegerfield(L, HTTP_MOVED_TEMPORARILY);
+ makeintegerfield(L, PROXYREQ_NONE);
+ makeintegerfield(L, PROXYREQ_PROXY);
+ makeintegerfield(L, PROXYREQ_REVERSE);
+ makeintegerfield(L, PROXYREQ_RESPONSE);
+ makeintegerfield(L, PROXYREQ_RESPONSE);
+ makeintegerfield(L, AUTHZ_DENIED);
+ makeintegerfield(L, AUTHZ_GRANTED);
+ makeintegerfield(L, AUTHZ_NEUTRAL);
+ makeintegerfield(L, AUTHZ_GENERAL_ERROR);
+ makeintegerfield(L, AUTHZ_DENIED_NO_USER);
/*
- lua_pushinteger(L, HTTP_CONTINUE);
- lua_setfield(L, -2, "HTTP_CONTINUE");
- lua_pushinteger(L, HTTP_SWITCHING_PROTOCOLS);
- lua_setfield(L, -2, "HTTP_SWITCHING_PROTOCOLS");
- lua_pushinteger(L, HTTP_PROCESSING);
- lua_setfield(L, -2, "HTTP_PROCESSING");
- lua_pushinteger(L, HTTP_OK);
- lua_setfield(L, -2, "HTTP_OK");
- lua_pushinteger(L, HTTP_CREATED);
- lua_setfield(L, -2, "HTTP_CREATED");
- lua_pushinteger(L, HTTP_ACCEPTED);
- lua_setfield(L, -2, "HTTP_ACCEPTED");
- lua_pushinteger(L, HTTP_NON_AUTHORITATIVE);
- lua_setfield(L, -2, "HTTP_NON_AUTHORITATIVE");
- lua_pushinteger(L, HTTP_NO_CONTENT);
- lua_setfield(L, -2, "HTTP_NO_CONTENT");
- lua_pushinteger(L, HTTP_RESET_CONTENT);
- lua_setfield(L, -2, "HTTP_RESET_CONTENT");
- lua_pushinteger(L, HTTP_PARTIAL_CONTENT);
- lua_setfield(L, -2, "HTTP_PARTIAL_CONTENT");
- lua_pushinteger(L, HTTP_MULTI_STATUS);
- lua_setfield(L, -2, "HTTP_MULTI_STATUS");
- lua_pushinteger(L, HTTP_MULTIPLE_CHOICES);
- lua_setfield(L, -2, "HTTP_MULTIPLE_CHOICES");
- lua_pushinteger(L, HTTP_MOVED_PERMANENTLY);
- lua_setfield(L, -2, "HTTP_MOVED_PERMANENTLY");
- lua_pushinteger(L, HTTP_SEE_OTHER);
- lua_setfield(L, -2, "HTTP_SEE_OTHER");
- lua_pushinteger(L, HTTP_NOT_MODIFIED);
- lua_setfield(L, -2, "HTTP_NOT_MODIFIED");
- lua_pushinteger(L, HTTP_USE_PROXY);
- lua_setfield(L, -2, "HTTP_USE_PROXY");
- lua_pushinteger(L, HTTP_TEMPORARY_REDIRECT);
- lua_setfield(L, -2, "HTTP_TEMPORARY_REDIRECT");
- lua_pushinteger(L, HTTP_BAD_REQUEST);
- lua_setfield(L, -2, "HTTP_BAD_REQUEST");
- lua_pushinteger(L, HTTP_UNAUTHORIZED);
- lua_setfield(L, -2, "HTTP_UNAUTHORIZED");
- lua_pushinteger(L, HTTP_PAYMENT_REQUIRED);
- lua_setfield(L, -2, "HTTP_PAYMENT_REQUIRED");
- lua_pushinteger(L, HTTP_FORBIDDEN);
- lua_setfield(L, -2, "HTTP_FORBIDDEN");
- lua_pushinteger(L, HTTP_NOT_FOUND);
- lua_setfield(L, -2, "HTTP_NOT_FOUND");
- lua_pushinteger(L, HTTP_METHOD_NOT_ALLOWED);
- lua_setfield(L, -2, "HTTP_METHOD_NOT_ALLOWED");
- lua_pushinteger(L, HTTP_NOT_ACCEPTABLE);
- lua_setfield(L, -2, "HTTP_NOT_ACCEPTABLE");
- lua_pushinteger(L, HTTP_PROXY_AUTHENTICATION_REQUIRED);
- lua_setfield(L, -2, "HTTP_PROXY_AUTHENTICATION_REQUIRED");
- lua_pushinteger(L, HTTP_REQUEST_TIME_OUT);
- lua_setfield(L, -2, "HTTP_REQUEST_TIME_OUT");
- lua_pushinteger(L, HTTP_CONFLICT);
- lua_setfield(L, -2, "HTTP_CONFLICT");
- lua_pushinteger(L, HTTP_GONE);
- lua_setfield(L, -2, "HTTP_GONE");
- lua_pushinteger(L, HTTP_LENGTH_REQUIRED);
- lua_setfield(L, -2, "HTTP_LENGTH_REQUIRED");
- lua_pushinteger(L, HTTP_PRECONDITION_FAILED);
- lua_setfield(L, -2, "HTTP_PRECONDITION_FAILED");
- lua_pushinteger(L, HTTP_REQUEST_ENTITY_TOO_LARGE);
- lua_setfield(L, -2, "HTTP_REQUEST_ENTITY_TOO_LARGE");
- lua_pushinteger(L, HTTP_REQUEST_URI_TOO_LARGE);
- lua_setfield(L, -2, "HTTP_REQUEST_URI_TOO_LARGE");
- lua_pushinteger(L, HTTP_UNSUPPORTED_MEDIA_TYPE);
- lua_setfield(L, -2, "HTTP_UNSUPPORTED_MEDIA_TYPE");
- lua_pushinteger(L, HTTP_RANGE_NOT_SATISFIABLE);
- lua_setfield(L, -2, "HTTP_RANGE_NOT_SATISFIABLE");
- lua_pushinteger(L, HTTP_EXPECTATION_FAILED);
- lua_setfield(L, -2, "HTTP_EXPECTATION_FAILED");
- lua_pushinteger(L, HTTP_UNPROCESSABLE_ENTITY);
- lua_setfield(L, -2, "HTTP_UNPROCESSABLE_ENTITY");
- lua_pushinteger(L, HTTP_LOCKED);
- lua_setfield(L, -2, "HTTP_LOCKED");
- lua_pushinteger(L, HTTP_FAILED_DEPENDENCY);
- lua_setfield(L, -2, "HTTP_FAILED_DEPENDENCY");
- lua_pushinteger(L, HTTP_UPGRADE_REQUIRED);
- lua_setfield(L, -2, "HTTP_UPGRADE_REQUIRED");
- lua_pushinteger(L, HTTP_INTERNAL_SERVER_ERROR);
- lua_setfield(L, -2, "HTTP_INTERNAL_SERVER_ERROR");
- lua_pushinteger(L, HTTP_NOT_IMPLEMENTED);
- lua_setfield(L, -2, "HTTP_NOT_IMPLEMENTED");
- lua_pushinteger(L, HTTP_BAD_GATEWAY);
- lua_setfield(L, -2, "HTTP_BAD_GATEWAY");
- lua_pushinteger(L, HTTP_SERVICE_UNAVAILABLE);
- lua_setfield(L, -2, "HTTP_SERVICE_UNAVAILABLE");
- lua_pushinteger(L, HTTP_GATEWAY_TIME_OUT);
- lua_setfield(L, -2, "HTTP_GATEWAY_TIME_OUT");
- lua_pushinteger(L, HTTP_VERSION_NOT_SUPPORTED);
- lua_setfield(L, -2, "HTTP_VERSION_NOT_SUPPORTED");
- lua_pushinteger(L, HTTP_VARIANT_ALSO_VARIES);
- lua_setfield(L, -2, "HTTP_VARIANT_ALSO_VARIES");
- lua_pushinteger(L, HTTP_INSUFFICIENT_STORAGE);
- lua_setfield(L, -2, "HTTP_INSUFFICIENT_STORAGE");
- lua_pushinteger(L, HTTP_NOT_EXTENDED);
- lua_setfield(L, -2, "HTTP_NOT_EXTENDED");
+ makeintegerfield(L, HTTP_CONTINUE);
+ makeintegerfield(L, HTTP_SWITCHING_PROTOCOLS);
+ makeintegerfield(L, HTTP_PROCESSING);
+ makeintegerfield(L, HTTP_OK);
+ makeintegerfield(L, HTTP_CREATED);
+ makeintegerfield(L, HTTP_ACCEPTED);
+ makeintegerfield(L, HTTP_NON_AUTHORITATIVE);
+ makeintegerfield(L, HTTP_NO_CONTENT);
+ makeintegerfield(L, HTTP_RESET_CONTENT);
+ makeintegerfield(L, HTTP_PARTIAL_CONTENT);
+ makeintegerfield(L, HTTP_MULTI_STATUS);
+ makeintegerfield(L, HTTP_ALREADY_REPORTED);
+ makeintegerfield(L, HTTP_IM_USED);
+ makeintegerfield(L, HTTP_MULTIPLE_CHOICES);
+ makeintegerfield(L, HTTP_MOVED_PERMANENTLY);
+ makeintegerfield(L, HTTP_MOVED_TEMPORARILY);
+ makeintegerfield(L, HTTP_SEE_OTHER);
+ makeintegerfield(L, HTTP_NOT_MODIFIED);
+ makeintegerfield(L, HTTP_USE_PROXY);
+ makeintegerfield(L, HTTP_TEMPORARY_REDIRECT);
+ makeintegerfield(L, HTTP_PERMANENT_REDIRECT);
+ makeintegerfield(L, HTTP_BAD_REQUEST);
+ makeintegerfield(L, HTTP_UNAUTHORIZED);
+ makeintegerfield(L, HTTP_PAYMENT_REQUIRED);
+ makeintegerfield(L, HTTP_FORBIDDEN);
+ makeintegerfield(L, HTTP_NOT_FOUND);
+ makeintegerfield(L, HTTP_METHOD_NOT_ALLOWED);
+ makeintegerfield(L, HTTP_NOT_ACCEPTABLE);
+ makeintegerfield(L, HTTP_PROXY_AUTHENTICATION_REQUIRED);
+ makeintegerfield(L, HTTP_REQUEST_TIME_OUT);
+ makeintegerfield(L, HTTP_CONFLICT);
+ makeintegerfield(L, HTTP_GONE);
+ makeintegerfield(L, HTTP_LENGTH_REQUIRED);
+ makeintegerfield(L, HTTP_PRECONDITION_FAILED);
+ makeintegerfield(L, HTTP_REQUEST_ENTITY_TOO_LARGE);
+ makeintegerfield(L, HTTP_REQUEST_URI_TOO_LARGE);
+ makeintegerfield(L, HTTP_UNSUPPORTED_MEDIA_TYPE);
+ makeintegerfield(L, HTTP_RANGE_NOT_SATISFIABLE);
+ makeintegerfield(L, HTTP_EXPECTATION_FAILED);
+ makeintegerfield(L, HTTP_UNPROCESSABLE_ENTITY);
+ makeintegerfield(L, HTTP_LOCKED);
+ makeintegerfield(L, HTTP_FAILED_DEPENDENCY);
+ makeintegerfield(L, HTTP_UPGRADE_REQUIRED);
+ makeintegerfield(L, HTTP_PRECONDITION_REQUIRED);
+ makeintegerfield(L, HTTP_TOO_MANY_REQUESTS);
+ makeintegerfield(L, HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE);
+ makeintegerfield(L, HTTP_INTERNAL_SERVER_ERROR);
+ makeintegerfield(L, HTTP_NOT_IMPLEMENTED);
+ makeintegerfield(L, HTTP_BAD_GATEWAY);
+ makeintegerfield(L, HTTP_SERVICE_UNAVAILABLE);
+ makeintegerfield(L, HTTP_GATEWAY_TIME_OUT);
+ makeintegerfield(L, HTTP_VERSION_NOT_SUPPORTED);
+ makeintegerfield(L, HTTP_VARIANT_ALSO_VARIES);
+ makeintegerfield(L, HTTP_INSUFFICIENT_STORAGE);
+ makeintegerfield(L, HTTP_LOOP_DETECTED);
+ makeintegerfield(L, HTTP_NOT_EXTENDED);
+ makeintegerfield(L, HTTP_NETWORK_AUTHENTICATION_REQUIRED);
*/
}
@@ -240,6 +196,7 @@ AP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L)
/* callback for cleaning up a lua vm when pool is closed */
static apr_status_t cleanup_lua(void *l)
{
+ AP_DEBUG_ASSERT(l != NULL);
lua_close((lua_State *) l);
return APR_SUCCESS;
}
@@ -319,7 +276,7 @@ static int loadjitmodule(lua_State *L, apr_pool_t *lifecycle_pool) {
#endif
-static apr_status_t vm_construct(void **vm, void *params, apr_pool_t *lifecycle_pool)
+static apr_status_t vm_construct(lua_State **vm, void *params, apr_pool_t *lifecycle_pool)
{
lua_State* L;
@@ -357,24 +314,10 @@ static apr_status_t vm_construct(void **vm, void *params, apr_pool_t *lifecycle_
"loading lua file %s", spec->file);
rc = luaL_loadfile(L, spec->file);
if (rc != 0) {
- char *err;
- switch (rc) {
- case LUA_ERRSYNTAX:
- err = "syntax error";
- break;
- case LUA_ERRMEM:
- err = "memory allocation error";
- break;
- case LUA_ERRFILE:
- err = "error opening or reading file";
- break;
- default:
- err = "unknown error";
- break;
- }
ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(01482)
- "Loading lua file %s: %s",
- spec->file, err);
+ "Error loading %s: %s", spec->file,
+ rc == LUA_ERRMEM ? "memory allocation error"
+ : lua_tostring(L, 0));
return APR_EBADF;
}
lua_pcall(L, 0, LUA_MULTRET, 0);
@@ -407,7 +350,8 @@ AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
"creating lua_State with file %s", spec->file);
/* not available, so create */
- if(!vm_construct((void **)&L, spec, lifecycle_pool)) {
+ if(!vm_construct(&L, spec, lifecycle_pool)) {
+ AP_DEBUG_ASSERT(L != NULL);
apr_pool_userdata_set(L,
spec->file,
cleanup_lua,
diff --git a/modules/lua/lua_vmprep.h b/modules/lua/lua_vmprep.h
index be1750df..1d3758ca 100644
--- a/modules/lua/lua_vmprep.h
+++ b/modules/lua/lua_vmprep.h
@@ -54,7 +54,7 @@ typedef struct
apr_array_header_t *package_cpaths;
/* name of base file to load in the vm */
- char *file;
+ const char *file;
/* APL_SCOPE_ONCE | APL_SCOPE_REQUEST | APL_SCOPE_CONN | APL_SCOPE_THREAD */
int scope;
@@ -75,8 +75,8 @@ typedef struct
typedef struct
{
- char *function_name;
- char *file_name;
+ const char *function_name;
+ const char *file_name;
int scope;
ap_regex_t *uri_pattern;
const char *bytecode;
diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c
index 095e54fd..b5b626d1 100644
--- a/modules/lua/mod_lua.c
+++ b/modules/lua/mod_lua.c
@@ -24,6 +24,7 @@
#include "lua_config.h"
#include "apr_optional.h"
#include "mod_ssl.h"
+#include "mod_auth.h"
#ifdef APR_HAS_THREADS
#include "apr_thread_proc.h"
@@ -39,11 +40,22 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_request,
static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *lua_ssl_val = NULL;
static APR_OPTIONAL_FN_TYPE(ssl_is_https) *lua_ssl_is_https = NULL;
- module AP_MODULE_DECLARE_DATA lua_module;
+module AP_MODULE_DECLARE_DATA lua_module;
#define AP_LUA_HOOK_FIRST (APR_HOOK_FIRST - 1)
#define AP_LUA_HOOK_LAST (APR_HOOK_LAST + 1)
+typedef struct {
+ const char *name;
+ const char *file_name;
+ const char *function_name;
+ ap_lua_vm_spec *spec;
+ apr_array_header_t *args;
+} lua_authz_provider_spec;
+
+apr_hash_t *lua_authz_providers;
+
+
/**
* error reporting if lua has an error.
* Extracts the error from lua stack and prints
@@ -78,73 +90,114 @@ static int lua_open_hook(lua_State *L, apr_pool_t *p)
return OK;
}
+static const char *scope_to_string(unsigned int scope)
+{
+ switch (scope) {
+ case AP_LUA_SCOPE_ONCE:
+ case AP_LUA_SCOPE_UNSET:
+ return "once";
+ case AP_LUA_SCOPE_REQUEST:
+ return "request";
+ case AP_LUA_SCOPE_CONN:
+ return "conn";
+#if APR_HAS_THREADS
+ case AP_LUA_SCOPE_THREAD:
+ return "thread";
+#endif
+ default:
+ ap_assert(0);
+ }
+}
+
+static ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool,
+ request_rec *r,
+ const ap_lua_dir_cfg *cfg,
+ const ap_lua_server_cfg *server_cfg,
+ const char *filename,
+ const char *bytecode,
+ apr_size_t bytecode_len,
+ const char *function,
+ const char *what)
+{
+ apr_pool_t *pool;
+ ap_lua_vm_spec *spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
+
+ spec->scope = cfg->vm_scope;
+ spec->pool = r->pool;
+ spec->package_paths = cfg->package_paths;
+ spec->package_cpaths = cfg->package_cpaths;
+ spec->cb = &lua_open_callback;
+ spec->cb_arg = NULL;
+ spec->bytecode = bytecode;
+ spec->bytecode_len = bytecode_len;
+
+ if (filename) {
+ char *file;
+ apr_filepath_merge(&file, server_cfg->root_path,
+ filename, APR_FILEPATH_NOTRELATIVE, r->pool);
+ spec->file = file;
+ }
+ else {
+ spec->file = r->filename;
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, APLOGNO(02313)
+ "%s details: scope: %s, file: %s, func: %s",
+ what, scope_to_string(spec->scope), spec->file,
+ function ? function : "-");
+
+ switch (spec->scope) {
+ case AP_LUA_SCOPE_ONCE:
+ case AP_LUA_SCOPE_UNSET:
+ apr_pool_create(&pool, r->pool);
+ break;
+ case AP_LUA_SCOPE_REQUEST:
+ pool = r->pool;
+ break;
+ case AP_LUA_SCOPE_CONN:
+ pool = r->connection->pool;
+ break;
+#if APR_HAS_THREADS
+ case AP_LUA_SCOPE_THREAD:
+ pool = apr_thread_pool_get(r->connection->current_thread);
+ break;
+#endif
+ default:
+ ap_assert(0);
+ }
+
+ *lifecycle_pool = pool;
+ return spec;
+}
+
/**
* "main"
*/
static int lua_handler(request_rec *r)
{
- ap_lua_dir_cfg *dcfg;
- apr_pool_t *pool;
if (strcmp(r->handler, "lua-script")) {
return DECLINED;
}
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01472) "handling [%s] in mod_lua",
- r->filename);
- dcfg = ap_get_module_config(r->per_dir_config, &lua_module);
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(01472)
+ "handling [%s] in mod_lua", r->filename);
+ /* XXX: This seems wrong because it may generate wrong headers for HEAD requests */
if (!r->header_only) {
lua_State *L;
+ apr_pool_t *pool;
const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
&lua_module);
- ap_lua_vm_spec *spec = NULL;
+ ap_lua_vm_spec *spec = create_vm_spec(&pool, r, cfg, NULL, NULL, NULL,
+ 0, "handle", "request handler");
- spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
- spec->scope = dcfg->vm_scope;
- spec->pool = r->pool;
- spec->file = r->filename;
- spec->package_paths = cfg->package_paths;
- spec->package_cpaths = cfg->package_cpaths;
- spec->cb = &lua_open_callback;
- spec->cb_arg = NULL;
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01473)
- "request details scope:%u, filename:%s, function:%s",
- spec->scope,
- spec->file,
- "handle");
-
- switch (spec->scope) {
- case AP_LUA_SCOPE_ONCE:
- case AP_LUA_SCOPE_UNSET:
- apr_pool_create(&pool, r->pool);
- break;
- case AP_LUA_SCOPE_REQUEST:
- pool = r->pool;
- break;
- case AP_LUA_SCOPE_CONN:
- pool = r->connection->pool;
- break;
- case AP_LUA_SCOPE_THREAD:
- #if APR_HAS_THREADS
- pool = apr_thread_pool_get(r->connection->current_thread);
- break;
- #endif
- default:
- ap_assert(0);
- }
-
- L = ap_lua_get_lua_state(pool,
- spec);
-
+ L = ap_lua_get_lua_state(pool, spec);
if (!L) {
/* TODO annotate spec with failure reason */
r->status = HTTP_INTERNAL_SERVER_ERROR;
ap_rputs("Unable to compile VM, see logs", r);
return HTTP_INTERNAL_SERVER_ERROR;
}
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01474) "got a vm!");
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, APLOGNO(01474) "got a vm!");
lua_getglobal(L, "handle");
if (!lua_isfunction(L, -1)) {
ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01475)
@@ -163,7 +216,6 @@ static int lua_handler(request_rec *r)
-
/* ---------------- Configury stuff --------------- */
/** harnesses for magic hooks **/
@@ -190,46 +242,12 @@ static int lua_request_rec_hook_harness(request_rec *r, const char *name, int ap
if (hook_spec == NULL) {
continue;
}
- spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
-
- spec->file = hook_spec->file_name;
- spec->scope = cfg->vm_scope;
- spec->bytecode = hook_spec->bytecode;
- spec->bytecode_len = hook_spec->bytecode_len;
- spec->pool = r->pool;
- spec->package_paths = cfg->package_paths;
- spec->package_cpaths = cfg->package_cpaths;
- spec->cb = &lua_open_callback;
- spec->cb_arg = NULL;
-
- apr_filepath_merge(&spec->file, server_cfg->root_path,
- spec->file, APR_FILEPATH_NOTRELATIVE, r->pool);
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01476)
- "request details scope:%u, filename:%s, function:%s",
- spec->scope,
- spec->file,
- hook_spec->function_name ? hook_spec->function_name : "-");
-
- switch (spec->scope) {
- case AP_LUA_SCOPE_ONCE:
- case AP_LUA_SCOPE_UNSET:
- apr_pool_create(&pool, r->pool);
- break;
- case AP_LUA_SCOPE_REQUEST:
- pool = r->pool;
- break;
- case AP_LUA_SCOPE_CONN:
- pool = r->connection->pool;
- break;
- case AP_LUA_SCOPE_THREAD:
- #if APR_HAS_THREADS
- pool = apr_thread_pool_get(r->connection->current_thread);
- break;
- #endif
- default:
- ap_assert(0);
- }
+ spec = create_vm_spec(&pool, r, cfg, server_cfg,
+ hook_spec->file_name,
+ hook_spec->bytecode,
+ hook_spec->bytecode_len,
+ hook_spec->function_name,
+ "request hook");
L = ap_lua_get_lua_state(pool, spec);
@@ -450,16 +468,15 @@ static const char *register_named_block_function_hook(const char *name,
{
cr_ctx ctx;
- char buf[32];
lua_State *lvm;
char *tmp;
int rv;
ap_directive_t **current;
hack_section_baton *baton;
- apr_snprintf(buf, sizeof(buf), "%u", cmd->config_file->line_number);
- spec->file_name = apr_pstrcat(cmd->pool, cmd->config_file->name, ":",
- buf, NULL);
+ spec->file_name = apr_psprintf(cmd->pool, "%s:%u",
+ cmd->config_file->name,
+ cmd->config_file->line_number);
if (function) {
spec->function_name = (char *) function;
}
@@ -959,6 +976,131 @@ AP_LUA_DECLARE(int) ap_lua_ssl_is_https(conn_rec *c)
/*******************************/
+static const char *lua_authz_parse(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *provider_name;
+ lua_authz_provider_spec *spec;
+
+ apr_pool_userdata_get((void**)&provider_name, AUTHZ_PROVIDER_NAME_NOTE,
+ cmd->temp_pool);
+ ap_assert(provider_name != NULL);
+
+ spec = apr_hash_get(lua_authz_providers, provider_name, APR_HASH_KEY_STRING);
+ ap_assert(spec != NULL);
+
+ if (require_line && *require_line) {
+ const char *arg;
+ spec->args = apr_array_make(cmd->pool, 2, sizeof(const char *));
+ while ((arg = ap_getword_conf(cmd->pool, &require_line)) && *arg) {
+ APR_ARRAY_PUSH(spec->args, const char *) = arg;
+ }
+ }
+
+ *parsed_require_line = spec;
+ return NULL;
+}
+
+static authz_status lua_authz_check(request_rec *r, const char *require_line,
+ const void *parsed_require_line)
+{
+ apr_pool_t *pool;
+ ap_lua_vm_spec *spec;
+ lua_State *L;
+ ap_lua_server_cfg *server_cfg = ap_get_module_config(r->server->module_config,
+ &lua_module);
+ const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
+ &lua_module);
+ const lua_authz_provider_spec *prov_spec = parsed_require_line;
+ int result;
+ int nargs = 0;
+
+ spec = create_vm_spec(&pool, r, cfg, server_cfg, prov_spec->file_name,
+ NULL, 0, prov_spec->function_name, "authz provider");
+
+ L = ap_lua_get_lua_state(pool, spec);
+ if (L == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02314)
+ "Unable to compile VM for authz provider %s", prov_spec->name);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ lua_getglobal(L, prov_spec->function_name);
+ if (!lua_isfunction(L, -1)) {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02319)
+ "Unable to find function %s in %s",
+ prov_spec->function_name, prov_spec->file_name);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ ap_lua_run_lua_request(L, r);
+ if (prov_spec->args) {
+ int i;
+ if (!lua_checkstack(L, prov_spec->args->nelts)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02315)
+ "Error: authz provider %s: too many arguments", prov_spec->name);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ for (i = 0; i < prov_spec->args->nelts; i++) {
+ const char *arg = APR_ARRAY_IDX(prov_spec->args, i, const char *);
+ lua_pushstring(L, arg);
+ }
+ nargs = prov_spec->args->nelts;
+ }
+ if (lua_pcall(L, 1 + nargs, 1, 0)) {
+ const char *err = lua_tostring(L, -1);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02316)
+ "Error executing authz provider %s: %s", prov_spec->name, err);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ if (!lua_isnumber(L, -1)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02317)
+ "Error: authz provider %s did not return integer", prov_spec->name);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ result = lua_tointeger(L, -1);
+ switch (result) {
+ case AUTHZ_DENIED:
+ case AUTHZ_GRANTED:
+ case AUTHZ_NEUTRAL:
+ case AUTHZ_GENERAL_ERROR:
+ case AUTHZ_DENIED_NO_USER:
+ return result;
+ default:
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02318)
+ "Error: authz provider %s: invalid return value %d",
+ prov_spec->name, result);
+ }
+ return AUTHZ_GENERAL_ERROR;
+}
+
+static const authz_provider lua_authz_provider =
+{
+ &lua_authz_check,
+ &lua_authz_parse,
+};
+
+static const char *register_authz_provider(cmd_parms *cmd, void *_cfg,
+ const char *name, const char *file,
+ const char *function)
+{
+ lua_authz_provider_spec *spec;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err)
+ return err;
+
+ spec = apr_pcalloc(cmd->pool, sizeof(*spec));
+ spec->name = name;
+ spec->file_name = file;
+ spec->function_name = function;
+
+ apr_hash_set(lua_authz_providers, name, APR_HASH_KEY_STRING, spec);
+ ap_register_auth_provider(cmd->pool, AUTHZ_PROVIDER_GROUP, name,
+ AUTHZ_PROVIDER_VERSION,
+ &lua_authz_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ return NULL;
+}
+
+
command_rec lua_commands[] = {
AP_INIT_TAKE1("LuaRoot", register_lua_root, NULL, OR_ALL,
@@ -970,6 +1112,8 @@ command_rec lua_commands[] = {
AP_INIT_TAKE1("LuaPackageCPath", register_package_cdir, NULL, OR_ALL,
"Add a directory to lua's package.cpath"),
+ AP_INIT_TAKE3("LuaAuthzProvider", register_authz_provider, NULL, RSRC_CONF|EXEC_ON_READ,
+ "Provide an authorization provider"),
AP_INIT_TAKE23("LuaHookTranslateName", register_translate_name_hook, NULL,
OR_ALL,
@@ -1202,6 +1346,9 @@ static void lua_register_hooks(apr_pool_t *p)
APR_OPTIONAL_HOOK(ap_lua, lua_request, lua_request_hook, NULL, NULL,
APR_HOOK_REALLY_FIRST);
+
+ /* providers */
+ lua_authz_providers = apr_hash_make(p);
}
AP_DECLARE_MODULE(lua) = {
diff --git a/modules/lua/mod_lua.h b/modules/lua/mod_lua.h
index 5394f7a4..52ff96ad 100644
--- a/modules/lua/mod_lua.h
+++ b/modules/lua/mod_lua.h
@@ -40,6 +40,9 @@
#include "apr_time.h"
#include "apr_hooks.h"
+/* Allow for Lua 5.2 backwards compatibility */
+#define LUA_COMPAT_ALL
+
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
@@ -113,7 +116,7 @@ typedef struct
apr_hash_t *hooks; /* <wombat_hook_info> */
/* the actual directory being configured */
- char *dir;
+ const char *dir;
/* Whether Lua scripts in a sub-dir are run before parents */
ap_lua_inherit_t inherit;
@@ -131,7 +134,7 @@ typedef struct
typedef struct
{
- char *function_name;
+ const char *function_name;
ap_lua_vm_spec *spec;
} mapped_request_details;
@@ -144,7 +147,7 @@ typedef struct
typedef struct
{
lua_State *L;
- char *function;
+ const char *function;
} ap_lua_filter_ctx;
extern module AP_MODULE_DECLARE_DATA lua_module;
diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c
index cba118c6..5f3232b8 100644
--- a/modules/mappers/mod_negotiation.c
+++ b/modules/mappers/mod_negotiation.c
@@ -2656,9 +2656,9 @@ static char *make_variant_list(request_rec *r, negotiation_state *neg)
* need to change the calculation of max_vlist_array above.
*/
*((const char **) apr_array_push(arr)) = "<li><a href=\"";
- *((const char **) apr_array_push(arr)) = filename;
+ *((const char **) apr_array_push(arr)) = ap_escape_path_segment(r->pool, filename);
*((const char **) apr_array_push(arr)) = "\">";
- *((const char **) apr_array_push(arr)) = filename;
+ *((const char **) apr_array_push(arr)) = ap_escape_html(r->pool, filename);
*((const char **) apr_array_push(arr)) = "</a> ";
*((const char **) apr_array_push(arr)) = description;
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 8f5d3972..9823a7fa 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -190,6 +190,7 @@ static const char* really_last_key = "rewrite_really_last";
#define OPTION_INHERIT 1<<1
#define OPTION_INHERIT_BEFORE 1<<2
#define OPTION_NOSLASH 1<<3
+#define OPTION_ANYURI 1<<4
#ifndef RAND_MAX
#define RAND_MAX 32767
@@ -401,7 +402,7 @@ static int proxy_available;
/* Locks/Mutexes */
static apr_global_mutex_t *rewrite_mapr_lock_acquire = NULL;
-const char *rewritemap_mutex_type = "rewrite-map";
+static const char *rewritemap_mutex_type = "rewrite-map";
/* Optional functions imported from mod_ssl when loaded: */
static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL;
@@ -2893,6 +2894,9 @@ static const char *cmd_rewriteoptions(cmd_parms *cmd,
"LimitInternalRecursion directive and will be "
"ignored.");
}
+ else if (!strcasecmp(w, "allowanyuri")) {
+ options |= OPTION_ANYURI;
+ }
else {
return apr_pstrcat(cmd->pool, "RewriteOptions: unknown option '",
w, "'", NULL);
@@ -2932,8 +2936,7 @@ static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, const char *a1,
sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
- newmap = apr_palloc(cmd->pool, sizeof(rewritemap_entry));
- newmap->func = NULL;
+ newmap = apr_pcalloc(cmd->pool, sizeof(rewritemap_entry));
if (strncasecmp(a2, "txt:", 4) == 0) {
if ((fname = ap_server_root_relative(cmd->pool, a2+4)) == NULL) {
@@ -2944,7 +2947,6 @@ static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, const char *a1,
newmap->type = MAPTYPE_TXT;
newmap->datafile = fname;
newmap->checkfile = fname;
- newmap->checkfile2= NULL;
newmap->cachename = apr_psprintf(cmd->pool, "%pp:%s",
(void *)cmd->server, a1);
}
@@ -2957,7 +2959,6 @@ static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, const char *a1,
newmap->type = MAPTYPE_RND;
newmap->datafile = fname;
newmap->checkfile = fname;
- newmap->checkfile2= NULL;
newmap->cachename = apr_psprintf(cmd->pool, "%pp:%s",
(void *)cmd->server, a1);
}
@@ -3031,17 +3032,10 @@ static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, const char *a1,
}
newmap->type = MAPTYPE_PRG;
- newmap->datafile = NULL;
newmap->checkfile = newmap->argv[0];
- newmap->checkfile2= NULL;
- newmap->cachename = NULL;
}
else if (strncasecmp(a2, "int:", 4) == 0) {
newmap->type = MAPTYPE_INT;
- newmap->datafile = NULL;
- newmap->checkfile = NULL;
- newmap->checkfile2= NULL;
- newmap->cachename = NULL;
newmap->func = (char *(*)(request_rec *,char *))
apr_hash_get(mapfunc_hash, a2+4, strlen(a2+4));
if (newmap->func == NULL) {
@@ -3058,12 +3052,9 @@ static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, const char *a1,
newmap->type = MAPTYPE_TXT;
newmap->datafile = fname;
newmap->checkfile = fname;
- newmap->checkfile2= NULL;
newmap->cachename = apr_psprintf(cmd->pool, "%pp:%s",
(void *)cmd->server, a1);
}
- newmap->fpin = NULL;
- newmap->fpout = NULL;
if (newmap->checkfile
&& (apr_stat(&st, newmap->checkfile, APR_FINFO_MIN,
@@ -3243,37 +3234,60 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
newcond->ptype = CONDPAT_AP_EXPR;
}
else if (*a2 && a2[1]) {
- if (!a2[2] && *a2 == '-') {
- switch (a2[1]) {
- case 'f': newcond->ptype = CONDPAT_FILE_EXISTS; break;
- case 's': newcond->ptype = CONDPAT_FILE_SIZE; break;
- case 'd': newcond->ptype = CONDPAT_FILE_DIR; break;
- case 'x': newcond->ptype = CONDPAT_FILE_XBIT; break;
- case 'h': newcond->ptype = CONDPAT_FILE_LINK; break;
- case 'L': newcond->ptype = CONDPAT_FILE_LINK; break;
- case 'U': newcond->ptype = CONDPAT_LU_URL; break;
- case 'F': newcond->ptype = CONDPAT_LU_FILE; break;
- case 'l': if (a2[2] == 't')
- a2 += 3, newcond->ptype = CONDPAT_INT_LT;
- else if (a2[2] == 'e')
- a2 += 3, newcond->ptype = CONDPAT_INT_LE;
- else /* Historical; prefer -L or -h instead */
- newcond->ptype = CONDPAT_FILE_LINK;
- break;
- case 'g': if (a2[2] == 't')
- a2 += 3, newcond->ptype = CONDPAT_INT_GT;
- else if (a2[2] == 'e')
- a2 += 3, newcond->ptype = CONDPAT_INT_GE;
- break;
- case 'e': if (a2[2] == 'q')
- a2 += 3, newcond->ptype = CONDPAT_INT_EQ;
- break;
- case 'n': if (a2[2] == 'e') {
- /* Inversion, ensure !-ne == -eq */
- a2 += 3, newcond->ptype = CONDPAT_INT_EQ;
- newcond->flags ^= CONDFLAG_NOTMATCH;
- }
- break;
+ if (*a2 == '-') {
+ if (!a2[2]) {
+ switch (a2[1]) {
+ case 'f': newcond->ptype = CONDPAT_FILE_EXISTS; break;
+ case 's': newcond->ptype = CONDPAT_FILE_SIZE; break;
+ case 'd': newcond->ptype = CONDPAT_FILE_DIR; break;
+ case 'x': newcond->ptype = CONDPAT_FILE_XBIT; break;
+ case 'h': newcond->ptype = CONDPAT_FILE_LINK; break;
+ case 'L': newcond->ptype = CONDPAT_FILE_LINK; break;
+ case 'l': newcond->ptype = CONDPAT_FILE_LINK; break;
+ case 'U': newcond->ptype = CONDPAT_LU_URL; break;
+ case 'F': newcond->ptype = CONDPAT_LU_FILE; break;
+ }
+ }
+ else if (a2[3]) {
+ switch (a2[1]) {
+ case 'l':
+ if (a2[2] == 't') {
+ a2 += 3;
+ newcond->ptype = CONDPAT_INT_LT;
+ }
+ else if (a2[2] == 'e') {
+ a2 += 3;
+ newcond->ptype = CONDPAT_INT_LE;
+ }
+ break;
+
+ case 'g':
+ if (a2[2] == 't') {
+ a2 += 3;
+ newcond->ptype = CONDPAT_INT_GT;
+ }
+ else if (a2[2] == 'e') {
+ a2 += 3;
+ newcond->ptype = CONDPAT_INT_GE;
+ }
+ break;
+
+ case 'e':
+ if (a2[2] == 'q') {
+ a2 += 3;
+ newcond->ptype = CONDPAT_INT_EQ;
+ }
+ break;
+
+ case 'n':
+ if (a2[2] == 'e') {
+ /* Inversion, ensure !-ne == -eq */
+ a2 += 3;
+ newcond->ptype = CONDPAT_INT_EQ;
+ newcond->flags ^= CONDFLAG_NOTMATCH;
+ }
+ break;
+ }
}
}
else {
@@ -4419,8 +4433,16 @@ static int hook_uri2file(request_rec *r)
return DECLINED;
}
- if ((r->unparsed_uri[0] == '*' && r->unparsed_uri[1] == '\0')
- || !r->uri || r->uri[0] != '/') {
+ /* Unless the anyuri option is set, ensure that the input to the
+ * first rule really is a URL-path, avoiding security issues with
+ * poorly configured rules. See CVE-2011-3368, CVE-2011-4317. */
+ if ((dconf->options & OPTION_ANYURI) == 0
+ && ((r->unparsed_uri[0] == '*' && r->unparsed_uri[1] == '\0')
+ || !r->uri || r->uri[0] != '/')) {
+ rewritelog((r, 8, NULL, "Declining, request-URI '%s' is not a URL-path. "
+ "Consult the manual entry for the RewriteOptions directive "
+ "for options and caveats about matching other strings.",
+ r->uri));
return DECLINED;
}
diff --git a/modules/metadata/mod_setenvif.c b/modules/metadata/mod_setenvif.c
index 80825cce..65214cd4 100644
--- a/modules/metadata/mod_setenvif.c
+++ b/modules/metadata/mod_setenvif.c
@@ -165,17 +165,15 @@ static void *merge_setenvif_config(apr_pool_t *p, void *basev, void *overridesv)
#define ICASE_MAGIC ((void *)(&setenvif_module))
#define SEI_MAGIC_HEIRLOOM "setenvif-phase-flag"
+static ap_regex_t *is_header_regex_regex;
+
static int is_header_regex(apr_pool_t *p, const char* name)
{
/* If a Header name contains characters other than:
* -,_,[A-Z\, [a-z] and [0-9].
* assume the header name is a regular expression.
*/
- ap_regex_t *preg = ap_pregcomp(p, "^[-A-Za-z0-9_]*$",
- (AP_REG_EXTENDED | AP_REG_NOSUB ));
- ap_assert(preg != NULL);
-
- if (ap_regexec(preg, name, 0, NULL, 0)) {
+ if (ap_regexec(is_header_regex_regex, name, 0, NULL, 0)) {
return 1;
}
@@ -633,6 +631,10 @@ static void register_hooks(apr_pool_t *p)
{
ap_hook_header_parser(match_headers, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_post_read_request(match_headers, NULL, NULL, APR_HOOK_MIDDLE);
+
+ is_header_regex_regex = ap_pregcomp(p, "^[-A-Za-z0-9_]*$",
+ (AP_REG_EXTENDED | AP_REG_NOSUB ));
+ ap_assert(is_header_regex_regex != NULL);
}
AP_DECLARE_MODULE(setenvif) =
diff --git a/modules/proxy/NWGNUproxy b/modules/proxy/NWGNUproxy
index cade4acb..6342e613 100644
--- a/modules/proxy/NWGNUproxy
+++ b/modules/proxy/NWGNUproxy
@@ -277,6 +277,7 @@ $(OBJDIR)/mod_proxy.imp:
@echo $(DL) ap_proxy_canon_netloc,$(DL)>> $@
@echo $(DL) ap_proxy_canonenc,$(DL)>> $@
@echo $(DL) ap_proxy_checkproxyblock,$(DL)>> $@
+ @echo $(DL) ap_proxy_checkproxyblock2,$(DL)>> $@
@echo $(DL) ap_proxy_conn_is_https,$(DL)>> $@
@echo $(DL) ap_proxy_connect_backend,$(DL)>> $@
@echo $(DL) ap_proxy_connect_to_backend,$(DL)>> $@
diff --git a/modules/proxy/NWGNUproxylbm_busy b/modules/proxy/NWGNUproxylbm_busy
index 394af7a6..c1b91f6b 100644
--- a/modules/proxy/NWGNUproxylbm_busy
+++ b/modules/proxy/NWGNUproxylbm_busy
@@ -19,6 +19,7 @@ XINCDIRS += \
$(APR)/include \
$(APRUTIL)/include \
$(AP_WORK)/include \
+ $(AP_WORK)/modules/proxy \
$(AP_WORK)/modules/http \
$(NWOS) \
$(EOLIST)
diff --git a/modules/proxy/NWGNUproxylbm_hb b/modules/proxy/NWGNUproxylbm_hb
index 80f2f822..19563da6 100644
--- a/modules/proxy/NWGNUproxylbm_hb
+++ b/modules/proxy/NWGNUproxylbm_hb
@@ -19,6 +19,7 @@ XINCDIRS += \
$(APR)/include \
$(APRUTIL)/include \
$(AP_WORK)/include \
+ $(AP_WORK)/modules/proxy \
$(AP_WORK)/modules/http \
$(NWOS) \
$(EOLIST)
diff --git a/modules/proxy/NWGNUproxylbm_req b/modules/proxy/NWGNUproxylbm_req
index 0170056c..6a2c4cd0 100644
--- a/modules/proxy/NWGNUproxylbm_req
+++ b/modules/proxy/NWGNUproxylbm_req
@@ -19,6 +19,7 @@ XINCDIRS += \
$(APR)/include \
$(APRUTIL)/include \
$(AP_WORK)/include \
+ $(AP_WORK)/modules/proxy \
$(AP_WORK)/modules/http \
$(NWOS) \
$(EOLIST)
diff --git a/modules/proxy/NWGNUproxylbm_traf b/modules/proxy/NWGNUproxylbm_traf
index 1960453b..1927d626 100644
--- a/modules/proxy/NWGNUproxylbm_traf
+++ b/modules/proxy/NWGNUproxylbm_traf
@@ -19,6 +19,7 @@ XINCDIRS += \
$(APR)/include \
$(APRUTIL)/include \
$(AP_WORK)/include \
+ $(AP_WORK)/modules/proxy \
$(AP_WORK)/modules/http \
$(NWOS) \
$(EOLIST)
diff --git a/modules/proxy/ajp_header.c b/modules/proxy/ajp_header.c
index dc86defa..3e906514 100644
--- a/modules/proxy/ajp_header.c
+++ b/modules/proxy/ajp_header.c
@@ -139,7 +139,7 @@ static const unsigned char sc_for_req_method_table[] = {
SC_M_PUT,
SC_M_POST,
SC_M_DELETE,
- 0, /* M_DELETE */
+ 0, /* M_CONNECT */
SC_M_OPTIONS,
SC_M_TRACE,
0, /* M_PATCH */
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index f9a80090..431efb87 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -44,7 +44,6 @@ APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
* can't trust directory_walk/file_walk since these are
* not in our filesystem. Prevents mod_http from serving
* the TRACE request we will set aside to handle later.
- * type_checker: set type to PROXY_MAGIC_TYPE if filename begins proxy:
* fix_ups: convert the URL stored in the filename to the
* canonical form.
* handler: handle proxy requests
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index 5ad91fb5..0bce5065 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -534,6 +534,18 @@ PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, cha
char **passwordp, char **hostp, apr_port_t *port);
PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message);
PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr);
+
+/** Test whether the hostname/address of the request are blocked by the ProxyBlock
+ * configuration.
+ * @param r request
+ * @param conf server configuration
+ * @param hostname hostname from request URI
+ * @param addr resolved address of hostname, or NULL if not known
+ * @return OK on success, or else an errro
+ */
+PROXY_DECLARE(int) ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf,
+ const char *hostname, apr_sockaddr_t *addr);
+
PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r);
/* DEPRECATED (will be replaced with ap_proxy_connect_backend */
PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, apr_sockaddr_t *, const char *, proxy_server_conf *, request_rec *);
diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
index 93cb1530..3736156a 100644
--- a/modules/proxy/mod_proxy_ajp.c
+++ b/modules/proxy/mod_proxy_ajp.c
@@ -207,7 +207,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
/* send request headers */
status = ajp_send_header(conn->sock, r, maxsize, uri);
if (status != APR_SUCCESS) {
- conn->close++;
+ conn->close = 1;
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00868)
"request failed to %pI (%s)",
conn->worker->cp->addr,
@@ -234,7 +234,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
status = ajp_alloc_data_msg(r->pool, &buff, &bufsiz, &msg);
if (status != APR_SUCCESS) {
/* We had a failure: Close connection to backend */
- conn->close++;
+ conn->close = 1;
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00869)
"ajp_alloc_data_msg failed");
return HTTP_INTERNAL_SERVER_ERROR;
@@ -255,7 +255,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
if (status != APR_SUCCESS) {
/* We had a failure: Close connection to backend */
- conn->close++;
+ conn->close = 1;
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00871)
"ap_get_brigade failed");
apr_brigade_destroy(input_brigade);
@@ -275,7 +275,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
status = apr_brigade_flatten(input_brigade, buff, &bufsiz);
if (status != APR_SUCCESS) {
/* We had a failure: Close connection to backend */
- conn->close++;
+ conn->close = 1;
apr_brigade_destroy(input_brigade);
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00874)
"apr_brigade_flatten");
@@ -290,7 +290,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
ajp_msg_log(r, msg, "First ajp_send_data_msg: ajp_ilink_send packet dump");
if (status != APR_SUCCESS) {
/* We had a failure: Close connection to backend */
- conn->close++;
+ conn->close = 1;
apr_brigade_destroy(input_brigade);
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00876)
"send failed to %pI (%s)",
@@ -319,7 +319,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
* for later resusage by the next request again.
* Close it to clean things up.
*/
- conn->close++;
+ conn->close = 1;
return HTTP_BAD_REQUEST;
}
}
@@ -330,7 +330,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
(ajp_msg_t **)&(conn->data));
if (status != APR_SUCCESS) {
/* We had a failure: Close connection to backend */
- conn->close++;
+ conn->close = 1;
apr_brigade_destroy(input_brigade);
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00878)
"read response failed from %pI (%s)",
@@ -559,7 +559,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
* But: Close this connection to the backend.
*/
if (r->connection->aborted) {
- conn->close++;
+ conn->close = 1;
output_failed = 0;
result = CMD_AJP13_END_RESPONSE;
request_ended = 1;
@@ -597,7 +597,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
"Processing of request failed backend: %i, "
"output: %i", backend_failed, output_failed);
/* We had a failure: Close connection to backend */
- conn->close++;
+ conn->close = 1;
/* Return DONE to avoid error messages being added to the stream */
if (data_sent) {
rv = DONE;
@@ -607,7 +607,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00891)
"Processing of request didn't terminate cleanly");
/* We had a failure: Close connection to backend */
- conn->close++;
+ conn->close = 1;
backend_failed = 1;
/* Return DONE to avoid error messages being added to the stream */
if (data_sent) {
@@ -616,7 +616,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
}
else if (!conn_reuse) {
/* Our backend signalled connection close */
- conn->close++;
+ conn->close = 1;
}
else {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00892)
@@ -679,7 +679,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
apr_brigade_destroy(output_brigade);
if (apr_table_get(r->subprocess_env, "proxy-nokeepalive")) {
- conn->close++;
+ conn->close = 1;
}
return rv;
@@ -701,29 +701,15 @@ static int proxy_ajp_handler(request_rec *r, proxy_worker *worker,
int retry;
proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
&proxy_module);
-
- /*
- * Note: Memory pool allocation.
- * A downstream keepalive connection is always connected to the existence
- * (or not) of an upstream keepalive connection. If this is not done then
- * load balancing against multiple backend servers breaks (one backend
- * server ends up taking 100% of the load), and the risk is run of
- * downstream keepalive connections being kept open unnecessarily. This
- * keeps webservers busy and ties up resources.
- *
- * As a result, we allocate all sockets out of the upstream connection
- * pool, and when we want to reuse a socket, we check first whether the
- * connection ID of the current upstream connection is the same as that
- * of the connection when the socket was opened.
- */
- apr_pool_t *p = r->connection->pool;
- apr_uri_t *uri = apr_palloc(r->connection->pool, sizeof(*uri));
-
+ apr_pool_t *p = r->pool;
+ apr_uri_t *uri;
if (strncasecmp(url, "ajp:", 4) != 0) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00894) "declining URL %s", url);
return DECLINED;
}
+
+ uri = apr_palloc(p, sizeof(*uri));
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00895) "serving URL %s", url);
/* create space for state information */
@@ -772,7 +758,7 @@ static int proxy_ajp_handler(request_rec *r, proxy_worker *worker,
* TCP connection gets closed and try it once again.
*/
if (status != APR_SUCCESS) {
- backend->close++;
+ backend->close = 1;
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00897)
"cping/cpong failed to %pI (%s)",
worker->cp->addr, worker->s->hostname);
diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
index 96e0901e..1feb2d7c 100644
--- a/modules/proxy/mod_proxy_balancer.c
+++ b/modules/proxy/mod_proxy_balancer.c
@@ -437,6 +437,17 @@ static void force_recovery(proxy_balancer *balancer, server_rec *s)
}
}
+static apr_status_t decrement_busy_count(void *worker_)
+{
+ proxy_worker *worker = worker_;
+
+ if (worker->s->busy) {
+ worker->s->busy--;
+ }
+
+ return APR_SUCCESS;
+}
+
static int proxy_balancer_pre_request(proxy_worker **worker,
proxy_balancer **balancer,
request_rec *r,
@@ -570,6 +581,8 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
}
(*worker)->s->busy++;
+ apr_pool_cleanup_register(r->pool, *worker, decrement_busy_count,
+ apr_pool_cleanup_null);
/* Add balancer/worker info to env. */
apr_table_setn(r->subprocess_env,
@@ -623,7 +636,7 @@ static int proxy_balancer_post_request(proxy_worker *worker,
for (i = 0; i < balancer->errstatuses->nelts; i++) {
int val = ((int *)balancer->errstatuses->elts)[i];
if (r->status == val) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01174)
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01174)
"%s: Forcing worker (%s) into error state "
"due to status code %d matching 'failonstatus' "
"balancer parameter",
@@ -642,11 +655,7 @@ static int proxy_balancer_post_request(proxy_worker *worker,
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01176)
"proxy_balancer_post_request for (%s)", balancer->s->name);
- if (worker && worker->s->busy)
- worker->s->busy--;
-
return OK;
-
}
static void recalc_factors(proxy_balancer *balancer)
@@ -744,7 +753,6 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog,
s = s->next;
continue;
}
-
if (conf->balancers->nelts) {
conf->max_balancers = conf->balancers->nelts + conf->bgrowth;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01178) "Doing balancers create: %d, %d (%d)",
diff --git a/modules/proxy/mod_proxy_connect.c b/modules/proxy/mod_proxy_connect.c
index 9a14eb71..0cf5693c 100644
--- a/modules/proxy/mod_proxy_connect.c
+++ b/modules/proxy/mod_proxy_connect.c
@@ -205,7 +205,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
conn_rec *backconn;
apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
- apr_status_t err, rv;
+ apr_status_t rv;
apr_size_t nbytes;
char buffer[HUGE_STRING_LEN];
apr_socket_t *client_socket = ap_get_conn_socket(c);
@@ -216,7 +216,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
const apr_pollfd_t *signalled;
apr_int32_t pollcnt, pi;
apr_int16_t pollevent;
- apr_sockaddr_t *uri_addr, *connect_addr;
+ apr_sockaddr_t *nexthop;
apr_uri_t uri;
const char *connectname;
@@ -246,37 +246,32 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01019)
"connecting %s to %s:%d", url, uri.hostname, uri.port);
- /* do a DNS lookup for the destination host */
- err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port,
- 0, p);
- if (APR_SUCCESS != err) {
+ /* Determine host/port of next hop; from request URI or of a proxy. */
+ connectname = proxyname ? proxyname : uri.hostname;
+ connectport = proxyname ? proxyport : uri.port;
+
+ /* Do a DNS lookup for the next hop */
+ rv = apr_sockaddr_info_get(&nexthop, connectname, APR_UNSPEC,
+ connectport, 0, p);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO()
+ "failed to resolve hostname '%s'", connectname);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
apr_pstrcat(p, "DNS lookup failure for: ",
- uri.hostname, NULL));
+ connectname, NULL));
}
- /* are we connecting directly, or via a proxy? */
- if (proxyname) {
- connectname = proxyname;
- connectport = proxyport;
- err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC,
- proxyport, 0, p);
- }
- else {
- connectname = uri.hostname;
- connectport = uri.port;
- connect_addr = uri_addr;
+ /* Check ProxyBlock directive on the hostname/address. */
+ if (ap_proxy_checkproxyblock2(r, conf, uri.hostname,
+ proxyname ? NULL : nexthop) != OK) {
+ return ap_proxyerror(r, HTTP_FORBIDDEN,
+ "Connect to remote machine blocked");
}
+
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
"connecting to remote proxy %s on port %d",
connectname, connectport);
- /* check if ProxyBlock directive on this host */
- if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) {
- return ap_proxyerror(r, HTTP_FORBIDDEN,
- "Connect to remote machine blocked");
- }
-
/* Check if it is an allowed port */
if(!allowed_port(c_conf, uri.port)) {
return ap_proxyerror(r, HTTP_FORBIDDEN,
@@ -289,15 +284,6 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
* We have determined who to connect to. Now make the connection.
*/
- /* get all the possible IP addresses for the destname and loop through them
- * until we get a successful connection
- */
- if (APR_SUCCESS != err) {
- return ap_proxyerror(r, HTTP_BAD_GATEWAY,
- apr_pstrcat(p, "DNS lookup failure for: ",
- connectname, NULL));
- }
-
/*
* At this point we have a list of one or more IP addresses of
* the machine to connect to. If configured, reorder this
@@ -308,7 +294,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
* For now we do nothing, ie we get DNS round robin.
* XXX FIXME
*/
- failed = ap_proxy_connect_to_backend(&sock, "CONNECT", connect_addr,
+ failed = ap_proxy_connect_to_backend(&sock, "CONNECT", nexthop,
connectname, conf, r);
/* handle a permanent error from the above loop */
@@ -355,7 +341,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
/* peer reset */
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01021)
"an error occurred creating a new connection "
- "to %pI (%s)", connect_addr, connectname);
+ "to %pI (%s)", nexthop, connectname);
apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
@@ -370,7 +356,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
"connection complete to %pI (%s)",
- connect_addr, connectname);
+ nexthop, connectname);
apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu",
backconn->local_addr->port));
diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c
index d0df5fa1..0f844163 100644
--- a/modules/proxy/mod_proxy_fcgi.c
+++ b/modules/proxy/mod_proxy_fcgi.c
@@ -748,10 +748,10 @@ recv_again:
apr_brigade_cleanup(ob);
tmp_b = apr_bucket_eos_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(ob, tmp_b);
+ r->status = status;
ap_pass_brigade(r->output_filters, ob);
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01070)
"Error parsing script headers");
- r->status = status;
rv = APR_EINVAL;
break;
}
diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c
index d5aabd69..33237d6f 100644
--- a/modules/proxy/mod_proxy_ftp.c
+++ b/modules/proxy/mod_proxy_ftp.c
@@ -1143,7 +1143,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
}
/* check if ProxyBlock directive on this host */
- if (OK != ap_proxy_checkproxyblock(r, conf, connect_addr)) {
+ if (OK != ap_proxy_checkproxyblock2(r, conf, connectname, connect_addr)) {
return ap_proxyerror(r, HTTP_FORBIDDEN,
"Connect to remote machine blocked");
}
@@ -1725,7 +1725,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
if (len != 0)
buf = apr_pstrcat(p, "LIST ", path, CRLF, NULL);
else if (cwd == NULL || strchr(cwd, '/') != NULL)
- buf = apr_pstrcat(p, "LIST -lag", CRLF, NULL);
+ buf = "LIST -lag" CRLF;
else
buf = "LIST" CRLF;
}
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
index 64b95a2f..243c9a5e 100644
--- a/modules/proxy/mod_proxy_http.c
+++ b/modules/proxy/mod_proxy_http.c
@@ -795,14 +795,14 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r,
}
buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.0" CRLF, NULL);
force10 = 1;
- p_conn->close++;
+ p_conn->close = 1;
} else {
buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.1" CRLF, NULL);
force10 = 0;
}
if (apr_table_get(r->subprocess_env, "proxy-nokeepalive")) {
origin->keepalive = AP_CONN_CLOSE;
- p_conn->close++;
+ p_conn->close = 1;
}
ap_xlate_proto_to_ascii(buf, strlen(buf));
e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
@@ -1019,7 +1019,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r,
*/
if (!r->kept_body && r->main) {
/* XXX: Why DON'T sub-requests use keepalives? */
- p_conn->close++;
+ p_conn->close = 1;
if (old_cl_val) {
old_cl_val = NULL;
apr_table_unset(r->headers_in, "Content-Length");
@@ -1056,7 +1056,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r,
apr_table_unset(r->headers_in, "Content-Length");
old_cl_val = NULL;
origin->keepalive = AP_CONN_CLOSE;
- p_conn->close++;
+ p_conn->close = 1;
}
/* Prefetch MAX_MEM_SPOOL bytes
@@ -1705,7 +1705,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01106)
"bad HTTP/%d.%d header returned by %s (%s)",
major, minor, r->uri, r->method);
- backend->close += 1;
+ backend->close = 1;
/*
* ap_send_error relies on a headers_out to be present. we
* are in a bad position here.. so force everything we send out
@@ -1746,7 +1746,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
"server %s:%d returned Transfer-Encoding"
" and Content-Length",
backend->hostname, backend->port);
- backend->close += 1;
+ backend->close = 1;
}
/*
@@ -1755,8 +1755,9 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
*/
te = apr_table_get(r->headers_out, "Transfer-Encoding");
/* strip connection listed hop-by-hop headers from response */
- backend->close += ap_find_token(p,
- apr_table_get(r->headers_out, "Connection"), "close");
+ if (ap_find_token(p, apr_table_get(r->headers_out, "Connection"),
+ "close"))
+ backend->close = 1;
ap_proxy_clear_connection(p, r->headers_out);
if ((buf = apr_table_get(r->headers_out, "Content-Type"))) {
ap_set_content_type(r, apr_pstrdup(p, buf));
@@ -1801,7 +1802,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
/* cancel keepalive if HTTP/1.0 or less */
if ((major < 1) || (minor < 1)) {
- backend->close += 1;
+ backend->close = 1;
origin->keepalive = AP_CONN_CLOSE;
}
} else {
@@ -1809,7 +1810,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
backasswards = 1;
r->status = 200;
r->status_line = "200 OK";
- backend->close += 1;
+ backend->close = 1;
}
if (ap_is_HTTP_INFO(proxy_status)) {
@@ -1964,8 +1965,9 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
/* ap_get_brigade will return success with an empty brigade
* for a non-blocking read which would block: */
- if (APR_STATUS_IS_EAGAIN(rv)
- || (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))) {
+ if (mode == APR_NONBLOCK_READ
+ && (APR_STATUS_IS_EAGAIN(rv)
+ || (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)))) {
/* flush to the client and switch to blocking mode */
e = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
@@ -2236,8 +2238,24 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
* so.
*/
if (is_ssl) {
+ proxy_dir_conf *dconf;
+ const char *ssl_hostname;
+
+ /*
+ * In the case of ProxyPreserveHost on use the hostname of
+ * the request if present otherwise use the one from the
+ * backend request URI.
+ */
+ dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
+ if ((dconf->preserve_host != 0) && (r->hostname != NULL)) {
+ ssl_hostname = r->hostname;
+ }
+ else {
+ ssl_hostname = uri->hostname;
+ }
+
apr_table_set(backend->connection->notes, "proxy-request-hostname",
- uri->hostname);
+ ssl_hostname);
}
}
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index fe2ac43e..4aaaf9bc 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -373,7 +373,7 @@ PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *mes
NULL));
/* Allow "error-notes" string to be printed by ap_send_error_response() */
- apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*"));
+ apr_table_setn(r->notes, "verbose-error-to", "*");
r->status_line = apr_psprintf(r->pool, "%3.3u Proxy Error", statuscode);
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00898) "%s returned by %s", message,
@@ -759,48 +759,63 @@ static int proxy_match_word(struct dirconn_entry *This, request_rec *r)
return host != NULL && ap_strstr_c(host, This->name) != NULL;
}
-/* checks whether a host in uri_addr matches proxyblock */
+/* Backwards-compatible interface. */
PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf,
apr_sockaddr_t *uri_addr)
{
+ return ap_proxy_checkproxyblock2(r, conf, uri_addr->hostname, uri_addr);
+}
+
+#define MAX_IP_STR_LEN (46)
+
+PROXY_DECLARE(int) ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf,
+ const char *hostname, apr_sockaddr_t *addr)
+{
int j;
- apr_sockaddr_t * src_uri_addr = uri_addr;
+
/* XXX FIXME: conf->noproxies->elts is part of an opaque structure */
for (j = 0; j < conf->noproxies->nelts; j++) {
struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
- struct apr_sockaddr_t *conf_addr = npent[j].addr;
- uri_addr = src_uri_addr;
+ struct apr_sockaddr_t *conf_addr;
+
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
"checking remote machine [%s] against [%s]",
- uri_addr->hostname, npent[j].name);
- if (ap_strstr_c(uri_addr->hostname, npent[j].name)
- || npent[j].name[0] == '*') {
+ hostname, npent[j].name);
+ if (ap_strstr_c(hostname, npent[j].name) || npent[j].name[0] == '*') {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00916)
"connect to remote machine %s blocked: name %s "
- "matched", uri_addr->hostname, npent[j].name);
+ "matched", hostname, npent[j].name);
return HTTP_FORBIDDEN;
}
- while (conf_addr) {
- uri_addr = src_uri_addr;
- while (uri_addr) {
- char *conf_ip;
- char *uri_ip;
- apr_sockaddr_ip_get(&conf_ip, conf_addr);
- apr_sockaddr_ip_get(&uri_ip, uri_addr);
+
+ /* No IP address checks if no IP address was passed in,
+ * i.e. the forward address proxy case, where this server does
+ * not resolve the hostname. */
+ if (!addr)
+ continue;
+
+ for (conf_addr = npent[j].addr; conf_addr; conf_addr = conf_addr->next) {
+ char caddr[MAX_IP_STR_LEN], uaddr[MAX_IP_STR_LEN];
+ apr_sockaddr_t *uri_addr;
+
+ if (apr_sockaddr_ip_getbuf(caddr, sizeof caddr, conf_addr))
+ continue;
+
+ for (uri_addr = addr; uri_addr; uri_addr = uri_addr->next) {
+ if (apr_sockaddr_ip_getbuf(uaddr, sizeof uaddr, uri_addr))
+ continue;
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
- "ProxyBlock comparing %s and %s", conf_ip,
- uri_ip);
- if (!apr_strnatcasecmp(conf_ip, uri_ip)) {
+ "ProxyBlock comparing %s and %s", caddr, uaddr);
+ if (!strcmp(caddr, uaddr)) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00917)
- "connect to remote machine %s blocked: "
- "IP %s matched", uri_addr->hostname, conf_ip);
+ "connect to remote machine %s blocked: "
+ "IP %s matched", hostname, caddr);
return HTTP_FORBIDDEN;
}
- uri_addr = uri_addr->next;
}
- conf_addr = conf_addr->next;
}
}
+
return OK;
}
@@ -852,7 +867,7 @@ PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r,
(balancer = ap_proxy_get_balancer(r->pool, sconf, real, 1))) {
int n, l3 = 0;
proxy_worker **worker = (proxy_worker **)balancer->workers->elts;
- const char *urlpart = ap_strchr_c(real, '/');
+ const char *urlpart = ap_strchr_c(real + sizeof(BALANCER_PREFIX) - 1, '/');
if (urlpart) {
if (!urlpart[1])
urlpart = NULL;
@@ -2128,7 +2143,8 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
}
}
/* check if ProxyBlock directive on this host */
- if (OK != ap_proxy_checkproxyblock(r, conf, conn->addr)) {
+ if (OK != ap_proxy_checkproxyblock2(r, conf, uri->hostname,
+ proxyname ? NULL : conn->addr)) {
return ap_proxyerror(r, HTTP_FORBIDDEN,
"Connect to remote machine blocked");
}
diff --git a/modules/session/config.m4 b/modules/session/config.m4
index 719fe915..7a38185d 100644
--- a/modules/session/config.m4
+++ b/modules/session/config.m4
@@ -47,7 +47,7 @@ if test "$session_mods_enable_crypto" != "no"; then
], [ap_HAVE_APR_CRYPTO="yes"], [ap_HAVE_APR_CRYPTO="no"])
CPPFLAGS="$saved_CPPFLAGS"
if test $ap_HAVE_APR_CRYPTO = "no"; then
- AC_MSG_WARN([Your APR does not include SSL/EVP support.])
+ AC_MSG_WARN([Your APR does not include SSL/EVP support. To enable it: configure --with-crypto])
if test "$enable_session_crypto" != "" -a "$enable_session_crypto" != "no"; then
AC_MSG_ERROR([mod_session_crypto cannot be enabled])
fi
diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c
index e053619a..7f855c72 100644
--- a/modules/session/mod_session.c
+++ b/modules/session/mod_session.c
@@ -373,7 +373,7 @@ static apr_status_t session_identity_decode(request_rec * r, session_rec * z)
}
/* decode what we have */
- encoded = apr_pstrcat(r->pool, z->encoded, NULL);
+ encoded = apr_pstrdup(r->pool, z->encoded);
pair = apr_strtok(encoded, sep, &last);
while (pair && pair[0]) {
char *plast = NULL;
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index fe7aeae5..0872da8a 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -138,6 +138,9 @@ static const command_rec ssl_config_cmds[] = {
"('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
SSL_CMD_SRV(HonorCipherOrder, FLAG,
"Use the server's cipher ordering preference")
+ SSL_CMD_SRV(Compression, FLAG,
+ "Enable SSL level compression"
+ "(`on', `off')")
SSL_CMD_SRV(InsecureRenegotiation, FLAG,
"Enable support for insecure renegotiation")
SSL_CMD_ALL(UserName, TAKE1,
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
index 6aab7641..15993f16 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/modules/ssl/ssl_engine_config.c
@@ -207,6 +207,9 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
#ifdef HAVE_FIPS
sc->fips = UNSET;
#endif
+#ifndef OPENSSL_NO_COMP
+ sc->compression = UNSET;
+#endif
modssl_ctx_init_proxy(sc, p);
@@ -328,6 +331,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
#ifdef HAVE_FIPS
cfgMergeBool(fips);
#endif
+#ifndef OPENSSL_NO_COMP
+ cfgMergeBool(compression);
+#endif
modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
@@ -663,6 +669,23 @@ static const char *ssl_cmd_check_file(cmd_parms *parms,
}
+const char *ssl_cmd_SSLCompression(cmd_parms *cmd, void *dcfg, int flag)
+{
+#if !defined(OPENSSL_NO_COMP)
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+#ifndef SSL_OP_NO_COMPRESSION
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err)
+ return "This version of openssl does not support configuring "
+ "compression within <VirtualHost> sections.";
+#endif
+ sc->compression = flag ? TRUE : FALSE;
+ return NULL;
+#else
+ return "Setting Compression mode unsupported; not implemented by the SSL library";
+#endif
+}
+
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag)
{
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 5d816478..7c121737 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -349,7 +349,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
else {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01885) "FIPS mode failed");
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
}
}
@@ -438,7 +438,7 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p)
"Init: Failed to load Crypto Device API `%s'",
mc->szCryptoDevice);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
if (strEQ(mc->szCryptoDevice, "chil")) {
@@ -450,7 +450,7 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p)
"Init: Failed to enable Crypto Device API `%s'",
mc->szCryptoDevice);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01890)
"Init: loaded Crypto Device API `%s'",
@@ -473,7 +473,7 @@ static void ssl_init_server_check(server_rec *s,
if (!mctx->pks->cert_files[0] && !mctx->pkcs7) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01891)
"No SSL Certificate set [hint: SSLCertificateFile]");
- ssl_die();
+ ssl_die(s);
}
/*
@@ -489,7 +489,7 @@ static void ssl_init_server_check(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01892)
"Illegal attempt to re-initialise SSL for server "
"(SSLEngine On should go in the VirtualHost, not in global scope.)");
- ssl_die();
+ ssl_die(s);
}
}
@@ -515,7 +515,7 @@ static void ssl_init_ctx_tls_extensions(server_rec *s,
"Unable to initialize TLS servername extension "
"callback (incompatible OpenSSL version?)");
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
#ifdef HAVE_OCSP_STAPLING
@@ -546,7 +546,7 @@ static void ssl_init_ctx_protocol(server_rec *s,
if (protocol == SSL_PROTOCOL_NONE) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
"No SSL protocols available [hint: SSLProtocol]");
- ssl_die();
+ ssl_die(s);
}
cp = apr_pstrcat(p,
@@ -622,6 +622,18 @@ static void ssl_init_ctx_protocol(server_rec *s,
}
#endif
+
+#ifndef OPENSSL_NO_COMP
+ if (sc->compression == FALSE) {
+#ifdef SSL_OP_NO_COMPRESSION
+ /* OpenSSL >= 1.0 only */
+ SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
+#elif OPENSSL_VERSION_NUMBER >= 0x00908000L
+ sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
+#endif
+ }
+#endif
+
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
if (sc->insecure_reneg == TRUE) {
SSL_CTX_set_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
@@ -731,7 +743,7 @@ static void ssl_init_ctx_verify(server_rec *s,
"Unable to configure verify locations "
"for client authentication");
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) {
@@ -746,7 +758,7 @@ static void ssl_init_ctx_verify(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896)
"Unable to determine list of acceptable "
"CA certificates for client authentication");
- ssl_die();
+ ssl_die(s);
}
SSL_CTX_set_client_CA_list(ctx, ca_list);
@@ -791,7 +803,7 @@ static void ssl_init_ctx_cipher_suite(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01898)
"Unable to configure permitted SSL ciphers");
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
}
@@ -815,7 +827,7 @@ static void ssl_init_ctx_crl(server_rec *s,
"Host %s: CRL checking has been enabled, but "
"neither %sCARevocationFile nor %sCARevocationPath "
"is configured", mctx->sc->vhost_id, cfgp, cfgp);
- ssl_die();
+ ssl_die(s);
}
return;
}
@@ -829,7 +841,7 @@ static void ssl_init_ctx_crl(server_rec *s,
"Host %s: unable to configure X.509 CRL storage "
"for certificate revocation", mctx->sc->vhost_id);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
switch (mctx->crl_check_mode) {
@@ -915,7 +927,7 @@ static void ssl_init_ctx_cert_chain(server_rec *s,
if (n < 0) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903)
"Failed to configure CA certificate chain!");
- ssl_die();
+ ssl_die(s);
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01904)
@@ -973,14 +985,14 @@ static int ssl_server_import_cert(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02233)
"Unable to import %s server certificate", type);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02234)
"Unable to configure %s server certificate", type);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
#ifdef HAVE_OCSP_STAPLING
@@ -1029,14 +1041,14 @@ static int ssl_server_import_key(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02237)
"Unable to import %s server private key", type);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02238)
"Unable to configure %s server private key", type);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
/*
@@ -1188,7 +1200,7 @@ static void ssl_init_server_certs(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01910)
"Oops, no " KEYTYPES " server certificate found "
"for '%s:%d'?!", s->server_hostname, s->port);
- ssl_die();
+ ssl_die(s);
}
for (i = 0; i < SSL_AIDX_MAX; i++) {
@@ -1208,7 +1220,7 @@ static void ssl_init_server_certs(server_rec *s,
)) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01911)
"Oops, no " KEYTYPES " server private key found?!");
- ssl_die();
+ ssl_die(s);
}
}
@@ -1238,7 +1250,7 @@ static void ssl_init_ticket_key(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02286)
"Failed to open ticket key file %s: (%d) %pm",
path, rv, &rv);
- ssl_die();
+ ssl_die(s);
}
rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEY_LEN, &len);
@@ -1247,7 +1259,7 @@ static void ssl_init_ticket_key(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02287)
"Failed to read %d bytes from %s: (%d) %pm",
TLSEXT_TICKET_KEY_LEN, path, rv, &rv);
- ssl_die();
+ ssl_die(s);
}
memcpy(ticket_key->key_name, buf, 16);
@@ -1260,7 +1272,7 @@ static void ssl_init_ticket_key(server_rec *s,
"Unable to initialize TLS session ticket key callback "
"(incompatible OpenSSL version?)");
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02288)
@@ -1315,7 +1327,7 @@ static void ssl_init_proxy_certs(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
"incomplete client cert configured for SSL proxy "
"(missing or encrypted private key?)");
- ssl_die();
+ ssl_die(s);
return;
}
}
@@ -1338,7 +1350,7 @@ static void ssl_init_proxy_certs(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02208)
"SSL proxy client cert initialization failed");
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
X509_STORE_load_locations(store, pkp->ca_cert_file, NULL);
@@ -1628,7 +1640,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02211)
"Failed to open Certificate Path `%s'",
ca_path);
- ssl_die();
+ ssl_die(s);
}
while ((apr_dir_read(&direntry, finfo_flags, dir)) == APR_SUCCESS) {
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
index 2ffe21f4..510e1606 100644
--- a/modules/ssl/ssl_engine_io.c
+++ b/modules/ssl/ssl_engine_io.c
@@ -813,12 +813,12 @@ static apr_status_t ssl_filter_write(ap_filter_t *f,
/* Just use a simple request. Any request will work for this, because
* we use a flag in the conn_rec->conn_vector now. The fake request just
* gets the request back to the Apache core so that a response can be sent.
- *
- * To avoid calling back for more data from the socket, use an HTTP/0.9
- * request, and tack on an EOS bucket.
+ * Since we use an HTTP/1.x request, we also have to inject the empty line
+ * that terminates the headers, or the core will read more data from the
+ * socket.
*/
#define HTTP_ON_HTTPS_PORT \
- "GET /" CRLF
+ "GET / HTTP/1.0" CRLF
#define HTTP_ON_HTTPS_PORT_BUCKET(alloc) \
apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, \
@@ -848,6 +848,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
{
SSLConnRec *sslconn = myConnConfig(f->c);
apr_bucket *bucket;
+ int send_eos = 1;
switch (status) {
case MODSSL_ERROR_HTTP_ON_HTTPS:
@@ -857,11 +858,12 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
"trying to send HTML error page");
ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, sslconn->server);
- sslconn->non_ssl_request = 1;
+ sslconn->non_ssl_request = NON_SSL_SEND_HDR_SEP;
ssl_io_filter_disable(sslconn, f);
/* fake the request line */
bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc);
+ send_eos = 0;
break;
case MODSSL_ERROR_BAD_GATEWAY:
@@ -877,9 +879,10 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
}
APR_BRIGADE_INSERT_TAIL(bb, bucket);
- bucket = apr_bucket_eos_create(f->c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, bucket);
-
+ if (send_eos) {
+ bucket = apr_bucket_eos_create(f->c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+ }
return APR_SUCCESS;
}
@@ -1282,6 +1285,13 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
}
if (!inctx->ssl) {
+ SSLConnRec *sslconn = myConnConfig(f->c);
+ if (sslconn->non_ssl_request == NON_SSL_SEND_HDR_SEP) {
+ apr_bucket *bucket = apr_bucket_immortal_create(CRLF, 2, f->c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
+ sslconn->non_ssl_request = NON_SSL_SET_ERROR_MSG;
+ return APR_SUCCESS;
+ }
return ap_get_brigade(f->next, bb, mode, block, readbytes);
}
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 35b2a854..e514a74b 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -140,37 +140,16 @@ int ssl_hook_ReadReq(request_rec *r)
return DECLINED;
}
- if (sslconn->non_ssl_request) {
- const char *errmsg;
- char *thisurl;
- char *thisport = "";
- int port = ap_get_server_port(r);
-
- if (!ap_is_default_port(port, r)) {
- thisport = apr_psprintf(r->pool, ":%u", port);
- }
-
- thisurl = ap_escape_html(r->pool,
- apr_psprintf(r->pool, "https://%s%s/",
- ap_get_server_name_for_url(r),
- thisport));
-
- errmsg = apr_psprintf(r->pool,
- "Reason: You're speaking plain HTTP "
- "to an SSL-enabled server port.<br />\n"
- "Instead use the HTTPS scheme to access "
- "this URL, please.<br />\n"
- "<blockquote>Hint: "
- "<a href=\"%s\"><b>%s</b></a></blockquote>",
- thisurl, thisurl);
-
- apr_table_setn(r->notes, "error-notes", errmsg);
+ if (sslconn->non_ssl_request == NON_SSL_SET_ERROR_MSG) {
+ apr_table_setn(r->notes, "error-notes",
+ "Reason: You're speaking plain HTTP to an SSL-enabled "
+ "server port.<br />\n Instead use the HTTPS scheme to "
+ "access this URL, please.<br />\n");
/* Now that we have caught this error, forget it. we are done
* with using SSL on this request.
*/
- sslconn->non_ssl_request = 0;
-
+ sslconn->non_ssl_request = NON_SSL_OK;
return HTTP_BAD_REQUEST;
}
diff --git a/modules/ssl/ssl_engine_log.c b/modules/ssl/ssl_engine_log.c
index 31861ca7..3f6d6edc 100644
--- a/modules/ssl/ssl_engine_log.c
+++ b/modules/ssl/ssl_engine_log.c
@@ -63,12 +63,23 @@ static const char *ssl_log_annotation(const char *error)
return ssl_log_annotate[i].cpAnnotation;
}
-void ssl_die(void)
+void ssl_die(server_rec *s)
{
+ if (s != NULL && s->is_virtual && s->error_fname != NULL)
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL, APLOGNO(02311)
+ "Fatal error initialising mod_ssl, exiting. "
+ "See %s for more information",
+ ap_server_root_relative(s->process->pool,
+ s->error_fname));
+ else
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL, APLOGNO(02312)
+ "Fatal error initialising mod_ssl, exiting.");
+
/*
* This is used for fatal errors and here
* it is common module practice to really
* exit from the complete program.
+ * XXX: The config hooks should return errors instead of calling exit().
*/
exit(1);
}
diff --git a/modules/ssl/ssl_engine_pphrase.c b/modules/ssl/ssl_engine_pphrase.c
index 1fa4a2ef..23ccaf4a 100644
--- a/modules/ssl/ssl_engine_pphrase.c
+++ b/modules/ssl/ssl_engine_pphrase.c
@@ -196,7 +196,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
"Server should be SSL-aware but has no certificate "
"configured [Hint: SSLCertificateFile] (%s:%d)",
pServ->defn_name, pServ->defn_line_number);
- ssl_die();
+ ssl_die(pServ);
}
/* Bitmasks for all key algorithms configured for this server;
@@ -225,14 +225,14 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02201)
"Init: Can't open server certificate file %s",
szPath);
- ssl_die();
+ ssl_die(s);
}
if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02241)
"Init: Unable to read server certificate from"
" file %s", szPath);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02202)
"Init: Read server certificate from '%s'",
@@ -249,7 +249,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
"Init: Multiple %s server certificates not "
"allowed", an);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
algoCert |= at;
@@ -328,7 +328,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02243)
"Init: Can't open server private key file "
"%s",szPath);
- ssl_die();
+ ssl_die(s);
}
/*
@@ -425,7 +425,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
"Init: SSLPassPhraseDialog builtin is not "
"supported on Win32 (key file "
"%s)", szPath);
- ssl_die();
+ ssl_die(s);
}
#endif /* WIN32 */
@@ -464,7 +464,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
apr_file_printf(writetty, "**Stopped\n");
}
}
- ssl_die();
+ ssl_die(pServ);
}
/* If a cached private key was found, nothing more to do
@@ -479,7 +479,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
"file %s [Hint: Perhaps it is in a separate file? "
" See SSLCertificateKeyFile]", szPath);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
/*
@@ -493,7 +493,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
"Init: Multiple %s server private keys not "
"allowed", an);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
- ssl_die();
+ ssl_die(s);
}
algoKey |= at;
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index 1b5d0428..f2fb7d52 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -180,6 +180,11 @@
#define HAVE_TLSV1_X
#endif
+#if !defined(OPENSSL_NO_COMP) && !defined(SSL_OP_NO_COMPRESSION) \
+ && OPENSSL_VERSION_NUMBER < 0x00908000L
+#define OPENSSL_NO_COMP
+#endif
+
/* mod_ssl headers */
#include "ssl_util_ssl.h"
@@ -454,7 +459,11 @@ typedef struct {
int verify_depth;
int is_proxy;
int disabled;
- int non_ssl_request;
+ enum {
+ NON_SSL_OK = 0, /* is SSL request, or error handling completed */
+ NON_SSL_SEND_HDR_SEP, /* Need to send the header separator */
+ NON_SSL_SET_ERROR_MSG /* Need to set the error message */
+ } non_ssl_request;
/* Track the handshake/renegotiation state for the connection so
* that all client-initiated renegotiations can be rejected, as a
@@ -669,6 +678,9 @@ struct SSLSrvConfigRec {
#ifdef HAVE_FIPS
BOOL fips;
#endif
+#ifndef OPENSSL_NO_COMP
+ BOOL compression;
+#endif
};
/**
@@ -723,6 +735,7 @@ const char *ssl_cmd_SSLCARevocationPath(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag);
+const char *ssl_cmd_SSLCompression(cmd_parms *, void *, int flag);
const char *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLSessionCache(cmd_parms *, void *, const char *);
@@ -902,7 +915,7 @@ int ssl_stapling_mutex_reinit(server_rec *, apr_pool_t *);
#define SSL_STAPLING_MUTEX_TYPE "ssl-stapling"
/** Logfile Support */
-void ssl_die(void);
+void ssl_die(server_rec *);
void ssl_log_ssl_error(const char *, int, int, server_rec *);
/* ssl_log_xerror, ssl_log_cxerror and ssl_log_rxerror are wrappers for the
diff --git a/modules/ssl/ssl_scache.c b/modules/ssl/ssl_scache.c
index 2c8d1bc8..d32f8e1d 100644
--- a/modules/ssl/ssl_scache.c
+++ b/modules/ssl/ssl_scache.c
@@ -63,7 +63,7 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p)
if (rv) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01872)
"Could not initialize stapling cache. Exiting.");
- ssl_die();
+ ssl_die(s);
}
}
#endif
@@ -88,7 +88,7 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p)
if (rv) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01874)
"Could not initialize session cache. Exiting.");
- ssl_die();
+ ssl_die(s);
}
}
diff --git a/modules/ssl/ssl_util.c b/modules/ssl/ssl_util.c
index 6b5a7de6..475fe4d2 100644
--- a/modules/ssl/ssl_util.c
+++ b/modules/ssl/ssl_util.c
@@ -76,8 +76,7 @@ apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd,
return NULL;
if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
return NULL;
- if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL)
- return NULL;
+ proc = apr_pcalloc(p, sizeof(apr_proc_t));
if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
return NULL;
return proc->out;
@@ -287,7 +286,7 @@ STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7)
f = fopen(pkcs7, "r");
if (!f) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02212) "Can't open %s", pkcs7);
- ssl_die();
+ ssl_die(s);
}
p7 = PEM_read_PKCS7(f, NULL, NULL, NULL);
@@ -314,13 +313,13 @@ STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7)
default:
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02213)
"Don't understand PKCS7 file %s", pkcs7);
- ssl_die();
+ ssl_die(s);
}
if (!certs) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02214)
"No certificates in %s", pkcs7);
- ssl_die();
+ ssl_die(s);
}
fclose(f);
@@ -376,24 +375,11 @@ static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
* allocated memory from a pool, create a subpool that we can blow
* away in the destruction callback.
*/
- rv = apr_pool_create(&p, dynlockpool);
- if (rv != APR_SUCCESS) {
- ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, dynlockpool,
- APLOGNO(02183) "Failed to create subpool for dynamic lock");
- return NULL;
- }
-
+ apr_pool_create(&p, dynlockpool);
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p,
"Creating dynamic lock");
- value = (struct CRYPTO_dynlock_value *)apr_palloc(p,
- sizeof(struct CRYPTO_dynlock_value));
- if (!value) {
- ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, 0, p,
- APLOGNO(02185) "Failed to allocate dynamic lock structure");
- return NULL;
- }
-
+ value = apr_palloc(p, sizeof(struct CRYPTO_dynlock_value));
value->pool = p;
/* Keep our own copy of the place from which we were created,
using our own pool. */
diff --git a/modules/ssl/ssl_util_ocsp.c b/modules/ssl/ssl_util_ocsp.c
index 94ef4cd0..e5c5e58d 100644
--- a/modules/ssl/ssl_util_ocsp.c
+++ b/modules/ssl/ssl_util_ocsp.c
@@ -153,7 +153,13 @@ static char *get_line(apr_bucket_brigade *bbout, apr_bucket_brigade *bbin,
return NULL;
}
- if (len && line[len-1] != APR_ASCII_LF) {
+ if (len == 0) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02321)
+ "empty response from OCSP server");
+ return NULL;
+ }
+
+ if (line[len-1] != APR_ASCII_LF) {
ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01979)
"response header line too long from OCSP server");
return NULL;
diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c
index 3ff08dcc..89be7f53 100644
--- a/modules/ssl/ssl_util_stapling.c
+++ b/modules/ssl/ssl_util_stapling.c
@@ -662,12 +662,12 @@ void modssl_init_stapling(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
if (mc->stapling_cache == NULL) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01958)
"SSLStapling: no stapling cache available");
- ssl_die();
+ ssl_die(s);
}
if (ssl_stapling_mutex_init(s, ptemp) == FALSE) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01959)
"SSLStapling: cannot initialise stapling mutex");
- ssl_die();
+ ssl_die(s);
}
/* Set some default values for parameters if they are not set */
if (mctx->stapling_resptime_skew == UNSET) {