Skip to content

Commit

Permalink
parse proxy protocol and poc
Browse files Browse the repository at this point in the history
  • Loading branch information
grkarthik committed Dec 23, 2023
1 parent e535473 commit 326bd4e
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/lib/radius.c
Original file line number Diff line number Diff line change
Expand Up @@ -2517,6 +2517,7 @@ bool rad_packet_ok(RADIUS_PACKET *packet, int flags, decode_fail_t *reason)
uint32_t num_attributes;
decode_fail_t failure = DECODE_FAIL_NONE;

fprintf(stderr, "radius packet ok function");
/*
* Check for packets smaller than the packet header.
*
Expand Down
12 changes: 12 additions & 0 deletions src/lib/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ int fr_tcp_read_packet(RADIUS_PACKET *packet, int flags)

len = recv(packet->sockfd, packet->vector + packet->data_len,
4 - packet->data_len, 0);

fprintf(stderr, "packet length: %d.... packet data is not defined...\n", len);
if (len == 0) return -2; /* clean close */

#ifdef ECONNRESET
Expand All @@ -90,6 +92,8 @@ int fr_tcp_read_packet(RADIUS_PACKET *packet, int flags)

packet_len = (packet->vector[2] << 8) | packet->vector[3];

fprintf(stderr, "radius packet length is: %d....\n", packet_len);

if (packet_len < RADIUS_HDR_LEN) {
fr_strerror_printf("Discarding packet: Smaller than RFC minimum of 20 bytes");
return -1;
Expand All @@ -110,6 +114,7 @@ int fr_tcp_read_packet(RADIUS_PACKET *packet, int flags)
}

packet->data_len = packet_len;
fprintf(stderr, "data_len: %d...\n", packet->data_len);
packet->partial = 4;
memcpy(packet->data, packet->vector, 4);
}
Expand All @@ -121,20 +126,27 @@ int fr_tcp_read_packet(RADIUS_PACKET *packet, int flags)
packet->data_len - packet->partial, 0);
if (len == 0) return -2; /* clean close */

fprintf(stderr, "packet length: %d.......\n", len);

#ifdef ECONNRESET
if ((len < 0) && (errno == ECONNRESET)) { /* forced */
fprintf(stderr, "ECONNRESET.......\n");
return -2;
}
#endif

if (len < 0) {
fprintf(stderr, "Error receiving packet.......\n");
fr_strerror_printf("Error receiving packet: %s", fr_syserror(errno));
return -1;
}

packet->partial += len;

fprintf(stderr, "%d < %d \n", packet->partial, packet->data_len);

if (packet->partial < packet->data_len) {
fprintf(stderr, "(packet->partial < packet->data_len)....");
return 0;
}

Expand Down
153 changes: 142 additions & 11 deletions src/main/listen.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,25 +777,133 @@ static int dual_tcp_recv(rad_listen_t *listener)
RADCLIENT *client = sock->client;
REQUEST *request = sock->request;

char *eos;
unsigned long num;
int src_port, dst_port;
ssize_t len;
uint8_t *proxy_header;
uint8_t const *p;
uint8_t const *start;
uint8_t const *eol;
int af;
char *argv[5];
int argc;
uint8_t proxy_protocol_parsed = 0;
// parse the ip, port
fr_ipaddr_t src, dst;

rad_assert(client != NULL);

if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;

if (listener->proxy_protocol) {
rcode = proxy_protocol_check(listener, request);
if (rcode < 0) {
RDEBUG("(TCP) Closing PROXY TCP socket from client port %u", sock->other_port);
// rcode = proxy_protocol_check(listener, request);
// if (rcode < 0) {
// RDEBUG("(TCP) Closing PROXY TCP socket from client port %u", sock->other_port);
// close it? tls_socket_close(listener);
return 0;
}
if (rcode == 0) return 1;
// return 0;
// }
// if (rcode == 0) return 1;

/*
* The buffer might already have data. In that
* case, we don't want to do a blocking read
* later.
*/
// already_read = (sock->ssn->dirty_in.used > 0);
// if (!sock->packet) {
// fprintf(stderr, "initializing sock->packet\n");
// sock->packet = rad_alloc(sock, false);
// sock->packet->sockfd = listener->fd;
// }


// Let's see if the PROXY line is well-formed

proxy_header = talloc_array(sock, uint8_t, 107);
len = recv(listener->fd, proxy_header, 107, MSG_PEEK);
fprintf(stderr, "received data of length: %d\n", len);

// read to make sense of the header "PROXY TCP"
if (memcmp(proxy_header, "PROXY TCP", 9) == 0) {
fprintf(stderr, "received proxy protocol header\n");
// extract the fields now
p = proxy_header;
start = proxy_header;
while ((p + 1) < proxy_header + 107) {
if ((p[0] == 0x0d) && (p[1] == 0x0a)) {
eol = p;
fprintf(stderr, "found ctrl character within length: %d\n", eol - start);
break;
}
/*
* Other control characters, or non-ASCII data.
* That's a problem.
*/
if ((*p < ' ') || (*p >= 0x80)) {
invalid_data:
DEBUG("(TLS) Closing PROXY socket from client port %u - received invalid data", sock->other_port);
return -1;
}
p++;
}

p = proxy_header;
p += 9;
fprintf(stderr, "af_inet: %c\n", *p);

if (*p == '4') {
af = AF_INET;
}
if (*p == '6') {
af = AF_INET6;
}

p++;
if (*p != ' ') return -1;
p++;

proxy_header[eol - proxy_header] = '\0';

argc = str2argv((char *) p, (char **) &argv, 5);
fprintf(stderr, "arg count: %d\n", argc);

for (size_t i = 0; i < 4; i++) {
fprintf(stderr, "%s\n", argv[i]);
}

memset(&src, 0, sizeof(src));
memset(&dst, 0, sizeof(dst));

if (fr_pton(&src, argv[0], -1, af, false) < 0) goto invalid_data;
if (fr_pton(&dst, argv[1], -1, af, false) < 0) goto invalid_data;


num = strtoul(argv[2], &eos, 10);
if (num > 65535) goto invalid_data;
if (*eos) goto invalid_data;
src_port = num;

num = strtoul(argv[3], &eos, 10);
if (num > 65535) goto invalid_data;
if (*eos) goto invalid_data;
dst_port = num;

fprintf(stderr, "src_port: %d, dst_port: %d\n", src_port, dst_port);

proxy_protocol_parsed = 1;

// read the proxy header and remove from the stream
len = recv(listener->fd, proxy_header, eol - proxy_header, 0);
fprintf(stderr, "removing %d bytes\n", len);
talloc_free(proxy_header);
}
// const unsigned char *byte_ptr = proxy_header;
// for (size_t i = 0; i < 9; i++) {
// fprintf(stderr, "%c", byte_ptr[i]);
// }

fprintf(stderr, "finished printing and processing \n");
}

/*
Expand All @@ -806,11 +914,34 @@ static int dual_tcp_recv(rad_listen_t *listener)
if (!sock->packet) return 0;

sock->packet->sockfd = listener->fd;
sock->packet->src_ipaddr = sock->other_ipaddr;
sock->packet->src_port = sock->other_port;
sock->packet->dst_ipaddr = sock->my_ipaddr;
sock->packet->dst_port = sock->my_port;
sock->packet->proto = sock->proto;

if (proxy_protocol_parsed) {
fprintf(stderr, "proxy protocol parsed \n");
sock->haproxy_src_ipaddr = sock->other_ipaddr;
sock->haproxy_src_port = sock->other_port;

sock->haproxy_dst_ipaddr = sock->my_ipaddr;
sock->haproxy_dst_port = sock->my_port;

sock->my_ipaddr = dst;
sock->my_port = dst_port;

sock->other_ipaddr = src;
sock->other_port = src_port;

sock->packet->src_ipaddr = sock->other_ipaddr;
sock->packet->src_port = sock->other_port;
sock->packet->dst_ipaddr = sock->my_ipaddr;
sock->packet->dst_port = sock->my_port;
sock->packet->proto = sock->proto;

} else {
sock->packet->src_ipaddr = sock->other_ipaddr;
sock->packet->src_port = sock->other_port;
sock->packet->dst_ipaddr = sock->my_ipaddr;
sock->packet->dst_port = sock->my_port;
sock->packet->proto = sock->proto;
}
}

/*
Expand Down

0 comments on commit 326bd4e

Please sign in to comment.