/[gentoo-x86]/net-misc/stunnel/files/stunnel-4.56-xforwarded-for.patch
Gentoo

Contents of /net-misc/stunnel/files/stunnel-4.56-xforwarded-for.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download)
Sun Jun 16 16:04:11 2013 UTC (17 months, 1 week ago) by blueness
Branch: MAIN
Version bump, security bug #460278

(Portage version: 2.1.12.2/cvs/Linux x86_64, signed Manifest commit with key 0xF52D4BBA)

1 diff -Naur stunnel-4.56.orig/src/client.c stunnel-4.56/src/client.c
2 --- stunnel-4.56.orig/src/client.c 2013-03-14 18:54:24.000000000 -0400
3 +++ stunnel-4.56/src/client.c 2013-06-16 11:24:39.000000000 -0400
4 @@ -75,6 +75,12 @@
5 c=str_alloc(sizeof(CLI));
6 str_detach(c);
7 c->opt=opt;
8 + /* some options need space to add some information */
9 + if (c->opt->option.xforwardedfor)
10 + c->buffsize = BUFFSIZE - BUFF_RESERVED;
11 + else
12 + c->buffsize = BUFFSIZE;
13 + c->crlf_seen=0;
14 c->local_rfd.fd=rfd;
15 c->local_wfd.fd=wfd;
16 return c;
17 @@ -501,6 +507,28 @@
18 }
19 #endif
20
21 +/* Moves all data from the buffer <buffer> between positions <start> and <stop>
22 + * to insert <string> of length <len>. <start> and <stop> are updated to their
23 + * new respective values, and the number of characters inserted is returned.
24 + * If <len> is too long, nothing is done and -1 is returned.
25 + * Note that neither <string> nor <buffer> can be NULL.
26 + */
27 +static int buffer_insert_with_len(char *buffer, int *start, int *stop, int limit, char *string, int len) {
28 + if (len > limit - *stop)
29 + return -1;
30 + if (*start > *stop)
31 + return -1;
32 + memmove(buffer + *start + len, buffer + *start, *stop - *start);
33 + memcpy(buffer + *start, string, len);
34 + *start += len;
35 + *stop += len;
36 + return len;
37 +}
38 +
39 +static int buffer_insert(char *buffer, int *start, int *stop, int limit, char *string) {
40 + return buffer_insert_with_len(buffer, start, stop, limit, string, strlen(string));
41 +}
42 +
43 /****************************** transfer data */
44 static void transfer(CLI *c) {
45 int watchdog=0; /* a counter to detect an infinite loop */
46 @@ -519,7 +547,7 @@
47 do { /* main loop of client data transfer */
48 /****************************** initialize *_wants_* */
49 read_wants_read=!(SSL_get_shutdown(c->ssl)&SSL_RECEIVED_SHUTDOWN)
50 - && c->ssl_ptr<BUFFSIZE && !read_wants_write;
51 + && c->ssl_ptr<c->buffsize && !read_wants_write;
52 write_wants_write=!(SSL_get_shutdown(c->ssl)&SSL_SENT_SHUTDOWN)
53 && c->sock_ptr && !write_wants_read;
54
55 @@ -528,7 +556,7 @@
56 /* for plain socket open data strem = open file descriptor */
57 /* make sure to add each open socket to receive exceptions! */
58 if(sock_open_rd) /* only poll if the read file descriptor is open */
59 - s_poll_add(c->fds, c->sock_rfd->fd, c->sock_ptr<BUFFSIZE, 0);
60 + s_poll_add(c->fds, c->sock_rfd->fd, c->sock_ptr<c->buffsize, 0);
61 if(sock_open_wr) /* only poll if the write file descriptor is open */
62 s_poll_add(c->fds, c->sock_wfd->fd, 0, c->ssl_ptr);
63 /* poll SSL file descriptors unless SSL shutdown was completed */
64 @@ -683,7 +711,7 @@
65 /****************************** read from socket */
66 if(sock_open_rd && sock_can_rd) {
67 num=readsocket(c->sock_rfd->fd,
68 - c->sock_buff+c->sock_ptr, BUFFSIZE-c->sock_ptr);
69 + c->sock_buff+c->sock_ptr, c->buffsize-c->sock_ptr);
70 switch(num) {
71 case -1:
72 if(parse_socket_error(c, "readsocket"))
73 @@ -720,7 +748,7 @@
74 /****************************** update *_wants_* based on new *_ptr */
75 /* this update is also required for SSL_pending() to be used */
76 read_wants_read=!(SSL_get_shutdown(c->ssl)&SSL_RECEIVED_SHUTDOWN)
77 - && c->ssl_ptr<BUFFSIZE && !read_wants_write;
78 + && c->ssl_ptr<c->buffsize && !read_wants_write;
79 write_wants_write=!(SSL_get_shutdown(c->ssl)&SSL_SENT_SHUTDOWN)
80 && c->sock_ptr && !write_wants_read;
81
82 @@ -730,12 +758,73 @@
83 * writesocket() above made some room in c->ssl_buff */
84 (read_wants_write && ssl_can_wr)) {
85 read_wants_write=0;
86 - num=SSL_read(c->ssl, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr);
87 + num=SSL_read(c->ssl, c->ssl_buff+c->ssl_ptr, c->buffsize-c->ssl_ptr);
88 switch(err=SSL_get_error(c->ssl, num)) {
89 case SSL_ERROR_NONE:
90 if(num==0)
91 s_log(LOG_DEBUG, "SSL_read returned 0");
92 - c->ssl_ptr+=num;
93 + if (c->buffsize != BUFFSIZE && c->opt->option.xforwardedfor) { /* some work left to do */
94 + int last = c->ssl_ptr;
95 + c->ssl_ptr += num;
96 +
97 + /* Look for end of HTTP headers between last and ssl_ptr.
98 + * To achieve this reliably, we have to count the number of
99 + * successive [CR]LF and to memorize it in case it's spread
100 + * over multiple segments. --WT.
101 + */
102 + while (last < c->ssl_ptr) {
103 + if (c->ssl_buff[last] == '\n') {
104 + if (++c->crlf_seen == 2)
105 + break;
106 + } else if (last < c->ssl_ptr - 1 &&
107 + c->ssl_buff[last] == '\r' &&
108 + c->ssl_buff[last+1] == '\n') {
109 + if (++c->crlf_seen == 2)
110 + break;
111 + last++;
112 + } else if (c->ssl_buff[last] != '\r')
113 + /* don't refuse '\r' because we may get a '\n' on next read */
114 + c->crlf_seen = 0;
115 + last++;
116 + }
117 + if (c->crlf_seen >= 2) {
118 + /* We have all the HTTP headers now. We don't need to
119 + * reserve any space anymore. <ssl_ptr> points to the
120 + * first byte of unread data, and <last> points to the
121 + * exact location where we want to insert our headers,
122 + * which is right before the empty line.
123 + */
124 + c->buffsize = BUFFSIZE;
125 +
126 + if (c->opt->option.xforwardedfor) {
127 + /* X-Forwarded-For: xxxx \r\n\0 */
128 + char xforw[17 + IPLEN + 3];
129 +
130 + /* We will insert our X-Forwarded-For: header here.
131 + * We need to write the IP address, but if we use
132 + * sprintf, it will pad with the terminating 0.
133 + * So we will pass via a temporary buffer allocated
134 + * on the stack.
135 + */
136 + memcpy(xforw, "X-Forwarded-For: ", 17);
137 + if (getnameinfo(&c->peer_addr.sa,
138 + c->peer_addr_len,
139 + xforw + 17, IPLEN, NULL, 0,
140 + NI_NUMERICHOST) == 0) {
141 + strcat(xforw + 17, "\r\n");
142 + buffer_insert(c->ssl_buff, &last, &c->ssl_ptr,
143 + c->buffsize, xforw);
144 + }
145 + /* last still points to the \r\n and ssl_ptr to the
146 + * end of the buffer, so we may add as many headers
147 + * as wee need to.
148 + */
149 + }
150 + }
151 + }
152 + else
153 + c->ssl_ptr+=num;
154 +
155 watchdog=0; /* reset watchdog */
156 break;
157 case SSL_ERROR_WANT_WRITE:
158 diff -Naur stunnel-4.56.orig/src/common.h stunnel-4.56/src/common.h
159 --- stunnel-4.56.orig/src/common.h 2013-03-13 09:41:57.000000000 -0400
160 +++ stunnel-4.56/src/common.h 2013-06-16 11:23:12.000000000 -0400
161 @@ -52,6 +52,12 @@
162 /* I/O buffer size - 18432 is the maximum size of SSL record payload */
163 #define BUFFSIZE 18432
164
165 +/* maximum space reserved for header insertion in BUFFSIZE */
166 +#define BUFF_RESERVED 1024
167 +
168 +/* IP address and TCP port textual representation length */
169 +#define IPLEN 128
170 +
171 /* how many bytes of random input to read from files for PRNG */
172 /* OpenSSL likes at least 128 bits, so 64 bytes seems plenty. */
173 #define RANDOM_BYTES 64
174 diff -Naur stunnel-4.56.orig/src/options.c stunnel-4.56/src/options.c
175 --- stunnel-4.56.orig/src/options.c 2013-06-16 11:17:49.000000000 -0400
176 +++ stunnel-4.56/src/options.c 2013-06-16 11:23:12.000000000 -0400
177 @@ -1032,6 +1032,29 @@
178 }
179 #endif
180
181 + /* xforwardedfor */
182 + switch(cmd) {
183 + case CMD_BEGIN:
184 + section->option.xforwardedfor=0;
185 + break;
186 + case CMD_EXEC:
187 + if(strcasecmp(opt, "xforwardedfor"))
188 + break;
189 + if(!strcasecmp(arg, "yes"))
190 + section->option.xforwardedfor=1;
191 + else if(!strcasecmp(arg, "no"))
192 + section->option.xforwardedfor=0;
193 + else
194 + return "argument should be either 'yes' or 'no'";
195 + return NULL; /* OK */
196 + case CMD_DEFAULT:
197 + break;
198 + case CMD_HELP:
199 + s_log(LOG_NOTICE, "%-15s = yes|no append an HTTP X-Forwarded-For header",
200 + "xforwardedfor");
201 + break;
202 + }
203 +
204 /* exec */
205 switch(cmd) {
206 case CMD_BEGIN:
207 diff -Naur stunnel-4.56.orig/src/prototypes.h stunnel-4.56/src/prototypes.h
208 --- stunnel-4.56.orig/src/prototypes.h 2013-06-16 11:17:49.000000000 -0400
209 +++ stunnel-4.56/src/prototypes.h 2013-06-16 11:23:12.000000000 -0400
210 @@ -205,6 +205,7 @@
211 unsigned int accept:1; /* endpoint: accept */
212 unsigned int client:1;
213 unsigned int delayed_lookup:1;
214 + unsigned int xforwardedfor:1;
215 #ifdef USE_LIBWRAP
216 unsigned int libwrap:1;
217 #endif
218 @@ -434,6 +435,8 @@
219 FD *ssl_rfd, *ssl_wfd; /* read and write SSL descriptors */
220 int sock_bytes, ssl_bytes; /* bytes written to socket and SSL */
221 s_poll_set *fds; /* file descriptors */
222 + int buffsize; /* current buffer size, may be lower than BUFFSIZE */
223 + int crlf_seen; /* the number of successive CRLF seen */
224 } CLI;
225
226 CLI *alloc_client_session(SERVICE_OPTIONS *, int, int);

  ViewVC Help
Powered by ViewVC 1.1.20