From d986cc5f2aefc64263b330287365b51403744165 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Tue, 8 Sep 2009 22:16:45 +0000 Subject: [PATCH] proxy acl git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14794 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia.c | 85 +++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 8374337f5d..8a6a0a0f2f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -482,6 +482,8 @@ struct sofia_profile { switch_queue_t *sql_queue; char *acl[SOFIA_MAX_ACL]; uint32_t acl_count; + char *proxy_acl{SOFIA_MAX_ACL]; + uint32_t proxy_acl_count; char *reg_acl[SOFIA_MAX_ACL]; uint32_t reg_acl_count; char *nat_acl[SOFIA_MAX_ACL]; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 7e7fbaf53b..650fa4e145 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -29,6 +29,7 @@ * Bret McDanel * Marcel Barbulescu * Norman Brandinger + * Raymond Chandler * * * sofia.c -- SOFIA SIP Endpoint (sofia code) @@ -1605,6 +1606,8 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) /* you could change profile->foo here if it was a minor change like context or dialplan ... */ profile->rport_level = 1; /* default setting */ profile->acl_count = 0; + profile->reg_acl_count = 0; + profile->proxy_acl_count = 0; sofia_set_pflag(profile, PFLAG_STUN_ENABLED); profile->ib_calls = 0; profile->ob_calls = 0; @@ -1763,6 +1766,13 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) } 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-proxy-acl")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "apply proxy acl [%s]\n", val); + if (profile->proxy_acl_count < SOFIA_MAX_ACL) { + profile->proxy_acl[profile->proxy_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); @@ -2156,6 +2166,8 @@ switch_status_t config_sofia(int reload, char *profile_name) char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s [%s]\n", var, val); + if (!strcasecmp(var, "debug")) { profile->debug = atoi(val); } else if (!strcasecmp(var, "sip-trace") && switch_true(val)) { @@ -2556,6 +2568,12 @@ switch_status_t config_sofia(int reload, char *profile_name) } 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-proxy-acl")) { + if (profile->proxy_acl_count < SOFIA_MAX_ACL) { + profile->proxy_acl[profile->proxy_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); @@ -4480,6 +4498,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t } #define url_set_chanvars(session, url, varprefix) _url_set_chanvars(session, url, #varprefix "_user", #varprefix "_host", #varprefix "_port", #varprefix "_uri", #varprefix "_params") + const char *_url_set_chanvars(switch_core_session_t *session, url_t *url, const char *user_var, const char *host_var, const char *port_var, const char *uri_var, const char *params_var) { @@ -4551,6 +4570,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ const char *context = NULL; const char *dialplan = NULL; char network_ip[80]; + char proxied_client_ip[80]; switch_event_t *v_event = NULL; uint32_t sess_count = switch_core_session_count(); uint32_t sess_max = switch_core_session_limit(0); @@ -4643,13 +4663,66 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ is_auth = 1; } } else { - if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", network_ip, switch_str_nil(last_acl)); - nua_respond(nh, SIP_403_FORBIDDEN, TAG_END()); - goto fail; + int network_ip_is_proxy = 0; + /* Check if network_ip is a proxy allowed to send us calls */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%d acls to check for proxy\n", profile->proxy_acl_count); + + for (x = 0; x < profile->proxy_acl_count; x++) { + last_acl = profile->proxy_acl[x]; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "checking %s against acl %s\n", network_ip, last_acl); + if (switch_check_network_list_ip_token(network_ip, last_acl, &token)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, + "%s is a proxy according to the %s acl\n", + network_ip, last_acl + ); + network_ip_is_proxy = 1; + break; + } + } + /* + * if network_ip is a proxy allowed to send calls, check for auth + * ip header and see if it matches against the inbound acl + */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "network ip is a proxy [%d]\n", network_ip_is_proxy); + + if (network_ip_is_proxy) { + for (un = sip->sip_unknown; un; un = un->un_next) { + if (!strcasecmp(un->un_name, "X-AUTH-IP")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "found auth ip [%s] header of [%s]\n", + un->un_name, un->un_value + ); + if (!switch_strlen_zero(un->un_value)) { + for (x = 0; x < profile->acl_count; x++) { + last_acl = profile->acl[x]; + if ((ok = switch_check_network_list_ip_token(un->un_value, last_acl, &token))) { + switch_copy_string(proxied_client_ip, un->un_value, sizeof (proxied_client_ip)); + break; + } + } + } + } + } + } + + if (!ok) { + if (!sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", network_ip, switch_str_nil(last_acl)); + nua_respond(nh, SIP_403_FORBIDDEN, TAG_END()); + goto fail; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n", + network_ip, switch_str_nil(last_acl)); + } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Rejected by acl \"%s\". Falling back to Digest auth.\n", - network_ip, switch_str_nil(last_acl)); + if (token) { + switch_set_string(acl_token, token); + } + if (sofia_test_pflag(profile, PFLAG_AUTH_CALLS)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s Approved by acl \"%s[%s]\". Access Granted.\n", + proxied_client_ip, switch_str_nil(last_acl), acl_token); + is_auth = 1; + } } } }