add domain-based acl auth thingy

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9056 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2008-07-16 17:44:54 +00:00
parent 74c511f421
commit 4722de507b
8 changed files with 150 additions and 87 deletions

View File

@ -1642,7 +1642,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);
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);
SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration);
SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration);

View File

@ -783,7 +783,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_set_terminator(sw
SWITCH_DECLARE(switch_say_method_t) switch_ivr_get_say_method_by_name(const char *name);
SWITCH_DECLARE(switch_say_type_t) switch_ivr_get_say_type_by_name(const char *name);
SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *session, const char *data);
/** @} */
SWITCH_END_EXTERN_C

View File

@ -413,12 +413,17 @@ SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char clos
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_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token);
#define switch_network_list_add_cidr(_list, _cidr_str, _ok) switch_network_list_add_cidr_token(_list, _cidr_str, _ok, NULL)
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);
SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_network_list_t *list, uint32_t ip, const char **token);
#define switch_network_list_validate_ip(_list, _ip) switch_network_list_validate_ip_token(_list, _ip, NULL);
#define switch_test_subnet(_ip, _net, _mask) (_mask ? ((_net & _mask) == (_ip & _mask)) : _net ? _net == _ip : 1)
int switch_inet_pton(int af, const char *src, void *dst);
int switch_inet_pton(int af, const char *src, void *dst);
/* malloc or DIE macros */
#ifdef NDEBUG

View File

@ -365,54 +365,7 @@ SWITCH_STANDARD_APP(three_way_function)
#define SET_USER_SYNTAX "<user>@<domain>"
SWITCH_STANDARD_APP(set_user_function)
{
switch_xml_t x_domain, xml = NULL, x_user, x_param, x_params;
char *user, *mailbox, *domain;
switch_channel_t *channel = switch_core_session_get_channel(session);
if (switch_strlen_zero(data)) {
goto error;
}
user = switch_core_session_strdup(session, data);
if (!(domain = strchr(user, '@'))) {
goto error;
}
*domain++ = '\0';
if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
goto done;
}
if ((mailbox = (char *) switch_xml_attr(x_user, "mailbox"))) {
switch_channel_set_variable(channel, "mailbox", mailbox);
}
if ((x_params = switch_xml_child(x_user, "variables"))) {
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (var && val) {
switch_channel_set_variable(channel, var, val);
}
}
}
switch_channel_set_variable(channel, "user_name", user);
switch_channel_set_variable(channel, "domain_name", domain);
goto done;
error:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No user@domain specified.\n");
done:
if (xml) {
switch_xml_free(xml);
}
switch_ivr_set_user(session, data);
}
SWITCH_STANDARD_APP(ring_ready_function)

View File

@ -2965,6 +2965,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
int network_port = 0;
char *is_nat = NULL;
char *acl_token = NULL;
if (sess_count >= sess_max || !(profile->pflags & PFLAG_RUNNING)) {
nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
@ -3018,23 +3019,27 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
}
}
}
if (profile->acl_count) {
uint32_t x = 0;
int ok = 1;
char *last_acl = NULL;
const char *token;
for (x = 0; x < profile->acl_count; x++) {
last_acl = profile->acl[x];
if (!(ok = switch_check_network_list_ip(network_ip, last_acl))) {
if (!(ok = switch_check_network_list_ip_token(network_ip, last_acl, &token))) {
break;
}
}
if (ok) {
if (token) {
acl_token = strdup(token);
}
if ((profile->pflags & PFLAG_AUTH_CALLS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Approved by acl %s. Access Granted.\n",
network_ip, switch_str_nil(last_acl));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Approved by acl %s[%s]. Access Granted.\n",
network_ip, switch_str_nil(last_acl), switch_str_nil(acl_token));
is_auth = 1;
}
} else {
@ -3090,6 +3095,19 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
channel = tech_pvt->channel = switch_core_session_get_channel(session);
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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Authenticating user %s\n", acl_token);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error Authenticating user %s\n", acl_token);
}
}
free(acl_token);
acl_token = NULL;
}
if (sip->sip_contact && sip->sip_contact->m_url) {
char tmp[35] = "";
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);

View File

@ -691,7 +691,7 @@ typedef struct {
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_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token)
{
switch_network_list_t *list;
uint32_t ip, net, mask, bits;
@ -703,7 +703,7 @@ SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip(const char *ip_str, c
ip = htonl(ip);
if ((list = switch_core_hash_find(IP_LIST.hash, list_name))) {
ok = switch_network_list_validate_ip(list, ip);
ok = switch_network_list_validate_ip_token(list, ip, token);
} else if (strchr(list_name, '/')) {
switch_parse_cidr(list_name, &net, &mask, &bits);
ok = switch_test_subnet(ip, net, mask);
@ -761,7 +761,7 @@ 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;
const char *cidr = NULL, *host = NULL, *mask = NULL, *domain = NULL;
switch_bool_t ok = default_type;
const char *type = switch_xml_attr(x_node, "type");
@ -772,35 +772,55 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
cidr = switch_xml_attr(x_node, "cidr");
host = switch_xml_attr(x_node, "host");
mask = switch_xml_attr(x_node, "mask");
domain = switch_xml_attr(x_node, "domain");
if (cidr) {
if (domain) {
switch_event_t *my_params = NULL;
switch_xml_t x_domain, xml_root;
switch_xml_t ut;
switch_event_create(&my_params, SWITCH_EVENT_MESSAGE);
switch_assert(my_params);
switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "domain", domain);
switch_event_add_header_string(my_params, SWITCH_STACK_BOTTOM, "purpose", "network-list");
if (switch_xml_locate_domain(domain, my_params, &xml_root, &x_domain) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate domain %s\n", domain);
continue;
}
for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) {
const char *user_cidr = switch_xml_attr(ut, "cidr");
const char *id = switch_xml_attr(ut, "id");
if (id && user_cidr) {
char *token = switch_mprintf("%s@%s", id, domain);
switch_assert(token);
if (switch_network_list_add_cidr_token(list, user_cidr, ok, token) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding %s (%s) [%s] to list %s\n",
user_cidr, ok ? "allow" : "deny", switch_str_nil(token), name);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Adding %s (%s) [%s] to list %s\n",
user_cidr, ok ? "allow" : "deny", switch_str_nil(token), name);
}
free(token);
}
}
switch_xml_free(xml_root);
} else 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);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "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);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
"Adding %s/%s (%s) to list %s\n", host, mask, ok ? "allow" : "deny", name);
}
}
}
switch_core_hash_insert(IP_LIST.hash, name, list);
}

View File

@ -1760,6 +1760,64 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, c
}
SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *session, const char *data)
{
switch_xml_t x_domain, xml = NULL, x_user, x_param, x_params;
char *user, *mailbox, *domain;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_FALSE;
if (switch_strlen_zero(data)) {
goto error;
}
user = switch_core_session_strdup(session, data);
if (!(domain = strchr(user, '@'))) {
goto error;
}
*domain++ = '\0';
if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
goto done;
}
status = SWITCH_STATUS_SUCCESS;
if ((mailbox = (char *) switch_xml_attr(x_user, "mailbox"))) {
switch_channel_set_variable(channel, "mailbox", mailbox);
}
if ((x_params = switch_xml_child(x_user, "variables"))) {
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (var && val) {
switch_channel_set_variable(channel, var, val);
}
}
}
switch_channel_set_variable(channel, "user_name", user);
switch_channel_set_variable(channel, "domain_name", domain);
goto done;
error:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No user@domain specified.\n");
done:
if (xml) {
switch_xml_free(xml);
}
return status;
}
/* For Emacs:
* Local Variables:
* mode:c

View File

@ -43,6 +43,7 @@ struct switch_network_node {
uint32_t mask;
uint32_t bits;
switch_bool_t ok;
char *token;
struct switch_network_node *next;
};
typedef struct switch_network_node switch_network_node_t;
@ -77,7 +78,7 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t
return SWITCH_STATUS_SUCCESS;
}
SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip(switch_network_list_t *list, uint32_t ip)
SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_network_list_t *list, uint32_t ip, const char **token)
{
switch_network_node_t *node;
switch_bool_t ok = list->default_type;
@ -90,15 +91,19 @@ SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip(switch_network_lis
} else {
ok = SWITCH_FALSE;
}
bits = node->bits;
if (token) {
*token = node->token;
}
}
}
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)
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)
{
uint32_t ip, mask, bits;
switch_network_node_t *node;
@ -114,13 +119,16 @@ SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr(switch_network_list
node->ok = ok;
node->bits = bits;
if (!switch_strlen_zero(token)) {
node->token = switch_core_strdup(list->pool, token);
}
node->next = list->node_head;
list->node_head = node;
return SWITCH_STATUS_SUCCESS;
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;