more auth
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2861 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
346eb82c5a
commit
168c69bb36
|
@ -100,6 +100,10 @@ struct sip_alias_node {
|
|||
|
||||
typedef struct sip_alias_node sip_alias_node_t;
|
||||
|
||||
typedef enum {
|
||||
PFLAG_AUTH_CALLS = (1 << 0),
|
||||
} PFLAGS;
|
||||
|
||||
typedef enum {
|
||||
TFLAG_IO = (1 << 0),
|
||||
TFLAG_INBOUND = (1 << 1),
|
||||
|
@ -149,6 +153,7 @@ struct sofia_profile {
|
|||
int codec_ms;
|
||||
int dtmf_duration;
|
||||
unsigned int flags;
|
||||
unsigned int pflags;
|
||||
uint32_t max_calls;
|
||||
nua_t *nua;
|
||||
switch_memory_pool_t *pool;
|
||||
|
@ -1343,9 +1348,13 @@ static switch_status_t sofia_outgoing_channel(switch_core_session_t *session, sw
|
|||
if ((host = strchr(dest, '%'))) {
|
||||
char buf[128];
|
||||
*host++ = '\0';
|
||||
find_reg_url(profile, dest, host, buf, sizeof(buf));
|
||||
tech_pvt->dest = switch_core_session_strdup(nsession, buf);
|
||||
dest = tech_pvt->dest + 4;
|
||||
if (find_reg_url(profile, dest, host, buf, sizeof(buf))) {
|
||||
tech_pvt->dest = switch_core_session_strdup(nsession, buf);
|
||||
dest = tech_pvt->dest + 4;
|
||||
} else {
|
||||
terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
tech_pvt->dest = switch_core_session_alloc(nsession, strlen(dest) + 5);
|
||||
snprintf(tech_pvt->dest, strlen(dest) + 5, "sip:%s", dest);
|
||||
|
@ -1655,69 +1664,6 @@ static void sip_i_state(int status,
|
|||
|
||||
}
|
||||
|
||||
static void sip_i_invite(nua_t *nua,
|
||||
sofia_profile_t *profile,
|
||||
nua_handle_t *nh,
|
||||
switch_core_session_t *session,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[])
|
||||
{
|
||||
|
||||
|
||||
if (!session) {
|
||||
if ((session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
|
||||
private_object_t *tech_pvt = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
sip_from_t const *from = sip->sip_from;
|
||||
sip_to_t const *to = sip->sip_to;
|
||||
char *displayname;
|
||||
char username[256];
|
||||
|
||||
|
||||
if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
|
||||
terminate_session(&session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
displayname = switch_core_session_strdup(session, (char *) from->a_display);
|
||||
if (*displayname == '"') {
|
||||
char *p;
|
||||
|
||||
displayname++;
|
||||
if ((p = strchr(displayname, '"'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(username, sizeof(username), "%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
|
||||
attach_private(session, profile, tech_pvt, username);
|
||||
|
||||
snprintf(username, sizeof(username), "sip:%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
|
||||
tech_pvt->contact = sip_contact_create(tech_pvt->home, URL_STRING_MAKE(username), NULL);
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
|
||||
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
(char *) from->a_url->url_user,
|
||||
profile->dialplan,
|
||||
displayname,
|
||||
(char *) from->a_url->url_user,
|
||||
(char *) from->a_url->url_host,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(char *)modname,
|
||||
profile->context,
|
||||
(char *) to->a_url->url_user)) != 0) {
|
||||
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
|
||||
}
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_INBOUND);
|
||||
nua_handle_bind(nh, session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *get_auth_data(char *dbname, char *nonce, char *npassword, uint32_t len, switch_mutex_t *mutex)
|
||||
{
|
||||
|
@ -1780,12 +1726,18 @@ static char *get_auth_data(char *dbname, char *nonce, char *npassword, uint32_t
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void sip_i_register(nua_t *nua,
|
||||
sofia_profile_t *profile,
|
||||
nua_handle_t *nh,
|
||||
switch_core_session_t *session,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[])
|
||||
|
||||
typedef enum {
|
||||
REG_REGISTER,
|
||||
REG_INVITE
|
||||
} sofia_regtype_t;
|
||||
|
||||
static uint8_t handle_register(nua_t *nua,
|
||||
sofia_profile_t *profile,
|
||||
nua_handle_t *nh,
|
||||
switch_core_session_t *session,
|
||||
sip_t const *sip,
|
||||
sofia_regtype_t regtype)
|
||||
{
|
||||
sip_from_t const *from = sip->sip_from;
|
||||
sip_expires_t const *expires = sip->sip_expires;
|
||||
|
@ -1801,9 +1753,15 @@ static void sip_i_register(nua_t *nua,
|
|||
char *contact_user = (char *) contact->m_url->url_user;
|
||||
char *contact_host = (char *) contact->m_url->url_host;
|
||||
char buf[512];
|
||||
char *passwd;
|
||||
uint8_t ok = 0, stale = 0;
|
||||
char *passwd = NULL;
|
||||
uint8_t ok = 0, stale = 0, ret = 0;
|
||||
long exptime = expires ? expires->ex_delta : 60;
|
||||
|
||||
if (regtype == REG_REGISTER) {
|
||||
authorization = sip->sip_authorization;
|
||||
} else if (regtype == REG_INVITE) {
|
||||
authorization = sip->sip_proxy_authorization;
|
||||
}
|
||||
|
||||
if (authorization) {
|
||||
int index;
|
||||
|
@ -1811,7 +1769,6 @@ static void sip_i_register(nua_t *nua,
|
|||
char npassword[512] = "";
|
||||
char *nonce, *uri, *qop, *cnonce, *nc, *input, *response;
|
||||
nonce = uri = qop = cnonce = nc = response = NULL;
|
||||
|
||||
for(index = 0; (cur=(char*)authorization->au_params[index]); index++) {
|
||||
char *var, *val, *p, *work;
|
||||
var = val = work = NULL;
|
||||
|
@ -1845,13 +1802,21 @@ static void sip_i_register(nua_t *nua,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (get_auth_data(profile->dbname, nonce, npassword, sizeof(npassword), profile->reg_mutex)) {
|
||||
su_md5_t ctx;
|
||||
char uridigest[2 * SU_MD5_DIGEST_SIZE + 1];
|
||||
char bigdigest[2 * SU_MD5_DIGEST_SIZE + 1];
|
||||
char *regstr;
|
||||
|
||||
input = switch_core_db_mprintf("REGISTER:%q", uri);
|
||||
if (regtype == REG_REGISTER) {
|
||||
regstr = "REGISTER";
|
||||
} else if (regtype == REG_INVITE) {
|
||||
regstr = "INVITE";
|
||||
} else {
|
||||
regstr = "WTF";
|
||||
}
|
||||
|
||||
input = switch_core_db_mprintf("%s:%q", regstr, uri);
|
||||
su_md5_init(&ctx);
|
||||
su_md5_strupdate(&ctx, input);
|
||||
su_md5_hexdigest(&ctx, uridigest);
|
||||
|
@ -1884,7 +1849,7 @@ static void sip_i_register(nua_t *nua,
|
|||
|
||||
if (!ok && !stale) {
|
||||
nua_respond(nh, SIP_401_UNAUTHORIZED, TAG_END());
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1896,17 +1861,18 @@ static void sip_i_register(nua_t *nua,
|
|||
contact_host
|
||||
);
|
||||
|
||||
|
||||
if (switch_xml_locate("directory", "domain", "name", (char *)from->a_url->url_host, &xml, &domain, params) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
if (switch_xml_locate("directory", "domain", "name", from_host, &xml, &domain, params) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of directory failed\n");
|
||||
nua_respond(nh, SIP_401_UNAUTHORIZED, SIPTAG_CONTACT(contact), TAG_END());
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(user = switch_xml_find_child(domain, "user", "id", from_user))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", from_user, from_host);
|
||||
nua_respond(nh, SIP_401_UNAUTHORIZED, SIPTAG_CONTACT(contact), TAG_END());
|
||||
switch_xml_free(xml);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1919,7 +1885,6 @@ static void sip_i_register(nua_t *nua,
|
|||
if (!strcasecmp(var, "password")) {
|
||||
passwd = val;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (passwd) {
|
||||
|
@ -1954,16 +1919,30 @@ static void sip_i_register(nua_t *nua,
|
|||
stale ? " stale=\"true\"," : "");
|
||||
|
||||
|
||||
nua_respond(nh, SIP_401_UNAUTHORIZED,
|
||||
SIPTAG_WWW_AUTHENTICATE_STR(auth_str),
|
||||
TAG_END());
|
||||
if (regtype == REG_REGISTER) {
|
||||
nua_respond(nh, SIP_401_UNAUTHORIZED,
|
||||
SIPTAG_WWW_AUTHENTICATE_STR(auth_str),
|
||||
TAG_END());
|
||||
} else if (regtype == REG_INVITE) {
|
||||
nua_respond(nh, SIP_407_PROXY_AUTH_REQUIRED,
|
||||
SIPTAG_PROXY_AUTHENTICATE_STR(auth_str),
|
||||
TAG_END());
|
||||
|
||||
}
|
||||
|
||||
execute_sql(profile->dbname, sql, profile->reg_mutex);
|
||||
switch_core_db_free(sql);
|
||||
switch_core_db_free(auth_str);
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
switch_xml_free(xml);
|
||||
return;
|
||||
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
|
||||
|
@ -1972,24 +1951,26 @@ static void sip_i_register(nua_t *nua,
|
|||
from_host,
|
||||
contact_user,
|
||||
contact_host,
|
||||
(long) time(NULL) + (long)expires->ex_delta);
|
||||
(long) time(NULL) + (long)exptime);
|
||||
|
||||
} else {
|
||||
sql = switch_core_db_mprintf("update sip_registrations set contact='sip:%q@%q', expires=%ld where user='%q' and host='%q'",
|
||||
contact_user,
|
||||
contact_host,
|
||||
(long) time(NULL) + (long)expires->ex_delta,
|
||||
(long) time(NULL) + (long)exptime,
|
||||
from_user,
|
||||
from_host);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
|
||||
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", from_user);
|
||||
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-host", "%s", from_host);
|
||||
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact-user", "%s", contact_user);
|
||||
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact-host", "%s", contact_host);
|
||||
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long)expires->ex_delta);
|
||||
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long)exptime);
|
||||
switch_event_fire(&s_event);
|
||||
}
|
||||
|
||||
|
@ -1999,18 +1980,104 @@ static void sip_i_register(nua_t *nua,
|
|||
sql = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got a Register from [%s@%s] contact [%s@%s] expires %ld\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Register from [%s@%s] contact [%s@%s] expires %ld\n",
|
||||
from_user,
|
||||
from_host,
|
||||
contact_user,
|
||||
contact_host,
|
||||
(long)expires->ex_delta
|
||||
(long)exptime
|
||||
);
|
||||
|
||||
if (regtype == REG_REGISTER) {
|
||||
nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(contact), TAG_END());
|
||||
return 1;
|
||||
}
|
||||
|
||||
nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(contact), TAG_END());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void sip_i_invite(nua_t *nua,
|
||||
sofia_profile_t *profile,
|
||||
nua_handle_t *nh,
|
||||
switch_core_session_t *session,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[])
|
||||
{
|
||||
|
||||
|
||||
if (!session) {
|
||||
|
||||
if ((profile->pflags & PFLAG_AUTH_CALLS)) {
|
||||
if (handle_register(nua, profile, nh, session, sip, REG_INVITE)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
|
||||
private_object_t *tech_pvt = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
sip_from_t const *from = sip->sip_from;
|
||||
sip_to_t const *to = sip->sip_to;
|
||||
char *displayname;
|
||||
char username[256];
|
||||
|
||||
|
||||
if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
|
||||
terminate_session(&session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
displayname = switch_core_session_strdup(session, (char *) from->a_display);
|
||||
if (*displayname == '"') {
|
||||
char *p;
|
||||
|
||||
displayname++;
|
||||
if ((p = strchr(displayname, '"'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(username, sizeof(username), "%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
|
||||
attach_private(session, profile, tech_pvt, username);
|
||||
|
||||
snprintf(username, sizeof(username), "sip:%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
|
||||
tech_pvt->contact = sip_contact_create(tech_pvt->home, URL_STRING_MAKE(username), NULL);
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
|
||||
|
||||
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
(char *) from->a_url->url_user,
|
||||
profile->dialplan,
|
||||
displayname,
|
||||
(char *) from->a_url->url_user,
|
||||
(char *) from->a_url->url_host,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(char *)modname,
|
||||
profile->context,
|
||||
(char *) to->a_url->url_user)) != 0) {
|
||||
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
|
||||
}
|
||||
switch_set_flag_locked(tech_pvt, TFLAG_INBOUND);
|
||||
nua_handle_bind(nh, session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sip_i_register(nua_t *nua,
|
||||
sofia_profile_t *profile,
|
||||
nua_handle_t *nh,
|
||||
switch_core_session_t *session,
|
||||
sip_t const *sip,
|
||||
tagi_t tags[])
|
||||
{
|
||||
handle_register(nua, profile, nh, session, sip, REG_REGISTER);
|
||||
}
|
||||
|
||||
static void event_callback(nua_event_t event,
|
||||
|
@ -2179,6 +2246,7 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
|
|||
NUTAG_EARLY_MEDIA(1),
|
||||
NUTAG_AUTOANSWER(0),
|
||||
NUTAG_AUTOALERT(0),
|
||||
//NUTAG_AUTOTRYING(0),
|
||||
NUTAG_ALLOW("REGISTER"),
|
||||
SIPTAG_SUPPORTED_STR("100rel, precondition"),
|
||||
TAG_END());
|
||||
|
@ -2194,9 +2262,10 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
|
|||
nua_set_params(node->nua,
|
||||
NUTAG_EARLY_MEDIA(1),
|
||||
NUTAG_AUTOANSWER(0),
|
||||
NUTAG_AUTOALERT(0),
|
||||
//NUTAG_AUTOTRYING(0),
|
||||
NUTAG_ALLOW("REGISTER"),
|
||||
SIPTAG_SUPPORTED_STR("100rel, precondition"),
|
||||
NUTAG_AUTOALERT(0),
|
||||
TAG_END());
|
||||
|
||||
}
|
||||
|
@ -2331,6 +2400,10 @@ static switch_status_t config_sofia(int reload)
|
|||
profile->sipdomain = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcmp(var, "rtp-timer-name")) {
|
||||
profile->timer_name = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcmp(var, "auth-calls")) {
|
||||
if (switch_true(val)) {
|
||||
profile->pflags |= PFLAG_AUTH_CALLS;
|
||||
}
|
||||
} else if (!strcmp(var, "ext-sip-ip")) {
|
||||
profile->extsipip = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcmp(var, "bitpacking")) {
|
||||
|
|
Loading…
Reference in New Issue