View | Details | Raw Unified | Return to bug 59829
Collapse All | Expand All

(-)a/modules/metadata/mod_remoteip.c (-6 / +135 lines)
Lines 23-31 Link Here
23
#include "httpd.h"
23
#include "httpd.h"
24
#include "http_config.h"
24
#include "http_config.h"
25
#include "http_connection.h"
25
#include "http_connection.h"
26
#include "http_protocol.h"
27
#include "http_log.h"
26
#include "http_log.h"
28
#include "http_main.h"
27
#include "http_main.h"
28
#include "http_protocol.h"
29
#include "http_request.h"
29
#include "apr_strings.h"
30
#include "apr_strings.h"
30
#include "apr_lib.h"
31
#include "apr_lib.h"
31
#define APR_WANT_BYTEFUNC
32
#define APR_WANT_BYTEFUNC
Lines 55-60 typedef struct { Link Here
55
     * from the proxy-via IP header value list)
56
     * from the proxy-via IP header value list)
56
     */
57
     */
57
    const char *proxies_header_name;
58
    const char *proxies_header_name;
59
    /** A header that may indicate user is using a
60
     * HTTPS connection to the reverse-proxy, and
61
     * the value that it must match for it to do so.
62
     */
63
    const char *secure_header_name;
64
    const char *secure_header_value;
65
    unsigned short secure_port;
58
    /** A list of trusted proxies, ideally configured
66
    /** A list of trusted proxies, ideally configured
59
     *  with the most commonly encountered listed first
67
     *  with the most commonly encountered listed first
60
     */
68
     */
Lines 150-155 typedef struct { Link Here
150
    apr_sockaddr_t *client_addr;
158
    apr_sockaddr_t *client_addr;
151
    /** Character representation of the client */
159
    /** Character representation of the client */
152
    char *client_ip;
160
    char *client_ip;
161
    /** The port on which the proxy server received the connection */
162
    unsigned short server_port;
153
    /** Flag indicating that the PROXY header may be omitted on this
163
    /** Flag indicating that the PROXY header may be omitted on this
154
      connection (do not abort if it is missing). */
164
      connection (do not abort if it is missing). */
155
    int proxy_protocol_optional;
165
    int proxy_protocol_optional;
Lines 168-173 static void *create_remoteip_server_config(apr_pool_t *p, server_rec *s) Link Here
168
     * config->pp_optional = 0;
178
     * config->pp_optional = 0;
169
     */
179
     */
170
    config->pool = p;
180
    config->pool = p;
181
    config->secure_port = 443;
171
    return config;
182
    return config;
172
}
183
}
173
184
Lines 191-196 static void *merge_remoteip_server_config(apr_pool_t *p, void *globalv, Link Here
191
    config->pp_optional = server->pp_optional
202
    config->pp_optional = server->pp_optional
192
                          ? server->pp_optional
203
                          ? server->pp_optional
193
                          : global->pp_optional;
204
                          : global->pp_optional;
205
    config->secure_header_name = server->secure_header_name
206
                                ? server->secure_header_name
207
                                : global->secure_header_name;
208
    config->secure_header_value = server->secure_header_value
209
                                ? server->secure_header_value
210
                                : global->secure_header_value;
211
    config->secure_port = server->secure_port
212
                                ? server->secure_port
213
                                : global->secure_port;
194
    return config;
214
    return config;
195
}
215
}
196
216
Lines 212-217 static const char *proxies_header_name_set(cmd_parms *cmd, void *dummy, Link Here
212
    return NULL;
232
    return NULL;
213
}
233
}
214
234
235
static const char *secure_header_set(cmd_parms *cmd, void *dummy,
236
                                           const char *name, const char *value)
237
{
238
    remoteip_config_t *config = ap_get_module_config(cmd->server->module_config,
239
                                                     &remoteip_module);
240
    if (!name || !value)
241
        return "SecureIndicatorHeader requires header name and valid value";
242
243
    config->secure_header_name = name;
244
    config->secure_header_value = value;
245
    return NULL;
246
}
247
248
static int parse_validate_port(const char *src, unsigned short *dst)
249
{
250
    if (src) {
251
        char *tail;
252
        int intval;
253
        intval = apr_strtoi64(src, &tail, 0);
254
        if (errno == 0 && *tail == '\0' && intval > 0 && intval < 65536) {
255
            *dst = (unsigned short) intval;
256
            return 0; /* no error */
257
        }
258
        return 2; /* not a number or invaid port range */
259
    }
260
    return 1; /* null pointer */
261
}
262
263
static const char *secure_port_set(cmd_parms *cmd, void *dummy, const char *value)
264
{
265
    remoteip_config_t *config = ap_get_module_config(cmd->server->module_config,
266
                                                     &remoteip_module);
267
    if (parse_validate_port(value, &config->secure_port)) 
268
        return "SecureIndicatorSSLPort must be an integer between 0 and 65536";
269
270
    return NULL;
271
}
272
215
/* Would be quite nice if APR exported this */
273
/* Would be quite nice if APR exported this */
216
/* apr:network_io/unix/sockaddr.c */
274
/* apr:network_io/unix/sockaddr.c */
217
static int looks_like_ip(const char *ipstr)
275
static int looks_like_ip(const char *ipstr)
Lines 506-511 static int remoteip_modify_request(request_rec *r) Link Here
506
    char *proxy_ips = NULL;
564
    char *proxy_ips = NULL;
507
    char *parse_remote;
565
    char *parse_remote;
508
    char *eos;
566
    char *eos;
567
    char *secure = NULL;
509
    unsigned char *addrbyte;
568
    unsigned char *addrbyte;
510
569
511
    /* If no RemoteIPInternalProxy, RemoteIPInternalProxyList, RemoteIPTrustedProxy
570
    /* If no RemoteIPInternalProxy, RemoteIPInternalProxyList, RemoteIPTrustedProxy
Lines 540-545 static int remoteip_modify_request(request_rec *r) Link Here
540
        r->useragent_addr = conn_config->client_addr;
599
        r->useragent_addr = conn_config->client_addr;
541
        r->useragent_ip = conn_config->client_ip;
600
        r->useragent_ip = conn_config->client_ip;
542
601
602
        if (conn_config->server_port == config->secure_port) {
603
            apr_table_setn(r->subprocess_env, "HTTPS", "on");
604
        }
605
543
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
606
        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
544
                      "Using %s as client's IP from PROXY protocol", r->useragent_ip);
607
                      "Using %s as client's IP from PROXY protocol", r->useragent_ip);
545
        return OK;
608
        return OK;
Lines 698-703 static int remoteip_modify_request(request_rec *r) Link Here
698
        return OK;
761
        return OK;
699
    }
762
    }
700
763
764
    if (config->secure_header_name) {
765
        secure = (char *) apr_table_get(r->headers_in, config->secure_header_name);
766
    }
767
768
    if (secure) {
769
        if (!strcmp(secure, config->secure_header_value)) {
770
            apr_table_setn(r->subprocess_env, "HTTPS", "on");
771
        }
772
        /* Header is available. Unset even if no match. */
773
        apr_table_unset(r->headers_in, config->secure_header_name);
774
    }
775
    else {
776
        secure = NULL;
777
    }
778
701
    /* Port is not known so set it to zero; otherwise it can be misleading */
779
    /* Port is not known so set it to zero; otherwise it can be misleading */
702
    req->useragent_addr->port = 0;
780
    req->useragent_addr->port = 0;
703
781
Lines 724-736 static int remoteip_modify_request(request_rec *r) Link Here
724
802
725
    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
803
    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
726
                  req->proxy_ips
804
                  req->proxy_ips
727
                      ? "Using %s as client's IP by proxies %s"
805
                      ? "Using %s as client's IP by %s proxies %s via"
728
                      : "Using %s as client's IP by internal proxies%s",
806
                      : "Using %s as client's IP by %s internal proxies %s",
729
                  req->useragent_ip,
807
                  req->useragent_ip,
808
                  secure ? "HTTPS" : "HTTP",
730
                  (req->proxy_ips ? req->proxy_ips : ""));
809
                  (req->proxy_ips ? req->proxy_ips : ""));
731
    return OK;
810
    return OK;
732
}
811
}
733
812
813
static int remoteip_ssl_hook_Fixup(struct request_rec *r)
814
{
815
    request_rec *realreq = r;
816
    /* for internal redirect via mod_rewrite and other handlers */
817
    while (realreq->prev && apr_table_get(realreq->subprocess_env, "REDIRECT_STATUS"))
818
        realreq = realreq->prev;
819
820
    const char* secure = apr_table_get(realreq->subprocess_env, "HTTPS");
821
    if (secure && secure[0] == 'o' && secure[1] == 'n' && secure[2] == '\0')
822
        apr_table_setn(r->subprocess_env, "HTTPS", "on");
823
    return OK;
824
}
825
826
static const char* remoteip_read_scheme(const request_rec *r)
827
{
828
    const char* secure = (const char *) apr_table_get(r->subprocess_env, "HTTPS");
829
    if (secure && !strcmp(secure, "on"))
830
        return "https";
831
    return NULL;
832
}
833
834
static unsigned short remoteip_read_port(const request_rec *r)
835
{
836
    const char* secure = (const char *) apr_table_get(r->subprocess_env, "HTTPS");
837
    if (secure && !strcmp(secure, "on")) {
838
        remoteip_config_t *config = (remoteip_config_t *)
839
            ap_get_module_config(r->server->module_config, &remoteip_module);
840
        return config->secure_port;
841
    }
842
    return 0;
843
}
844
734
static int remoteip_is_server_port(apr_port_t port)
845
static int remoteip_is_server_port(apr_port_t port)
735
{
846
{
736
    ap_listen_rec *lr;
847
    ap_listen_rec *lr;
Lines 827-833 static remoteip_parse_status_t remoteip_process_v1_header(conn_rec *c, Link Here
827
938
828
    /* parse client-port */
939
    /* parse client-port */
829
    GET_NEXT_WORD("client-port")
940
    GET_NEXT_WORD("client-port")
830
    if (sscanf(word, "%hu", &port) != 1) {
941
    if (parse_validate_port(word, &port)) {
831
        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03501)
942
        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03501)
832
                      "RemoteIPProxyProtocol: error parsing port '%s' in header '%s'",
943
                      "RemoteIPProxyProtocol: error parsing port '%s' in header '%s'",
833
                      word, hdr->v1.line);
944
                      word, hdr->v1.line);
Lines 835-848 static remoteip_parse_status_t remoteip_process_v1_header(conn_rec *c, Link Here
835
    }
946
    }
836
947
837
    /* parse dest-port */
948
    /* parse dest-port */
838
    /* GET_NEXT_WORD("destination-port") - no-op since we don't care about it */
949
    GET_NEXT_WORD("destination-port")
950
951
    if (parse_validate_port(word, &conn_conf->server_port)) {
952
        ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03502)
953
                      "RemoteIPProxyProtocol: error parsing port '%s' in header '%s'",
954
                      word, hdr->v1.line);
955
        return HDR_ERROR;
956
    }
839
957
840
    /* create a socketaddr from the info */
958
    /* create a socketaddr from the info */
841
    ret = apr_sockaddr_info_get(&conn_conf->client_addr, host, family, port, 0,
959
    ret = apr_sockaddr_info_get(&conn_conf->client_addr, host, family, port, 0,
842
                                c->pool);
960
                                c->pool);
843
    if (ret != APR_SUCCESS) {
961
    if (ret != APR_SUCCESS) {
844
        conn_conf->client_addr = NULL;
962
        conn_conf->client_addr = NULL;
845
        ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03502)
963
        ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, c, APLOGNO(03503)
846
                      "RemoteIPProxyProtocol: error converting family '%d', host '%s',"
964
                      "RemoteIPProxyProtocol: error converting family '%d', host '%s',"
847
                      " and port '%hu' to sockaddr; header was '%s'",
965
                      " and port '%hu' to sockaddr; header was '%s'",
848
                      family, host, port, hdr->v1.line);
966
                      family, host, port, hdr->v1.line);
Lines 935-940 static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, Link Here
935
                        return HDR_ERROR;
1053
                        return HDR_ERROR;
936
                    }
1054
                    }
937
1055
1056
                    conn_conf->server_port = hdr->v2.addr.ip4.dst_port;
938
                    conn_conf->client_addr->sa.sin.sin_addr.s_addr =
1057
                    conn_conf->client_addr->sa.sin.sin_addr.s_addr =
939
                            hdr->v2.addr.ip4.src_addr;
1058
                            hdr->v2.addr.ip4.src_addr;
940
                    break;
1059
                    break;
Lines 951-956 static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, Link Here
951
                                      "RemoteIPProxyProtocol: error creating sockaddr");
1070
                                      "RemoteIPProxyProtocol: error creating sockaddr");
952
                        return HDR_ERROR;
1071
                        return HDR_ERROR;
953
                    }
1072
                    }
1073
                    conn_conf->server_port = hdr->v2.addr.ip6.dst_port;
954
                    memcpy(&conn_conf->client_addr->sa.sin6.sin6_addr.s6_addr,
1074
                    memcpy(&conn_conf->client_addr->sa.sin6.sin6_addr.s6_addr,
955
                           hdr->v2.addr.ip6.src_addr, 16);
1075
                           hdr->v2.addr.ip6.src_addr, 16);
956
                    break;
1076
                    break;
Lines 1232-1237 static const command_rec remoteip_cmds[] = Link Here
1232
                  RSRC_CONF | EXEC_ON_READ,
1352
                  RSRC_CONF | EXEC_ON_READ,
1233
                  "The filename to read the list of internal proxies, "
1353
                  "The filename to read the list of internal proxies, "
1234
                  "see the RemoteIPInternalProxy directive"),
1354
                  "see the RemoteIPInternalProxy directive"),
1355
    AP_INIT_TAKE2("SecureIndicatorHeader", secure_header_set, NULL, RSRC_CONF,
1356
                  "Specifies a request header and value that indicates a secure connection, "
1357
                  "e.g. \"X-Forwarded-Proto https\" or \"X-Secure-Connection on\""),
1358
    AP_INIT_TAKE1("SecureIndicatorSSLPort", secure_port_set, NULL, RSRC_CONF,
1359
                  "Port to be used for redirections if SecureIndicatorHeader is set, "
1360
                  "Default is \"SecureInidcatorSSLPort 443\" "),
1235
    AP_INIT_TAKE1("RemoteIPProxyProtocol", remoteip_enable_proxy_protocol, NULL,
1361
    AP_INIT_TAKE1("RemoteIPProxyProtocol", remoteip_enable_proxy_protocol, NULL,
1236
                  RSRC_CONF, "Enable PROXY protocol handling (`on', `off', `optional')"),
1362
                  RSRC_CONF, "Enable PROXY protocol handling (`on', `off', `optional')"),
1237
    { NULL }
1363
    { NULL }
Lines 1249-1254 static void register_hooks(apr_pool_t *p) Link Here
1249
    ap_hook_post_config(remoteip_hook_post_config, NULL, NULL, APR_HOOK_MIDDLE);
1375
    ap_hook_post_config(remoteip_hook_post_config, NULL, NULL, APR_HOOK_MIDDLE);
1250
    ap_hook_pre_connection(remoteip_hook_pre_connection, NULL, NULL, APR_HOOK_MIDDLE);
1376
    ap_hook_pre_connection(remoteip_hook_pre_connection, NULL, NULL, APR_HOOK_MIDDLE);
1251
    ap_hook_post_read_request(remoteip_modify_request, NULL, NULL, APR_HOOK_FIRST);
1377
    ap_hook_post_read_request(remoteip_modify_request, NULL, NULL, APR_HOOK_FIRST);
1378
    ap_hook_http_scheme(remoteip_read_scheme, NULL, NULL, APR_HOOK_FIRST);
1379
    ap_hook_default_port(remoteip_read_port, NULL, NULL, APR_HOOK_FIRST);
1380
    ap_hook_fixups(remoteip_ssl_hook_Fixup, NULL, NULL, APR_HOOK_MIDDLE);
1252
}
1381
}
1253
1382
1254
AP_DECLARE_MODULE(remoteip) = {
1383
AP_DECLARE_MODULE(remoteip) = {

Return to bug 59829