@@ -2797,3 +2797,118 @@ char const *sip_via_port(sip_via_t const *v, int *using_rport)
27972797 else
27982798 return SIP_DEFAULT_SERV ; /* 5060 */
27992799}
2800+
2801+ /**@SIP_HEADER sip_identity Identity Header
2802+ *
2803+ * The Identity header field specifies the "logical" recipient of the
2804+ * request. It is defined in @RFC8224 with semantics shown below,
2805+ * though for now it's parsed to a single 'value' field.
2806+ *
2807+ * @code
2808+ * Identity = "Identity" HCOLON signed-identity-digest SEMI
2809+ * ident-info *( SEMI ident-info-params )
2810+ * signed-identity-digest = 1*(base64-char / ".")
2811+ * ident-info = "info" EQUAL ident-info-uri
2812+ * ident-info-uri = LAQUOT absoluteURI RAQUOT
2813+ * ident-info-params = ident-info-alg / ident-type /
2814+ * ident-info-extension
2815+ * ident-info-alg = "alg" EQUAL token
2816+ * ident-type = "ppt" EQUAL token
2817+ * ident-info-extension = generic-param
2818+ *
2819+ * base64-char = ALPHA / DIGIT / "/" / "+"
2820+ * @endcode
2821+ *
2822+ * The parsed Identity header is stored in #sip_identity_t structure.
2823+ */
2824+
2825+ /**@ingroup sip_identity
2826+ * @typedef typedef struct sip_identity_s sip_identity_t;
2827+ *
2828+ * The structure #sip_identity_t contains representation of @Identity header.
2829+ *
2830+ * The #sip_identity_t is defined as follows:
2831+ * @code
2832+ * typedef struct {
2833+ * sip_common_t id_common[1]; // Common fragment info
2834+ * sip_error_t *id_next; // Link to next (dummy)
2835+ * char const *id_value; // Identity
2836+ * char const *id_info; // Info param containing URL of the cert, with no '<','>'
2837+ * } sip_identity_t;
2838+ * @endcode
2839+ *
2840+ */
2841+
2842+ static msg_xtra_f sip_identity_dup_xtra ;
2843+ static msg_dup_f sip_identity_dup_one ;
2844+ static msg_update_f sip_identity_update ;
2845+
2846+ msg_hclass_t sip_identity_class [] =
2847+ SIP_HEADER_CLASS (identity , "Identity" , "" , id_common , single , identity );
2848+
2849+ issize_t sip_identity_d (su_home_t * home , sip_header_t * h , char * s , isize_t slen )
2850+ {
2851+ sip_identity_t * id = (sip_identity_t * )h ;
2852+ char const * p = NULL , * pp = NULL , * ppp = NULL , * ie = NULL ;
2853+ char * result = NULL ;
2854+ size_t len = 0 ;
2855+
2856+ id -> id_value = strdup (s );
2857+ id -> id_info = NULL ;
2858+
2859+ p = strstr (s , "info=" );
2860+ if (p ) {
2861+
2862+ ie = strchr (p , ';' );
2863+ pp = strchr (p , '<' );
2864+ ppp = strchr (p , '>' );
2865+
2866+ // allow for a spaces between "info=" and opening '<'
2867+ // extract URI from inside "<>" but allow empty - let the higher level app decide what to do about it
2868+ if (ie && pp && ppp && (pp < ppp ) && (ppp < ie )) {
2869+
2870+ len = ppp - pp ;
2871+ if ((result = malloc (len ))) {
2872+ memcpy (result , pp + 1 , len - 1 );
2873+ result [len - 1 ] = '\0' ;
2874+ id -> id_info = result ;
2875+ }
2876+ }
2877+ }
2878+
2879+ return 0 ;
2880+ }
2881+
2882+ issize_t sip_identity_e (char b [], isize_t bsiz , sip_header_t const * h , int flags )
2883+ {
2884+ sip_identity_t const * id = (sip_identity_t * )h ;
2885+
2886+ return snprintf (b , bsiz , "%s" , id -> id_value );
2887+ }
2888+
2889+ isize_t sip_identity_dup_xtra (sip_header_t const * h , isize_t offset )
2890+ {
2891+ sip_identity_t const * id = (sip_identity_t * )h ;
2892+ return offset + MSG_STRING_SIZE (id -> id_value );
2893+ }
2894+
2895+ char * sip_identity_dup_one (sip_header_t * dst , sip_header_t const * src ,
2896+ char * b , isize_t xtra )
2897+ {
2898+ sip_identity_t * id = (sip_identity_t * )dst ;
2899+ sip_identity_t const * o = (sip_identity_t * )src ;
2900+
2901+ MSG_STRING_DUP (b , id -> id_value , o -> id_value );
2902+
2903+ return b ;
2904+ }
2905+
2906+ static int sip_identity_update (msg_common_t * h ,
2907+ char const * name , isize_t namelen ,
2908+ char const * value )
2909+ {
2910+ sip_identity_t * id = (sip_identity_t * )h ;
2911+
2912+ id -> id_value = strdup (value );
2913+ return 0 ;
2914+ }
0 commit comments