1 /*
2  * General protocol-agnostic payload-based sample fetches and ACLs
3  *
4  * Copyright 2000-2013 Willy Tarreau <w@1wt.eu>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  *
11  */
12 
13 #include <stdlib.h>
14 #include <string.h>
15 
16 #include <proto/acl.h>
17 #include <proto/arg.h>
18 #include <proto/channel.h>
19 #include <proto/pattern.h>
20 #include <proto/payload.h>
21 #include <proto/sample.h>
22 
23 
24 /************************************************************************/
25 /*       All supported sample fetch functions must be declared here     */
26 /************************************************************************/
27 
28 /* wait for more data as long as possible, then return TRUE. This should be
29  * used with content inspection.
30  */
31 static int
smp_fetch_wait_end(const struct arg * args,struct sample * smp,const char * kw,void * private)32 smp_fetch_wait_end(const struct arg *args, struct sample *smp, const char *kw, void *private)
33 {
34 	if (!(smp->opt & SMP_OPT_FINAL)) {
35 		smp->flags |= SMP_F_MAY_CHANGE;
36 		return 0;
37 	}
38 	smp->data.type = SMP_T_BOOL;
39 	smp->data.u.sint = 1;
40 	return 1;
41 }
42 
43 /* return the number of bytes in the request buffer */
44 static int
smp_fetch_len(const struct arg * args,struct sample * smp,const char * kw,void * private)45 smp_fetch_len(const struct arg *args, struct sample *smp, const char *kw, void *private)
46 {
47 	struct channel *chn;
48 
49 	if (!smp->strm)
50 		return 0;
51 
52 	chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
53 	smp->data.type = SMP_T_SINT;
54 	smp->data.u.sint = chn->buf->i;
55 	smp->flags = SMP_F_VOLATILE | SMP_F_MAY_CHANGE;
56 	return 1;
57 }
58 
59 /* Returns 0 if the client didn't send a SessionTicket Extension
60  * Returns 1 if the client sent SessionTicket Extension
61  * Returns 2 if the client also sent non-zero length SessionTicket
62  * Returns SMP_T_SINT data type
63  */
64 static int
smp_fetch_req_ssl_st_ext(const struct arg * args,struct sample * smp,const char * kw,void * private)65 smp_fetch_req_ssl_st_ext(const struct arg *args, struct sample *smp, const char *kw, void *private)
66 {
67 	int hs_len, ext_len, bleft;
68 	struct channel *chn;
69 	unsigned char *data;
70 
71 	if (!smp->strm)
72 		goto not_ssl_hello;
73 
74 	chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
75 	bleft = chn->buf->i;
76 	data = (unsigned char *)chn->buf->p;
77 
78 	/* Check for SSL/TLS Handshake */
79 	if (!bleft)
80 		goto too_short;
81 	if (*data != 0x16)
82 		goto not_ssl_hello;
83 
84 	/* Check for SSLv3 or later (SSL version >= 3.0) in the record layer*/
85 	if (bleft < 3)
86 		goto too_short;
87 	if (data[1] < 0x03)
88 		goto not_ssl_hello;
89 
90 	if (bleft < 5)
91 		goto too_short;
92 	hs_len = (data[3] << 8) + data[4];
93 	if (hs_len < 1 + 3 + 2 + 32 + 1 + 2 + 2 + 1 + 1 + 2 + 2)
94 		goto not_ssl_hello; /* too short to have an extension */
95 
96 	data += 5; /* enter TLS handshake */
97 	bleft -= 5;
98 
99 	/* Check for a complete client hello starting at <data> */
100 	if (bleft < 1)
101 		goto too_short;
102 	if (data[0] != 0x01) /* msg_type = Client Hello */
103 		goto not_ssl_hello;
104 
105 	/* Check the Hello's length */
106 	if (bleft < 4)
107 		goto too_short;
108 	hs_len = (data[1] << 16) + (data[2] << 8) + data[3];
109 	if (hs_len < 2 + 32 + 1 + 2 + 2 + 1 + 1 + 2 + 2)
110 		goto not_ssl_hello; /* too short to have an extension */
111 
112 	/* We want the full handshake here */
113 	if (bleft < hs_len)
114 		goto too_short;
115 
116 	data += 4;
117 	/* Start of the ClientHello message */
118 	if (data[0] < 0x03 || data[1] < 0x01) /* TLSv1 minimum */
119 		goto not_ssl_hello;
120 
121 	ext_len = data[34]; /* session_id_len */
122 	if (ext_len > 32 || ext_len > (hs_len - 35)) /* check for correct session_id len */
123 		goto not_ssl_hello;
124 
125 	/* Jump to cipher suite */
126 	hs_len -= 35 + ext_len;
127 	data   += 35 + ext_len;
128 
129 	if (hs_len < 4 ||                               /* minimum one cipher */
130 	    (ext_len = (data[0] << 8) + data[1]) < 2 || /* minimum 2 bytes for a cipher */
131 	    ext_len > hs_len)
132 		goto not_ssl_hello;
133 
134 	/* Jump to the compression methods */
135 	hs_len -= 2 + ext_len;
136 	data   += 2 + ext_len;
137 
138 	if (hs_len < 2 ||                       /* minimum one compression method */
139 	    data[0] < 1 || data[0] > hs_len)    /* minimum 1 bytes for a method */
140 		goto not_ssl_hello;
141 
142 	/* Jump to the extensions */
143 	hs_len -= 1 + data[0];
144 	data   += 1 + data[0];
145 
146 	if (hs_len < 2 ||                       /* minimum one extension list length */
147 	    (ext_len = (data[0] << 8) + data[1]) > hs_len - 2) /* list too long */
148 		goto not_ssl_hello;
149 
150 	hs_len = ext_len; /* limit ourselves to the extension length */
151 	data += 2;
152 
153 	while (hs_len >= 4) {
154 		int ext_type, ext_len;
155 
156 		ext_type = (data[0] << 8) + data[1];
157 		ext_len  = (data[2] << 8) + data[3];
158 
159 		if (ext_len > hs_len - 4) /* Extension too long */
160 			goto not_ssl_hello;
161 
162 		/* SesstionTicket extension */
163 		if (ext_type == 35) {
164 			smp->data.type = SMP_T_SINT;
165 			/* SessionTicket also present */
166 			if (ext_len > 0)
167 				smp->data.u.sint = 2;
168 			/* SessionTicket absent */
169 			else
170 				smp->data.u.sint = 1;
171 			smp->flags = SMP_F_VOLATILE;
172 			return 1;
173 		}
174 
175 		hs_len -= 4 + ext_len;
176 		data   += 4 + ext_len;
177 	}
178 	/* SessionTicket Extension not found */
179 	smp->data.type = SMP_T_SINT;
180 	smp->data.u.sint = 0;
181 	smp->flags = SMP_F_VOLATILE;
182 	return 1;
183 
184  too_short:
185 	smp->flags = SMP_F_MAY_CHANGE;
186 
187  not_ssl_hello:
188 	return 0;
189 }
190 
191 /* Returns TRUE if the client sent Supported Elliptic Curves Extension (0x000a)
192  * Mainly used to detect if client supports ECC cipher suites.
193  */
194 static int
smp_fetch_req_ssl_ec_ext(const struct arg * args,struct sample * smp,const char * kw,void * private)195 smp_fetch_req_ssl_ec_ext(const struct arg *args, struct sample *smp, const char *kw, void *private)
196 {
197 	int hs_len, ext_len, bleft;
198 	struct channel *chn;
199 	unsigned char *data;
200 
201 	if (!smp->strm)
202 		goto not_ssl_hello;
203 
204 	chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
205 	bleft = chn->buf->i;
206 	data = (unsigned char *)chn->buf->p;
207 
208 	/* Check for SSL/TLS Handshake */
209 	if (!bleft)
210 		goto too_short;
211 	if (*data != 0x16)
212 		goto not_ssl_hello;
213 
214 	/* Check for SSLv3 or later (SSL version >= 3.0) in the record layer*/
215 	if (bleft < 3)
216 		goto too_short;
217 	if (data[1] < 0x03)
218 		goto not_ssl_hello;
219 
220 	if (bleft < 5)
221 		goto too_short;
222 	hs_len = (data[3] << 8) + data[4];
223 	if (hs_len < 1 + 3 + 2 + 32 + 1 + 2 + 2 + 1 + 1 + 2 + 2)
224 		goto not_ssl_hello; /* too short to have an extension */
225 
226 	data += 5; /* enter TLS handshake */
227 	bleft -= 5;
228 
229 	/* Check for a complete client hello starting at <data> */
230 	if (bleft < 1)
231 		goto too_short;
232 	if (data[0] != 0x01) /* msg_type = Client Hello */
233 		goto not_ssl_hello;
234 
235 	/* Check the Hello's length */
236 	if (bleft < 4)
237 		goto too_short;
238 	hs_len = (data[1] << 16) + (data[2] << 8) + data[3];
239 	if (hs_len < 2 + 32 + 1 + 2 + 2 + 1 + 1 + 2 + 2)
240 		goto not_ssl_hello; /* too short to have an extension */
241 
242 	/* We want the full handshake here */
243 	if (bleft < hs_len)
244 		goto too_short;
245 
246 	data += 4;
247 	/* Start of the ClientHello message */
248 	if (data[0] < 0x03 || data[1] < 0x01) /* TLSv1 minimum */
249 		goto not_ssl_hello;
250 
251 	ext_len = data[34]; /* session_id_len */
252 	if (ext_len > 32 || ext_len > (hs_len - 35)) /* check for correct session_id len */
253 		goto not_ssl_hello;
254 
255 	/* Jump to cipher suite */
256 	hs_len -= 35 + ext_len;
257 	data   += 35 + ext_len;
258 
259 	if (hs_len < 4 ||                               /* minimum one cipher */
260 	    (ext_len = (data[0] << 8) + data[1]) < 2 || /* minimum 2 bytes for a cipher */
261 	    ext_len > hs_len)
262 		goto not_ssl_hello;
263 
264 	/* Jump to the compression methods */
265 	hs_len -= 2 + ext_len;
266 	data   += 2 + ext_len;
267 
268 	if (hs_len < 2 ||                       /* minimum one compression method */
269 	    data[0] < 1 || data[0] > hs_len)    /* minimum 1 bytes for a method */
270 		goto not_ssl_hello;
271 
272 	/* Jump to the extensions */
273 	hs_len -= 1 + data[0];
274 	data   += 1 + data[0];
275 
276 	if (hs_len < 2 ||                       /* minimum one extension list length */
277 	    (ext_len = (data[0] << 8) + data[1]) > hs_len - 2) /* list too long */
278 		goto not_ssl_hello;
279 
280 	hs_len = ext_len; /* limit ourselves to the extension length */
281 	data += 2;
282 
283 	while (hs_len >= 4) {
284 		int ext_type, ext_len;
285 
286 		ext_type = (data[0] << 8) + data[1];
287 		ext_len  = (data[2] << 8) + data[3];
288 
289 		if (ext_len > hs_len - 4) /* Extension too long */
290 			goto not_ssl_hello;
291 
292 		/* Elliptic curves extension */
293 		if (ext_type == 10) {
294 			smp->data.type = SMP_T_BOOL;
295 			smp->data.u.sint = 1;
296 			smp->flags = SMP_F_VOLATILE;
297 			return 1;
298 		}
299 
300 		hs_len -= 4 + ext_len;
301 		data   += 4 + ext_len;
302 	}
303 	/* server name not found */
304 	goto not_ssl_hello;
305 
306  too_short:
307 	smp->flags = SMP_F_MAY_CHANGE;
308 
309  not_ssl_hello:
310 
311 	return 0;
312 }
313 /* returns the type of SSL hello message (mainly used to detect an SSL hello) */
314 static int
smp_fetch_ssl_hello_type(const struct arg * args,struct sample * smp,const char * kw,void * private)315 smp_fetch_ssl_hello_type(const struct arg *args, struct sample *smp, const char *kw, void *private)
316 {
317 	int hs_len;
318 	int hs_type, bleft;
319 	struct channel *chn;
320 	const unsigned char *data;
321 
322 	if (!smp->strm)
323 		goto not_ssl_hello;
324 
325 	chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
326 	bleft = chn->buf->i;
327 	data = (const unsigned char *)chn->buf->p;
328 
329 	if (!bleft)
330 		goto too_short;
331 
332 	if ((*data >= 0x14 && *data <= 0x17) || (*data == 0xFF)) {
333 		/* SSLv3 header format */
334 		if (bleft < 9)
335 			goto too_short;
336 
337 		/* ssl version 3 */
338 		if ((data[1] << 16) + data[2] < 0x00030000)
339 			goto not_ssl_hello;
340 
341 		/* ssl message len must present handshake type and len */
342 		if ((data[3] << 8) + data[4] < 4)
343 			goto not_ssl_hello;
344 
345 		/* format introduced with SSLv3 */
346 
347 		hs_type = (int)data[5];
348 		hs_len = ( data[6] << 16 ) + ( data[7] << 8 ) + data[8];
349 
350 		/* not a full handshake */
351 		if (bleft < (9 + hs_len))
352 			goto too_short;
353 
354 	}
355 	else {
356 		goto not_ssl_hello;
357 	}
358 
359 	smp->data.type = SMP_T_SINT;
360 	smp->data.u.sint = hs_type;
361 	smp->flags = SMP_F_VOLATILE;
362 
363 	return 1;
364 
365  too_short:
366 	smp->flags = SMP_F_MAY_CHANGE;
367 
368  not_ssl_hello:
369 
370 	return 0;
371 }
372 
373 /* Return the version of the SSL protocol in the request. It supports both
374  * SSLv3 (TLSv1) header format for any message, and SSLv2 header format for
375  * the hello message. The SSLv3 format is described in RFC 2246 p49, and the
376  * SSLv2 format is described here, and completed p67 of RFC 2246 :
377  *    http://wp.netscape.com/eng/security/SSL_2.html
378  *
379  * Note: this decoder only works with non-wrapping data.
380  */
381 static int
smp_fetch_req_ssl_ver(const struct arg * args,struct sample * smp,const char * kw,void * private)382 smp_fetch_req_ssl_ver(const struct arg *args, struct sample *smp, const char *kw, void *private)
383 {
384 	int version, bleft, msg_len;
385 	const unsigned char *data;
386 	struct channel *req;
387 
388 	if (!smp->strm)
389 		return 0;
390 
391 	req = &smp->strm->req;
392 	msg_len = 0;
393 	bleft = req->buf->i;
394 	if (!bleft)
395 		goto too_short;
396 
397 	data = (const unsigned char *)req->buf->p;
398 	if ((*data >= 0x14 && *data <= 0x17) || (*data == 0xFF)) {
399 		/* SSLv3 header format */
400 		if (bleft < 11)
401 			goto too_short;
402 
403 		version = (data[1] << 16) + data[2]; /* record layer version: major, minor */
404 		msg_len = (data[3] <<  8) + data[4]; /* record length */
405 
406 		/* format introduced with SSLv3 */
407 		if (version < 0x00030000)
408 			goto not_ssl;
409 
410 		/* message length between 6 and 2^14 + 2048 */
411 		if (msg_len < 6 || msg_len > ((1<<14) + 2048))
412 			goto not_ssl;
413 
414 		bleft -= 5; data += 5;
415 
416 		/* return the client hello client version, not the record layer version */
417 		version = (data[4] << 16) + data[5]; /* client hello version: major, minor */
418 	} else {
419 		/* SSLv2 header format, only supported for hello (msg type 1) */
420 		int rlen, plen, cilen, silen, chlen;
421 
422 		if (*data & 0x80) {
423 			if (bleft < 3)
424 				goto too_short;
425 			/* short header format : 15 bits for length */
426 			rlen = ((data[0] & 0x7F) << 8) | data[1];
427 			plen = 0;
428 			bleft -= 2; data += 2;
429 		} else {
430 			if (bleft < 4)
431 				goto too_short;
432 			/* long header format : 14 bits for length + pad length */
433 			rlen = ((data[0] & 0x3F) << 8) | data[1];
434 			plen = data[2];
435 			bleft -= 3; data += 3;
436 		}
437 
438 		if (*data != 0x01)
439 			goto not_ssl;
440 		bleft--; data++;
441 
442 		if (bleft < 8)
443 			goto too_short;
444 		version = (data[0] << 16) + data[1]; /* version: major, minor */
445 		cilen   = (data[2] <<  8) + data[3]; /* cipher len, multiple of 3 */
446 		silen   = (data[4] <<  8) + data[5]; /* session_id_len: 0 or 16 */
447 		chlen   = (data[6] <<  8) + data[7]; /* 16<=challenge length<=32 */
448 
449 		bleft -= 8; data += 8;
450 		if (cilen % 3 != 0)
451 			goto not_ssl;
452 		if (silen && silen != 16)
453 			goto not_ssl;
454 		if (chlen < 16 || chlen > 32)
455 			goto not_ssl;
456 		if (rlen != 9 + cilen + silen + chlen)
457 			goto not_ssl;
458 
459 		/* focus on the remaining data length */
460 		msg_len = cilen + silen + chlen + plen;
461 	}
462 	/* We could recursively check that the buffer ends exactly on an SSL
463 	 * fragment boundary and that a possible next segment is still SSL,
464 	 * but that's a bit pointless. However, we could still check that
465 	 * all the part of the request which fits in a buffer is already
466 	 * there.
467 	 */
468 	if (msg_len > channel_recv_limit(req) + req->buf->data - req->buf->p)
469 		msg_len = channel_recv_limit(req) + req->buf->data - req->buf->p;
470 
471 	if (bleft < msg_len)
472 		goto too_short;
473 
474 	/* OK that's enough. We have at least the whole message, and we have
475 	 * the protocol version.
476 	 */
477 	smp->data.type = SMP_T_SINT;
478 	smp->data.u.sint = version;
479 	smp->flags = SMP_F_VOLATILE;
480 	return 1;
481 
482  too_short:
483 	smp->flags = SMP_F_MAY_CHANGE;
484  not_ssl:
485 	return 0;
486 }
487 
488 /* Try to extract the Server Name Indication that may be presented in a TLS
489  * client hello handshake message. The format of the message is the following
490  * (cf RFC5246 + RFC6066) :
491  * TLS frame :
492  *   - uint8  type                            = 0x16   (Handshake)
493  *   - uint16 version                        >= 0x0301 (TLSv1)
494  *   - uint16 length                                   (frame length)
495  *   - TLS handshake :
496  *     - uint8  msg_type                      = 0x01   (ClientHello)
497  *     - uint24 length                                 (handshake message length)
498  *     - ClientHello :
499  *       - uint16 client_version             >= 0x0301 (TLSv1)
500  *       - uint8 Random[32]                  (4 first ones are timestamp)
501  *       - SessionID :
502  *         - uint8 session_id_len (0..32)              (SessionID len in bytes)
503  *         - uint8 session_id[session_id_len]
504  *       - CipherSuite :
505  *         - uint16 cipher_len               >= 2      (Cipher length in bytes)
506  *         - uint16 ciphers[cipher_len/2]
507  *       - CompressionMethod :
508  *         - uint8 compression_len           >= 1      (# of supported methods)
509  *         - uint8 compression_methods[compression_len]
510  *       - optional client_extension_len               (in bytes)
511  *       - optional sequence of ClientHelloExtensions  (as many bytes as above):
512  *         - uint16 extension_type            = 0 for server_name
513  *         - uint16 extension_len
514  *         - opaque extension_data[extension_len]
515  *           - uint16 server_name_list_len             (# of bytes here)
516  *           - opaque server_names[server_name_list_len bytes]
517  *             - uint8 name_type              = 0 for host_name
518  *             - uint16 name_len
519  *             - opaque hostname[name_len bytes]
520  */
521 static int
smp_fetch_ssl_hello_sni(const struct arg * args,struct sample * smp,const char * kw,void * private)522 smp_fetch_ssl_hello_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
523 {
524 	int hs_len, ext_len, bleft;
525 	struct channel *chn;
526 	unsigned char *data;
527 
528 	if (!smp->strm)
529 		goto not_ssl_hello;
530 
531 	chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
532 	bleft = chn->buf->i;
533 	data = (unsigned char *)chn->buf->p;
534 
535 	/* Check for SSL/TLS Handshake */
536 	if (!bleft)
537 		goto too_short;
538 	if (*data != 0x16)
539 		goto not_ssl_hello;
540 
541 	/* Check for SSLv3 or later (SSL version >= 3.0) in the record layer*/
542 	if (bleft < 3)
543 		goto too_short;
544 	if (data[1] < 0x03)
545 		goto not_ssl_hello;
546 
547 	if (bleft < 5)
548 		goto too_short;
549 	hs_len = (data[3] << 8) + data[4];
550 	if (hs_len < 1 + 3 + 2 + 32 + 1 + 2 + 2 + 1 + 1 + 2 + 2)
551 		goto not_ssl_hello; /* too short to have an extension */
552 
553 	data += 5; /* enter TLS handshake */
554 	bleft -= 5;
555 
556 	/* Check for a complete client hello starting at <data> */
557 	if (bleft < 1)
558 		goto too_short;
559 	if (data[0] != 0x01) /* msg_type = Client Hello */
560 		goto not_ssl_hello;
561 
562 	/* Check the Hello's length */
563 	if (bleft < 4)
564 		goto too_short;
565 	hs_len = (data[1] << 16) + (data[2] << 8) + data[3];
566 	if (hs_len < 2 + 32 + 1 + 2 + 2 + 1 + 1 + 2 + 2)
567 		goto not_ssl_hello; /* too short to have an extension */
568 
569 	/* We want the full handshake here */
570 	if (bleft < hs_len)
571 		goto too_short;
572 
573 	data += 4;
574 	/* Start of the ClientHello message */
575 	if (data[0] < 0x03 || data[1] < 0x01) /* TLSv1 minimum */
576 		goto not_ssl_hello;
577 
578 	ext_len = data[34]; /* session_id_len */
579 	if (ext_len > 32 || ext_len > (hs_len - 35)) /* check for correct session_id len */
580 		goto not_ssl_hello;
581 
582 	/* Jump to cipher suite */
583 	hs_len -= 35 + ext_len;
584 	data   += 35 + ext_len;
585 
586 	if (hs_len < 4 ||                               /* minimum one cipher */
587 	    (ext_len = (data[0] << 8) + data[1]) < 2 || /* minimum 2 bytes for a cipher */
588 	    ext_len > hs_len)
589 		goto not_ssl_hello;
590 
591 	/* Jump to the compression methods */
592 	hs_len -= 2 + ext_len;
593 	data   += 2 + ext_len;
594 
595 	if (hs_len < 2 ||                       /* minimum one compression method */
596 	    data[0] < 1 || data[0] > hs_len)    /* minimum 1 bytes for a method */
597 		goto not_ssl_hello;
598 
599 	/* Jump to the extensions */
600 	hs_len -= 1 + data[0];
601 	data   += 1 + data[0];
602 
603 	if (hs_len < 2 ||                       /* minimum one extension list length */
604 	    (ext_len = (data[0] << 8) + data[1]) > hs_len - 2) /* list too long */
605 		goto not_ssl_hello;
606 
607 	hs_len = ext_len; /* limit ourselves to the extension length */
608 	data += 2;
609 
610 	while (hs_len >= 4) {
611 		int ext_type, name_type, srv_len, name_len;
612 
613 		ext_type = (data[0] << 8) + data[1];
614 		ext_len  = (data[2] << 8) + data[3];
615 
616 		if (ext_len > hs_len - 4) /* Extension too long */
617 			goto not_ssl_hello;
618 
619 		if (ext_type == 0) { /* Server name */
620 			if (ext_len < 2) /* need one list length */
621 				goto not_ssl_hello;
622 
623 			srv_len = (data[4] << 8) + data[5];
624 			if (srv_len < 4 || srv_len > hs_len - 6)
625 				goto not_ssl_hello; /* at least 4 bytes per server name */
626 
627 			name_type = data[6];
628 			name_len = (data[7] << 8) + data[8];
629 
630 			if (name_type == 0) { /* hostname */
631 				smp->data.type = SMP_T_STR;
632 				smp->data.u.str.str = (char *)data + 9;
633 				smp->data.u.str.len = name_len;
634 				smp->flags = SMP_F_VOLATILE | SMP_F_CONST;
635 				return 1;
636 			}
637 		}
638 
639 		hs_len -= 4 + ext_len;
640 		data   += 4 + ext_len;
641 	}
642 	/* server name not found */
643 	goto not_ssl_hello;
644 
645  too_short:
646 	smp->flags = SMP_F_MAY_CHANGE;
647 
648  not_ssl_hello:
649 
650 	return 0;
651 }
652 
653 /* Fetch the request RDP cookie identified in <cname>:<clen>, or any cookie if
654  * <clen> is empty (cname is then ignored). It returns the data into sample <smp>
655  * of type SMP_T_CSTR. Note: this decoder only works with non-wrapping data.
656  */
657 int
fetch_rdp_cookie_name(struct stream * s,struct sample * smp,const char * cname,int clen)658 fetch_rdp_cookie_name(struct stream *s, struct sample *smp, const char *cname, int clen)
659 {
660 	int bleft;
661 	const unsigned char *data;
662 
663 	smp->flags = SMP_F_CONST;
664 	smp->data.type = SMP_T_STR;
665 
666 	bleft = s->req.buf->i;
667 	if (bleft <= 11)
668 		goto too_short;
669 
670 	data = (const unsigned char *)s->req.buf->p + 11;
671 	bleft -= 11;
672 
673 	if (bleft <= 7)
674 		goto too_short;
675 
676 	if (strncasecmp((const char *)data, "Cookie:", 7) != 0)
677 		goto not_cookie;
678 
679 	data += 7;
680 	bleft -= 7;
681 
682 	while (bleft > 0 && *data == ' ') {
683 		data++;
684 		bleft--;
685 	}
686 
687 	if (clen) {
688 		if (bleft <= clen)
689 			goto too_short;
690 
691 		if ((data[clen] != '=') ||
692 		    strncasecmp(cname, (const char *)data, clen) != 0)
693 			goto not_cookie;
694 
695 		data += clen + 1;
696 		bleft -= clen + 1;
697 	} else {
698 		while (bleft > 0 && *data != '=') {
699 			if (*data == '\r' || *data == '\n')
700 				goto not_cookie;
701 			data++;
702 			bleft--;
703 		}
704 
705 		if (bleft < 1)
706 			goto too_short;
707 
708 		if (*data != '=')
709 			goto not_cookie;
710 
711 		data++;
712 		bleft--;
713 	}
714 
715 	/* data points to cookie value */
716 	smp->data.u.str.str = (char *)data;
717 	smp->data.u.str.len = 0;
718 
719 	while (bleft > 0 && *data != '\r') {
720 		data++;
721 		bleft--;
722 	}
723 
724 	if (bleft < 2)
725 		goto too_short;
726 
727 	if (data[0] != '\r' || data[1] != '\n')
728 		goto not_cookie;
729 
730 	smp->data.u.str.len = (char *)data - smp->data.u.str.str;
731 	smp->flags = SMP_F_VOLATILE | SMP_F_CONST;
732 	return 1;
733 
734  too_short:
735 	smp->flags = SMP_F_MAY_CHANGE | SMP_F_CONST;
736  not_cookie:
737 	return 0;
738 }
739 
740 /* Fetch the request RDP cookie identified in the args, or any cookie if no arg
741  * is passed. It is usable both for ACL and for samples. Note: this decoder
742  * only works with non-wrapping data. Accepts either 0 or 1 argument. Argument
743  * is a string (cookie name), other types will lead to undefined behaviour. The
744  * returned sample has type SMP_T_CSTR.
745  */
746 int
smp_fetch_rdp_cookie(const struct arg * args,struct sample * smp,const char * kw,void * private)747 smp_fetch_rdp_cookie(const struct arg *args, struct sample *smp, const char *kw, void *private)
748 {
749 	if (!smp->strm)
750 		return 0;
751 
752 	return fetch_rdp_cookie_name(smp->strm, smp, args ? args->data.str.str : NULL, args ? args->data.str.len : 0);
753 }
754 
755 /* returns either 1 or 0 depending on whether an RDP cookie is found or not */
756 static int
smp_fetch_rdp_cookie_cnt(const struct arg * args,struct sample * smp,const char * kw,void * private)757 smp_fetch_rdp_cookie_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
758 {
759 	int ret;
760 
761 	ret = smp_fetch_rdp_cookie(args, smp, kw, private);
762 
763 	if (smp->flags & SMP_F_MAY_CHANGE)
764 		return 0;
765 
766 	smp->flags = SMP_F_VOLATILE;
767 	smp->data.type = SMP_T_SINT;
768 	smp->data.u.sint = ret;
769 	return 1;
770 }
771 
772 /* extracts part of a payload with offset and length at a given position */
773 static int
smp_fetch_payload_lv(const struct arg * arg_p,struct sample * smp,const char * kw,void * private)774 smp_fetch_payload_lv(const struct arg *arg_p, struct sample *smp, const char *kw, void *private)
775 {
776 	unsigned int len_offset = arg_p[0].data.sint;
777 	unsigned int len_size = arg_p[1].data.sint;
778 	unsigned int buf_offset;
779 	unsigned int buf_size = 0;
780 	struct channel *chn;
781 	int i;
782 
783 	/* Format is (len offset, len size, buf offset) or (len offset, len size) */
784 	/* by default buf offset == len offset + len size */
785 	/* buf offset could be absolute or relative to len offset + len size if prefixed by + or - */
786 
787 	if (!smp->strm)
788 		return 0;
789 
790 	chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
791 	if (len_offset + len_size > chn->buf->i)
792 		goto too_short;
793 
794 	for (i = 0; i < len_size; i++) {
795 		buf_size = (buf_size << 8) + ((unsigned char *)chn->buf->p)[i + len_offset];
796 	}
797 
798 	/* buf offset may be implicit, absolute or relative. If the LSB
799 	 * is set, then the offset is relative otherwise it is absolute.
800 	 */
801 	buf_offset = len_offset + len_size;
802 	if (arg_p[2].type == ARGT_SINT) {
803 		if (arg_p[2].data.sint & 1)
804 			buf_offset += arg_p[2].data.sint >> 1;
805 		else
806 			buf_offset = arg_p[2].data.sint >> 1;
807 	}
808 
809 	if (!buf_size || buf_size > global.tune.bufsize || buf_offset + buf_size > global.tune.bufsize) {
810 		/* will never match */
811 		smp->flags = 0;
812 		return 0;
813 	}
814 
815 	if (buf_offset + buf_size > chn->buf->i)
816 		goto too_short;
817 
818 	/* init chunk as read only */
819 	smp->data.type = SMP_T_BIN;
820 	smp->flags = SMP_F_VOLATILE | SMP_F_CONST;
821 	chunk_initlen(&smp->data.u.str, chn->buf->p + buf_offset, 0, buf_size);
822 	return 1;
823 
824  too_short:
825 	smp->flags = SMP_F_MAY_CHANGE | SMP_F_CONST;
826 	return 0;
827 }
828 
829 /* extracts some payload at a fixed position and length */
830 static int
smp_fetch_payload(const struct arg * arg_p,struct sample * smp,const char * kw,void * private)831 smp_fetch_payload(const struct arg *arg_p, struct sample *smp, const char *kw, void *private)
832 {
833 	unsigned int buf_offset = arg_p[0].data.sint;
834 	unsigned int buf_size = arg_p[1].data.sint;
835 	struct channel *chn;
836 
837 	if (!smp->strm)
838 		return 0;
839 
840 	chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
841 	if (buf_size > global.tune.bufsize || buf_offset + buf_size > global.tune.bufsize) {
842 		/* will never match */
843 		smp->flags = 0;
844 		return 0;
845 	}
846 
847 	if (buf_offset + buf_size > chn->buf->i)
848 		goto too_short;
849 
850 	/* init chunk as read only */
851 	smp->data.type = SMP_T_BIN;
852 	smp->flags = SMP_F_VOLATILE | SMP_F_CONST;
853 	chunk_initlen(&smp->data.u.str, chn->buf->p + buf_offset, 0, buf_size ? buf_size : (chn->buf->i - buf_offset));
854 	if (!buf_size && channel_may_recv(chn) && !channel_input_closed(chn))
855 		smp->flags |= SMP_F_MAY_CHANGE;
856 
857 	return 1;
858 
859  too_short:
860 	smp->flags = SMP_F_MAY_CHANGE | SMP_F_CONST;
861 	return 0;
862 }
863 
864 /* This function is used to validate the arguments passed to a "payload_lv" fetch
865  * keyword. This keyword allows two positive integers and an optional signed one,
866  * with the second one being strictly positive and the third one being greater than
867  * the opposite of the two others if negative. It is assumed that the types are
868  * already the correct ones. Returns 0 on error, non-zero if OK. If <err_msg> is
869  * not NULL, it will be filled with a pointer to an error message in case of
870  * error, that the caller is responsible for freeing. The initial location must
871  * either be freeable or NULL.
872  *
873  * Note that offset2 is stored with SINT type, but its not directly usable as is.
874  * The value is contained in the 63 MSB and the LSB is used as a flag for marking
875  * the "relative" property of the value.
876  */
val_payload_lv(struct arg * arg,char ** err_msg)877 int val_payload_lv(struct arg *arg, char **err_msg)
878 {
879 	int relative = 0;
880 	const char *str;
881 
882 	if (arg[0].data.sint < 0) {
883 		memprintf(err_msg, "payload offset1 must be positive");
884 		return 0;
885 	}
886 
887 	if (!arg[1].data.sint) {
888 		memprintf(err_msg, "payload length must be > 0");
889 		return 0;
890 	}
891 
892 	if (arg[2].type == ARGT_STR && arg[2].data.str.len > 0) {
893 		if (arg[2].data.str.str[0] == '+' || arg[2].data.str.str[0] == '-')
894 			relative = 1;
895 		str = arg[2].data.str.str;
896 		arg[2].type = ARGT_SINT;
897 		arg[2].data.sint = read_int64(&str, str + arg[2].data.str.len);
898 		if (*str != '\0') {
899 			memprintf(err_msg, "payload offset2 is not a number");
900 			return 0;
901 		}
902 	   if (arg[0].data.sint + arg[1].data.sint + arg[2].data.sint < 0) {
903 			memprintf(err_msg, "payload offset2 too negative");
904 			return 0;
905 		}
906 		if (relative)
907 			arg[2].data.sint = ( arg[2].data.sint << 1 ) + 1;
908 	}
909 	return 1;
910 }
911 
912 /************************************************************************/
913 /*      All supported sample and ACL keywords must be declared here.    */
914 /************************************************************************/
915 
916 /* Note: must not be declared <const> as its list will be overwritten.
917  * Note: fetches that may return multiple types must be declared as the lowest
918  * common denominator, the type that can be casted into all other ones. For
919  * instance IPv4/IPv6 must be declared IPv4.
920  */
921 static struct sample_fetch_kw_list smp_kws = {ILH, {
922 	{ "payload",             smp_fetch_payload,        ARG2(2,SINT,SINT),      NULL,           SMP_T_BIN,  SMP_USE_L6REQ|SMP_USE_L6RES },
923 	{ "payload_lv",          smp_fetch_payload_lv,     ARG3(2,SINT,SINT,STR),  val_payload_lv, SMP_T_BIN,  SMP_USE_L6REQ|SMP_USE_L6RES },
924 	{ "rdp_cookie",          smp_fetch_rdp_cookie,     ARG1(0,STR),            NULL,           SMP_T_STR,  SMP_USE_L6REQ },
925 	{ "rdp_cookie_cnt",      smp_fetch_rdp_cookie_cnt, ARG1(0,STR),            NULL,           SMP_T_SINT, SMP_USE_L6REQ },
926 	{ "rep_ssl_hello_type",  smp_fetch_ssl_hello_type, 0,                      NULL,           SMP_T_SINT, SMP_USE_L6RES },
927 	{ "req_len",             smp_fetch_len,            0,                      NULL,           SMP_T_SINT, SMP_USE_L6REQ },
928 	{ "req_ssl_hello_type",  smp_fetch_ssl_hello_type, 0,                      NULL,           SMP_T_SINT, SMP_USE_L6REQ },
929 	{ "req_ssl_sni",         smp_fetch_ssl_hello_sni,  0,                      NULL,           SMP_T_STR,  SMP_USE_L6REQ },
930 	{ "req_ssl_ver",         smp_fetch_req_ssl_ver,    0,                      NULL,           SMP_T_SINT, SMP_USE_L6REQ },
931 
932 	{ "req.len",             smp_fetch_len,            0,                      NULL,           SMP_T_SINT, SMP_USE_L6REQ },
933 	{ "req.payload",         smp_fetch_payload,        ARG2(2,SINT,SINT),      NULL,           SMP_T_BIN,  SMP_USE_L6REQ },
934 	{ "req.payload_lv",      smp_fetch_payload_lv,     ARG3(2,SINT,SINT,STR),  val_payload_lv, SMP_T_BIN,  SMP_USE_L6REQ },
935 	{ "req.rdp_cookie",      smp_fetch_rdp_cookie,     ARG1(0,STR),            NULL,           SMP_T_STR,  SMP_USE_L6REQ },
936 	{ "req.rdp_cookie_cnt",  smp_fetch_rdp_cookie_cnt, ARG1(0,STR),            NULL,           SMP_T_SINT, SMP_USE_L6REQ },
937 	{ "req.ssl_ec_ext",      smp_fetch_req_ssl_ec_ext, 0,                      NULL,           SMP_T_BOOL, SMP_USE_L6REQ },
938 	{ "req.ssl_st_ext",      smp_fetch_req_ssl_st_ext, 0,                      NULL,           SMP_T_SINT, SMP_USE_L6REQ },
939 	{ "req.ssl_hello_type",  smp_fetch_ssl_hello_type, 0,                      NULL,           SMP_T_SINT, SMP_USE_L6REQ },
940 	{ "req.ssl_sni",         smp_fetch_ssl_hello_sni,  0,                      NULL,           SMP_T_STR,  SMP_USE_L6REQ },
941 	{ "req.ssl_ver",         smp_fetch_req_ssl_ver,    0,                      NULL,           SMP_T_SINT, SMP_USE_L6REQ },
942 	{ "res.len",             smp_fetch_len,            0,                      NULL,           SMP_T_SINT, SMP_USE_L6RES },
943 	{ "res.payload",         smp_fetch_payload,        ARG2(2,SINT,SINT),      NULL,           SMP_T_BIN,  SMP_USE_L6RES },
944 	{ "res.payload_lv",      smp_fetch_payload_lv,     ARG3(2,SINT,SINT,STR),  val_payload_lv, SMP_T_BIN,  SMP_USE_L6RES },
945 	{ "res.ssl_hello_type",  smp_fetch_ssl_hello_type, 0,                      NULL,           SMP_T_SINT, SMP_USE_L6RES },
946 	{ "wait_end",            smp_fetch_wait_end,       0,                      NULL,           SMP_T_BOOL, SMP_USE_INTRN },
947 	{ /* END */ },
948 }};
949 
950 
951 /* Note: must not be declared <const> as its list will be overwritten.
952  * Please take care of keeping this list alphabetically sorted.
953  */
954 static struct acl_kw_list acl_kws = {ILH, {
955 	{ "payload",            "req.payload",        PAT_MATCH_BIN },
956 	{ "payload_lv",         "req.payload_lv",     PAT_MATCH_BIN },
957 	{ "req_rdp_cookie",     "req.rdp_cookie",     PAT_MATCH_STR },
958 	{ "req_rdp_cookie_cnt", "req.rdp_cookie_cnt", PAT_MATCH_INT },
959 	{ "req_ssl_sni",        "req.ssl_sni",        PAT_MATCH_STR },
960 	{ "req_ssl_ver",        "req.ssl_ver",        PAT_MATCH_INT, pat_parse_dotted_ver },
961 	{ "req.ssl_ver",        "req.ssl_ver",        PAT_MATCH_INT, pat_parse_dotted_ver },
962 	{ /* END */ },
963 }};
964 
965 
966 __attribute__((constructor))
__payload_init(void)967 static void __payload_init(void)
968 {
969 	sample_register_fetches(&smp_kws);
970 	acl_register_keywords(&acl_kws);
971 }
972 
973 /*
974  * Local variables:
975  *  c-indent-level: 8
976  *  c-basic-offset: 8
977  * End:
978  */
979