add acl stuff

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7966 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale committed 2008-03-26 22:14:09 +00:00
1 parent 9943975660
commit bba65f4a1e
15 files changed
+464 -3

No files matched your search

@@ -271,6 +271,63 @@ end:
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_MODULE_LOAD_FUNCTION(mod_commands_load)
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_MODULE_LOAD_FUNCTION(mod_commands_load)
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>");
@@ -200,6 +200,28 @@ SWITCH_STANDARD_APP(send_dtmf_function)
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_MODULE_LOAD_FUNCTION(mod_dptools_load)
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);
+7
View File
@@ -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 @@ struct sofia_profile {
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 {
+24
View File
@@ -1195,6 +1195,18 @@ switch_status_t config_sofia(int reload, char *profile_name)
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 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
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)) {
+17
View File
@@ -655,6 +655,23 @@ void sofia_reg_handle_sip_i_register(nua_t * nua, sofia_profile_t *profile, nua_
{
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());
@@ -71,6 +71,9 @@ struct listener {
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 @@ static struct {
uint8_t ready;
} listen_list;
#define MAX_ACL 100
static struct {
switch_mutex_t *mutex;
char *ip;
@@ -91,6 +96,8 @@ static struct {
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 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t * thread, void *obj
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 @@ static int config(void)
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_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime)
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 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime)
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_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime)
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;
}