diff --git a/qse/cmd/http/httpd.c b/qse/cmd/http/httpd.c index e38a3be7..a56b22af 100644 --- a/qse/cmd/http/httpd.c +++ b/qse/cmd/http/httpd.c @@ -204,6 +204,7 @@ struct loccfg_t unsigned int allow_upgrade: 1; unsigned int dns_enabled: 1; unsigned int urs_enabled: 1; + unsigned int x_forwarded: 1; qse_nwad_t dns_nwad; /* TODO: multiple dns */ qse_nwad_t urs_nwad; /* TODO: multiple urs */ int dns_timeout; @@ -646,6 +647,11 @@ proxy_ok: root->u.proxy.urs_prerewrite_mod = loccfg->proxy.urs_prerewrite_mod; } + if (loccfg->proxy.x_forwarded) + { + root->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_X_FORWARDED; + } + if (loccfg->proxy.allow_upgrade) { root->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_ALLOW_UPGRADE; @@ -1522,6 +1528,11 @@ static int load_loccfg_proxy (qse_httpd_t* httpd, qse_xli_t* xli, qse_xli_list_t if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("upgrade")); if (pair) cfg->proxy.allow_upgrade = get_boolean ((qse_xli_str_t*)pair->val); + pair = QSE_NULL; + if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("x-forwarded")); + if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("x-forwarded")); + if (pair) cfg->proxy.x_forwarded = get_boolean ((qse_xli_str_t*)pair->val); + pair = QSE_NULL; if (proxy) pair = qse_xli_findpair (xli, proxy, QSE_T("pseudonym")); if (!pair && default_proxy) pair = qse_xli_findpair (xli, default_proxy, QSE_T("pseudonym")); @@ -2059,6 +2070,7 @@ static int open_config_file (qse_httpd_t* httpd) { QSE_T("server-default.proxy.connect"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server-default.proxy.intercept"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server-default.proxy.upgrade"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server-default.proxy.x-forwarded"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server-default.proxy.pseudonym"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server-default.proxy.dns-enabled"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server-default.proxy.dns-server"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, @@ -2115,7 +2127,8 @@ static int open_config_file (qse_httpd_t* httpd) { QSE_T("server.host.location.proxy.http"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server.host.location.proxy.connect"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server.host.location.proxy.intercept"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host.location.proxy.upgrade"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.proxy.upgrade"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, + { QSE_T("server.host.location.proxy.x-forwarded"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server.host.location.proxy.pseudonym"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server.host.location.proxy.dns-enabled"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, { QSE_T("server.host.location.proxy.dns-server"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, diff --git a/qse/cmd/http/httpd.conf b/qse/cmd/http/httpd.conf index 5cc950f3..ecf6cdf6 100644 --- a/qse/cmd/http/httpd.conf +++ b/qse/cmd/http/httpd.conf @@ -136,10 +136,11 @@ server-default { # Default proxy configuration #################################################################### proxy { - http = yes; # yes/on, no/off - connect = yes; # yes/on, no/off - intercept = yes; # yes/proxy/on, local, no/off, - upgrade = yes; # yes/on, no/off + http = yes; # yes/on, no/off + connect = yes; # yes/on, no/off + intercept = yes; # yes/proxy/on, local, no/off, + upgrade = yes; # yes/on, no/off + x-forwarded = yes; # yes/on, no/off #pseudonym = "nice-host"; diff --git a/qse/include/qse/http/httpd.h b/qse/include/qse/http/httpd.h index 0458f6a0..2905190c 100644 --- a/qse/include/qse/http/httpd.h +++ b/qse/include/qse/http/httpd.h @@ -769,12 +769,13 @@ enum qse_httpd_rsrc_proxy_flag_t { QSE_HTTPD_RSRC_PROXY_RAW = (1 << 0), /* raw proxying. set this for CONNECT */ QSE_HTTPD_RSRC_PROXY_TRANSPARENT = (1 << 1), - QSE_HTTPD_RSRC_PROXY_ALLOW_UPGRADE = (1 << 2), - QSE_HTTPD_RSRC_PROXY_DST_STR = (1 << 3), /* destination is an unresovled string pointed to by dst.str */ - QSE_HTTPD_RSRC_PROXY_ENABLE_DNS = (1 << 4), /* dns service enabled (udp) */ - QSE_HTTPD_RSRC_PROXY_ENABLE_URS = (1 << 5), /* url rewriting enabled (udp) */ - QSE_HTTPD_RSRC_PROXY_DNS_SERVER = (1 << 6), /* dns address specified */ - QSE_HTTPD_RSRC_PROXY_URS_SERVER = (1 << 7), /* urs address specified */ + QSE_HTTPD_RSRC_PROXY_ALLOW_UPGRADE = (1 << 2), /* allow protocol upgrade */ + QSE_HTTPD_RSRC_PROXY_X_FORWARDED = (1 << 3), /* add x-forwarded-for and x-forwarded-proto */ + QSE_HTTPD_RSRC_PROXY_DST_STR = (1 << 4), /* destination is an unresovled string pointed to by dst.str */ + QSE_HTTPD_RSRC_PROXY_ENABLE_DNS = (1 << 5), /* dns service enabled (udp) */ + QSE_HTTPD_RSRC_PROXY_ENABLE_URS = (1 << 6), /* url rewriting enabled (udp) */ + QSE_HTTPD_RSRC_PROXY_DNS_SERVER = (1 << 7), /* dns address specified */ + QSE_HTTPD_RSRC_PROXY_URS_SERVER = (1 << 8), /* urs address specified */ }; typedef enum qse_httpd_rsrc_proxy_flag_t qse_httpd_rsrc_proxy_flag_t; diff --git a/qse/lib/http/httpd-proxy.c b/qse/lib/http/httpd-proxy.c index 016c072a..612bf153 100644 --- a/qse/lib/http/httpd-proxy.c +++ b/qse/lib/http/httpd-proxy.c @@ -53,10 +53,10 @@ struct task_proxy_t #define PROXY_URL_PREREWRITTEN (1 << 12) /* URL has been prerewritten in prerewrite(). */ #define PROXY_URL_REWRITTEN (1 << 13) #define PROXY_URL_REDIRECTED (1 << 14) -#define PROXY_X_FORWARDED_FOR (1 << 15) /* X-Forwarded-For: added */ +#define PROXY_X_FORWARDED (1 << 15) /* Add X-Forwarded-For and X-Forwarded-Proto */ #define PROXY_VIA (1 << 16) /* Via: added to the request */ #define PROXY_VIA_RETURNING (1 << 17) /* Via: added to the response */ -#define PROXY_ALLOW_UPGRADE (1 << 28) +#define PROXY_ALLOW_UPGRADE (1 << 18) #define PROXY_UPGRADE_REQUESTED (1 << 19) #define PROXY_PROTOCOL_SWITCHED (1 << 20) #define PROXY_GOT_BAD_REQUEST (1 << 21) @@ -259,58 +259,11 @@ static int proxy_capture_client_header (qse_htre_t* req, const qse_mchar_t* key, { task_proxy_t* proxy = (task_proxy_t*)ctx; -#if 0 - if (!(proxy->flags & PROXY_TRANSPARENT)) - { - if (!(proxy->flags & PROXY_X_FORWARDED_FOR) && qse_mbscasecmp (key, QSE_MT("X-Forwarded-For")) == 0) - { - /* append to X-Forwarded-For if it exists in the header. - * note that it add a comma even if the existing value is empty. - * actually, no such value must be sent in by a well-behaving - * client/proxy/load-balancer, etc. */ - qse_mchar_t extra[128]; - - proxy->flags |= PROXY_X_FORWARDED_FOR; - qse_nwadtombs (&proxy->client->remote_addr, extra, QSE_COUNTOF(extra), QSE_NWADTOMBS_ADDR); - - return proxy_add_header_to_buffer_with_extra_data (proxy, proxy->reqfwdbuf, key, val, QSE_MT(", %hs"), extra); - } - } - - - if (!(proxy->httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && !(proxy->flags & PROXY_VIA)) - { - if (qse_mbscasecmp (key, QSE_MT("Via")) == 0) - { - qse_mchar_t extra[128]; - const qse_mchar_t* pseudonym; - - proxy->flags |= PROXY_VIA; - if (proxy->pseudonym[0]) - { - pseudonym = proxy->pseudonym; - } - else - { - qse_nwadtombs (&proxy->client->local_addr, extra, QSE_COUNTOF(extra), QSE_NWADTOMBS_ALL); - pseudonym = extra; - } - - return proxy_add_header_to_buffer_with_extra_data ( - proxy, proxy->reqfwdbuf, key, val, - QSE_MT(", %d.%d %hs (%hs)"), - (int)proxy->version.major, - (int)proxy->version.minor, - pseudonym, - qse_httpd_getname(proxy->httpd)); - } - } -#endif - /* EXPERIMENTAL: REMOVE HEADERS. * FOR EXAMPLE, You can remove Referer or forge it to give analysis systems harder time */ if (qse_mbscasecmp (key, QSE_MT("Transfer-Encoding")) != 0 && - qse_mbscasecmp (key, QSE_MT("Content-Length")) != 0 /* EXPERIMENTAL */ /* && + qse_mbscasecmp (key, QSE_MT("Content-Length")) != 0 && + qse_mbscasecmp (key, QSE_MT("Proxy-Connection")) != 0 /* EXPERIMENTAL */ /* && qse_mbscasecmp (key, QSE_MT("Referer")) != 0*/) { return proxy_add_header_to_buffer (proxy, proxy->reqfwdbuf, key, val); @@ -325,7 +278,8 @@ static int proxy_capture_client_trailer (qse_htre_t* req, const qse_mchar_t* key if (qse_mbscasecmp (key, QSE_MT("Transfer-Encoding")) != 0 && qse_mbscasecmp (key, QSE_MT("Content-Length")) != 0 && - qse_mbscasecmp (key, QSE_MT("Connection")) != 0) + qse_mbscasecmp (key, QSE_MT("Connection")) != 0 && + qse_mbscasecmp (key, QSE_MT("Proxy-Connection")) != 0) { return proxy_add_header_to_buffer (proxy, proxy->reqfwdbuf, key, val); } @@ -983,6 +937,7 @@ static int task_init_proxy ( if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_RAW) proxy->flags |= PROXY_RAW; if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_TRANSPARENT) proxy->flags |= PROXY_TRANSPARENT; + if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_X_FORWARDED) proxy->flags |= PROXY_X_FORWARDED; if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_ALLOW_UPGRADE) proxy->flags |= PROXY_ALLOW_UPGRADE; proxy->peer.local = arg->rsrc->src.nwad; @@ -1131,11 +1086,8 @@ qse_mbs_ncat (proxy->reqfwdbuf, spc, QSE_COUNTOF(spc)); qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("\r\n")) == (qse_size_t)-1 || qse_htre_walkheaders (arg->req, proxy_capture_client_header, proxy) <= -1) goto nomem_oops; - /*if (!(proxy->flags & (PROXY_TRANSPARENT | PROXY_X_FORWARDED_FOR)))*/ - if (!(proxy->flags & PROXY_TRANSPARENT)) + if ((proxy->flags & (PROXY_TRANSPARENT | PROXY_X_FORWARDED)) == PROXY_X_FORWARDED) { - /* X-Forwarded-For is not added by proxy_capture_client_header() - * above. I don't care if it's included in the trailer. */ qse_mchar_t extra[128]; /* client's ip address */ diff --git a/qse/lib/http/httpd-std.c b/qse/lib/http/httpd-std.c index c2038551..58a7e1fd 100644 --- a/qse/lib/http/httpd-std.c +++ b/qse/lib/http/httpd-std.c @@ -631,6 +631,7 @@ static int init_xtn_ssl (qse_httpd_t* httpd, qse_httpd_server_t* server) } + /* TODO: SSL_CTX_set_verify(); SSL_CTX_set_verify_depth() */ /* TODO: CRYPTO_set_id_callback (); */ /* TODO: CRYPTO_set_locking_callback (); */