mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-11-02 01:25:11 +00:00
add acl stuff
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7966 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user