]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
enable PROXY protocol and X-Forwarded-For
authorapfutura satip <satip@apfutura.net>
Thu, 16 Mar 2017 11:37:10 +0000 (12:37 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 4 Apr 2017 10:56:48 +0000 (12:56 +0200)
src/channels.c
src/config.c
src/config.h
src/http.c

index b483ab64501566ac2184d2be8a4f2e6440556023..ece0068564e50770832450dd6eba65eefb09e3ff 100644 (file)
@@ -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));
index 2b81fbb1cad56c043d76398251d178d963dc6141..dad2723ccb9c3eb680c7179e6d965362a919db61 100644 (file)
@@ -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),
index a2a7f648e95fbccdea70db51ef5f400a6cb65e98..afeaec42a7857f36f82c02ca13fd215861e0b20b 100644 (file)
@@ -34,6 +34,7 @@ typedef struct config {
   int uilevel_nochange;
   int ui_quicktips;
   int digest;
+  int proxy;
   char *realm;
   char *wizard;
   char *full_version;
index 2736715907b542607a811e8b58d66832f2bb0e36..17d27e6f3be93c94c584c6d942a6aa46fdabd576 100644 (file)
@@ -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;