From: apfutura satip Date: Thu, 16 Mar 2017 11:37:10 +0000 (+0100) Subject: enable PROXY protocol and X-Forwarded-For X-Git-Tag: v4.2.1~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=366b0dd24ffabb12999bf7171b70458c73182e88;p=thirdparty%2Ftvheadend.git enable PROXY protocol and X-Forwarded-For --- diff --git a/src/channels.c b/src/channels.c index b483ab645..ece006856 100644 --- a/src/channels.c +++ b/src/channels.c @@ -74,6 +74,8 @@ channel_class_changed ( idnode_t *self ) { channel_t *ch = (channel_t *)self; + tvhdebug(LS_CHANNEL, "channel '%s' changed", channel_get_name(ch)); + /* update the EPG channel <-> channel mapping here */ if (ch->ch_enabled && ch->ch_epgauto) epggrab_channel_add(ch); @@ -90,6 +92,7 @@ channel_class_save ( idnode_t *self, char *filename, size_t fsize ) char ubuf[UUID_HEX_SIZE]; /* save channel (on demand) */ if (ch->ch_dont_save == 0) { + tvhdebug(LS_CHANNEL, "channel '%s' save", channel_get_name(ch)); c = htsmsg_create_map(); idnode_save(&ch->ch_id, c); snprintf(filename, fsize, "channel/config/%s", idnode_uuid_as_str(&ch->ch_id, ubuf)); diff --git a/src/config.c b/src/config.c index 2b81fbb1c..dad2723cc 100644 --- a/src/config.c +++ b/src/config.c @@ -1667,6 +1667,7 @@ config_boot ( const char *path, gid_t gid, uid_t uid ) config.idnode.in_class = &config_class; config.ui_quicktips = 1; config.digest = 1; + config.proxy = 0; config.realm = strdup("tvheadend"); config.info_area = strdup("login,storage,time"); config.cookie_expires = 7; @@ -2118,6 +2119,20 @@ const idclass_t config_class = { .opts = PO_EXPERT, .group = 1 }, + { + .type = PT_BOOL, + .id = "proxy", + .name = N_("Use PROXY protocol & X-Forwarded-For"), + .desc = N_("PROXY protocol is an extension for support incoming " + "TCP connections from a remote server (like a firewall) " + "sending the original IP address of the client. " + "The HTTP header 'X-Forwarded-For' do the same with " + "HTTP connections. Both enable tunneled connections." + "This option should be disabled for standard usage."), + .off = offsetof(config_t, proxy), + .opts = PO_EXPERT, + .group = 1 + }, { .type = PT_U32, .intextra = INTEXTRA_RANGE(1, 0x7ff, 1), diff --git a/src/config.h b/src/config.h index a2a7f648e..afeaec42a 100644 --- a/src/config.h +++ b/src/config.h @@ -34,6 +34,7 @@ typedef struct config { int uilevel_nochange; int ui_quicktips; int digest; + int proxy; char *realm; char *wizard; char *full_version; diff --git a/src/http.c b/src/http.c index 273671590..17d27e6f3 100644 --- a/src/http.c +++ b/src/http.c @@ -1102,7 +1102,13 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill) char authbuf[150]; hc->hc_url_orig = tvh_strdupa(hc->hc_url); + + v = (config.proxy) ? http_arg_get(&hc->hc_args, "X-Forwarded-For") : NULL; + if (v) + tcp_get_ip_from_str(v, (struct sockaddr*)hc->hc_peer); + tcp_get_str_from_ip((struct sockaddr*)hc->hc_peer, authbuf, sizeof(authbuf)); + hc->hc_peer_ipstr = tvh_strdupa(authbuf); hc->hc_representative = hc->hc_peer_ipstr; hc->hc_username = NULL; @@ -1462,6 +1468,48 @@ http_serve_requests(http_connection_t *hc) if ((cmdline = tcp_read_line(hc->hc_fd, &spill)) == NULL) goto error; + // PROXY Protocol v1 support + // Format: 'PROXY TCP4 192.168.0.1 192.168.0.11 56324 9981\r\n' + // SRC-ADDRESS DST-ADDRESS SPORT DPORT + // + if ((config.proxy) && (strlen(cmdline) >= 6) && (strncmp(cmdline,"PROXY ",6) == 0 )) { + tvhinfo(LS_HTTP, "[PROXY] PROXY protocol detected! cmdline='%s'",cmdline); + + char* pl = cmdline + 6; + + if ((cmdline = tcp_read_line(hc->hc_fd, &spill)) == NULL) { + goto error; // No more data after the PROXY protocol + } + + if ( (strlen(pl) >= 7) && (strncmp(pl,"UNKNOWN",7) == 0)) + goto error; // Unknown PROXY protocol + + if ( (strlen(pl) < 5) || (strncmp(pl,"TCP4 ",5) != 0)) + goto error; // Only IPv4 supported + pl += 5; + + // Check the SRC-ADDRESS + c = pl; + char ch; + for ( ;; ) { + if (strlen(pl) == 0) goto error; // Incomplete PROXY format + ch = *pl++; + if (ch == ' ') break; + if (ch != '.' && (ch < '0' || ch > '9')) goto error; // Not valid IP address + } + if (((pl-c) < 8) || ((pl-c) > 16)) goto error; // Not valid IP address + + // Here 'c' points to a dotted IPv4 SRC-ADRRESS + char srcaddr[16]; + memset(srcaddr, 0, 16); + strncpy(srcaddr, c, (pl-c)-1); + + // Don't care about DST-ADDRESS, SRC-PORT & DST-PORT + // All it's OK, push the original client IP + tvhinfo(LS_HTTP, "[PROXY] Original source='%s'",srcaddr); + http_arg_set(&hc->hc_args, "X-Forwarded-For", srcaddr); + } + if((n = http_tokenize(cmdline, argv, 3, -1)) != 3) goto error;