src/payload.c
static int
smp_fetch_req_ssl_ver(struct proxy *px, struct session *s, void *l7, unsigned int opt,
                      const struct arg *args, struct sample *smp)
{
	int version, bleft, msg_len;
	const unsigned char *data;

	if (!s || !s->req)
		return 0;

	msg_len = 0;
	bleft = s->req->buf->i;
	if (!bleft)
		goto too_short;

	data = (const unsigned char *)s->req->buf->p;
	if ((*data >= 0x14 && *data <= 0x17) || (*data == 0xFF)) {
		/* SSLv3 header format */
		if (bleft < 5)
			goto too_short;

		version = (data[1] << 16) + data[2]; /* version: major, minor */
		msg_len = (data[3] <<  8) + data[4]; /* record length */

		/* format introduced with SSLv3 */
		if (version < 0x00030000)
			goto not_ssl;

		/* message length between 1 and 2^14 + 2048 */
		if (msg_len < 1 || msg_len > ((1<<14) + 2048))
			goto not_ssl;

		bleft -= 5; data += 5;
	} else {
		/* SSLv2 header format, only supported for hello (msg type 1) */
		int rlen, plen, cilen, silen, chlen;

		if (*data & 0x80) {
			if (bleft < 3)
				goto too_short;
			/* short header format : 15 bits for length */
			rlen = ((data[0] & 0x7F) << 8) | data[1];
			plen = 0;
			bleft -= 2; data += 2;
		} else {
			if (bleft < 4)
				goto too_short;
			/* long header format : 14 bits for length + pad length */
			rlen = ((data[0] & 0x3F) << 8) | data[1];
			plen = data[2];
			bleft -= 3; data += 2;
		}

		if (*data != 0x01)
			goto not_ssl;
		bleft--; data++;

		if (bleft < 8)
			goto too_short;
		version = (data[0] << 16) + data[1]; /* version: major, minor */
		cilen   = (data[2] <<  8) + data[3]; /* cipher len, multiple of 3 */
		silen   = (data[4] <<  8) + data[5]; /* session_id_len: 0 or 16 */
		chlen   = (data[6] <<  8) + data[7]; /* 16<=challenge length<=32 */

		bleft -= 8; data += 8;
		if (cilen % 3 != 0)
			goto not_ssl;
		if (silen && silen != 16)
			goto not_ssl;
		if (chlen < 16 || chlen > 32)
			goto not_ssl;
		if (rlen != 9 + cilen + silen + chlen)
			goto not_ssl;

		/* focus on the remaining data length */
		msg_len = cilen + silen + chlen + plen;
	}
	/* We could recursively check that the buffer ends exactly on an SSL
	 * fragment boundary and that a possible next segment is still SSL,
	 * but that's a bit pointless. However, we could still check that
	 * all the part of the request which fits in a buffer is already
	 * there.
	 */
	if (msg_len > buffer_max_len(s->req) + s->req->buf->data - s->req->buf->p)
		msg_len = buffer_max_len(s->req) + s->req->buf->data - s->req->buf->p;

	if (bleft < msg_len)
		goto too_short;

	/* OK that's enough. We have at least the whole message, and we have
	 * the protocol version.
	 */
	smp->type = SMP_T_UINT;
	smp->data.uint = version;
	smp->flags = SMP_F_VOLATILE;
	return 1;

 too_short:
	smp->flags = SMP_F_MAY_CHANGE;
 not_ssl:
	return 0;
}
/* Return the version of the SSL protocol in the request. It supports both
 * SSLv3 (TLSv1) header format for any message, and SSLv2 header format for
 * the hello message. The SSLv3 format is described in RFC 2246 p49, and the
 * SSLv2 format is described here, and completed p67 of RFC 2246 :
 *    http://wp.netscape.com/eng/security/SSL_2.html
 *
 * Note: this decoder only works with non-wrapping data.
 */
Return the version of the SSL protocol in the request. It supports both
SSLv3 (TLSv1) header format for any message, and SSLv2 header format for
the hello message.

this decoder only works with non-wrapping data.
Return the version of the SSL protocol in the request . It supports both SSLv3 ( TLSv1 ) header format for any message and SSLv2 header format for the hello message . this decoder only works with non - wrapping data .
static int
smp_fetch_req_ssl_ver(struct proxy *px, struct session *s, void *l7, unsigned int opt,
                      const struct arg *args, struct sample *smp)
{
	int version, bleft, msg_len;
	const unsigned char *data;
	if (!s || !s->req)
		return 0;
	msg_len = 0;
	bleft = s->req->buf->i;
	if (!bleft)
		goto too_short;
	data = (const unsigned char *)s->req->buf->p;
	if ((*data >= 0x14 && *data <= 0x17) || (*data == 0xFF)) {
		if (bleft < 5)
			goto too_short;
		version = (data[1] << 16) + data[2]; 
		msg_len = (data[3] <<  8) + data[4]; 
		if (version < 0x00030000)
			goto not_ssl;
		if (msg_len < 1 || msg_len > ((1<<14) + 2048))
			goto not_ssl;
		bleft -= 5; data += 5;
	} else {
		int rlen, plen, cilen, silen, chlen;
		if (*data & 0x80) {
			if (bleft < 3)
				goto too_short;
			rlen = ((data[0] & 0x7F) << 8) | data[1];
			plen = 0;
			bleft -= 2; data += 2;
		} else {
			if (bleft < 4)
				goto too_short;
			rlen = ((data[0] & 0x3F) << 8) | data[1];
			plen = data[2];
			bleft -= 3; data += 2;
		}
		if (*data != 0x01)
			goto not_ssl;
		bleft--; data++;
		if (bleft < 8)
			goto too_short;
		version = (data[0] << 16) + data[1]; 
		cilen   = (data[2] <<  8) + data[3]; 
		silen   = (data[4] <<  8) + data[5]; 
		chlen   = (data[6] <<  8) + data[7]; 
		bleft -= 8; data += 8;
		if (cilen % 3 != 0)
			goto not_ssl;
		if (silen && silen != 16)
			goto not_ssl;
		if (chlen < 16 || chlen > 32)
			goto not_ssl;
		if (rlen != 9 + cilen + silen + chlen)
			goto not_ssl;
		msg_len = cilen + silen + chlen + plen;
	}
	if (msg_len > buffer_max_len(s->req) + s->req->buf->data - s->req->buf->p)
		msg_len = buffer_max_len(s->req) + s->req->buf->data - s->req->buf->p;
	if (bleft < msg_len)
		goto too_short;
	smp->type = SMP_T_UINT;
	smp->data.uint = version;
	smp->flags = SMP_F_VOLATILE;
	return 1;
 too_short:
	smp->flags = SMP_F_MAY_CHANGE;
 not_ssl:
	return 0;
}
static int smp_fetch_req_ssl_ver ( struct proxy * px , struct session * s , void * l7 , unsigned int opt , const struct arg * args , struct sample * smp ) { int version , bleft , msg_len ; const unsigned char * data ; if ( ! s || ! s -> req ) return 0 ; msg_len = 0 ; bleft = s -> req -> buf -> i ; if ( ! bleft ) goto too_short ; data = ( const unsigned char * ) s -> req -> buf -> p ; if ( ( * data >= 0x14 && * data <= 0x17 ) || ( * data == 0xFF ) ) { if ( bleft < 5 ) goto too_short ; version = ( data [ 1 ] << 16 ) + data [ 2 ] ; msg_len = ( data [ 3 ] << 8 ) + data [ 4 ] ; if ( version < 0x00030000 ) goto not_ssl ; if ( msg_len < 1 || msg_len > ( ( 1 << 14 ) + 2048 ) ) goto not_ssl ; bleft -= 5 ; data += 5 ; } else { int rlen , plen , cilen , silen , chlen ; if ( * data & 0x80 ) { if ( bleft < 3 ) goto too_short ; rlen = ( ( data [ 0 ] & 0x7F ) << 8 ) | data [ 1 ] ; plen = 0 ; bleft -= 2 ; data += 2 ; } else { if ( bleft < 4 ) goto too_short ; rlen = ( ( data [ 0 ] & 0x3F ) << 8 ) | data [ 1 ] ; plen = data [ 2 ] ; bleft -= 3 ; data += 2 ; } if ( * data != 0x01 ) goto not_ssl ; bleft -- ; data ++ ; if ( bleft < 8 ) goto too_short ; version = ( data [ 0 ] << 16 ) + data [ 1 ] ; cilen = ( data [ 2 ] << 8 ) + data [ 3 ] ; silen = ( data [ 4 ] << 8 ) + data [ 5 ] ; chlen = ( data [ 6 ] << 8 ) + data [ 7 ] ; bleft -= 8 ; data += 8 ; if ( cilen % 3 != 0 ) goto not_ssl ; if ( silen && silen != 16 ) goto not_ssl ; if ( chlen < 16 || chlen > 32 ) goto not_ssl ; if ( rlen != 9 + cilen + silen + chlen ) goto not_ssl ; msg_len = cilen + silen + chlen + plen ; } if ( msg_len > buffer_max_len ( s -> req ) + s -> req -> buf -> data - s -> req -> buf -> p ) msg_len = buffer_max_len ( s -> req ) + s -> req -> buf -> data - s -> req -> buf -> p ; if ( bleft < msg_len ) goto too_short ; smp -> type = SMP_T_UINT ; smp -> data . uint = version ; smp -> flags = SMP_F_VOLATILE ; return 1 ; too_short : smp -> flags = SMP_F_MAY_CHANGE ; not_ssl : return 0 ; }
Return the version of the SSL protocol in the request.
Return the version of the SSL protocol in the request .
/* SSLv3 header format */ /* version: major, minor */ /* record length */ /* format introduced with SSLv3 */ /* message length between 1 and 2^14 + 2048 */ /* SSLv2 header format, only supported for hello (msg type 1) */ /* short header format : 15 bits for length */ /* long header format : 14 bits for length + pad length */ /* version: major, minor */ /* cipher len, multiple of 3 */ /* session_id_len: 0 or 16 */ /* 16<=challenge length<=32 */ /* focus on the remaining data length */ /* We could recursively check that the buffer ends exactly on an SSL
	 * fragment boundary and that a possible next segment is still SSL,
	 * but that's a bit pointless. However, we could still check that
	 * all the part of the request which fits in a buffer is already
	 * there.
	 */ /* OK that's enough. We have at least the whole message, and we have
	 * the protocol version.
	 */