From 76370f4d1767bb0dcf828a3d6cde6e015b2cfa03 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 23 Jan 2015 15:06:16 -0600 Subject: [PATCH] auto urlencode user portion of sip uri --- src/include/switch_utils.h | 26 +++++++++++++ src/mod/endpoints/mod_sofia/mod_sofia.c | 52 +++++++++++++++++++++++++ src/switch_utils.c | 14 +++++-- 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 523e3a4768..395c1b5e16 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -43,6 +43,9 @@ SWITCH_BEGIN_EXTERN_C +#define SWITCH_URL_UNSAFE "\r\n \"#%&+:;<=>?@[\\]^`{|}" + + /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii http://www.azillionmonkeys.com/qed/asmexample.html */ @@ -971,6 +974,29 @@ SWITCH_DECLARE(char *) switch_util_quote_shell_arg_pool(const char *string, swit #define SWITCH_READ_ACCEPTABLE(status) (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE) + +static inline int switch_needs_url_encode(const char *s) +{ + const char hex[] = "0123456789ABCDEF"; + const char *p, *e = end_of_p(s); + + + for(p = s; p && *p; p++) { + if (*p == '%' && e-p > 1) { + if (strchr(hex, *(p+1)) && strchr(hex, *(p+2))) { + p++; + continue; + } + } + + if (strchr(SWITCH_URL_UNSAFE, *p)) { + return 1; + } + } + + return 0; +} + SWITCH_DECLARE(char *) switch_url_encode(const char *url, char *buf, size_t len); SWITCH_DECLARE(char *) switch_url_decode(char *s); SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 223bb195b3..68453edf34 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4247,6 +4247,54 @@ static switch_status_t sofia_manage(char *relative_oid, switch_management_action return SWITCH_STATUS_SUCCESS; } +static void protect_dest_uri(switch_caller_profile_t *cp) +{ + char *p = cp->destination_number, *o = p; + char *q = NULL, *e = NULL, *qenc = NULL; + switch_size_t enclen = 0; + + while((p = strchr(p, '/'))) { + q = p++; + } + + if (q) { + const char *i; + int go = 0; + + for (i = q+1; i && *i && *i != '@'; i++) { + if (strchr(SWITCH_URL_UNSAFE, *i)) { + go = 1; + } + } + + if (!go) return; + + *q++ = '\0'; + } else { + return; + } + + if (!strncasecmp(q, "sips:", 5)) { + q += 5; + } else if (!strncasecmp(q, "sip:", 4)) { + q += 4; + } + + if (!(e = strchr(q, '@'))) { + return; + } + + *e++ = '\0'; + + if (switch_needs_url_encode(q)) { + enclen = (strlen(q) * 2) + 2; + qenc = switch_core_alloc(cp->pool, enclen); + switch_url_encode(q, qenc, enclen); + } + + cp->destination_number = switch_core_sprintf(cp->pool, "%s/%s@%s", o, qenc ? qenc : q, e); +} + static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) @@ -4272,6 +4320,10 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session goto error; } + if (!switch_true(switch_event_get_header(var_event, "sofia_suppress_url_encoding"))) { + protect_dest_uri(outbound_profile); + } + if (!(nsession = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid")))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n"); diff --git a/src/switch_utils.c b/src/switch_utils.c index 444333ec12..905442e6ce 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -2923,9 +2923,8 @@ SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms) SWITCH_DECLARE(char *) switch_url_encode(const char *url, char *buf, size_t len) { - const char *p; + const char *p, *e = end_of_p(url); size_t x = 0; - const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}"; const char hex[] = "0123456789ABCDEF"; if (!buf) { @@ -2939,10 +2938,19 @@ SWITCH_DECLARE(char *) switch_url_encode(const char *url, char *buf, size_t len) len--; for (p = url; *p; p++) { + int ok = 0; + if (x >= len) { break; } - if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) { + + if (*p == '%' && e-p > 1) { + if (strchr(hex, *(p+1)) && strchr(hex, *(p+2))) { + ok = 1; + } + } + + if (!ok && (*p < ' ' || *p > '~' || strchr(SWITCH_URL_UNSAFE, *p))) { if ((x + 3) > len) { break; }