From 5aaffb68aefcb56abb2cb3086bd3555a00efdae4 Mon Sep 17 00:00:00 2001 From: Maximilian Fridrich Date: Tue, 2 May 2023 10:00:34 +0200 Subject: [PATCH] uric/contact: fix display name and contact header uri escaping (#762) * uric: fix display name uri escaping In display names, LWS may not be escaped according to RFC 3261 section 25.1. * contact: escape Contact header SIP URI * uri,contact: improve uri escaping of user part * dialog: do not escape display name in FROM header The display name is sent as a quoted-string which must not be escaped. Further, basically all UTF-8 characters are allowed in display names, so not checking it should be fine for almost all cases. * uric: remove unused functions --- include/re_uri.h | 1 + src/sip/contact.c | 12 ++++++++---- src/sip/dialog.c | 4 +--- src/uri/uri.c | 16 ++++++++++++++++ src/uri/uric.c | 40 ---------------------------------------- 5 files changed, 26 insertions(+), 47 deletions(-) diff --git a/include/re_uri.h b/include/re_uri.h index 2843b69e6..c8436bf9d 100644 --- a/include/re_uri.h +++ b/include/re_uri.h @@ -44,6 +44,7 @@ int uri_param_unescape(struct re_printf *pf, const struct pl *pl); int uri_header_escape(struct re_printf *pf, const struct pl *pl); int uri_header_unescape(struct re_printf *pf, const struct pl *pl); int uri_display_name_escape(struct re_printf *pf, const struct pl *pl); +int uri_escape_user(struct re_printf *pf, const char *user); int uri_escape(struct re_printf *pf, const char *uri); int uri_escape_pl(struct re_printf *pf, const struct pl *pl); int uri_unescape_pl(struct re_printf *pf, const struct pl *pl); diff --git a/src/sip/contact.c b/src/sip/contact.c index 670338428..6cb89b08e 100644 --- a/src/sip/contact.c +++ b/src/sip/contact.c @@ -47,11 +47,15 @@ int sip_contact_print(struct re_printf *pf, const struct sip_contact *contact) if (!contact) return 0; - if (contact->uri && strchr(contact->uri, ':')) - return re_hprintf(pf, "Contact: <%s>\r\n", contact->uri); - else - return re_hprintf(pf, "Contact: \r\n", + if (contact->uri && strchr(contact->uri, ':')) { + return re_hprintf(pf, "Contact: <%H>\r\n", uri_escape, + contact->uri); + } + else { + return re_hprintf(pf, "Contact: \r\n", + uri_escape_user, contact->uri, contact->addr, sip_transp_param(contact->tp)); + } } diff --git a/src/sip/dialog.c b/src/sip/dialog.c index ebf009e91..89a9376d1 100644 --- a/src/sip/dialog.c +++ b/src/sip/dialog.c @@ -122,9 +122,7 @@ int sip_dialog_alloc(struct sip_dialog **dlgp, dlg->cpos = dlg->mb->pos; err |= mbuf_printf(dlg->mb, "From: "); if (from_name) { - pl_set_str(&pl, from_name); - err |= mbuf_printf(dlg->mb, "\"%H\" ", uri_display_name_escape, - &pl); + err |= mbuf_printf(dlg->mb, "\"%s\" ", from_name); } err |= mbuf_printf(dlg->mb, "<%H>", uri_escape, from_uri); err |= mbuf_printf(dlg->mb, ";tag=%016llx\r\n", ltag); diff --git a/src/uri/uri.c b/src/uri/uri.c index 6d9375ad4..3858081fe 100644 --- a/src/uri/uri.c +++ b/src/uri/uri.c @@ -271,6 +271,22 @@ int uri_headers_apply(const struct pl *pl, uri_apply_h *ah, void *arg) } +/** + * Escape user part of SIP URI + * + * @param pf Print function to encode into + * @param user User part of SIP URI + * + * @return 0 if success, otherwise errorcode + */ +int uri_escape_user(struct re_printf *pf, const char *user) +{ + struct pl pl; + pl_set_str(&pl, user); + return uri_user_escape(pf, &pl); +} + + static int uri_escape_helper(struct re_printf *pf, const struct pl *pl, bool unescape) { diff --git a/src/uri/uric.c b/src/uri/uric.c index f59e0849a..bb9545ee5 100644 --- a/src/uri/uric.c +++ b/src/uri/uric.c @@ -120,33 +120,6 @@ static bool is_param_unreserved(char c) } -static bool is_token_non_alphanum(int c) -{ - switch (c) { - - case '-': - case '.': - case '!': - case '%': - case '*': - case '_': - case '+': - case '`': - case '\'': - case '~': - return true; - default: - return false; - } -} - - -static bool is_token(char c) -{ - return isalnum((unsigned char)c) || is_token_non_alphanum(c); -} - - static bool is_paramchar(char c) { return is_param_unreserved(c) || is_unreserved(c); @@ -332,16 +305,3 @@ int uri_header_unescape(struct re_printf *pf, const struct pl *pl) return comp_unescape(pf, pl, is_hvalue); } - -/** - * Escape display name - * - * @param pf Print function - * @param pl String to escape - * - * @return 0 if success, otherwise errorcode - */ -int uri_display_name_escape(struct re_printf *pf, const struct pl *pl) -{ - return comp_escape(pf, pl, is_token); -}