]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
auto urlencode user portion of sip uri
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 23 Jan 2015 21:06:16 +0000 (15:06 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Sat, 24 Jan 2015 03:06:02 +0000 (21:06 -0600)
src/include/switch_utils.h
src/mod/endpoints/mod_sofia/mod_sofia.c
src/switch_utils.c

index 523e3a47689e34b4e6488d69807f0130e1156662..395c1b5e16378184b9c92a240e945ffd4018e399 100644 (file)
@@ -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,
index 223bb195b3180d4784783c6db96f2acb85cdec0d..68453edf3494d7c57297d3717ee9eb912b3ed9d7 100644 (file)
@@ -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");
index 444333ec127f2fe6c1e6d57f4f6376d23d6b6eb0..905442e6cea84b82ff130b3240eb1210d4871903 100644 (file)
@@ -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;
                        }