Don't let invalid invalid Content-Length header go beyond ap_read_request()
and protocol validation. The check in ap_http_filter() is still useful if
some modules mangles the header, but it's too late for the usual case.
It helps simplifying a lot of duplicated code based on apr_strtoff(), while
also rejecting leading plus/minus signs which are dissalowed in Content-Length
and (Content-)Range headers.
Yann Ylavic [Fri, 15 May 2020 12:27:13 +0000 (12:27 +0000)]
ap_filter_output_pending(): test where each filter should yield after running.
Since running a filter may pass data next to it, ap_filter_output_pending()
should test for ap_filter_should_yield(f->next) after each f call, otherwise
it won't take into account new pending data in filters it just walked.
Yann Ylavic [Thu, 14 May 2020 09:02:13 +0000 (09:02 +0000)]
mod_proxy: binary search for ProxyErrorOverride status codes.
The list can be rather long, speed up runtime by sorting the status codes in
error_override_codes and using binary search from ap_proxy_should_override().
Yann Ylavic [Tue, 12 May 2020 12:20:57 +0000 (12:20 +0000)]
mod_proxy_http: handle Upgrade requests and upgraded protocol forwarding.
If the request Upgrade header matches the worker upgrade= parameter and
the backend switches the protocol, do the tunneling in mod_proxy_http.
This allows to keep the protocol to HTTP until the backend really
switches the protocol, and apply usual output filters.
When configured to forward Upgrade mechanism, we want the backend to be
able to announce its Upgrade protocol to the client (e.g. with 426
Upgrade Required response) and thus forward back the Upgrade header that
matches the one(s) configured in the worker upgrade= parameter.
modules/proxy/mod_proxy.h:
modules/proxy/proxy_util.c:
ap_proxy_worker_can_upgrade(): added helper to determine whether a
proxy worker is configured to forward an Upgrade protocol.
include/ap_mmn.h:
Bump MMN minor for ap_proxy_worker_can_upgrade().
modules/proxy/mod_proxy.c:
set_worker_param(): handle worker parameter upgrade=ANY as upgrade=*
(should the "any" protocol scheme be something some day..).
modules/proxy/mod_proxy_wstunnel.c:
proxy_wstunnel_handler(): use ap_proxy_worker_can_upgrade() to match
the Upgrade header. Axe handling of upgrade=NONE, it makes no sense to
Upgrade a connection if the client did not ask for it, nor to configure
mod_proxy_wstunnel to use a worker with upgrade=NONE by the way.
modules/proxy/mod_proxy_http.c:
proxy_http_req_t: add fields force10 (force HTTP/1.0) and upgrade (value
of the Upgrade header sent by the client if it matches the configuration,
NULL otherwise).
proxy_http_handler(): use ap_proxy_worker_can_upgrade() to determine
whether the request is electable for end to end protocol upgrading and set
req->upgrade accordingly.
terminate_headers(): handle Connection and Upgrade headers to send to the
backend, according to req->force10 and req->upgrade set before.
ap_proxy_http_prefetch(): use req->force10 and terminate_headers().
send_continue_body(): added helper to send the body retained for end to
end 100-continue handling.
ap_proxy_http_process_response(): use ap_proxy_worker_can_upgrade() to
match the response Upgrade header and forward it back if it matches the
configured one(s). That is for 101 Switching Protocol obviously but also
any other status code which is not overidden, at the backend wish. If the
protocol is switching, create a proxy tunnel and run it, using the minimal
timeout from the client or backend connection.
Yann Ylavic [Sun, 10 May 2020 15:15:21 +0000 (15:15 +0000)]
util_expr: allow to specify only one of ap_expr_eval_ctx_t's r/c/s.
Depending on where the expression is evaluated, a request_rec might not be
available, so allow to specify only a conn_rec or a server_rec (at least) in
the passed in ap_expr_eval_ctx_t.
Joe Orton [Thu, 7 May 2020 15:34:04 +0000 (15:34 +0000)]
mod_ssl: Update the ssl_var_lookup() API:
a) constify return value and variable name passed-in
b) require that pool argument is non-NULL
c) add gcc warning attributes for NULL arguments or ignored result.
This allows removal of inefficient internal duplication of constant
strings which was necessary only to allow non-const char *, and
removal of unsafe casts to/from const in various places.
* modules/ssl/ssl_engine_vars.c (ssl_var_lookup): Assume pool is
non-NULL; return constant and remove apr_pstrdup of constant
result string. Also constify variable name.
(ssl_var_lookup_*): Update to return const char * and avoid
duplication where now possible.
* modules/ssl/mod_ssl.h: Update ssl_var_lookup() optional function
API description and add GCC warning attributes as per private API.
* modules/ssl/ssl_engine_init.c (ssl_add_version_components): Adjust
for const return value.
* modules/ssl/ssl_engine_io.c (ssl_io_filter_handshake): Pass c->pool
to ssl_var_lookup.
* modules/ssl/ssl_engine_kernel.c (ssl_hook_Access): Pass r->pool to
ssl_var_lookup, expect const return and dup the string since r->user
is char *.
(log_tracing_state): Pass c->pool to ssl_var_lookup.
* modules/http2/h2_h2.c (h2_is_acceptable_connection): Assume
return value of ssl_var_lookup is const.
Joe Orton [Thu, 7 May 2020 10:34:12 +0000 (10:34 +0000)]
mod_ssl: Drop SSLRandomSeed implementation with OpenSSL 1.1.1.
Require that OpenSSL is configured with a suitable entropy source,
or fail startup otherwise.
* modules/ssl/ssl_private.h:
Define MODSSL_USE_SSLRAND for OpenSSL < 1.1.1.
(SSLModConfigRec): Only define pid, aRandSeed for <1.1.1.
(ssl_rand_seed): Define as noop if !MODSSL_USE_SSLRAND.
* modules/ssl/ssl_engine_init.c (ssl_init_Module):
Only initialize mc->pid for MODSSL_USE_SSLRAND.
Fail if RAND_status() returns zero.
(ssl_init_Child): Drop getpid and srand for !MODSSL_USE_SSLRAND.
* modules/ssl/ssl_engine_rand.c: ifdef-out for !MODSSL_USE_SSLRAND.
(ssl_rand_seed): Drop warning if PRNG not seeded (now a startup
error as above).
* modules/ssl/ssl_engine_config.c (ssl_config_global_create): Drop
aRandSeed initialization. (ssl_cmd_SSLRandomSeed): Log a warning if
used w/!MODSSL_USE_SSLRAND.
Joe Orton [Wed, 6 May 2020 15:30:14 +0000 (15:30 +0000)]
mod_ssl: Minor cleanup to avoid defining init handling functions for
pre-1.1 builds where they are noops or unused. No functional change
(intended).
* modules/ssl/mod_ssl.c: Define NEED_MANUAL_OPENSSL_INIT for builds
where pre-1.1 OpenSSL needs "manual" initialization/cleanup. Only
define modssl_running_statically for this case (otherwise it is set
and never read).
(modssl_is_prelinked): Only define for NEED_MANUAL_OPENSSL_INIT.
(ssl_cleanup_pre_config): Only define for NEED_MANUAL_OPENSSL_INIT;
otherwise it is a noop returning APR_SUCCESS;
(ssl_hook_pre_config): Only install the cleanup and initialize
modssl_is_prelinked for NEED_MANUAL_OPENSSL_INIT build.
* modules/ssl/ssl_engine_io.c (bio_filter_out_write,
bio_filter_in_read): #ifdef-out reneg protection if
SSL_OP_NO_RENEGOTATION is defined.
* modules/ssl/ssl_engine_init.c (ssl_init_ctx_protocol):
Enable SSL_OP_NO_RENEGOTATION.
(ssl_init_ctx_callbacks): Only enable the "info" callback if
debug-level logging *or* OpenSSL doesn't support SSL_OP_NO_RENEGOTATION.
* modules/ssl/ssl_engine_kernel.c (ssl_hook_Access_classic): Use
modssl_set_reneg_state to set the reneg protection mode.
(ssl_hook_Access_modern): Drop manipulation of the reneg mode which
does nothing for TLSv1.3 already.
(ssl_callback_Info): Only enable reneg protection if
SSL_OP_NO_RENEGOTATION is *not* defined.
* modules/ssl/ssl_util_ssl.c (modssl_set_reneg_state): New function.
Joe Orton [Mon, 4 May 2020 09:23:03 +0000 (09:23 +0000)]
mod_ssl: Calculate the MD5 digest used as the session context once per
vhost at startup, rather than building it for each new connection.
* modules/ssl/ssl_private.h (struct SSLSrvConfigRec):
Replace vhost_id_len field with vhost_md5.
* modules/ssl/ssl_engine_init.c (ssl_init_Module): Build the
sc->vhost_md5 hash here.
* modules/ssl/mod_ssl.c: Fail at compile time if the
SSL_set_session_id_context() API constraint on context length is
violated.
(ssl_init_ssl_connection): Use sc->vhost_md5.
* modules/ssl/ssl_engine_kernel.c (ssl_find_vhost): Use sc->vhost_md5
after renegotiation.
Joe Orton [Mon, 4 May 2020 08:58:02 +0000 (08:58 +0000)]
Prior to r1877345 mc->pPool was the process pool (s->process->pool).
Drop the field from SSLModConfigRec and use pconf instead (where
appropriate) to match the new SSLModConfigRec lifetime.
* modules/ssl/ssl_engine_kernel.c (ssl_callback_DelSessionCacheEntry):
Explicitly (and probably unsafely) use the process pool.
* modules/ssl/ssl_engine_config.c (ssl_cmd_SSLRandomSeed): Use
cmd->pool to allocate paths.
* modules/ssl/ssl_engine_init.c (ssl_init_Module): Use pconf
to allocate the keylog_file.
* modules/ssl/ssl_engine_vars.c (ssl_var_lookup): Drop lookup
of SSLModConfigRec and use s->process->pool when no pool is
passed.
Joe Orton [Mon, 4 May 2020 08:32:23 +0000 (08:32 +0000)]
mod_ssl: Use retained data API for storing private keys across reloads.
Allocate SSLModConfigRec from pconf rather than the process pool.
* modules/ssl/ssl_private.h: Add modssl_retained_data_t structure and
move private key storage here from SSLModConfigRec. Add retained
pointer to SSLModConfigRec.
* modules/ssl/ssl_engine_config.c (ssl_config_global_create): Take
pool argument; allocate SSLModConfigRec from there and
initialize mc->retained. SSLModConfigRec no longer cached for the
process lifetime.
(ssl_init_Module): Sanity check that sc->mc is correct.
(ssl_init_server_certs): Use private keys from mc->retained.
* modules/ssl/ssl_engine_pphrase.c
(privkey_vhost_keyid): Rename from asn1_table_vhost_key and
update to use the retained structure.
(ssl_load_encrypted_pkey): Update for above.
* modules/ssl/ssl_engine_init.c (ssl_init_Module): Remove
(apparently) redundant call to ssl_config_global_create and
add debug asserts to validate that is safe.
Joe Orton [Fri, 1 May 2020 16:08:13 +0000 (16:08 +0000)]
* modules/ssl/ssl_engine_init.c (ssl_add_version_components,
ssl_init_Module): Use temporary pool for variable lookup results
which don't need to live in pconf.
Joe Orton [Fri, 1 May 2020 15:15:59 +0000 (15:15 +0000)]
Move FIPS mode config option to SSLModConfigRec since it is a global
SSL library setting. Additionally, always log the FIPS mode since it
can be set outside of the httpd config.
* modules/ssl/ssl_private.h (SSLModConfigRec): Move fips field here.
(SSLSrvConfigRec): ... from here.
* modules/ssl/ssl_engine_config.c (ssl_cmd_SSLFIPS): Adjust for fips
field move.
* modules/ssl/ssl_engine_init.c (ssl_init_Module): Adjust for fips
field move. Always log the OpenSSL FIPS mode state even if SSLFIPS
is not used.
Joe Orton [Fri, 1 May 2020 08:17:16 +0000 (08:17 +0000)]
Add gcc-10 job, drop gcc-9 config from allow_failures (seems stable again).
Use -O2 for all gcc -Werror jobs otherwise warnings triggered under e.g.
aggressive inlining are not found.
util_filter: axe misleading AP_BUCKET_IS_MORPHING() macro and fix comments.
Morphing buckets are not only those with ->length == -1, so the macro is
misleading. Modify comments to talk about opaque buckets when length == -1
and about morphing buckets (once) for opaque and FILE buckets.
Provide a compatible version of ssl_callback_SessionTicket() which does not
use the deprecated HMAC_CTX and HMAC_Init_ex(), replaced by EVP_MAC_CTX and
EVP_MAC_CTX_set_params() respectively. This requires adapting struct
modssl_ticket_key_t to replace hmac_secret[] with OSSL_PARAM mac_params[],
created once at load time still.
The callback is registered by SSL_CTX_set_tlsext_ticket_key_evp_cb() instead
of SSL_CTX_set_tlsext_ticket_key_cb().
Since BIO_eof() may now be called openssl-3 state machine, the never-called
assertion in bio_filter_in_ctrl() does not hold anymore, and we have to
handle BIO_CTRL_EOF. For any other cmd, we continue to AP_DEBUG_ASSERT(0) and
log an error, yet the return value is changed from -1 to 0 which is the usual
unhandled value.
Note that OpenSSL 3.0.0 is still in alpha stage as of now, the API shouldn't
change though, neither breakage to 1.x.x API.
systemd dependencies are only needed by mod_systemd.
They should currently not be needed by httpd directly
or any other binary. So no need to add them to
HTTPD_LIBS.
Joe Orton [Thu, 23 Apr 2020 08:26:26 +0000 (08:26 +0000)]
Add optional options= argument to Listen to add listener-specific
socket options.
Reimplement "use_specific_errors" listener flag under generic
ap_listen_rec flags field holding all listener-specific options.
* include/ap_listen.h: Add AP_LISTEN_* flags.
(ap_listen_rec): Rename use_specific_errors to flags.
* server/listen.c (make_sock): Set APR_SO_FREEBIND if
AP_LISTEN_FREEBIND flag is set on listener; set APR_SO_REUSEPORT
unconditionally if AP_LISTEN_REUSEPORT is set.
(alloc_listener): Take flags argument.
(ap_setup_listeners): Set AP_LISTEN_SPECIFIC_ERRORS flag here.
(ap_set_listener): Parse optional options=... argument, catch
typos and fail if protocol name contains a "=".
(ap_duplicate_listeners): Duplicate flags.
core: follow up to r1876664: allow ErrorDocument to read body when applicable
Unless ap_read_request() failed to read the request line or header, or
Transfer-Encoding is invalid, we can still provide the request body to custom
error handlers (ErrorDocument) that ask it (e.g. internal redirects to CGI).
So this commit splits early failure path (previously die_early label) in two,
die_unusable_input and die_before_hooks, where the latter preserves input
filters (including HTTP_IN).
Also, the code to apply the connection timeout and r->per_dir_config from the
server is now in a new apply_server_config() helper since it's used multiple
times. Note that apr_socket_timeout_set() is a noop if the new timeout is the
same as the one already in place, so there is no need to cache the old timeout
nor use apr_socket_timeout_get(). Likewise, r->server is initially set to
c->base_server so apply_server_config() is overall a noop when no change is
needed.
Fix the way we are looking for "TLS/1.0" tokens.
ap_find_token() is more robust than expecting the token to be the first one in the 'Upgrade' header field.
Joe Orton [Mon, 20 Apr 2020 09:25:39 +0000 (09:25 +0000)]
* support/suexec.c (safe_strtol): New function.
(main): Use ^ to be avoid using atoi(); try to catch more string to
integer and integer to uid/gid conversion errors/surprises.
core, h2: common ap_parse_request_line() and ap_check_request_header() code.
Extract parsing/validation code from read_request_line() and ap_read_request()
into ap_parse_request_line() and ap_check_request_header() helpers such that
mod_http2 can validate its HTTP/1 request with the same/configured policy.
Joe Orton [Thu, 16 Apr 2020 18:22:43 +0000 (18:22 +0000)]
* server/mpm/prefork/prefork.c (prefork_pre_config): Use pconf as
passed to the hook with ap_fatal_signal_child_setup, since
prefork.c's pconf "global" is not set until the (later) open_logs
hook, and if built as a DSO it may be reset inbetween.
Joe Orton [Thu, 16 Apr 2020 17:55:48 +0000 (17:55 +0000)]
* modules/core/mod_watchdog.c (wd_worker): Fix crashes snuck into
r1876599 where a destroyed pool was reused. Rename the "ctx"
variable to reflect its purpose. Also tweak the pool tags.