]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-11987: [sofia-sip] Add SIPTAG_IDENTITY_STR and sofia-sip Identity Header handling
authorPiotr Gregor <piotr@dataandsignal.com>
Thu, 1 Aug 2019 20:03:41 +0000 (21:03 +0100)
committerAndrey Volk <andywolk@gmail.com>
Thu, 8 Aug 2019 20:23:43 +0000 (00:23 +0400)
libs/sofia-sip/.update
libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c
libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip.h
libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip_header.h

index 7aefc860d674a06848554617cb461ca84049638d..9c8dbe86549bfaecbf500057211f652f68563bc6 100644 (file)
@@ -1 +1 @@
-Wed Jul 17 14:35:37 EDT 2019
+Thu Aug  8 15:09:57 CDT 2019
index d2e1c0875e72b40ceb559c39cab00d0dcaeeff69..85f4aa2328fd813b121949457567377114427519 100644 (file)
@@ -2797,3 +2797,122 @@ char const *sip_via_port(sip_via_t const *v, int *using_rport)
   else
     return SIP_DEFAULT_SERV;   /* 5060 */
 }
+
+/**@SIP_HEADER sip_identity Identity Header
+ *
+ * The Identity header field specifies the "logical" recipient of the
+ * request. It is defined in @RFC8224 with semantics shown below,
+ * though for now it's parsed to a single 'value' field.
+ *
+ * @code
+ *  Identity = "Identity" HCOLON signed-identity-digest SEMI
+ *                             ident-info *( SEMI ident-info-params )
+ *              signed-identity-digest = 1*(base64-char / ".")
+ *              ident-info = "info" EQUAL ident-info-uri
+ *              ident-info-uri = LAQUOT absoluteURI RAQUOT
+ *              ident-info-params = ident-info-alg / ident-type /
+ *              ident-info-extension
+ *              ident-info-alg = "alg" EQUAL token
+ *              ident-type = "ppt" EQUAL token
+ *              ident-info-extension = generic-param
+ *
+ *              base64-char = ALPHA / DIGIT / "/" / "+"
+ * @endcode
+ *
+ * The parsed Identity header is stored in #sip_identity_t structure.
+ */
+
+/**@ingroup sip_identity
+ * @typedef typedef struct sip_identity_s sip_identity_t;
+ *
+ * The structure #sip_identity_t contains representation of @Identity header.
+ *
+ * The #sip_identity_t is defined as follows:
+ * @code
+ * typedef struct {
+ *   sip_common_t       id_common[1];    // Common fragment info
+ *   sip_error_t               *id_next;        // Link to next (dummy)
+ *   char const                        *id_value;              // Identity
+ *   char const                        *id_info;               // Info param containing URL of the cert, with no '<','>'
+ * } sip_identity_t;
+ * @endcode
+ *
+ */
+
+static msg_xtra_f sip_identity_dup_xtra;
+static msg_dup_f sip_identity_dup_one;
+static msg_update_f sip_identity_update;
+
+msg_hclass_t sip_identity_class[] =
+SIP_HEADER_CLASS(identity, "Identity", "", id_common, single, identity);
+
+issize_t sip_identity_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
+{
+  sip_identity_t *id = (sip_identity_t *)h;
+  char const *p = NULL, *pp = NULL, *ppp = NULL, *ib = NULL, *ie = NULL;
+  size_t len = 0;
+
+  id->id_value = strdup(s);
+  id->id_info = NULL;
+
+  p = strstr(s, "info=");
+  if (p) {
+         ib = p + 5;
+         ie = strchr(p, ';');
+         pp = strchr(p, '<');
+
+         if (!ie) return 0;
+
+         if (pp && pp < ie) {
+
+                 // info= with opening '<'
+                 // must contain closing '>' before ';'
+                 ppp = strchr(pp, '>');
+                 if (!ppp || ppp > ie) {
+                         return 0;
+                 } else {
+                         ib = pp + 1;
+                         ie = ppp - 1;
+                 }
+         }
+
+         len = ie - ib + 1;
+         id->id_info = strndup(ib, len);
+  }
+
+  return 0;
+}
+
+issize_t sip_identity_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
+{
+  sip_identity_t const *id = (sip_identity_t *)h;
+
+  return snprintf(b, bsiz, "%s", id->id_value);
+}
+
+isize_t sip_identity_dup_xtra(sip_header_t const *h, isize_t offset)
+{
+  sip_identity_t const *id = (sip_identity_t *)h;
+  return offset + MSG_STRING_SIZE(id->id_value);
+}
+
+char *sip_identity_dup_one(sip_header_t *dst, sip_header_t const *src,
+                      char *b, isize_t xtra)
+{
+  sip_identity_t *id = (sip_identity_t *)dst;
+  sip_identity_t const *o = (sip_identity_t *)src;
+
+  MSG_STRING_DUP(b, id->id_value, o->id_value);
+
+  return b;
+}
+
+static int sip_identity_update(msg_common_t *h,
+                            char const *name, isize_t namelen,
+                            char const *value)
+{
+  sip_identity_t *id = (sip_identity_t *)h;
+
+  id->id_value = strdup(value);
+  return 0;
+}
index 37ae836598d865e30c2d52f2fb597638eea2b105..aef7baae0f46480dbcd5698898b4e790aa6beb6d 100644 (file)
@@ -215,6 +215,9 @@ typedef msg_list_t                  sip_allow_events_t;
 /* RFC 3323 - @Privacy */
 typedef struct sip_privacy_s sip_privacy_t;
 
+/* SIP Identity Header, e.g. STIR-Shaken SIP Identity Header, RFC 8224 */
+typedef struct sip_identity_s sip_identity_t;
+
 /* RFC 3327 - @Path */
 typedef struct sip_route_s                 sip_path_t;
 
@@ -259,6 +262,7 @@ struct sip_s {
   sip_to_t                 *sip_to;            /**< To (t) */
   sip_call_id_t             *sip_call_id;      /**< Call-ID (i) */
   sip_cseq_t               *sip_cseq;          /**< CSeq */
+  sip_identity_t                   *sip_identity;              /**< Identity */
   sip_contact_t             *sip_contact;      /**< Contact (m) */
   sip_rseq_t                *sip_rseq;          /**< RSeq */
   sip_rack_t                *sip_rack;          /**< RAck */
@@ -474,6 +478,17 @@ struct sip_cseq_s
   char const    *cs_method_name;    /**< Method name */
 };
 
+/**@ingroup sip_identity
+ * @brief Structure for @Identity SIP header.
+ */
+struct sip_identity_s
+{
+  sip_common_t   id_common[1]; /**< Common fragment info */
+  sip_error_t   *id_next;              /**< Link to next (dummy) */
+  char const    *id_value;             /**< Identity text as shown in SIP Header */
+  char const   *id_info;               /**< Info param containing URL of the cert */
+};
+
 /**@ingroup sip_contact
  * @brief Structure for @Contact header field.
  */
@@ -920,6 +935,7 @@ union sip_header_u
 
   sip_separator_t            sh_separator[1];
   sip_payload_t              sh_payload[1];
+  sip_identity_t                       sh_identity[1];
 };
 
 SOFIA_END_DECLS
index 8e212b11f35c103887112f6d39314bf3aeeafa7a..78d6de525de03f97b733c385aa22463cdc5ecdec 100644 (file)
@@ -224,6 +224,10 @@ SOFIAPUBFUN sip_call_id_t *sip_call_id_create(su_home_t *home,
 SOFIAPUBFUN sip_cseq_t *sip_cseq_create(su_home_t *, uint32_t seq,
                                        unsigned method, char const *name);
 
+/** Create a @Identity header object.  */
+SOFIAPUBFUN sip_identity_t *sip_identity_create(su_home_t *, uint32_t seq,
+                                       unsigned method, char const *name);
+
 /** Create a @Contact header object. */
 SOFIAPUBFUN sip_contact_t * sip_contact_create(su_home_t *,
                                               url_string_t const *url,