@@ -121,6 +121,20 @@ typedef struct
121121
122122#pragma pack()
123123
124+ typedef struct
125+ {
126+ uint8_t type ;
127+ uint16_t length ;
128+ uint8_t value [1 ];
129+ } tlv_t ;
130+
131+ struct _tlv_array_t
132+ {
133+ uint32_t len ; /* Number of elements */
134+ uint32_t size ; /* Allocated elements */
135+ tlv_t * * tlvs ; /* Pointer to tlv_t* elements */
136+ };
137+
124138static const char * errors [] = {
125139 "No error" ,
126140 "Invalid PROXY protocol version given. Only 1 and 2 are valid" ,
@@ -246,21 +260,21 @@ static void tlv_array_clear(tlv_array_t *tlv_array)
246260 tlv_array -> len = 0 ;
247261 tlv_array -> size = 0 ;
248262 free (tlv_array -> tlvs );
249-
263+ tlv_array -> tlvs = NULL ;
250264}
251265
252266uint8_t * pp_info_get_tlv_value (const pp_info_t * pp_info , uint8_t type , uint8_t subtype , uint16_t * value_len_out )
253267{
254268 * value_len_out = 0 ;
255- if (!pp_info -> tlv_array . tlvs || !pp_info -> tlv_array . len )
269+ if (!pp_info -> tlv_array -> tlvs || !pp_info -> tlv_array -> len )
256270 {
257271 return NULL ;
258272 }
259273
260274 uint32_t i ;
261- for (i = 0 ; i < pp_info -> tlv_array . len ; i ++ )
275+ for (i = 0 ; i < pp_info -> tlv_array -> len ; i ++ )
262276 {
263- tlv_t * tlv = pp_info -> tlv_array . tlvs [i ];
277+ tlv_t * tlv = pp_info -> tlv_array -> tlvs [i ];
264278 if (tlv -> type == type )
265279 {
266280 if (subtype > 0 )
@@ -281,15 +295,19 @@ uint8_t *pp_info_get_tlv_value(const pp_info_t *pp_info, uint8_t type, uint8_t s
281295
282296void pp_info_clear (pp_info_t * pp_info )
283297{
284- tlv_array_clear (& pp_info -> tlv_array );
298+ if (pp_info -> tlv_array )
299+ {
300+ tlv_array_clear (pp_info -> tlv_array );
301+ free (pp_info -> tlv_array );
302+ }
285303 memset (pp_info , 0 , sizeof (* pp_info ));
286304}
287305
288306uint8_t * pp2_create_hdr (uint8_t fam , const pp_info_t * pp_info , uint32_t * pp2_hdr_len , uint32_t * error )
289307{
290308 proxy_hdr_v2_t proxy_hdr_v2 = {
291309 .sig = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" ,
292- .ver_cmd = pp_info -> v2local ? '\x20' : '\x21' ,
310+ .ver_cmd = pp_info -> pp2_info . local ? '\x20' : '\x21' ,
293311 };
294312
295313 uint8_t transport_protocol = fam & 0x0f ;
@@ -305,7 +323,7 @@ uint8_t *pp2_create_hdr(uint8_t fam, const pp_info_t *pp_info, uint32_t *pp2_hdr
305323 if (address_family == 0x0 )
306324 {
307325 len = 0 ;
308- if (!pp_info -> v2local )
326+ if (!pp_info -> pp2_info . local )
309327 {
310328 * error = ERR_PP2_TRANSPORT_FAMILY ;
311329 return NULL ;
@@ -526,7 +544,7 @@ static uint32_t crc32c(const uint8_t *buf, uint32_t len)
526544}
527545
528546/* Verifies and parses a version 2 PROXY protocol header */
529- static int32_t ppv2_parse (uint8_t * pkt , uint32_t pktlen , pp_info_t * pp_info )
547+ static int32_t pp2_parse_hdr (uint8_t * pkt , uint32_t pktlen , pp_info_t * pp_info )
530548{
531549 const uint8_t * ppv2_hdr = pkt ;
532550 const proxy_hdr_v2_t * proxy_hdr_v2 = (proxy_hdr_v2_t * ) pkt ;
@@ -551,11 +569,11 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
551569 uint8_t cmd = proxy_hdr_v2 -> ver_cmd & 0x0f ;
552570 if (cmd == 0x0 )
553571 {
554- pp_info -> v2local = 1 ;
572+ pp_info -> pp2_info . local = 1 ;
555573 }
556574 else if (cmd == 0x1 )
557575 {
558- pp_info -> v2local = 0 ;
576+ pp_info -> pp2_info . local = 0 ;
559577 }
560578 else
561579 {
@@ -662,6 +680,10 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
662680
663681 /* TLVs */
664682 /* Any TLV vector must be at least 3 bytes */
683+ if (tlv_vectors_len > 3 )
684+ {
685+ pp_info -> tlv_array = malloc (sizeof (* pp_info -> tlv_array ));
686+ }
665687 while (tlv_vectors_len > 3 )
666688 {
667689 pp2_tlv_t * pp2_tlv = (pp2_tlv_t * ) pkt ;
@@ -676,7 +698,7 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
676698 {
677699 case PP2_TYPE_ALPN : /* Byte sequence */
678700 case PP2_TYPE_AUTHORITY : /* UTF8 */
679- if (!tlv_array_append_tlv_new (& pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value ))
701+ if (!tlv_array_append_tlv_new (pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value ))
680702 {
681703 return ERR_HEAP_ALLOC ;
682704 }
@@ -702,7 +724,7 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
702724 return ERR_PP2_TYPE_CRC32C ;
703725 }
704726
705- if (!tlv_array_append_tlv_new (& pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , & crc32c_chksum ))
727+ if (!tlv_array_append_tlv_new (pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , & crc32c_chksum ))
706728 {
707729 return ERR_HEAP_ALLOC ;
708730 }
@@ -715,20 +737,23 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
715737 {
716738 return ERR_PP2_TYPE_UNIQUE_ID ;
717739 }
718- if (!tlv_array_append_tlv_new (& pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value ))
740+ if (!tlv_array_append_tlv_new (pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value ))
719741 {
720742 return ERR_HEAP_ALLOC ;
721743 }
722744 break ;
723745 case PP2_TYPE_SSL :
724746 {
725747 pp2_tlv_ssl_t * pp2_tlv_ssl = (pp2_tlv_ssl_t * )pp2_tlv -> value ;
726- /* TODO save client, verify in pp_info_t */
727- /*if (!(pp2_tlv_ssl->client & PP2_CLIENT_SSL || pp2_tlv_ssl->client & PP2_CLIENT_CERT_CONN || pp2_tlv_ssl->client & PP2_CLIENT_CERT_SESS))
728- {
729- break;
730- }*/
748+
749+ /* Set the pp2_ssl_info */
750+ pp_info -> pp2_info .pp2_ssl_info .ssl = !!(pp2_tlv_ssl -> client & PP2_CLIENT_SSL );
751+ pp_info -> pp2_info .pp2_ssl_info .cert_in_connection = !!(pp2_tlv_ssl -> client & PP2_CLIENT_CERT_CONN );
752+ pp_info -> pp2_info .pp2_ssl_info .cert_in_session = !!(pp2_tlv_ssl -> client & PP2_CLIENT_CERT_SESS );
753+ pp_info -> pp2_info .pp2_ssl_info .cert_verified = !pp2_tlv_ssl -> verify ;
754+
731755 uint16_t pp2_tlvs_ssl_len = pp2_tlv_len - sizeof (pp2_tlv_ssl -> client ) - sizeof (pp2_tlv_ssl -> verify );
756+ uint8_t tlv_ssl_version_found = 0 ;
732757 uint16_t pp2_sub_tlv_offset = 0 ;
733758 while (pp2_sub_tlv_offset < pp2_tlvs_ssl_len )
734759 {
@@ -737,17 +762,17 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
737762 switch (pp2_sub_tlv_ssl -> type )
738763 {
739764 case PP2_SUBTYPE_SSL_VERSION : /* US-ASCII */
765+ tlv_ssl_version_found = 1 ;
740766 case PP2_SUBTYPE_SSL_CIPHER : /* US-ASCII */
741767 case PP2_SUBTYPE_SSL_SIG_ALG : /* US-ASCII */
742768 case PP2_SUBTYPE_SSL_KEY_ALG : /* US-ASCII */
743- /* +1 to save it as a string */
744- if (!tlv_array_append_tlv_new_usascii (& pp_info -> tlv_array , pp2_sub_tlv_ssl -> type , pp2_sub_tlv_ssl_len , pp2_sub_tlv_ssl -> value ))
769+ if (!tlv_array_append_tlv_new_usascii (pp_info -> tlv_array , pp2_sub_tlv_ssl -> type , pp2_sub_tlv_ssl_len , pp2_sub_tlv_ssl -> value ))
745770 {
746771 return ERR_HEAP_ALLOC ;
747772 }
748773 break ;
749774 case PP2_SUBTYPE_SSL_CN : /* UTF8 */
750- if (!tlv_array_append_tlv_new (& pp_info -> tlv_array , pp2_sub_tlv_ssl -> type , pp2_sub_tlv_ssl_len , pp2_sub_tlv_ssl -> value ))
775+ if (!tlv_array_append_tlv_new (pp_info -> tlv_array , pp2_sub_tlv_ssl -> type , pp2_sub_tlv_ssl_len , pp2_sub_tlv_ssl -> value ))
751776 {
752777 return ERR_HEAP_ALLOC ;
753778 }
@@ -758,14 +783,14 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
758783
759784 pp2_sub_tlv_offset += 3 + pp2_sub_tlv_ssl_len ;
760785 }
761- if (pp2_sub_tlv_offset > pp2_tlvs_ssl_len )
786+ if (pp2_sub_tlv_offset > pp2_tlvs_ssl_len || ( pp_info -> pp2_info . pp2_ssl_info . ssl && ! tlv_ssl_version_found ) )
762787 {
763788 return ERR_PP2_TYPE_SSL ;
764789 }
765790 break ;
766791 }
767792 case PP2_TYPE_NETNS : /* US-ASCII */
768- if (!tlv_array_append_tlv_new_usascii (& pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value ))
793+ if (!tlv_array_append_tlv_new_usascii (pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value ))
769794 {
770795 return ERR_HEAP_ALLOC ;
771796 }
@@ -781,7 +806,7 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
781806 if (pp2_tlv_aws -> type == PP2_SUBTYPE_AWS_VPCE_ID ) /* US-ASCII */
782807 {
783808 /* Example: \x1vpce-08d2bf15fac5001c9 */
784- if (!tlv_array_append_tlv_new_usascii (& pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value ))
809+ if (!tlv_array_append_tlv_new_usascii (pp_info -> tlv_array , pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value ))
785810 {
786811 return ERR_HEAP_ALLOC ;
787812 }
@@ -799,7 +824,7 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
799824 if (pp2_tlv_azure -> type == PP2_TYPE_AZURE ) /* 32-bit number */
800825 {
801826 tlv_t * tlv = tlv_new (pp2_tlv -> type , pp2_tlv_len , pp2_tlv -> value );
802- if (!tlv || !tlv_array_append_tlv (& pp_info -> tlv_array , tlv ))
827+ if (!tlv || !tlv_array_append_tlv (pp_info -> tlv_array , tlv ))
803828 {
804829 return ERR_HEAP_ALLOC ;
805830 }
@@ -816,7 +841,7 @@ static int32_t ppv2_parse(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
816841 return sizeof (proxy_hdr_v2_t ) + len ;
817842}
818843
819- static int32_t ppv1_parse (const uint8_t * pkt , uint32_t pktlen , pp_info_t * pp_info )
844+ static int32_t pp1_parse_hdr (const uint8_t * pkt , uint32_t pktlen , pp_info_t * pp_info )
820845{
821846 char block [PP1_MAX_LENGHT ] = { 0 };
822847 char * ptr = block ;
@@ -979,11 +1004,11 @@ int32_t pp_parse_hdr(uint8_t *pkt, uint32_t pktlen, pp_info_t *pp_info)
9791004 memset (pp_info , 0 , sizeof (* pp_info ));
9801005 if (pktlen >= 16 && !memcmp (pkt , "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" , 12 ))
9811006 {
982- return ppv2_parse (pkt , pktlen , pp_info );
1007+ return pp2_parse_hdr (pkt , pktlen , pp_info );
9831008 }
9841009 else if (pktlen >= 8 && !memcmp (pkt , "\x50\x52\x4F\x58\x59" , 5 ))
9851010 {
986- return ppv1_parse (pkt , pktlen , pp_info );;
1011+ return pp1_parse_hdr (pkt , pktlen , pp_info );;
9871012 }
9881013 else
9891014 {
0 commit comments