Project

General

Profile

Feature #4247 ยป [TVHE-devel] enable PROXY protocol and X-Forwarded-For.diff

DSA APF, 2017-02-21 08:55

View differences:

tvheadend/src/config.c 2017-02-18 13:07:29.000000000 +0100
1676 1676
  config.idnode.in_class = &config_class;
1677 1677
  config.ui_quicktips = 1;
1678 1678
  config.digest = 1;
1679
  config.proxy = 0;
1679 1680
  config.realm = strdup("tvheadend");
1680 1681
  config.info_area = strdup("login,storage,time");
1681 1682
  config.cookie_expires = 7;
......
2127 2128
      .opts   = PO_EXPERT,
2128 2129
      .group  = 1
2129 2130
    },
2131
    {
2132
      .type   = PT_BOOL,
2133
      .id     = "proxy",
2134
      .name   = N_("Use PROXY protocol & X-Forwarded-For"),
2135
      .desc   = N_("PROXY protocol is an extension for support incoming "
2136
                   "TCP connections from a remote server (like a firewall) "
2137
                   "sending the original IP address of the client. "
2138
                   "The HTTP header 'X-Forwarded-For' do the same with "
2139
                   "HTTP connections. Both enable tunneled connections."
2140
                   "This option should be disabled for standard usage."),
2141
      .off    = offsetof(config_t, proxy),
2142
      .opts   = PO_EXPERT,
2143
      .group  = 1
2144
    },
2130 2145
    {
2131 2146
      .type   = PT_U32,
2132 2147
      .intextra = INTEXTRA_RANGE(1, 0x7ff, 1),
tvheadend/src/config.h 2017-02-18 13:07:29.000000000 +0100
34 34
  int uilevel_nochange;
35 35
  int ui_quicktips;
36 36
  int digest;
37
  int proxy;
37 38
  char *realm;
38 39
  char *wizard;
39 40
  char *full_version;
tvheadend/src/http.c 2017-02-18 13:07:29.000000000 +0100
1100 1100
  char authbuf[150];
1101 1101

  
1102 1102
  hc->hc_url_orig = tvh_strdupa(hc->hc_url);
1103

  
1104
  v = (config.proxy) ? http_arg_get(&hc->hc_args, "x-forwarded-for") : NULL;
1105
  if (v)
1106
    tcp_get_sockaddr((struct sockaddr*)hc->hc_peer, v);
1107

  
1103 1108
  tcp_get_str_from_ip((struct sockaddr*)hc->hc_peer, authbuf, sizeof(authbuf));
1109

  
1104 1110
  hc->hc_peer_ipstr = tvh_strdupa(authbuf);
1105 1111
  hc->hc_representative = hc->hc_peer_ipstr;
1106 1112
  hc->hc_username = NULL;
......
1460 1466
    if ((cmdline = tcp_read_line(hc->hc_fd, &spill)) == NULL)
1461 1467
      goto error;
1462 1468

  
1469
    // PROXY Protocol v1 support
1470
    // Format: 'PROXY TCP4 192.168.0.1 192.168.0.11 56324 9981\r\n'
1471
    //                     SRC-ADDRESS DST-ADDRESS  SPORT DPORT
1472
    //
1473
    if ((config.proxy) && (strlen(cmdline) >= 6) && (strncmp(cmdline,"PROXY ",6) == 0 )) {
1474
        tvhinfo(LS_HTTP, "[PROXY] PROXY protocol detected! cmdline='%s'",cmdline);
1475

  
1476
        char* pl = cmdline + 6;
1477

  
1478
        if ((cmdline = tcp_read_line(hc->hc_fd, &spill)) == NULL) {
1479
            goto error;  // No more data after the PROXY protocol
1480
        }
1481

  
1482
        if ( (strlen(pl) >= 7) && (strncmp(pl,"UNKNOWN",7) == 0))
1483
            goto error;  // Unknown PROXY protocol
1484
        
1485
        if ( (strlen(pl) < 5) || (strncmp(pl,"TCP4 ",5) != 0))
1486
            goto error;  // Only IPv4 supported
1487
        pl += 5;
1488

  
1489
        // Check the SRC-ADDRESS
1490
        c = pl;
1491
        char ch;
1492
        for ( ;; ) {
1493
            if (strlen(pl) == 0) goto error;  // Incomplete PROXY format
1494
            ch = *pl++;
1495
            if (ch == ' ') break;
1496
            if (ch != '.' && (ch < '0' || ch > '9')) goto error;  // Not valid IP address
1497
        }
1498
        if (((pl-c) < 8) || ((pl-c) > 16)) goto error;  // Not valid IP address
1499
        
1500
        // Here 'c' points to a dotted IPv4 SRC-ADRRESS
1501
        char srcaddr[16];
1502
        memset(srcaddr, 0, 16);
1503
        strncpy(srcaddr, c, (pl-c)-1);
1504

  
1505
        // Don't care about DST-ADDRESS, SRC-PORT & DST-PORT
1506
        // All it's OK, push the original client IP
1507
        tvhinfo(LS_HTTP, "[PROXY] Original source='%s'",srcaddr);
1508
        http_arg_set(&hc->hc_args, "x-forwarded-for", srcaddr);
1509
    }
1510
  
1463 1511
    if((n = http_tokenize(cmdline, argv, 3, -1)) != 3)
1464 1512
      goto error;
1465 1513
    
tvheadend/src/tcp.c 2017-02-18 13:07:29.0000000007 +0100
446 446
/**
447 447
 *
448 448
 */
449
int
450
tcp_get_sockaddr(struct sockaddr *sa, const char *s)
451
{
452
  if(sa == NULL || s == NULL)
453
    return -1;
454

  
455
  struct sockaddr_in *sin = (struct sockaddr_in*)sa;
456
  struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
457

  
458
  if (inet_pton(AF_INET, s, &sin->sin_addr) == 1)
459
    sa->sa_family = AF_INET;
460
  else if (inet_pton(AF_INET6, s, &sin6->sin6_addr) == 1)
461
    sa->sa_family = AF_INET6;
462
  else
463
    return -1;
464

  
465
  return 0;
466
}
467

  
468
/**
469
 *
470
 */
449 471
static tvhpoll_t *tcp_server_poll;
450 472
static uint32_t tcp_server_launch_id;
451 473

  
tvheadend/src/tcp.h 2017-02-18 13:07:29.000000000 +0100
94 94

  
95 95
char *tcp_get_str_from_ip(const struct sockaddr *sa, char *dst, size_t maxlen);
96 96

  
97
int tcp_get_sockaddr(struct sockaddr *sa, const char *s);
98

  
97 99
struct sockaddr *tcp_get_ip_from_str(const char *str, struct sockaddr *sa);
98 100

  
99 101
int tcp_socket_dead(int fd);
    (1-1/1)