]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add domain-based acl auth thingy
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 16 Jul 2008 17:44:54 +0000 (17:44 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 16 Jul 2008 17:44:54 +0000 (17:44 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9056 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_core.h
src/include/switch_ivr.h
src/include/switch_utils.h
src/mod/applications/mod_dptools/mod_dptools.c
src/mod/endpoints/mod_sofia/sofia.c
src/switch_core.c
src/switch_ivr.c
src/switch_utils.c

index 89e4741c628956afb765364e7284340f3303378f..8bfdfcf038565001aa4631baf40cc7aadd51baf5 100644 (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);
index 52e60dd7ad102644369ba79b66c218b5bfcdd320..56a0a0f48b2c37eae18447fa26d5f9ae7d2df83c 100644 (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
index 0acc2ad2b05bca5f40acc7cd286fb08a3ee3222a..157254814996d849802b4fb98798463fea8ec8db 100644 (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
index 77dda423323ba066d0d2926e82bd5246cd3b175d..98d8296d2a28f63180aa00279de5292cfbefc8cb 100644 (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)
index 9f22dcd08a958cc3d791726adf95a5ef02869c3c..801474707dd04051ad919d261bfcb0cb765844ad 100644 (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);
index 411616e23d2cfdde7ab892c1b77528f57158a7cc..d86af82b3f93889bf507fc1f5ad528e9cbb5064d 100644 (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");
-
-                                       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);
+                                       domain = switch_xml_attr(x_node, "domain");
+
+                                       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) {
+                                                       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);
                                }
index 7ebb131a647f3f933b303d3941863e0b3aa06b76..b0c76dbd932c88a87c2c8b95e740f898b580f604 100644 (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
index fb371517ce2a562f2a5e0d6e5b64eec1e60f5066..04c66d2c7a3f1c32de4edeab890cce31af1df146 100644 (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;