From 46c1b4217cccbfbcd7db421438e875870c55bcd3 Mon Sep 17 00:00:00 2001
From: Luis Azedo <luis@2600hz.com>
Date: Fri, 20 Oct 2017 14:59:09 +0100
Subject: [PATCH 1/4] FS-10746 [mod_sofia] allow authoritative proxy to provide
 token

---
 src/mod/endpoints/mod_sofia/mod_sofia.h |  1 +
 src/mod/endpoints/mod_sofia/sofia.c     | 78 ++++++++++++++++---------
 2 files changed, 50 insertions(+), 29 deletions(-)

diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 46d215a2d5..929fc60db6 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -309,6 +309,7 @@ typedef enum {
 	PFLAG_FIRE_BYE_RESPONSE_EVENTS,
 	PFLAG_AUTO_INVITE_100,
 	PFLAG_UPDATE_REFRESHER,
+	PFLAG_AUTH_REQUIRE_USER,
 
 	/* No new flags below this line */
 	PFLAG_MAX
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 617446e983..cccd6bde80 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -4591,6 +4591,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
 					sofia_clear_pflag(profile, PFLAG_MAKE_EVERY_TRANSFER_A_NIGHTMARE);
 					sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS);
 					sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
+					sofia_clear_pflag(profile, PFLAG_AUTH_REQUIRE_USER);
 					profile->shutdown_type = "false";
 					profile->local_network = "localnet.auto";
 					sofia_set_flag(profile, TFLAG_ENABLE_SOA);
@@ -5486,6 +5487,12 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
 						profile->nonce_ttl = atoi(val);
 					} else if (!strcasecmp(var, "max-auth-validity") && !zstr(val)) {
 						profile->max_auth_validity = atoi(val);
+					} else if (!strcasecmp(var, "auth-require-user")) {
+						if (switch_true(val)) {
+							sofia_set_pflag(profile, PFLAG_AUTH_REQUIRE_USER);
+						} else {
+							sofia_clear_pflag(profile, PFLAG_AUTH_REQUIRE_USER);
+						}
 					} else if (!strcasecmp(var, "accept-blind-reg")) {
 						if (switch_true(val)) {
 							sofia_set_pflag(profile, PFLAG_BLIND_REG);
@@ -10232,54 +10239,57 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 			 * ip header and see if it matches against the inbound acl
 			 */
 			if (network_ip_is_proxy) {
+				const char * x_auth_ip = sofia_glue_get_unknown_header(sip, "X-AUTH-IP");
+				const char * x_auth_token = sofia_glue_get_unknown_header(sip, "X-AUTH-Token");
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "network ip is a proxy\n");
 
-				for (un = sip->sip_unknown; un; un = un->un_next) {
-					if (!strcasecmp(un->un_name, "X-AUTH-IP")) {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found auth ip [%s] header of [%s]\n", un->un_name, un->un_value);
-						if (!zstr(un->un_value)) {
-							for (x = 0; x < profile->acl_count; x++) {
-								last_acl = profile->acl[x];
-								if ((ok = switch_check_network_list_ip_token(un->un_value, last_acl, &token))) {
-									switch_copy_string(proxied_client_ip, un->un_value, sizeof(proxied_client_ip));
-									break;
-								}
-							}
+				if (!zstr(x_auth_token) && !zstr(x_auth_ip)) {
+					switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
+					token = x_auth_token;
+					ok = 1;
+				} else if (!zstr(x_auth_ip)) {
+					for (x = 0; x < profile->acl_count; x++) {
+						last_acl = profile->acl[x];
+						if ((ok = switch_check_network_list_ip_token(x_auth_ip, last_acl, &token))) {
+							switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
+							break;
 						}
 					}
 				}
-			}
 
-			if (!ok) {
-
-				if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
-					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", network_ip, switch_str_nil(last_acl));
-
-					if (!acl_context) {
+				if (!ok) {
+					if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", x_auth_ip, switch_str_nil(last_acl));
 						nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
 						goto fail;
+					} else {
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
+										  x_auth_ip, switch_str_nil(last_acl));
 					}
 				} else {
-					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
-									  network_ip, switch_str_nil(last_acl));
-				}
-			} else {
-				if (token) {
-					switch_set_string(acl_token, token);
-				}
-				if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
+					if (token) {
+						switch_set_string(acl_token, token);
+					}
 					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
 									  proxied_client_ip, switch_str_nil(last_acl), acl_token);
 					switch_set_string(sip_acl_authed_by, last_acl);
 					switch_set_string(sip_acl_token, acl_token);
-
 					is_auth = 1;
-
+				}
+			} else {
+				if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", network_ip, switch_str_nil(last_acl));
+					nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
+					goto fail;
+				} else {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
+									  network_ip, switch_str_nil(last_acl));
 				}
 			}
 		}
 	}
 
+
 	if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS) && sofia_test_pflag(profile, PFLAG_BLIND_AUTH)) {
 		char *user;
 		switch_status_t blind_result = SWITCH_STATUS_FALSE;
@@ -10343,10 +10353,20 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 	if (*acl_token) {
 		switch_channel_set_variable(channel, "acl_token", acl_token);
 		if (strchr(acl_token, '@')) {
-			if (switch_ivr_set_user(session, acl_token) == SWITCH_STATUS_SUCCESS) {
+			switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS);
+			for (un = sip->sip_unknown; un; un = un->un_next) {
+				switch_event_add_header_string(v_event, SWITCH_STACK_BOTTOM, un->un_name, un->un_value);
+			};
+			if (switch_ivr_set_user_extended(session, acl_token, v_event) == SWITCH_STATUS_SUCCESS) {
+				switch_event_destroy(&v_event);
 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Authenticating user %s\n", acl_token);
 			} else {
+				switch_event_destroy(&v_event);
 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Error Authenticating user %s\n", acl_token);
+				if(sofia_test_pflag(profile, PFLAG_AUTH_REQUIRE_USER)) {
+					nua_respond(nh, SIP_480_TEMPORARILY_UNAVAILABLE, TAG_END());
+					goto fail;
+				}
 			}
 		}
 	}

From 60956d7f85412d120642c1fded9a975bc7bbe4dd Mon Sep 17 00:00:00 2001
From: Luis Azedo <luis@2600hz.com>
Date: Tue, 13 Mar 2018 19:41:45 +0000
Subject: [PATCH 2/4] FS-11025 [core] allow/check ports in network lists

---
 src/include/switch_core.h  |   1 +
 src/include/switch_utils.h |  16 ++++++
 src/switch_core.c          |  44 +++++++++++----
 src/switch_utils.c         | 106 ++++++++++++++++++++++++++++++++-----
 4 files changed, 146 insertions(+), 21 deletions(-)

diff --git a/src/include/switch_core.h b/src/include/switch_core.h
index 526fe26323..7631fc287f 100644
--- a/src/include/switch_core.h
+++ b/src/include/switch_core.h
@@ -2427,6 +2427,7 @@ SWITCH_DECLARE(const char *) switch_lookup_timezone(const char *tz_name);
 SWITCH_DECLARE(switch_status_t) switch_strftime_tz(const char *tz, const char *format, char *date, size_t len, switch_time_t thetime);
 SWITCH_DECLARE(switch_status_t) switch_time_exp_tz_name(const char *tz, switch_time_exp_t *tm, switch_time_t thetime);
 SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload);
+SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_port_token(const char *ip_str, int port, const char *list_name, const char **token);
 SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token);
 #define switch_check_network_list_ip(_ip_str, _list_name) switch_check_network_list_ip_token(_ip_str, _list_name, NULL)
 SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable);
diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h
index 10242525f1..62ec7c8d41 100644
--- a/src/include/switch_utils.h
+++ b/src/include/switch_utils.h
@@ -46,6 +46,16 @@ SWITCH_BEGIN_EXTERN_C
 
 #define SWITCH_URL_UNSAFE "\r\n #%&+:;<=>?@[\\]^`{|}\""
 
+#define MAX_NETWORK_PORTS 10
+
+struct switch_network_port_range {
+	int port;
+	int ports[MAX_NETWORK_PORTS];
+	int min_port;
+	int max_port;
+};
+typedef struct switch_network_port_range switch_network_port_range_t;
+typedef switch_network_port_range_t* switch_network_port_range_p;
 
 static inline char *switch_get_hex_bytes(switch_byte_t *buf, switch_size_t datalen, char *new_buf, switch_size_t new_datalen)
 {
@@ -1270,6 +1280,12 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_networ
 
 SWITCH_DECLARE(char *) switch_network_ipv4_mapped_ipv6_addr(const char* ip_str);
 SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok);
+
+SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_port_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token, switch_network_port_range_p port);
+SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_port_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok, switch_network_port_range_p port);
+
+SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_port_token(switch_network_list_t *list, uint32_t ip, int port, const char **token);
+SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_port_token(switch_network_list_t *list, ip_t ip, int port, const char **token);
 SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_network_list_t *list, uint32_t ip, const char **token);
 SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_token(switch_network_list_t *list, ip_t ip, const char **token);
 #define switch_network_list_validate_ip(_list, _ip) switch_network_list_validate_ip_token(_list, _ip, NULL);
diff --git a/src/switch_core.c b/src/switch_core.c
index 596ef2bbe4..0fb040fbbd 100644
--- a/src/switch_core.c
+++ b/src/switch_core.c
@@ -1370,7 +1370,7 @@ typedef struct {
 
 static switch_ip_list_t IP_LIST = { 0 };
 
-SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)
+SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_port_token(const char *ip_str, int port, const char *list_name, const char **token)
 {
 	switch_network_list_t *list;
 	ip_t  ip, mask, net;
@@ -1398,9 +1398,9 @@ SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_
 
 	if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {
 		if (ipv6) {
-			ok = switch_network_list_validate_ip6_token(list, ip, token);
+			ok = switch_network_list_validate_ip6_port_token(list, ip, port, token);
 		} else {
-			ok = switch_network_list_validate_ip_token(list, ip.v4, token);
+			ok = switch_network_list_validate_ip_port_token(list, ip.v4, port, token);
 		}
 	} else if (strchr(list_name, '/')) {
 		if (strchr(list_name, ',')) {
@@ -1443,6 +1443,10 @@ SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_
 	return ok;
 }
 
+SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)
+{
+	return switch_check_network_list_ip_port_token(ip_str, 0, list_name, token);
+}
 
 SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
 {
@@ -1589,9 +1593,12 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
 
 
 				for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) {
-					const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL;
+					const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL, *port = NULL;
 					switch_bool_t ok = default_type;
 					const char *type = switch_xml_attr(x_node, "type");
+					switch_network_port_range_t port_range;
+					char *argv[MAX_NETWORK_PORTS] = { 0 };
+					int argc = 0, i;
 
 					if (type) {
 						ok = switch_true(type);
@@ -1602,6 +1609,25 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
 					mask = switch_xml_attr(x_node, "mask");
 					domain = switch_xml_attr(x_node, "domain");
 
+					memset(&port_range, 0, sizeof(switch_network_port_range_t));
+
+					if( (port = switch_xml_attr(x_node, "port")) != NULL) {
+						port_range.port = atoi(port);
+					}
+
+					if( (port = switch_xml_attr(x_node, "ports")) != NULL) {
+						argc = switch_separate_string((char*)port, ',', argv, (sizeof(argv) / sizeof(argv[0])));
+						for(i=0; i < argc; i++) {
+							port_range.ports[i] = atoi(argv[i]);
+						}
+					}
+					if( (port = switch_xml_attr(x_node, "port-min")) != NULL) {
+						port_range.min_port = atoi(port);
+					}
+					if( (port = switch_xml_attr(x_node, "port-max")) != NULL) {
+						port_range.max_port = atoi(port);
+					}
+
 					if (domain) {
 						switch_event_t *my_params = NULL;
 						switch_xml_t x_domain, xml_root;
@@ -1646,7 +1672,7 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
 										if (id && user_cidr) {
 											char *token = switch_mprintf("%s@%s", id, domain);
 											switch_assert(token);
-											switch_network_list_add_cidr_token(list, user_cidr, ok, token);
+											switch_network_list_add_cidr_port_token(list, user_cidr, ok, token, &port_range);
 											free(token);
 										}
 									}
@@ -1656,13 +1682,13 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
 
 						switch_xml_free(xml_root);
 					} else if (cidr) {
-						switch_network_list_add_cidr(list, cidr, ok);
+						switch_network_list_add_cidr_port_token(list, cidr, ok, NULL, &port_range);
 					} else if (host && mask) {
-						switch_network_list_add_host_mask(list, host, mask, ok);
+						switch_network_list_add_host_port_mask(list, host, mask, ok, &port_range);
 					}
-
-					switch_core_hash_insert(IP_LIST.hash, name, list);
 				}
+
+				switch_core_hash_insert(IP_LIST.hash, name, list);
 			}
 		}
 
diff --git a/src/switch_utils.c b/src/switch_utils.c
index 52ec8f6327..2ac0a0e415 100644
--- a/src/switch_utils.c
+++ b/src/switch_utils.c
@@ -54,6 +54,7 @@ struct switch_network_node {
 	switch_bool_t ok;
 	char *token;
 	char *str;
+	switch_network_port_range_t port_range;
 	struct switch_network_node *next;
 };
 typedef struct switch_network_node switch_network_node_t;
@@ -467,7 +468,8 @@ SWITCH_DECLARE(switch_bool_t) switch_testv6_subnet(ip_t _ip, ip_t _net, ip_t _ma
 			else return SWITCH_TRUE;
 		}
 }
-SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_token(switch_network_list_t *list, ip_t ip, const char **token)
+
+SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_port_token(switch_network_list_t *list, ip_t ip, int port, const char **token)
 {
 	switch_network_node_t *node;
 	switch_bool_t ok = list->default_type;
@@ -494,7 +496,29 @@ SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_token(switch_netw
 	return ok;
 }
 
-SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_network_list_t *list, uint32_t ip, const char **token)
+SWITCH_DECLARE(switch_bool_t) is_port_in_node(int port, switch_network_node_t *node)
+{
+	if(port == 0)
+		return SWITCH_TRUE;
+	if(node->port_range.port != 0 && node->port_range.port != port)
+		return SWITCH_FALSE;
+	if(node->port_range.ports[0] != 0) {
+		int i;
+		for(i=0; i < MAX_NETWORK_PORTS && node->port_range.ports[i] != 0; i++) {
+			if(port == node->port_range.ports[i])
+				return SWITCH_TRUE;
+		}
+		return SWITCH_FALSE;
+	}
+	if(node->port_range.min_port != 0 || node->port_range.max_port != 0) {
+		if(port >= node->port_range.min_port && port <= node->port_range.max_port)
+			return SWITCH_TRUE;
+		return SWITCH_FALSE;
+	}
+	return SWITCH_TRUE;
+}
+
+SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_port_token(switch_network_list_t *list, uint32_t ip, int port, const char **token)
 {
 	switch_network_node_t *node;
 	switch_bool_t ok = list->default_type;
@@ -502,7 +526,7 @@ SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_netwo
 
 	for (node = list->node_head; node; node = node->next) {
 		if (node->family == AF_INET6) continue; /* want AF_INET */
-		if (node->bits >= bits && switch_test_subnet(ip, node->ip.v4, node->mask.v4)) {
+		if (node->bits >= bits && switch_test_subnet(ip, node->ip.v4, node->mask.v4) && is_port_in_node(port, node)) {
 			if (node->ok) {
 				ok = SWITCH_TRUE;
 			} else {
@@ -520,6 +544,16 @@ SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_netwo
 	return ok;
 }
 
+SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_token(switch_network_list_t *list, ip_t ip, const char **token)
+{
+	return switch_network_list_validate_ip6_port_token(list, ip, 0, token);
+}
+
+SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_network_list_t *list, uint32_t ip, const char **token)
+{
+	return switch_network_list_validate_ip_port_token(list, ip, 0, token);
+}
+
 SWITCH_DECLARE(char *) switch_network_ipv4_mapped_ipv6_addr(const char* ip_str)
 {
 	/* ipv4 mapped ipv6 address */
@@ -531,22 +565,52 @@ SWITCH_DECLARE(char *) switch_network_ipv4_mapped_ipv6_addr(const char* ip_str)
 	return strdup(ip_str + 7);
 }
 
+SWITCH_DECLARE(char*) switch_network_port_range_to_string(switch_network_port_range_p port)
+{
+	if (!port) {
+		return NULL;
+	}
+
+	if (port->port != 0) {
+		return switch_mprintf("port: %i ", port->port);
+	}
+
+	if (port->ports[0] != 0) {
+		int i, written = 0;
+		char buf[MAX_NETWORK_PORTS * 6];
+	    for (i = 0; i < MAX_NETWORK_PORTS && port->ports[i] != 0; i++) {
+	    	written += snprintf(buf + written, sizeof(buf) - written, (i != 0 ? ", %u" : "%u"), port->ports[i]);
+	    }
+		return switch_mprintf("ports: [%s] ", buf);
+	}
+
+	if (port->min_port != 0 || port->max_port != 0) {
+		return switch_mprintf("port range: [%i-%i] ", port->min_port, port->max_port);
+	}
+
+	return NULL;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_network_list_perform_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok,
-																		   const char *token)
+																		   const char *token, switch_network_port_range_p port)
 {
 	ip_t ip, mask;
 	uint32_t bits;
 	switch_network_node_t *node;
 	char *ipv4 = NULL;
+	char *ports = NULL;
 
 	if ((ipv4 = switch_network_ipv4_mapped_ipv6_addr(cidr_str))) {
 		cidr_str = ipv4;
 	}
 
+	ports = switch_network_port_range_to_string(port);
+
 	if (switch_parse_cidr(cidr_str, &ip, &mask, &bits)) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Adding %s (%s) [%s] to list %s\n",
-						  cidr_str, ok ? "allow" : "deny", switch_str_nil(token), list->name);
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Adding %s %s(%s) [%s] to list %s\n",
+						  cidr_str, ports ? ports : "", ok ? "allow" : "deny", switch_str_nil(token), list->name);
 		switch_safe_free(ipv4);
+		switch_safe_free(ports);
 		return SWITCH_STATUS_GENERR;
 	}
 
@@ -557,6 +621,10 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_perform_add_cidr_token(switc
 	node->ok = ok;
 	node->bits = bits;
 	node->str = switch_core_strdup(list->pool, cidr_str);
+	if(port) {
+		memcpy(&node->port_range, port, sizeof(switch_network_port_range_t));
+	}
+
 
 	if (strchr(cidr_str,':')) {
 		node->family = AF_INET6;
@@ -571,14 +639,15 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_perform_add_cidr_token(switc
 	node->next = list->node_head;
 	list->node_head = node;
 
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) [%s] to list %s\n",
-					  cidr_str, ok ? "allow" : "deny", switch_str_nil(token), list->name);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s %s(%s) [%s] to list %s\n",
+					  cidr_str, ports ? ports : "", ok ? "allow" : "deny", switch_str_nil(token), list->name);
 
 	switch_safe_free(ipv4);
+	switch_safe_free(ports);
 	return SWITCH_STATUS_SUCCESS;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token)
+SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_port_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token, switch_network_port_range_p port)
 {
 	char *cidr_str_dup = NULL;
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
@@ -592,20 +661,25 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_networ
 		if ((argc = switch_separate_string(cidr_str_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
 			for (i = 0; i < argc; i++) {
 				switch_status_t this_status;
-				if ((this_status = switch_network_list_perform_add_cidr_token(list, argv[i], ok, token)) != SWITCH_STATUS_SUCCESS) {
+				if ((this_status = switch_network_list_perform_add_cidr_token(list, argv[i], ok, token, port)) != SWITCH_STATUS_SUCCESS) {
 					status = this_status;
 				}
 			}
 		}
 	} else {
-		status = switch_network_list_perform_add_cidr_token(list, cidr_str, ok, token);
+		status = switch_network_list_perform_add_cidr_token(list, cidr_str, ok, token, port);
 	}
 
 	switch_safe_free(cidr_str_dup);
 	return status;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok)
+SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token)
+{
+	return switch_network_list_add_cidr_port_token(list, cidr_str, ok, token, NULL);
+}
+
+SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_port_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok, switch_network_port_range_p port)
 {
 	ip_t ip, mask;
 	switch_network_node_t *node;
@@ -618,6 +692,9 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network
 	node->ip.v4 = ntohl(ip.v4);
 	node->mask.v4 = ntohl(mask.v4);
 	node->ok = ok;
+	if(port) {
+		memcpy(&node->port_range, port, sizeof(switch_network_port_range_t));
+	}
 
 	/* http://graphics.stanford.edu/~seander/bithacks.html */
 	mask.v4 = mask.v4 - ((mask.v4 >> 1) & 0x55555555);
@@ -632,6 +709,11 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network
 	return SWITCH_STATUS_SUCCESS;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok)
+{
+	return switch_network_list_add_host_port_mask(list, host, mask_str, ok, NULL);
+}
+
 
 SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, uint32_t *bitp)
 {

From 254b739b96abaec50a0cfaf9d06955b9e0c26390 Mon Sep 17 00:00:00 2001
From: Luis Azedo <luis@2600hz.com>
Date: Tue, 13 Mar 2018 19:59:41 +0000
Subject: [PATCH 3/4] FS-11025 [mod_sofia] use ports for acl check

* optionally use port for acl check
* optionally lookup acl token from header
* optionally processed auth only by acl
---
 src/mod/endpoints/mod_sofia/mod_sofia.h |   4 +
 src/mod/endpoints/mod_sofia/sofia.c     | 138 ++++++++++++++++--------
 2 files changed, 100 insertions(+), 42 deletions(-)

diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 929fc60db6..f008335338 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -310,6 +310,8 @@ typedef enum {
 	PFLAG_AUTO_INVITE_100,
 	PFLAG_UPDATE_REFRESHER,
 	PFLAG_AUTH_REQUIRE_USER,
+	PFLAG_AUTH_CALLS_ACL_ONLY,
+	PFLAG_USE_PORT_FOR_ACL_CHECK,
 
 	/* No new flags below this line */
 	PFLAG_MAX
@@ -787,6 +789,8 @@ struct sofia_profile {
 	int bind_attempt_interval;
 	char *proxy_notify_events;
 	char *proxy_info_content_types;
+	char *acl_inbound_x_token_header;
+	char *acl_proxy_x_token_header;
 };
 
 
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index cccd6bde80..48a43ef5b7 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -4592,6 +4592,8 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
 					sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS);
 					sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
 					sofia_clear_pflag(profile, PFLAG_AUTH_REQUIRE_USER);
+					sofia_clear_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY);
+					sofia_clear_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK);
 					profile->shutdown_type = "false";
 					profile->local_network = "localnet.auto";
 					sofia_set_flag(profile, TFLAG_ENABLE_SOA);
@@ -5908,6 +5910,22 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
 						}  else {
 							sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
 						}
+					} else if (!strcasecmp(var, "auth-calls-acl-only")) {
+						if(switch_true(val)) {
+							sofia_set_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY);
+						}  else {
+							sofia_clear_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY);
+						}
+					} else if (!strcasecmp(var, "use-port-for-acl-check")) {
+						if(switch_true(val)) {
+							sofia_set_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK);
+						}  else {
+							sofia_clear_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK);
+						}
+					} else if (!strcasecmp(var, "apply-inbound-acl-x-token")) {
+						profile->acl_inbound_x_token_header = switch_core_strdup(profile->pool, val);
+					} else if (!strcasecmp(var, "apply-proxy-acl-x-token")) {
+						profile->acl_proxy_x_token_header = switch_core_strdup(profile->pool, val);
 					} else if (!strcasecmp(var, "proxy-hold")) {
 						if(switch_true(val)) {
 							sofia_set_pflag(profile, PFLAG_PROXY_HOLD);
@@ -10188,14 +10206,23 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 		int ok = 1;
 		char *last_acl = NULL;
 		const char *token = NULL;
+		int acl_port = sofia_test_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK) ? network_port : 0;
 
 		for (x = 0; x < profile->acl_count; x++) {
 			last_acl = profile->acl[x];
-			if ((ok = switch_check_network_list_ip_token(network_ip, last_acl, &token))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "verifying acl \"%s\" for ip/port %s:%i.\n",
+							  switch_str_nil(last_acl), network_ip, acl_port);
+			if ((ok = switch_check_network_list_ip_port_token(network_ip, acl_port, last_acl, &token))) {
 
 				if (profile->acl_pass_context[x]) {
 					acl_context = profile->acl_pass_context[x];
 				}
+				if(!token && profile->acl_inbound_x_token_header) {
+					const char * x_auth_token = sofia_glue_get_unknown_header(sip, profile->acl_inbound_x_token_header);
+					if (!zstr(x_auth_token)) {
+						token = x_auth_token;
+					}
+				}
 
 				break;
 			}
@@ -10220,76 +10247,103 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 			}
 		} else {
 			int network_ip_is_proxy = 0;
+			const char* x_auth_ip = network_ip;
 			/* Check if network_ip is a proxy allowed to send us calls */
 			if (profile->proxy_acl_count) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%d acls to check for proxy\n", profile->proxy_acl_count);
-			}
-
-			for (x = 0; x < profile->proxy_acl_count; x++) {
-				last_acl = profile->proxy_acl[x];
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "checking %s against acl %s\n", network_ip, last_acl);
-				if (switch_check_network_list_ip_token(network_ip, last_acl, &token)) {
-					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s is a proxy according to the %s acl\n", network_ip, last_acl);
-					network_ip_is_proxy = 1;
-					break;
+				for (x = 0; x < profile->proxy_acl_count; x++) {
+					last_acl = profile->proxy_acl[x];
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "checking %s against acl %s\n", network_ip, last_acl);
+					if (switch_check_network_list_ip_port_token(network_ip, network_port, last_acl, &token)) {
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s is a proxy according to the %s acl\n", network_ip, last_acl);
+						network_ip_is_proxy = 1;
+						break;
+					}
 				}
 			}
+
 			/*
 			 * if network_ip is a proxy allowed to send calls, check for auth
 			 * ip header and see if it matches against the inbound acl
 			 */
 			if (network_ip_is_proxy) {
-				const char * x_auth_ip = sofia_glue_get_unknown_header(sip, "X-AUTH-IP");
-				const char * x_auth_token = sofia_glue_get_unknown_header(sip, "X-AUTH-Token");
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "network ip is a proxy\n");
+				const char * x_auth_port = sofia_glue_get_unknown_header(sip, "X-AUTH-PORT");
+				int x_auth_port_i = sofia_test_pflag(profile, PFLAG_USE_PORT_FOR_ACL_CHECK) ? zstr(x_auth_port) ? 0 : atoi(x_auth_port) : 0;
 
-				if (!zstr(x_auth_token) && !zstr(x_auth_ip)) {
-					switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
-					token = x_auth_token;
-					ok = 1;
-				} else if (!zstr(x_auth_ip)) {
-					for (x = 0; x < profile->acl_count; x++) {
-						last_acl = profile->acl[x];
-						if ((ok = switch_check_network_list_ip_token(x_auth_ip, last_acl, &token))) {
-							switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
-							break;
-						}
+				/*
+				 * if network_ip is a proxy allowed to send calls,
+				 * authorize call if proxy provided matched token header
+				 */
+				if (profile->acl_proxy_x_token_header) {
+					const char * x_auth_token = sofia_glue_get_unknown_header(sip, profile->acl_proxy_x_token_header);
+					if (!zstr(x_auth_token)) {
+						token = x_auth_token;
+						switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
+						ok = 1;
 					}
 				}
 
-				if (!ok) {
-					if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", x_auth_ip, switch_str_nil(last_acl));
-						nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
-						goto fail;
-					} else {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
-										  x_auth_ip, switch_str_nil(last_acl));
+				if (!ok && (x_auth_ip = sofia_glue_get_unknown_header(sip, "X-AUTH-IP")) && !zstr(x_auth_ip)) {
+					for (x = 0; x < profile->acl_count; x++) {
+						last_acl = profile->acl[x];
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "verifying acl \"%s\" from proxy for ip/port %s:%i.\n",
+										  switch_str_nil(last_acl), x_auth_ip, x_auth_port_i);
+						if ((ok = switch_check_network_list_ip_port_token(x_auth_ip, x_auth_port_i, last_acl, &token))) {
+
+							switch_copy_string(proxied_client_ip, x_auth_ip, sizeof(proxied_client_ip));
+
+							if (profile->acl_pass_context[x]) {
+								acl_context = profile->acl_pass_context[x];
+							}
+
+							break;
+						}
+
+						if (profile->acl_fail_context[x]) {
+							acl_context = profile->acl_fail_context[x];
+						} else {
+							acl_context = NULL;
+						}
 					}
 				} else {
-					if (token) {
-						switch_set_string(acl_token, token);
-					}
+					x_auth_ip = network_ip;
+				}
+			}
+
+			if (ok) {
+				if (token) {
+					switch_set_string(acl_token, token);
+				}
+				if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
 					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n",
-									  proxied_client_ip, switch_str_nil(last_acl), acl_token);
+					                  x_auth_ip, switch_str_nil(last_acl), acl_token);
 					switch_set_string(sip_acl_authed_by, last_acl);
 					switch_set_string(sip_acl_token, acl_token);
 					is_auth = 1;
 				}
 			} else {
 				if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) {
-					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", network_ip, switch_str_nil(last_acl));
-					nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
-					goto fail;
-				} else {
-					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
-									  network_ip, switch_str_nil(last_acl));
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", x_auth_ip, switch_str_nil(last_acl));
+					if (!acl_context) {
+						nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
+						goto fail;
+					} else {
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n",
+										  x_auth_ip, switch_str_nil(last_acl));
+					}
 				}
 			}
 		}
 	}
 
 
+	if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS) && sofia_test_pflag(profile, PFLAG_AUTH_CALLS_ACL_ONLY)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP/Port %s %i Rejected by acls and auth-calls-acl-only flag is set, rejecting call\n",
+						  network_ip, network_port);
+		nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
+		goto fail;
+	}
+
 	if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS) && sofia_test_pflag(profile, PFLAG_BLIND_AUTH)) {
 		char *user;
 		switch_status_t blind_result = SWITCH_STATUS_FALSE;

From 6ceb9885d4bd10763b982255af732e3e6a8936ee Mon Sep 17 00:00:00 2001
From: lazedo <luis.azedo@factorlusitano.com>
Date: Tue, 5 Mar 2019 12:14:45 +0000
Subject: [PATCH 4/4] FS-9956 [mod_sofia] retain user lookup in blind & acl
 auth

* retains lookup to be used after caller context is created and
switch_ivr_set_user_xml is called
---
 src/mod/endpoints/mod_sofia/sofia.c | 77 ++++++++++++++++++++---------
 1 file changed, 54 insertions(+), 23 deletions(-)

diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 48a43ef5b7..bf21a353ab 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -10017,6 +10017,46 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
 
 }
 
+switch_status_t sofia_locate_user(char* user, switch_core_session_t *session, sip_t const *sip, switch_xml_t* x_user)
+{
+	char *username, *domain;
+	switch_event_t *v_event = NULL;
+	switch_status_t result = SWITCH_STATUS_FALSE;
+
+	if (!session) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (zstr(user)) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (!(username = switch_core_session_strdup(session, user))) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (!(domain = strchr(username, '@'))) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	*domain++ = '\0';
+
+	if (switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS) == SWITCH_STATUS_SUCCESS) {
+		sip_unknown_t *un;
+		for (un = sip->sip_unknown; un; un = un->un_next) {
+			switch_event_add_header_string(v_event, SWITCH_STACK_BOTTOM, un->un_name, un->un_value);
+		};
+	}
+
+	result = switch_xml_locate_user_merged("id", username, domain, NULL, x_user, v_event);
+
+	if (v_event) {
+		switch_event_destroy(&v_event);
+	}
+
+	return result;
+}
+
 void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, sofia_dispatch_event_t *de, tagi_t tags[])
 {
 	char key[128] = "";
@@ -10345,7 +10385,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 	}
 
 	if (!is_auth && sofia_test_pflag(profile, PFLAG_AUTH_CALLS) && sofia_test_pflag(profile, PFLAG_BLIND_AUTH)) {
-		char *user;
+		char *user = NULL;
 		switch_status_t blind_result = SWITCH_STATUS_FALSE;
 
 		if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
@@ -10354,15 +10394,14 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 
 		if (sip && sip->sip_from) {
 			user = switch_core_session_sprintf(session, "%s@%s", sip->sip_from->a_url->url_user, sip->sip_from->a_url->url_host);
-			switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS);
-			for (un = sip->sip_unknown; un; un = un->un_next) {
-				switch_event_add_header_string(v_event, SWITCH_STACK_BOTTOM, un->un_name, un->un_value);
-			};
-			blind_result = switch_ivr_set_user_extended(session, user, v_event);
-			switch_event_destroy(&v_event);
+			blind_result = sofia_locate_user(user, session, sip, &x_user);
 		}
-		if(!sofia_test_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT) || blind_result == SWITCH_STATUS_SUCCESS) {
+		if (!sofia_test_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT) || blind_result == SWITCH_STATUS_SUCCESS) {
 			is_auth++;
+		} else if (sofia_test_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT)) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "blind auth enforce result enabled and couldn't find user %s, rejecting call\n", user);
+			nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
+			goto fail;
 		}
 	}
 
@@ -10406,21 +10445,13 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
 
 	if (*acl_token) {
 		switch_channel_set_variable(channel, "acl_token", acl_token);
-		if (strchr(acl_token, '@')) {
-			switch_event_create(&v_event, SWITCH_EVENT_REQUEST_PARAMS);
-			for (un = sip->sip_unknown; un; un = un->un_next) {
-				switch_event_add_header_string(v_event, SWITCH_STACK_BOTTOM, un->un_name, un->un_value);
-			};
-			if (switch_ivr_set_user_extended(session, acl_token, v_event) == SWITCH_STATUS_SUCCESS) {
-				switch_event_destroy(&v_event);
-				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Authenticating user %s\n", acl_token);
-			} else {
-				switch_event_destroy(&v_event);
-				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Error Authenticating user %s\n", acl_token);
-				if(sofia_test_pflag(profile, PFLAG_AUTH_REQUIRE_USER)) {
-					nua_respond(nh, SIP_480_TEMPORARILY_UNAVAILABLE, TAG_END());
-					goto fail;
-				}
+		if (sofia_locate_user(acl_token, session, sip, &x_user) == SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Authenticating user %s\n", acl_token);
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Error Authenticating user %s\n", acl_token);
+			if (sofia_test_pflag(profile, PFLAG_AUTH_REQUIRE_USER)) {
+				nua_respond(nh, SIP_480_TEMPORARILY_UNAVAILABLE, TAG_END());
+				goto fail;
 			}
 		}
 	}