ASF Bugzilla – Attachment 34741 Details for
Bug 59829
Detect HTTPS marker from reverse proxy
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Fix data loss when using mod_rewrite
remoteip.patch (text/plain), 11.07 KB, created by
Yordan Gigov
on 2017-02-09 16:39:26 UTC
(
hide
)
Description:
Fix data loss when using mod_rewrite
Filename:
MIME Type:
Creator:
Yordan Gigov
Created:
2017-02-09 16:39:26 UTC
Size:
11.07 KB
patch
obsolete
>diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c >index 7969766..61f7aa7 100644 >--- a/modules/metadata/mod_remoteip.c >+++ b/modules/metadata/mod_remoteip.c >@@ -23,9 +23,10 @@ > #include "httpd.h" > #include "http_config.h" > #include "http_connection.h" >-#include "http_protocol.h" > #include "http_log.h" > #include "http_main.h" >+#include "http_protocol.h" >+#include "http_request.h" > #include "apr_strings.h" > #include "apr_lib.h" > #define APR_WANT_BYTEFUNC >@@ -55,6 +56,13 @@ typedef struct { > * from the proxy-via IP header value list) > */ > const char *proxies_header_name; >+ /** A header that may indicate user is using a >+ * HTTPS connection to the reverse-proxy, and >+ * the value that it must match for it to do so. >+ */ >+ const char *secure_header_name; >+ const char *secure_header_value; >+ unsigned short secure_port; > /** A list of trusted proxies, ideally configured > * with the most commonly encountered listed first > */ >@@ -150,6 +158,8 @@ typedef struct { > apr_sockaddr_t *client_addr; > /** Character representation of the client */ > char *client_ip; >+ /** The port on which the proxy server received the connection */ >+ unsigned short server_port; > /** Flag indicating that the PROXY header may be omitted on this > connection (do not abort if it is missing). */ > int proxy_protocol_optional; >@@ -168,6 +178,7 @@ static void *create_remoteip_server_config(apr_pool_t *p, server_rec *s) > * config->pp_optional = 0; > */ > config->pool = p; >+ config->secure_port = 443; > return config; > } > >@@ -191,6 +202,15 @@ static void *merge_remoteip_server_config(apr_pool_t *p, void *globalv, > config->pp_optional = server->pp_optional > ? server->pp_optional > : global->pp_optional; >+ config->secure_header_name = server->secure_header_name >+ ? server->secure_header_name >+ : global->secure_header_name; >+ config->secure_header_value = server->secure_header_value >+ ? server->secure_header_value >+ : global->secure_header_value; >+ config->secure_port = server->secure_port >+ ? server->secure_port >+ : global->secure_port; > return config; > } > >@@ -212,6 +232,44 @@ static const char *proxies_header_name_set(cmd_parms *cmd, void *dummy, > return NULL; > } > >+static const char *secure_header_set(cmd_parms *cmd, void *dummy, >+ const char *name, const char *value) >+{ >+ remoteip_config_t *config = ap_get_module_config(cmd->server->module_config, >+ &remoteip_module); >+ if (!name || !value) >+ return "SecureIndicatorHeader requires header name and valid value"; >+ >+ config->secure_header_name = name; >+ config->secure_header_value = value; >+ return NULL; >+} >+ >+static int parse_validate_port(const char *src, unsigned short *dst) >+{ >+ if (src) { >+ char *tail; >+ int intval; >+ intval = apr_strtoi64(src, &tail, 0); >+ if (errno == 0 && *tail == '\0' && intval > 0 && intval < 65536) { >+ *dst = (unsigned short) intval; >+ return 0; /* no error */ >+ } >+ return 2; /* not a number or invaid port range */ >+ } >+ return 1; /* null pointer */ >+} >+ >+static const char *secure_port_set(cmd_parms *cmd, void *dummy, const char *value) >+{ >+ remoteip_config_t *config = ap_get_module_config(cmd->server->module_config, >+ &remoteip_module); >+ if (parse_validate_port(value, &config->secure_port)) >+ return "SecureIndicatorSSLPort must be an integer between 0 and 65536"; >+ >+ return NULL; >+} >+ > /* Would be quite nice if APR exported this */ > /* apr:network_io/unix/sockaddr.c */ > static int looks_like_ip(const char *ipstr) >@@ -506,6 +564,7 @@ static int remoteip_modify_request(request_rec *r) > char *proxy_ips = NULL; > char *parse_remote; > char *eos; >+ char *secure = NULL; > unsigned char *addrbyte; > > /* If no RemoteIPInternalProxy, RemoteIPInternalProxyList, RemoteIPTrustedProxy >@@ -540,6 +599,10 @@ static int remoteip_modify_request(request_rec *r) > r->useragent_addr = conn_config->client_addr; > r->useragent_ip = conn_config->client_ip; > >+ if (conn_config->server_port == config->secure_port) { >+ apr_table_setn(r->subprocess_env, "HTTPS", "on"); >+ } >+ > ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, > "Using %s as client's IP from PROXY protocol", r->useragent_ip); > return OK; >@@ -698,6 +761,21 @@ static int remoteip_modify_request(request_rec *r) > return OK; > } > >+ if (config->secure_header_name) { >+ secure = (char *) apr_table_get(r->headers_in, config->secure_header_name); >+ } >+ >+ if (secure) { >+ if (!strcmp(secure, config->secure_header_value)) { >+ apr_table_setn(r->subprocess_env, "HTTPS", "on"); >+ } >+ /* Header is available. Unset even if no match. */ >+ apr_table_unset(r->headers_in, config->secure_header_name); >+ } >+ else { >+ secure = NULL; >+ } >+ > /* Port is not known so set it to zero; otherwise it can be misleading */ > req->useragent_addr->port = 0; > >@@ -724,13 +802,46 @@ static int remoteip_modify_request(request_rec *r) > > ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, > req->proxy_ips >- ? "Using %s as client's IP by proxies %s" >- : "Using %s as client's IP by internal proxies%s", >+ ? "Using %s as client's IP by %s proxies %s via" >+ : "Using %s as client's IP by %s internal proxies %s", > req->useragent_ip, >+ secure ? "HTTPS" : "HTTP", > (req->proxy_ips ? req->proxy_ips : "")); > return OK; > } > >+static int remoteip_ssl_hook_Fixup(struct request_rec *r) >+{ >+ request_rec *realreq = r; >+ /* for internal redirect via mod_rewrite and other handlers */ >+ while (realreq->prev && apr_table_get(realreq->subprocess_env, "REDIRECT_STATUS")) >+ realreq = realreq->prev; >+ >+ const char* secure = apr_table_get(realreq->subprocess_env, "HTTPS"); >+ if (secure && secure[0] == 'o' && secure[1] == 'n' && secure[2] == '\0') >+ apr_table_setn(r->subprocess_env, "HTTPS", "on"); >+ return OK; >+} >+ >+static const char* remoteip_read_scheme(const request_rec *r) >+{ >+ const char* secure = (const char *) apr_table_get(r->subprocess_env, "HTTPS"); >+ if (secure && !strcmp(secure, "on")) >+ return "https"; >+ return NULL; >+} >+ >+static unsigned short remoteip_read_port(const request_rec *r) >+{ >+ const char* secure = (const char *) apr_table_get(r->subprocess_env, "HTTPS"); >+ if (secure && !strcmp(secure, "on")) { >+ remoteip_config_t *config = (remoteip_config_t *) >+ ap_get_module_config(r->server->module_config, &remoteip_module); >+ return config->secure_port; >+ } >+ return 0; >+} >+ > static int remoteip_is_server_port(apr_port_t port) > { > ap_listen_rec *lr; >@@ -827,7 +938,7 @@ static remoteip_parse_status_t remoteip_process_v1_header(conn_rec *c, > > /* parse client-port */ > GET_NEXT_WORD("client-port") >- if (sscanf(word, "%hu", &port) != 1) { >+ if (parse_validate_port(word, &port)) { > ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03501) > "RemoteIPProxyProtocol: error parsing port '%s' in header '%s'", > word, hdr->v1.line); >@@ -835,14 +946,21 @@ static remoteip_parse_status_t remoteip_process_v1_header(conn_rec *c, > } > > /* parse dest-port */ >- /* GET_NEXT_WORD("destination-port") - no-op since we don't care about it */ >+ GET_NEXT_WORD("destination-port") >+ >+ if (parse_validate_port(word, &conn_conf->server_port)) { >+ ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03502) >+ "RemoteIPProxyProtocol: error parsing port '%s' in header '%s'", >+ word, hdr->v1.line); >+ return HDR_ERROR; >+ } > > /* create a socketaddr from the info */ > ret = apr_sockaddr_info_get(&conn_conf->client_addr, host, family, port, 0, > c->pool); > if (ret != APR_SUCCESS) { > conn_conf->client_addr = NULL; >- ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03502) >+ ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03503) > "RemoteIPProxyProtocol: error converting family '%d', host '%s'," > " and port '%hu' to sockaddr; header was '%s'", > family, host, port, hdr->v1.line); >@@ -935,6 +1053,7 @@ static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, > return HDR_ERROR; > } > >+ conn_conf->server_port = hdr->v2.addr.ip4.dst_port; > conn_conf->client_addr->sa.sin.sin_addr.s_addr = > hdr->v2.addr.ip4.src_addr; > break; >@@ -951,6 +1070,7 @@ static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, > "RemoteIPProxyProtocol: error creating sockaddr"); > return HDR_ERROR; > } >+ conn_conf->server_port = hdr->v2.addr.ip6.dst_port; > memcpy(&conn_conf->client_addr->sa.sin6.sin6_addr.s6_addr, > hdr->v2.addr.ip6.src_addr, 16); > break; >@@ -1232,6 +1352,12 @@ static const command_rec remoteip_cmds[] = > RSRC_CONF | EXEC_ON_READ, > "The filename to read the list of internal proxies, " > "see the RemoteIPInternalProxy directive"), >+ AP_INIT_TAKE2("SecureIndicatorHeader", secure_header_set, NULL, RSRC_CONF, >+ "Specifies a request header and value that indicates a secure connection, " >+ "e.g. \"X-Forwarded-Proto https\" or \"X-Secure-Connection on\""), >+ AP_INIT_TAKE1("SecureIndicatorSSLPort", secure_port_set, NULL, RSRC_CONF, >+ "Port to be used for redirections if SecureIndicatorHeader is set, " >+ "Default is \"SecureInidcatorSSLPort 443\" "), > AP_INIT_TAKE1("RemoteIPProxyProtocol", remoteip_enable_proxy_protocol, NULL, > RSRC_CONF, "Enable PROXY protocol handling (`on', `off', `optional')"), > { NULL } >@@ -1249,6 +1375,9 @@ static void register_hooks(apr_pool_t *p) > ap_hook_post_config(remoteip_hook_post_config, NULL, NULL, APR_HOOK_MIDDLE); > ap_hook_pre_connection(remoteip_hook_pre_connection, NULL, NULL, APR_HOOK_MIDDLE); > ap_hook_post_read_request(remoteip_modify_request, NULL, NULL, APR_HOOK_FIRST); >+ ap_hook_http_scheme(remoteip_read_scheme, NULL, NULL, APR_HOOK_FIRST); >+ ap_hook_default_port(remoteip_read_port, NULL, NULL, APR_HOOK_FIRST); >+ ap_hook_fixups(remoteip_ssl_hook_Fixup, NULL, NULL, APR_HOOK_MIDDLE); > } > > AP_DECLARE_MODULE(remoteip) = {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 59829
:
34024
|
34249
|
34495
|
34496
|
34504
|
34506
|
34507
|
34518
|
34709
|
34711
|
34741
|
34774
|
34781