[Freeswitch-svn] [commit] r7966 - in freeswitch/trunk: conf/autoload_configs conf/sip_profiles src src/include src/mod/applications/mod_commands src/mod/applications/mod_dptools src/mod/endpoints/mod_sofia src/mod/event_handlers/mod_event_socket

Freeswitch SVN anthm at freeswitch.org
Wed Mar 26 18:14:10 EDT 2008


Author: anthm
Date: Wed Mar 26 18:14:09 2008
New Revision: 7966

Modified:
   freeswitch/trunk/conf/autoload_configs/event_socket.conf.xml
   freeswitch/trunk/conf/sip_profiles/default.xml
   freeswitch/trunk/src/include/switch_apr.h
   freeswitch/trunk/src/include/switch_core.h
   freeswitch/trunk/src/include/switch_types.h
   freeswitch/trunk/src/include/switch_utils.h
   freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c
   freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
   freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
   freeswitch/trunk/src/switch_apr.c
   freeswitch/trunk/src/switch_core.c
   freeswitch/trunk/src/switch_utils.c

Log:
add acl stuff

Modified: freeswitch/trunk/conf/autoload_configs/event_socket.conf.xml
==============================================================================
--- freeswitch/trunk/conf/autoload_configs/event_socket.conf.xml	(original)
+++ freeswitch/trunk/conf/autoload_configs/event_socket.conf.xml	Wed Mar 26 18:14:09 2008
@@ -3,5 +3,6 @@
     <param name="listen-ip" value="127.0.0.1"/>
     <param name="listen-port" value="8021"/>
     <param name="password" value="ClueCon"/>
+    <!--<param name="apply-inbound-acl" value="lan"/>-->
   </settings>
 </configuration>

Modified: freeswitch/trunk/conf/sip_profiles/default.xml
==============================================================================
--- freeswitch/trunk/conf/sip_profiles/default.xml	(original)
+++ freeswitch/trunk/conf/sip_profiles/default.xml	Wed Mar 26 18:14:09 2008
@@ -29,6 +29,8 @@
     <param name="rtp-ip" value="$${local_ip_v4}"/>
     <param name="sip-ip" value="$${local_ip_v4}"/>
     <param name="hold-music" value="$${moh_uri}"/>
+    <!--<param name="apply-inbound-acl" value="lan"/>-->
+    <!--<param name="apply-register-acl" value="lan"/>-->
     <!--<param name="dtmf-type" value="info"/>-->
     <param name="record-template" value="$${base_dir}/recordings/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
     <!--enable to use presense and mwi -->

Modified: freeswitch/trunk/src/include/switch_apr.h
==============================================================================
--- freeswitch/trunk/src/include/switch_apr.h	(original)
+++ freeswitch/trunk/src/include/switch_apr.h	Wed Mar 26 18:14:09 2008
@@ -1232,7 +1232,7 @@
 SWITCH_DECLARE(switch_status_t) switch_socket_create_pollfd(switch_pollfd_t ** poll, switch_socket_t * sock, int16_t flags, switch_memory_pool_t *pool);
 
 SWITCH_DECLARE(switch_status_t) switch_match_glob(const char *pattern, switch_array_header_t **result, switch_memory_pool_t *p);
-
+SWITCH_DECLARE(switch_status_t) switch_socket_addr_get(switch_sockaddr_t **sa, switch_bool_t remote, switch_socket_t *sock);
 
  /** @} */
 

Modified: freeswitch/trunk/src/include/switch_core.h
==============================================================================
--- freeswitch/trunk/src/include/switch_core.h	(original)
+++ freeswitch/trunk/src/include/switch_core.h	Wed Mar 26 18:14:09 2008
@@ -1591,6 +1591,8 @@
 SWITCH_DECLARE(void) switch_core_setrlimits(void);
 SWITCH_DECLARE(void) switch_time_sync(void);
 SWITCH_DECLARE(time_t) switch_timestamp(time_t *t);
+SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload);
+SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip(const char *ip_str, const char *list_name);
 
 ///\}
 

Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h	(original)
+++ freeswitch/trunk/src/include/switch_types.h	Wed Mar 26 18:14:09 2008
@@ -1259,6 +1259,9 @@
 struct HashElem;
 typedef struct HashElem switch_hash_index_t;
 
+struct switch_network_list;
+typedef struct switch_network_list switch_network_list_t;
+
 
 #define SWITCH_API_VERSION 1
 #define SWITCH_MODULE_LOAD_ARGS (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool)

Modified: freeswitch/trunk/src/include/switch_utils.h
==============================================================================
--- freeswitch/trunk/src/include/switch_utils.h	(original)
+++ freeswitch/trunk/src/include/switch_utils.h	Wed Mar 26 18:14:09 2008
@@ -84,6 +84,7 @@
 !strcasecmp(expr, "true") ||\
 !strcasecmp(expr, "enabled") ||\
 !strcasecmp(expr, "active") ||\
+!strcasecmp(expr, "allow") ||\
 atoi(expr))) ? SWITCH_TRUE : SWITCH_FALSE
 /*!
   \brief find local ip of the box
@@ -347,6 +348,14 @@
 SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, const char *from, const char *headers, const char *body, const char *file);
 SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char close);
 
+SWITCH_DECLARE(int) switch_parse_cidr(const char *string, uint32_t *ip, uint32_t *mask, uint32_t *bitp);
+SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t **list, switch_bool_t default_type, switch_memory_pool_t *pool);
+SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok);
+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_bool_t) switch_network_list_validate_ip(switch_network_list_t *list, uint32_t ip);
+#define switch_test_subnet(_ip, _net, _mask) (_mask ? ((_net & _mask) == (_ip & _mask)) : _net == _ip)
+
+
 /* malloc or DIE macros */
 #ifdef NDEBUG
 #define switch_malloc(ptr, len) (void)( (!!(ptr = malloc(len))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%s", __FILE__, __LINE__),abort(), 0), ptr )

Modified: freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	Wed Mar 26 18:14:09 2008
@@ -271,6 +271,63 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
+SWITCH_STANDARD_API(reload_acl_function)
+{
+	const char *err;
+    switch_xml_t xml_root;
+
+    if (session) {
+        return SWITCH_STATUS_FALSE;
+    }
+
+	if (cmd && !strcmp(cmd, "reloadxml")) {
+		if ((xml_root = switch_xml_open_root(1, &err))) {
+			switch_xml_free(xml_root);
+		}
+	}
+
+	switch_load_network_lists(SWITCH_TRUE);
+
+	stream->write_function(stream, "+OK acl reloaded\n");
+	return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_STANDARD_API(acl_function)
+{
+	int argc;
+	char *mydata = NULL, *argv[3];
+
+	if (!cmd) {
+		goto error;
+	}
+
+	mydata = strdup(cmd);
+	switch_assert(mydata);
+
+	argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+
+	if (argc < 2) {
+		goto error;
+	}
+
+	if (switch_check_network_list_ip(argv[0], argv[1])) {
+		stream->write_function(stream, "true");    
+		goto ok;
+	}
+
+error:
+
+	stream->write_function(stream, "false");    
+
+ok:
+
+	switch_safe_free(mydata);
+
+	return SWITCH_STATUS_SUCCESS;
+
+}
+
+
 SWITCH_STANDARD_API(regex_function)
 {
 	switch_regex_t *re = NULL;
@@ -2186,6 +2243,7 @@
 	SWITCH_ADD_API(commands_api_interface, "killchan", "Kill Channel (depricated)", kill_function, KILL_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "uuid_kill", "Kill Channel", kill_function, KILL_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park Channel", park_function, PARK_SYNTAX);
+	SWITCH_ADD_API(commands_api_interface, "reloadacl", "Reload ACL", reload_acl_function, "[reloadxml]");
 	SWITCH_ADD_API(commands_api_interface, "reloadxml", "Reload XML", reload_function, "");
 	SWITCH_ADD_API(commands_api_interface, "unload", "Unload Module", unload_function, LOAD_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "load", "Load Module", load_function, LOAD_SYNTAX);
@@ -2226,6 +2284,7 @@
 	SWITCH_ADD_API(commands_api_interface, "is_lan_addr", "see if an ip is a lan addr", lan_addr_function, "<ip>");
 	SWITCH_ADD_API(commands_api_interface, "cond", "Eval a conditional", cond_function, "<expr> ? <true val> : <false val>");
 	SWITCH_ADD_API(commands_api_interface, "regex", "Eval a regex", regex_function, "<data>|<pattern>[|<subst string>]");
+	SWITCH_ADD_API(commands_api_interface, "acl", "compater an ip to an acl list", acl_function, "<ip> <list_name>");
 	SWITCH_ADD_API(commands_api_interface, "uuid_chat", "Send a chat message", uuid_chat, UUID_CHAT_SYNTAX);
 	SWITCH_ADD_API(commands_api_interface, "find_user_xml", "find a user", find_user_function, "<key> <user> <domain>");
 	SWITCH_ADD_API(commands_api_interface, "user_exists", "find a user", user_exists_function, "<key> <user> <domain>");

Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	Wed Mar 26 18:14:09 2008
@@ -200,6 +200,28 @@
 	switch_core_session_send_dtmf_string(session, (const char *) data);
 }
 
+SWITCH_STANDARD_APP(check_acl_function)
+{
+	int argc;
+    char *argv[2] = { 0 };
+	char *mydata;
+	switch_call_cause_t cause = SWITCH_CAUSE_CALL_REJECTED;
+
+	if (!switch_strlen_zero(data) && (mydata = switch_core_session_strdup(session, data))) {
+		if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) > 1) {
+			if (!switch_check_network_list_ip(argv[0], argv[1])) {
+				switch_channel_t *channel = switch_core_session_get_channel(session);
+				if (argc > 2) {
+					cause = switch_channel_str2cause(argv[2]);
+				}
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call failed acl check for ip %s on list %s\n", argv[0], argv[1]);
+				switch_channel_hangup(channel, cause);
+			}
+		}
+	}
+	
+}
+
 SWITCH_STANDARD_APP(transfer_function)
 {
 	int argc;
@@ -1760,6 +1782,8 @@
 	SWITCH_ADD_API(api_interface, "presence", "presence", presence_api_function, "<user> <rpid> <message>");
 	SWITCH_ADD_APP(app_interface, "privacy", "Set privacy on calls", "Set caller privacy on calls.", privacy_function, "off|on|name|full|number", SAF_SUPPORT_NOMEDIA);
 	SWITCH_ADD_APP(app_interface, "transfer", "Transfer a channel", TRANSFER_LONG_DESC, transfer_function, "<exten> [<dialplan> <context>]", SAF_SUPPORT_NOMEDIA);
+	SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list", 
+				   "Check an ip against an ACL list", check_acl_function, "<ip> <acl | cidr>", SAF_SUPPORT_NOMEDIA);
 	SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_SUPPORT_NOMEDIA);
 	SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
 	SWITCH_ADD_APP(app_interface, "strftime", NULL, NULL, strftime_function, NULL, SAF_SUPPORT_NOMEDIA);

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	Wed Mar 26 18:14:09 2008
@@ -46,6 +46,8 @@
 #include <switch_odbc.h>
 #endif
 
+#define SOFIA_MAX_ACL 100
+
 #define MODNAME "mod_sofia"
 static const switch_state_handler_table_t noop_state_handler = { 0 };
 struct sofia_gateway;
@@ -308,6 +310,11 @@
 	char *odbc_pass;
 	switch_odbc_handle_t *master_odbc;
 	switch_queue_t *sql_queue;
+	char *acl[SOFIA_MAX_ACL];
+	uint32_t acl_count;
+	char *reg_acl[SOFIA_MAX_ACL];
+	uint32_t reg_acl_count;
+
 };
 
 struct private_object {

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	Wed Mar 26 18:14:09 2008
@@ -1195,6 +1195,18 @@
 						profile->username = switch_core_strdup(profile->pool, val);
 					} else if (!strcasecmp(var, "context")) {
 						profile->context = switch_core_strdup(profile->pool, val);
+					} else if (!strcasecmp(var, "apply-inbound-acl")) {
+						if (profile->acl_count < SOFIA_MAX_ACL) {
+							profile->acl[profile->acl_count++] = switch_core_strdup(profile->pool, val);
+						} else {
+							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
+						}
+					} else if (!strcasecmp(var, "apply-register-acl")) {
+						if (profile->reg_acl_count < SOFIA_MAX_ACL) {
+							profile->reg_acl[profile->reg_acl_count++] = switch_core_strdup(profile->pool, val);
+						} else {
+							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
+						}
 					} else if (!strcasecmp(var, "alias")) {
 						sip_alias_node_t *node;
 						if ((node = switch_core_alloc(profile->pool, sizeof(*node)))) {
@@ -2478,6 +2490,18 @@
 	
 	get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
 
+	if (profile->acl_count) {
+		int x = 0;
+		for (x = 0 ; x < profile->acl_count; x++) {
+			if (!switch_check_network_list_ip(network_ip, profile->acl[x])) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl %s\n", network_ip,  profile->acl[x]);
+				nua_respond(nh, SIP_403_FORBIDDEN, TAG_END());
+				return;
+			}
+		}
+	}
+
+
 	if ((profile->pflags & PFLAG_AUTH_CALLS) || (!(profile->pflags & PFLAG_BLIND_AUTH) && (sip->sip_proxy_authorization || sip->sip_authorization))) {
 		if (strcmp(network_ip, profile->sipip)) {
 			if (sofia_reg_handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key), &v_event)) {

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c	Wed Mar 26 18:14:09 2008
@@ -655,6 +655,23 @@
 {
 	char key[128] = "";
 	switch_event_t *v_event = NULL;
+	char network_ip[80];
+	su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
+	
+	if (profile->reg_acl_count) {
+		int x = 0;
+
+		get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
+		
+		for (x = 0 ; x < profile->reg_acl_count; x++) {
+			if (!switch_check_network_list_ip(network_ip, profile->reg_acl[x])) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl %s\n", network_ip,  profile->reg_acl[x]);
+				nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());
+				goto end;
+			}
+		}
+	}
+
 
 	if (!(profile->mflags & MFLAG_REGISTER)) {
 		nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END());

Modified: freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c	(original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c	Wed Mar 26 18:14:09 2008
@@ -71,6 +71,9 @@
 	switch_core_session_t *session;
 	int lost_events;
 	int lost_logs;
+	switch_sockaddr_t *sa;
+	char remote_ip[50];
+	switch_port_t remote_port;
 	struct listener *next;
 };
 
@@ -84,6 +87,8 @@
 	uint8_t ready;
 } listen_list;
 
+#define MAX_ACL 100
+
 static struct {
 	switch_mutex_t *mutex;
 	char *ip;
@@ -91,6 +96,8 @@
 	char *password;
 	int done;
 	int threads;
+	char *acl[MAX_ACL];
+	uint32_t acl_count;
 } prefs;
 
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, prefs.ip);
@@ -1052,18 +1059,44 @@
 	switch_core_session_t *session = NULL;
 	switch_channel_t *channel = NULL;
 
+
 	switch_mutex_lock(listen_list.mutex);
 	prefs.threads++;
 	switch_mutex_unlock(listen_list.mutex);
 
 	switch_assert(listener != NULL);
 
+	if (prefs.acl_count && listener->sa && !switch_strlen_zero(listener->remote_ip)) {
+		int x = 0;
+		
+		for (x = 0 ; x < prefs.acl_count; x++) {
+			if (!switch_check_network_list_ip(listener->remote_ip, prefs.acl[x])) {
+				const char message[] = "Access Denied, go away.\n";
+				int mlen = strlen(message);
+
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl %s\n", listener->remote_ip,  prefs.acl[x]);
+
+				switch_snprintf(buf, sizeof(buf), "Content-Type: rude/rejection\nContent-Length %d\n\n", mlen);
+				len = strlen(buf);
+				switch_socket_send(listener->sock, buf, &len);
+				len = mlen;
+				switch_socket_send(listener->sock, message, &len);
+				goto done;
+			}
+		}
+	}
+
+
 	if ((session = listener->session)) {
 		channel = switch_core_session_get_channel(session);
 		switch_core_session_read_lock(session);
 	}
 
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open\n");
+	if (switch_strlen_zero(listener->remote_ip)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open\n");
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open from %s:%d\n", listener->remote_ip, listener->remote_port);
+	}
 
 	switch_socket_opt_set(listener->sock, SWITCH_SO_NONBLOCK, TRUE);
 	switch_set_flag_locked(listener, LFLAG_RUNNING);
@@ -1230,6 +1263,12 @@
 					prefs.port = (uint16_t) atoi(val);
 				} else if (!strcmp(var, "password")) {
 					set_pref_pass(val);
+				} else if (!strcasecmp(var, "apply-inbound-acl")) {
+					if (prefs.acl_count < MAX_ACL) {
+						prefs.acl[prefs.acl_count++] = strdup(val);
+					} else {
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", MAX_ACL);
+					}
 				}
 			}
 		}
@@ -1259,6 +1298,7 @@
 	switch_sockaddr_t *sa;
 	switch_socket_t *inbound_socket = NULL;
 	listener_t *listener;
+	int x = 0;
 
 	memset(&listen_list, 0, sizeof(listen_list));
 	config();
@@ -1335,6 +1375,9 @@
 		listener->format = EVENT_FORMAT_PLAIN;
 		switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
 		switch_core_hash_init(&listener->event_hash, listener->pool);
+		switch_socket_addr_get(&listener->sa, SWITCH_TRUE, listener->sock);
+		switch_get_addr(listener->remote_ip, sizeof(listener->remote_ip), listener->sa);
+		listener->remote_port = switch_sockaddr_get_port(listener->sa);
 		launch_listener_thread(listener);
 
 	}
@@ -1349,6 +1392,11 @@
 		switch_core_destroy_memory_pool(&listener_pool);
 	}
 
+
+	for (x = 0 ; x < prefs.acl_count; x++) {
+		switch_safe_free(prefs.acl[x]);
+	}
+
  fail:
 	return SWITCH_STATUS_TERM;
 }

Modified: freeswitch/trunk/src/switch_apr.c
==============================================================================
--- freeswitch/trunk/src/switch_apr.c	(original)
+++ freeswitch/trunk/src/switch_apr.c	Wed Mar 26 18:14:09 2008
@@ -521,6 +521,11 @@
 
 /* socket stubs */
 
+SWITCH_DECLARE(switch_status_t) switch_socket_addr_get(switch_sockaddr_t **sa, switch_bool_t remote, switch_socket_t *sock)
+{
+	return apr_socket_addr_get(sa, remote, sock);
+}
+
 SWITCH_DECLARE(switch_status_t) switch_socket_create(switch_socket_t ** new_sock, int family, int type, int protocol, switch_memory_pool_t *pool)
 {
 	return apr_socket_create(new_sock, family, type, protocol, pool);

Modified: freeswitch/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c	(original)
+++ freeswitch/trunk/src/switch_core.c	Wed Mar 26 18:14:09 2008
@@ -686,6 +686,132 @@
 	return;
 }
 
+typedef struct {
+	switch_memory_pool_t *pool;
+	switch_hash_t *hash;
+} switch_ip_list_t;
+
+static switch_ip_list_t IP_LIST = { 0 };
+
+SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip(const char *ip_str, const char *list_name)
+{
+	switch_network_list_t *list;
+	uint32_t ip, net, mask, bits;
+	switch_bool_t ok = SWITCH_FALSE;
+	
+	switch_mutex_lock(runtime.global_mutex);
+	inet_pton(AF_INET, ip_str, &ip);
+	
+	if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {
+		ok = switch_network_list_validate_ip(list, ip);
+	} else if (strchr(list_name, '/')) {
+		switch_parse_cidr(list_name, &net, &mask, &bits);
+		ok = switch_test_subnet(ip, net, mask);
+	}
+	switch_mutex_unlock(runtime.global_mutex);
+	
+	return ok;
+}
+
+
+SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
+{
+	switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, x_node = NULL, cfg = NULL;
+	switch_network_list_t *list;
+
+
+	switch_mutex_lock(runtime.global_mutex);
+
+	if (IP_LIST.hash) {
+		switch_core_hash_destroy(&IP_LIST.hash);
+	}
+
+	if (IP_LIST.pool) {
+		switch_core_destroy_memory_pool(&IP_LIST.pool);
+	}
+	
+	memset(&IP_LIST, 0, sizeof(IP_LIST));
+	switch_core_new_memory_pool(&IP_LIST.pool);
+	switch_core_hash_init(&IP_LIST.hash, IP_LIST.pool);
+	
+	if ((xml = switch_xml_open_cfg("acl.conf", &cfg, NULL))) {
+		if ((x_lists = switch_xml_child(cfg, "network-lists"))) {
+			for (x_list = switch_xml_child(x_lists, "list"); x_list; x_list = x_list->next) {
+				const char *name = switch_xml_attr(x_list, "name");
+				const char *dft = switch_xml_attr(x_list, "default");
+				switch_bool_t default_type = SWITCH_TRUE;
+
+				if (switch_strlen_zero(name)) {
+					continue;
+				}
+
+				if (dft) {
+					default_type = switch_true(dft);
+				}
+				
+				if (switch_network_list_create(&list, default_type, IP_LIST.pool) != SWITCH_STATUS_SUCCESS) {
+					abort();
+				}
+
+				if (reload) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
+				} else {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Created ip list %s default (%s)\n", name, default_type ? "allow" : "deny");
+				}
+
+
+				for (x_node = switch_xml_child(x_list, "node"); x_node; x_node = x_node->next) {
+					const char *cidr = NULL, *host = NULL, *mask = NULL;
+					switch_bool_t ok = default_type;
+					const char *type = switch_xml_attr(x_node, "type");
+
+					if (type) {
+						ok = switch_true(type);
+					}					
+
+					cidr = switch_xml_attr(x_node, "cidr");
+					host = switch_xml_attr(x_node, "host");
+					mask = switch_xml_attr(x_node, "mask");
+					
+					if (cidr) {
+						if (switch_network_list_add_cidr(list, cidr, ok) == SWITCH_STATUS_SUCCESS) {
+							if (reload) {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
+							} else {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
+							}
+						} else {
+							if (reload) {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, 
+												  "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
+							} else {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, 
+												  "Error Adding %s (%s) to list %s\n", cidr, ok ? "allow" : "deny", name);
+							}
+						}
+					} else if (host && mask) {
+						if (switch_network_list_add_host_mask(list, host, mask, ok) == SWITCH_STATUS_SUCCESS) {
+							if (reload) {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, 
+												  "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name);
+							} else {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, 
+												  "Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name);
+							}
+						}
+					}
+
+					switch_core_hash_insert(IP_LIST.hash, name, list);
+				}
+			}
+		}
+
+		switch_xml_free(xml);
+	}
+
+	switch_mutex_unlock(runtime.global_mutex);
+}
+
 SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)
 {
 	switch_xml_t xml = NULL, cfg = NULL;
@@ -733,7 +859,7 @@
 		apr_terminate();
 		return SWITCH_STATUS_MEMERR;
 	}
-	
+
 	if ((xml = switch_xml_open_cfg("switch.conf", &cfg, NULL))) {
 		switch_xml_t settings, param;
 
@@ -795,6 +921,7 @@
 				switch_core_hash_insert(runtime.global_vars, varr, vall);
 			}
 		}
+
 		switch_xml_free(xml);
 	}
 
@@ -914,6 +1041,7 @@
 #endif
 
 	signal(SIGHUP, handle_SIGHUP);
+	switch_load_network_lists(SWITCH_FALSE);	
 
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");

Modified: freeswitch/trunk/src/switch_utils.c
==============================================================================
--- freeswitch/trunk/src/switch_utils.c	(original)
+++ freeswitch/trunk/src/switch_utils.c	Wed Mar 26 18:14:09 2008
@@ -38,6 +38,138 @@
 #include "private/switch_core_pvt.h"
 #define ESCAPE_META '\\'
 
+struct switch_network_node {
+	uint32_t ip;
+	uint32_t mask;
+	uint32_t bits;
+	switch_bool_t ok;
+	struct switch_network_node *next;
+};
+typedef struct switch_network_node switch_network_node_t;
+
+struct switch_network_list {
+	struct switch_network_node *node_head;
+	switch_bool_t default_type;
+	switch_memory_pool_t *pool;
+};
+
+
+SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t **list, switch_bool_t default_type, switch_memory_pool_t *pool)
+{
+	switch_network_list_t *new_list;
+	
+	if (!pool) {
+		switch_core_new_memory_pool(&pool);
+	}
+
+	new_list = switch_core_alloc(pool, sizeof(**list));
+	new_list->pool = pool;
+	new_list->default_type = default_type;
+
+	*list = new_list;
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip(switch_network_list_t *list, uint32_t ip)
+{
+	switch_network_node_t *node;
+	switch_bool_t ok = list->default_type;
+	uint32_t bits = 0;
+
+	for (node = list->node_head; node; node = node->next) {
+		if (node->bits > bits && switch_test_subnet(ip, node->ip, node->mask)) {
+			if (node->ok) {
+				ok = SWITCH_TRUE;
+			} else {
+				ok = SWITCH_FALSE;
+			}
+			bits = node->bits;
+		}
+	}
+	
+	return ok;
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok)
+{
+	uint32_t ip, mask, bits;
+	switch_network_node_t *node;
+	
+	if (switch_parse_cidr(cidr_str, &ip, &mask, &bits)) {
+		return SWITCH_STATUS_GENERR;
+	}
+	
+	node = switch_core_alloc(list->pool, sizeof(*node));
+
+	node->ip = ip;
+	node->mask = mask;
+	node->ok = ok;
+	node->bits = bits;
+
+	node->next = list->node_head;
+	list->node_head = node;
+	
+	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)
+{
+	int ip, mask;
+	switch_network_node_t *node;
+
+	inet_pton(AF_INET, host, &ip);
+	inet_pton(AF_INET, mask_str, &mask);
+	
+	node = switch_core_alloc(list->pool, sizeof(*node));
+	
+	node->ip = ip;
+	node->mask = mask;
+	node->ok = ok;
+
+	/* http://graphics.stanford.edu/~seander/bithacks.html */
+	mask = mask - ((mask >> 1) & 0x55555555);
+    mask = (mask & 0x33333333) + ((mask >> 2) & 0x33333333);
+	node->bits = (((mask + (mask >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
+	
+	node->next = list->node_head;
+	list->node_head = node;
+	
+	return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_DECLARE(int) switch_parse_cidr(const char *string, uint32_t *ip, uint32_t *mask, uint32_t *bitp)
+{
+	char host[128] = "";
+	char *bit_str;
+	int32_t bits;
+
+	strncpy(host, string, sizeof(host) - 1);
+	bit_str = strchr(host, '/');
+
+	if (!bit_str) {
+		return -1;
+	}
+
+	*bit_str++ = '\0';
+	bits = atoi(bit_str);
+	
+	if (bits < 0 || bits > 32) {
+		return -2;
+	}
+
+	bits = atoi(bit_str);
+	inet_pton(AF_INET, host, ip);
+	*mask = 0xFFFFFFFF & ~(0xFFFFFFFF << bits);
+	*bitp = bits;
+
+	return 0;
+}
+
+
 SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char close)
 {
 	const char *e = NULL;



More information about the Freeswitch-svn mailing list