Created
December 1, 2012 06:29
-
-
Save hellysmile/4180827 to your computer and use it in GitHub Desktop.
X-Forwarded-For stunnel 4.54 patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -crB stunnel-4.54/src/client.c stunnel-4.54-patched/src/client.c | |
*** stunnel-4.54/src/client.c 2012-10-09 22:36:36.000000000 +0200 | |
--- stunnel-4.54-patched/src/client.c 2012-10-16 16:49:07.755373327 +0200 | |
*************** | |
*** 48,53 **** | |
--- 48,55 ---- | |
#define SHUT_RDWR 2 | |
#endif | |
+ #define IPLEN 40 | |
+ | |
static void client_try(CLI *); | |
static void client_run(CLI *); | |
static void init_local(CLI *); | |
*************** | |
*** 75,80 **** | |
--- 77,88 ---- | |
c=str_alloc(sizeof(CLI)); | |
str_detach(c); | |
c->opt=opt; | |
+ /* some options need space to add some information */ | |
+ if (c->opt->option.xforwardedfor) | |
+ c->buffsize = BUFFSIZE - BUFF_RESERVED; | |
+ else | |
+ c->buffsize = BUFFSIZE; | |
+ c->crlf_seen=0; | |
c->local_rfd.fd=rfd; | |
c->local_wfd.fd=wfd; | |
return c; | |
*************** | |
*** 501,506 **** | |
--- 509,537 ---- | |
} | |
#endif | |
+ /* Moves all data from the buffer <buffer> between positions <start> and <stop> | |
+ * to insert <string> of length <len>. <start> and <stop> are updated to their | |
+ * new respective values, and the number of characters inserted is returned. | |
+ * If <len> is too long, nothing is done and -1 is returned. | |
+ * Note that neither <string> nor <buffer> can be NULL. | |
+ */ | |
+ static int buffer_insert_with_len(char *buffer, int *start, int *stop, int limit, char *string, int len) { | |
+ if (len > limit - *stop) | |
+ return -1; | |
+ if (*start > *stop) | |
+ return -1; | |
+ memmove(buffer + *start + len, buffer + *start, *stop - *start); | |
+ memcpy(buffer + *start, string, len); | |
+ *start += len; | |
+ *stop += len; | |
+ return len; | |
+ } | |
+ | |
+ static int buffer_insert(char *buffer, int *start, int *stop, int limit, char *string) { | |
+ return buffer_insert_with_len(buffer, start, stop, limit, string, strlen(string)); | |
+ } | |
+ | |
+ | |
/****************************** transfer data */ | |
static void transfer(CLI *c) { | |
int watchdog=0; /* a counter to detect an infinite loop */ | |
*************** | |
*** 519,525 **** | |
do { /* main loop of client data transfer */ | |
/****************************** initialize *_wants_* */ | |
read_wants_read=!(SSL_get_shutdown(c->ssl)&SSL_RECEIVED_SHUTDOWN) | |
! && c->ssl_ptr<BUFFSIZE && !read_wants_write; | |
write_wants_write=!(SSL_get_shutdown(c->ssl)&SSL_SENT_SHUTDOWN) | |
&& c->sock_ptr && !write_wants_read; | |
--- 550,556 ---- | |
do { /* main loop of client data transfer */ | |
/****************************** initialize *_wants_* */ | |
read_wants_read=!(SSL_get_shutdown(c->ssl)&SSL_RECEIVED_SHUTDOWN) | |
! && c->ssl_ptr<c->buffsize && !read_wants_write; | |
write_wants_write=!(SSL_get_shutdown(c->ssl)&SSL_SENT_SHUTDOWN) | |
&& c->sock_ptr && !write_wants_read; | |
*************** | |
*** 528,534 **** | |
/* for plain socket open data strem = open file descriptor */ | |
/* make sure to add each open socket to receive exceptions! */ | |
if(sock_open_rd) | |
! s_poll_add(c->fds, c->sock_rfd->fd, c->sock_ptr<BUFFSIZE, 0); | |
if(sock_open_wr) | |
s_poll_add(c->fds, c->sock_wfd->fd, 0, c->ssl_ptr); | |
/* for SSL assume that sockets are open if there any pending requests */ | |
--- 559,565 ---- | |
/* for plain socket open data strem = open file descriptor */ | |
/* make sure to add each open socket to receive exceptions! */ | |
if(sock_open_rd) | |
! s_poll_add(c->fds, c->sock_rfd->fd, c->sock_ptr<c->buffsize, 0); | |
if(sock_open_wr) | |
s_poll_add(c->fds, c->sock_wfd->fd, 0, c->ssl_ptr); | |
/* for SSL assume that sockets are open if there any pending requests */ | |
*************** | |
*** 655,661 **** | |
/****************************** read from socket */ | |
if(sock_open_rd && sock_can_rd) { | |
num=readsocket(c->sock_rfd->fd, | |
! c->sock_buff+c->sock_ptr, BUFFSIZE-c->sock_ptr); | |
switch(num) { | |
case -1: | |
if(parse_socket_error(c, "readsocket")) | |
--- 686,692 ---- | |
/****************************** read from socket */ | |
if(sock_open_rd && sock_can_rd) { | |
num=readsocket(c->sock_rfd->fd, | |
! c->sock_buff+c->sock_ptr, c->buffsize-c->sock_ptr); | |
switch(num) { | |
case -1: | |
if(parse_socket_error(c, "readsocket")) | |
*************** | |
*** 692,698 **** | |
/****************************** update *_wants_* based on new *_ptr */ | |
/* this update is also required for SSL_pending() to be used */ | |
read_wants_read=!(SSL_get_shutdown(c->ssl)&SSL_RECEIVED_SHUTDOWN) | |
! && c->ssl_ptr<BUFFSIZE && !read_wants_write; | |
write_wants_write=!(SSL_get_shutdown(c->ssl)&SSL_SENT_SHUTDOWN) | |
&& c->sock_ptr && !write_wants_read; | |
--- 723,729 ---- | |
/****************************** update *_wants_* based on new *_ptr */ | |
/* this update is also required for SSL_pending() to be used */ | |
read_wants_read=!(SSL_get_shutdown(c->ssl)&SSL_RECEIVED_SHUTDOWN) | |
! && c->ssl_ptr<c->buffsize && !read_wants_write; | |
write_wants_write=!(SSL_get_shutdown(c->ssl)&SSL_SENT_SHUTDOWN) | |
&& c->sock_ptr && !write_wants_read; | |
*************** | |
*** 702,713 **** | |
* writesocket() above made some room in c->ssl_buff */ | |
(read_wants_write && ssl_can_wr)) { | |
read_wants_write=0; | |
! num=SSL_read(c->ssl, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr); | |
switch(err=SSL_get_error(c->ssl, num)) { | |
case SSL_ERROR_NONE: | |
if(num==0) | |
s_log(LOG_DEBUG, "SSL_read returned 0"); | |
! c->ssl_ptr+=num; | |
watchdog=0; /* reset watchdog */ | |
break; | |
case SSL_ERROR_WANT_WRITE: | |
--- 733,804 ---- | |
* writesocket() above made some room in c->ssl_buff */ | |
(read_wants_write && ssl_can_wr)) { | |
read_wants_write=0; | |
! num=SSL_read(c->ssl, c->ssl_buff+c->ssl_ptr, c->buffsize-c->ssl_ptr); | |
switch(err=SSL_get_error(c->ssl, num)) { | |
case SSL_ERROR_NONE: | |
if(num==0) | |
s_log(LOG_DEBUG, "SSL_read returned 0"); | |
! if (c->buffsize != BUFFSIZE && c->opt->option.xforwardedfor) { /* some work left to do */ | |
! int last = c->ssl_ptr; | |
! c->ssl_ptr += num; | |
! | |
! /* Look for end of HTTP headers between last and ssl_ptr. | |
! * To achieve this reliably, we have to count the number of | |
! * successive [CR]LF and to memorize it in case it's spread | |
! * over multiple segments. --WT. | |
! */ | |
! while (last < c->ssl_ptr) { | |
! if (c->ssl_buff[last] == '\n') { | |
! if (++c->crlf_seen == 2) | |
! break; | |
! } else if (last < c->ssl_ptr - 1 && | |
! c->ssl_buff[last] == '\r' && | |
! c->ssl_buff[last+1] == '\n') { | |
! if (++c->crlf_seen == 2) | |
! break; | |
! last++; | |
! } else if (c->ssl_buff[last] != '\r') | |
! /* don't refuse '\r' because we may get a '\n' on next read */ | |
! c->crlf_seen = 0; | |
! last++; | |
! } | |
! if (c->crlf_seen >= 2) { | |
! /* We have all the HTTP headers now. We don't need to | |
! * reserve any space anymore. <ssl_ptr> points to the | |
! * first byte of unread data, and <last> points to the | |
! * exact location where we want to insert our headers, | |
! * which is right before the empty line. | |
! */ | |
! c->buffsize = BUFFSIZE; | |
! | |
! if (c->opt->option.xforwardedfor) { | |
! /* X-Forwarded-For: xxxx \r\n\0 */ | |
! char xforw[17 + IPLEN + 3]; | |
! | |
! /* We will insert our X-Forwarded-For: header here. | |
! * We need to write the IP address, but if we use | |
! * sprintf, it will pad with the terminating 0. | |
! * So we will pass via a temporary buffer allocated | |
! * on the stack. | |
! */ | |
! memcpy(xforw, "X-Forwarded-For: ", 17); | |
! if (getnameinfo(&c->peer_addr.sa, | |
! c->peer_addr_len, | |
! xforw + 17, IPLEN, NULL, 0, | |
! NI_NUMERICHOST) == 0) { | |
! strcat(xforw + 17, "\r\n"); | |
! buffer_insert(c->ssl_buff, &last, &c->ssl_ptr, | |
! c->buffsize, xforw); | |
! } | |
! /* last still points to the \r\n and ssl_ptr to the | |
! * end of the buffer, so we may add as many headers | |
! * as wee need to. | |
! */ | |
! } | |
! } | |
! } | |
! else | |
! c->ssl_ptr+=num; | |
watchdog=0; /* reset watchdog */ | |
break; | |
case SSL_ERROR_WANT_WRITE: | |
diff -crB stunnel-4.54/src/common.h stunnel-4.54-patched/src/common.h | |
*** stunnel-4.54/src/common.h 2012-03-16 23:53:13.000000000 +0100 | |
--- stunnel-4.54-patched/src/common.h 2012-10-16 16:49:44.765371941 +0200 | |
*************** | |
*** 52,57 **** | |
--- 52,60 ---- | |
/* I/O buffer size - 18432 is the maximum size of SSL record payload */ | |
#define BUFFSIZE 18432 | |
+ /* maximum space reserved for header insertion in BUFFSIZE */ | |
+ #define BUFF_RESERVED 1024 | |
+ | |
/* how many bytes of random input to read from files for PRNG */ | |
/* OpenSSL likes at least 128 bits, so 64 bytes seems plenty. */ | |
#define RANDOM_BYTES 64 | |
Nur in stunnel-4.54-patched/src/: config.h. | |
Nur in stunnel-4.54-patched/src/: .deps. | |
Nur in stunnel-4.54-patched/src/: env.lo. | |
Nur in stunnel-4.54-patched/src/: .libs. | |
Nur in stunnel-4.54-patched/src/: libstunnel.la. | |
Nur in stunnel-4.54-patched/src/: Makefile. | |
diff -crB stunnel-4.54/src/options.c stunnel-4.54-patched/src/options.c | |
*** stunnel-4.54/src/options.c 2012-10-09 10:50:54.000000000 +0200 | |
--- stunnel-4.54-patched/src/options.c 2012-10-16 16:55:24.480375699 +0200 | |
*************** | |
*** 1032,1037 **** | |
--- 1032,1064 ---- | |
} | |
#endif | |
+ /* xforwardedfor */ | |
+ switch(cmd) { | |
+ case CMD_BEGIN: | |
+ section->option.xforwardedfor=0; | |
+ break; | |
+ case CMD_EXEC: | |
+ if(strcasecmp(opt, "xforwardedfor")) | |
+ break; | |
+ if(!strcasecmp(arg, "yes")) | |
+ section->option.xforwardedfor=1; | |
+ else if(!strcasecmp(arg, "no")) | |
+ section->option.xforwardedfor=0; | |
+ else | |
+ return "argument should be either 'yes' or 'no'"; | |
+ return NULL; /* OK */ | |
+ case CMD_END: | |
+ break; | |
+ case CMD_FREE: | |
+ break; | |
+ case CMD_DEFAULT: | |
+ break; | |
+ case CMD_HELP: | |
+ s_log(LOG_NOTICE, "%-15s = yes|no append an HTTP X-Forwarded-For header", | |
+ "xforwardedfor"); | |
+ break; | |
+ } | |
+ | |
/* exec */ | |
switch(cmd) { | |
case CMD_BEGIN: | |
diff -crB stunnel-4.54/src/prototypes.h stunnel-4.54-patched/src/prototypes.h | |
*** stunnel-4.54/src/prototypes.h 2012-10-09 10:43:54.000000000 +0200 | |
--- stunnel-4.54-patched/src/prototypes.h 2012-10-16 16:51:39.486366924 +0200 | |
*************** | |
*** 204,209 **** | |
--- 204,210 ---- | |
unsigned int accept:1; /* endpoint: accept */ | |
unsigned int client:1; | |
unsigned int delayed_lookup:1; | |
+ unsigned int xforwardedfor:1; | |
#ifdef USE_LIBWRAP | |
unsigned int libwrap:1; | |
#endif | |
*************** | |
*** 433,438 **** | |
--- 434,441 ---- | |
FD *ssl_rfd, *ssl_wfd; /* read and write SSL descriptors */ | |
int sock_bytes, ssl_bytes; /* bytes written to socket and SSL */ | |
s_poll_set *fds; /* file descriptors */ | |
+ int buffsize; /* current buffer size, may be lower than BUFFSIZE */ | |
+ int crlf_seen; /* the number of successive CRLF seen */ | |
} CLI; | |
CLI *alloc_client_session(SERVICE_OPTIONS *, int, int); | |
Nur in stunnel-4.54-patched/src/: stamp-h1. | |
Nur in stunnel-4.54-patched/src/: stunnel. | |
Nur in stunnel-4.54-patched/src/: stunnel3. | |
Nur in stunnel-4.54-patched/src/: stunnel-client.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-ctx.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-fd.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-file.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-libwrap.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-log.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-network.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-options.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-protocol.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-pty.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-resolver.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-ssl.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-sthreads.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-str.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-stunnel.o. | |
Nur in stunnel-4.54-patched/src/: stunnel-verify.o. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment