diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h
index 22a30c4793..cbb687936b 100644
--- a/src/include/switch_utils.h
+++ b/src/include/switch_utils.h
@@ -57,6 +57,7 @@ SWITCH_DECLARE(int) switch_isupper(int c);
SWITCH_DECLARE(int) switch_isxdigit(int c);
#define switch_goto_status(_status, _label) status = _status; goto _label
+#define switch_goto_int(_n, _i, _label) _n = _i; goto _label
#define switch_samples_per_packet(rate, interval) ((uint32_t)((float)rate / (1000.0f / (float)interval)))
#define SWITCH_SMAX 32767
#define SWITCH_SMIN -32768
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index ed65a2616c..b88db59193 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -1488,14 +1488,19 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam
}
cb->stream->write_function(cb->stream,
- "Call-ID: \t%s\n"
- "User: \t%s@%s\n"
- "Contact: \t%s\n"
- "Agent: \t%s\n"
- "Status: \t%s(%s) EXP(%s)\n"
- "Host: \t%s\n\n",
+ "Call-ID: \t%s\n"
+ "User: \t%s@%s\n"
+ "Contact: \t%s\n"
+ "Agent: \t%s\n"
+ "Status: \t%s(%s) EXP(%s)\n"
+ "Host: \t%s\n"
+ "IP: \t%s\n"
+ "Port: \t%s\n"
+ "Auth-User: \t%s\n"
+ "Auth-Realm: \t%s\n\n",
switch_str_nil(argv[0]), switch_str_nil(argv[1]), switch_str_nil(argv[2]), switch_str_nil(argv[3]),
- switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, switch_str_nil(argv[11]));
+ switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, switch_str_nil(argv[11]),
+ switch_str_nil(argv[12]), switch_str_nil(argv[13]), switch_str_nil(argv[14]), switch_str_nil(argv[15]));
return 0;
}
@@ -1516,16 +1521,22 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum
}
cb->stream->write_function(cb->stream,
- "\n"
- "%s\n"
- "%s@%s\n"
- "%s\n"
- "%s\n"
- "%s(%s) EXP(%s)\n"
- "%s\n"
- "\n",
- switch_str_nil(argv[0]), switch_str_nil(argv[1]), switch_str_nil(argv[2]), switch_amp_encode(switch_str_nil(argv[3]),xmlbuf,buflen),
- switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, switch_str_nil(argv[11]));
+ " \n"
+ " %s\n"
+ " %s@%s\n"
+ " %s\n"
+ " %s\n"
+ " %s(%s) exp(%s)\n"
+ " %s\n"
+ " %s\n"
+ " %s\n"
+ " %s\n"
+ " %s\n"
+ " \n",
+ switch_str_nil(argv[0]), switch_str_nil(argv[1]), switch_str_nil(argv[2]),
+ switch_amp_encode(switch_str_nil(argv[3]),xmlbuf,buflen),
+ switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, switch_str_nil(argv[11]),
+ switch_str_nil(argv[12]), switch_str_nil(argv[13]), switch_str_nil(argv[14]), switch_str_nil(argv[15]));
return 0;
}
@@ -1639,13 +1650,15 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
if (argv[4]) {
if (!strcasecmp(argv[3], "pres")) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
- "rpid,expires,user_agent,server_user,server_host,profile_name,hostname"
+ "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
+ "network_ip,network_port,sip_username,sip_realm"
" from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'",
profile->name, argv[4]);
}
} else {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
- "rpid,expires,user_agent,server_user,server_host,profile_name,hostname"
+ "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
+ "network_ip,network_port,sip_username,sip_realm"
" from sip_registrations where profile_name='%q' and contact like '%%%q%%'",
profile->name, argv[3]);
}
@@ -1653,7 +1666,8 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
if (!sql) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
- "rpid,expires,user_agent,server_user,server_host,profile_name,hostname"
+ "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
+ "network_ip,network_port,sip_username,sip_realm"
" from sip_registrations where profile_name='%q'",
profile->name);
}
@@ -1739,28 +1753,29 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
if (!strcasecmp(argv[0], "gateway")) {
if ((gp = sofia_reg_find_gateway(argv[1]))) {
switch_assert(gp->state < REG_STATE_LAST);
- stream->write_function(stream, "%s\n", header);
- stream->write_function(stream, "\n");
- stream->write_function(stream, "%s\n", switch_str_nil(gp->name));
- stream->write_function(stream, "%s\n", switch_str_nil(gp->register_scheme));
- stream->write_function(stream, "%s\n", switch_str_nil(gp->register_realm));
- stream->write_function(stream, "%s\n", switch_str_nil(gp->register_username));
- stream->write_function(stream, "%s\n", switch_strlen_zero(gp->register_password) ? "no" : "yes");
- stream->write_function(stream, "%s\n", switch_amp_encode(switch_str_nil(gp->register_from),xmlbuf,buflen));
- stream->write_function(stream, "%s\n", switch_amp_encode(switch_str_nil(gp->register_contact),xmlbuf,buflen));
- stream->write_function(stream, "%s\n", switch_amp_encode(switch_str_nil(gp->extension),xmlbuf,buflen));
- stream->write_function(stream, "%s\n", switch_str_nil(gp->register_to));
- stream->write_function(stream, "%s\n", switch_str_nil(gp->register_proxy));
- stream->write_function(stream, "%s\n", switch_str_nil(gp->register_context));
- stream->write_function(stream, "%s\n", switch_str_nil(gp->expires_str));
- stream->write_function(stream, "%d\n", gp->freq);
- stream->write_function(stream, "%d\n", gp->ping);
- stream->write_function(stream, "%d\n", gp->ping_freq);
- stream->write_function(stream, "%s\n", sofia_state_names[gp->state]);
- stream->write_function(stream, "%s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : "");
- stream->write_function(stream, "%d\n", gp->ib_calls);
- stream->write_function(stream, "%d\n", gp->ob_calls);
- stream->write_function(stream, "\n");
+ stream->write_function(stream, "%s\n", header);
+ stream->write_function(stream, " \n");
+ stream->write_function(stream, " %s\n", switch_str_nil(gp->name));
+ stream->write_function(stream, " %s\n", switch_str_nil(gp->register_scheme));
+ stream->write_function(stream, " %s\n", switch_str_nil(gp->register_realm));
+ stream->write_function(stream, " %s\n", switch_str_nil(gp->register_username));
+ stream->write_function(stream, " %s\n", switch_strlen_zero(gp->register_password) ? "no" : "yes");
+ stream->write_function(stream, " %s\n", switch_amp_encode(switch_str_nil(gp->register_from),xmlbuf,buflen));
+ stream->write_function(stream, " %s\n", switch_amp_encode(switch_str_nil(gp->register_contact),xmlbuf,buflen));
+ stream->write_function(stream, " %s\n", switch_amp_encode(switch_str_nil(gp->extension),xmlbuf,buflen));
+ stream->write_function(stream, " %s\n", switch_str_nil(gp->register_to));
+ stream->write_function(stream, " %s\n", switch_str_nil(gp->register_proxy));
+ stream->write_function(stream, " %s\n", switch_str_nil(gp->register_context));
+ stream->write_function(stream, " %s\n", switch_str_nil(gp->expires_str));
+ stream->write_function(stream, " %d\n", gp->freq);
+ stream->write_function(stream, " %d\n", gp->ping);
+ stream->write_function(stream, " %d\n", gp->ping_freq);
+ stream->write_function(stream, " %s\n", sofia_state_names[gp->state]);
+ stream->write_function(stream, " %s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : "");
+ stream->write_function(stream, " %d\n", gp->ib_calls);
+ stream->write_function(stream, " %d\n", gp->ob_calls);
+
+ stream->write_function(stream, " \n");
sofia_reg_release_gateway(gp);
} else {
stream->write_function(stream, "Invalid Gateway!\n");
@@ -1772,57 +1787,47 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
if ((argv[1]) && (profile = sofia_glue_find_profile(argv[1]))) {
if (!argv[2] || strcasecmp(argv[2], "reg")) {
stream->write_function(stream, "%s\n", header);
- stream->write_function(stream, "\n");
- stream->write_function(stream, "\n");
- stream->write_function(stream, "%s\n", switch_str_nil(argv[1]));
- stream->write_function(stream, "%s\n", profile->domain_name ? profile->domain_name : "N/A");
+ stream->write_function(stream, " \n");
+ stream->write_function(stream, " \n");
+ stream->write_function(stream, " %s\n", switch_str_nil(argv[1]));
+ stream->write_function(stream, " %s\n", profile->domain_name ? profile->domain_name : "N/A");
if (strcasecmp(argv[1], profile->name)) {
- stream->write_function(stream, "%s\n", switch_str_nil(profile->name));
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->name));
}
- stream->write_function(stream, "%s\n", switch_str_nil(profile->dbname));
- stream->write_function(stream, "%s\n", switch_str_nil(profile->presence_hosts));
- stream->write_function(stream, "%s\n", switch_str_nil(profile->dialplan));
- stream->write_function(stream, "%s\n", switch_str_nil(profile->context));
- stream->write_function(stream, "%s\n",
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->dbname));
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->presence_hosts));
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->dialplan));
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->context));
+ stream->write_function(stream, " %s\n",
switch_strlen_zero(profile->challenge_realm) ? "auto_to" : profile->challenge_realm);
- stream->write_function(stream, "%s\n", switch_str_nil(profile->rtpip));
- if (profile->extrtpip) {
- stream->write_function(stream, "%s\n", profile->extrtpip);
- }
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->rtpip));
+ stream->write_function(stream, " %s\n", profile->extrtpip);
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->sipip));
+ stream->write_function(stream, " %s\n", profile->extsipip);
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->url));
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->bindurl));
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->tls_url));
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->tls_bindurl));
+ stream->write_function(stream, " %s\n", switch_strlen_zero(profile->hold_music) ? "N/A" : profile->hold_music);
+ stream->write_function(stream, " %s\n", switch_strlen_zero(profile->outbound_proxy) ? "N/A" : profile->outbound_proxy);
+ stream->write_function(stream, " %s\n", switch_str_nil(profile->codec_string));
+ stream->write_function(stream, " %d\n", profile->te);
+ stream->write_function(stream, " rfc2833\n");
+ stream->write_function(stream, " info\n");
+ stream->write_function(stream, " none\n");
+ stream->write_function(stream, " %d\n", profile->cng_pt);
+ stream->write_function(stream, " %d\n", profile->session_timeout);
+ stream->write_function(stream, " %d\n", profile->max_proceeding);
+ stream->write_function(stream, " %s\n", sofia_test_flag(profile, TFLAG_INB_NOMEDIA) ? "true" : "false");
+ stream->write_function(stream, " %s\n", sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION) ? "true" : "false");
+ stream->write_function(stream, " %s\n", sofia_test_flag(profile, TFLAG_PROXY_MEDIA) ? "true" : "false");
+ stream->write_function(stream, " %s\n", sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION) ? "true" : "false");
+ stream->write_function(stream, " %s\n", sofia_test_pflag(profile, PFLAG_STUN_ENABLED) ? "true" : "false");
+ stream->write_function(stream, " %s\n", sofia_test_pflag(profile, PFLAG_STUN_AUTO_DISABLE) ? "true" : "false");
- stream->write_function(stream, "%s\n", switch_str_nil(profile->sipip));
- if (profile->extsipip) {
- stream->write_function(stream, "%s\n", profile->extsipip);
- }
- stream->write_function(stream, "%s\n", switch_str_nil(profile->url));
- stream->write_function(stream, "%s\n", switch_str_nil(profile->bindurl));
- if (sofia_test_pflag(profile, PFLAG_TLS)) {
- stream->write_function(stream, "%s\n", switch_str_nil(profile->tls_url));
- stream->write_function(stream, "%s\n", switch_str_nil(profile->tls_bindurl));
- }
- stream->write_function(stream, "%s\n", switch_strlen_zero(profile->hold_music) ? "N/A" : profile->hold_music);
- stream->write_function(stream, "%s\n", switch_strlen_zero(profile->outbound_proxy) ? "N/A" : profile->outbound_proxy);
- stream->write_function(stream, "%s\n", switch_str_nil(profile->codec_string));
- stream->write_function(stream, "%d\n", profile->te);
- if (profile->dtmf_type == DTMF_2833) {
- stream->write_function(stream, "rfc2833\n");
- } else if (profile->dtmf_type == DTMF_INFO) {
- stream->write_function(stream, "info\n");
- } else {
- stream->write_function(stream, "none\n");
- }
- stream->write_function(stream, "%d\n", profile->cng_pt);
- stream->write_function(stream, "%d\n", profile->session_timeout);
- stream->write_function(stream, "%d\n", profile->max_proceeding);
- stream->write_function(stream, "%s\n", sofia_test_flag(profile, TFLAG_INB_NOMEDIA) ? "true" : "false");
- stream->write_function(stream, "%s\n", sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION) ? "true" : "false");
- stream->write_function(stream, "%s\n", sofia_test_flag(profile, TFLAG_PROXY_MEDIA) ? "true" : "false");
- stream->write_function(stream, "%s\n", sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION) ? "true" : "false");
- stream->write_function(stream, "%s\n", sofia_test_pflag(profile, PFLAG_STUN_ENABLED) ? "true" : "false");
- stream->write_function(stream, "%s\n", sofia_test_pflag(profile, PFLAG_STUN_AUTO_DISABLE) ? "true" : "false");
}
- stream->write_function(stream, "\n");
- stream->write_function(stream, "\n");
+ stream->write_function(stream, " \n");
+ stream->write_function(stream, " \n");
cb.profile = profile;
cb.stream = stream;
@@ -1831,13 +1836,15 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
if (argv[4]) {
if (!strcasecmp(argv[3], "pres")) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
- "rpid,expires,user_agent,server_user,server_host,profile_name,hostname"
+ "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
+ "network_ip,network_port,sip_username,sip_realm"
" from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'",
profile->name, argv[4]);
}
} else {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
- "rpid,expires,user_agent,server_user,server_host,profile_name,hostname"
+ "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
+ "network_ip,network_port,sip_username,sip_realm"
" from sip_registrations where profile_name='%q' and contact like '%%%q%%'",
profile->name, argv[3]);
}
@@ -1845,7 +1852,8 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
if (!sql) {
sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
- "rpid,expires,user_agent,server_user,server_host,profile_name,hostname"
+ "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
+ "network_ip,network_port,sip_username,sip_realm"
" from sip_registrations where profile_name='%q'",
profile->name);
}
@@ -1853,8 +1861,8 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, show_reg_callback_xml, &cb);
free(sql);
- stream->write_function(stream, "\n");
- stream->write_function(stream, "\n");
+ stream->write_function(stream, "\n");
+ stream->write_function(stream, "\n");
sofia_glue_release_profile(profile);
} else {
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index c2de0e46a8..b8f665cc44 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -677,8 +677,10 @@ void sofia_presence_mwi_event_handler(switch_event_t *event);
void sofia_presence_cancel(void);
switch_status_t config_sofia(int reload, char *profile_name);
void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_regtype_t regtype, const char *realm, int stale);
-auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization, sip_t const *sip, const char *regstr,
- char *np, size_t nplen, char *ip, switch_event_t **v_event, long exptime, sofia_regtype_t regtype, const char *to_user);
+auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization,
+ sip_t const *sip, const char *regstr, char *np, size_t nplen, char *ip, switch_event_t **v_event,
+ long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params);
+
void sofia_reg_handle_sip_r_challenge(int status,
char const *phrase,
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 4754a5b368..d7041b28e6 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -406,7 +406,7 @@ void sofia_event_callback(nua_event_t event,
get_addr(network_ip, sizeof(network_ip), addrinfo->ai_addr, addrinfo->ai_addrlen);
auth_res = sofia_reg_parse_auth(profile, authorization, sip,
(char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, NULL, 0,
- REG_INVITE, NULL);
+ REG_INVITE, NULL, NULL);
}
if (auth_res != AUTH_OK) {
@@ -579,6 +579,12 @@ void event_handler(switch_event_t *event)
char *profile_name = switch_event_get_header(event, "orig-profile-name");
char *to_user = switch_event_get_header(event, "orig-to-user");
char *presence_hosts = switch_event_get_header(event, "presence-hosts");
+ char *network_ip = switch_event_get_header(event, "network-ip");
+ char *network_port = switch_event_get_header(event, "network-port");
+ char *username = switch_event_get_header(event, "username");
+ char *realm = switch_event_get_header(event, "realm");
+
+
sofia_profile_t *profile = NULL;
char guess_ip4[256];
@@ -606,10 +612,11 @@ void event_handler(switch_event_t *event)
switch_find_local_ip(guess_ip4, sizeof(guess_ip4), AF_INET);
sql = switch_mprintf("insert into sip_registrations "
- "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires,user_agent,server_user,server_host,profile_name,hostname) "
- "values ('%q', '%q','%q','%q','Registered', '%q', %ld, '%q', '%q', '%q','%q','%q')",
+ "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires,"
+ "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm) "
+ "values ('%q', '%q','%q','%q','Registered', '%q', %ld, '%q', '%q', '%q','%q','%q','%q','%q','%q','%q')",
call_id, from_user, from_host, presence_hosts, contact_str, rpid, expires, user_agent, to_user, guess_ip4,
- profile_name,mod_sofia_globals.hostname);
+ profile_name,mod_sofia_globals.hostname, network_ip, network_port, username, realm);
if (sql) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index ae5ec822c3..ab6a00fa1b 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -3191,7 +3191,9 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
" profile_name VARCHAR(255),\n"
" hostname VARCHAR(255),\n"
" network_ip VARCHAR(255),\n"
- " network_port VARCHAR(6)\n"
+ " network_port VARCHAR(6),\n"
+ " sip_username VARCHAR(255),\n"
+ " sip_realm VARCHAR(255)\n"
");\n";
@@ -3289,6 +3291,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
"create index sr_status on sip_registrations (status)",
"create index sr_network_ip on sip_registrations (network_ip)",
"create index sr_network_port on sip_registrations (network_port)",
+ "create index sr_sip_username on sip_registrations (sip_username)",
+ "create index sr_sip_realm on sip_registrations (sip_realm)",
"create index ss_call_id on sip_subscriptions (call_id)",
"create index ss_hostname on sip_subscriptions (hostname)",
"create index ss_sip_user on sip_subscriptions (sip_user)",
@@ -3329,7 +3333,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
test_sql = switch_mprintf("delete from sip_registrations where (contact like '%%TCP%%' "
"or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q' "
- "and network_ip!='-1' and network_port!='-1'",
+ "and network_ip!='-1' and network_port!='-1' and sip_username != '-1'",
mod_sofia_globals.hostname);
if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
@@ -3401,7 +3405,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
test_sql = switch_mprintf("delete from sip_registrations where (contact like '%%TCP%%' "
"or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q' "
- "and network_ip!='-1' and network_port!='-1'",
+ "and network_ip!='-1' and network_port!='-1' and sip_username != '-1'",
mod_sofia_globals.hostname);
switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_registrations", reg_sql);
@@ -3465,6 +3469,9 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
switch_core_db_exec(profile->master_db, "create index if not exists sr_status on sip_registrations (status)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_network_ip on sip_registrations (network_ip)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists sr_network_port on sip_registrations (network_port)", NULL, NULL, NULL);
+ switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_username on sip_registrations (sip_username)", NULL, NULL, NULL);
+ switch_core_db_exec(profile->master_db, "create index if not exists sr_sip_realm on sip_registrations (sip_realm)", NULL, NULL, NULL);
+
switch_core_db_exec(profile->master_db, "create index if not exists ss_call_id on sip_subscriptions (call_id)", NULL, NULL, NULL);
switch_core_db_exec(profile->master_db, "create index if not exists ss_hostname on sip_subscriptions (hostname)", NULL, NULL, NULL);
diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c
index b0cb856740..a166c58c1f 100644
--- a/src/mod/endpoints/mod_sofia/sofia_reg.c
+++ b/src/mod/endpoints/mod_sofia/sofia_reg.c
@@ -699,6 +699,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
char received_data[128] = "";
char *path_val = NULL;
su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
+ switch_event_t *auth_params = NULL;
+ int r = 0;
/* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
@@ -723,7 +725,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (!to_user || !to_host) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can not do authorization without a complete from header\n");
nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END());
- return 1;
+ switch_goto_int(r, 1, end);
}
if (!reg_host) {
@@ -840,7 +842,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (authorization) {
char *v_contact_str;
if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, sip->sip_request->rq_method_name,
- key, keylen, network_ip, v_event, exptime, regtype, to_user)) == AUTH_STALE) {
+ key, keylen, network_ip, v_event, exptime, regtype, to_user, &auth_params)) == AUTH_STALE) {
stale = 1;
}
@@ -913,7 +915,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
} else {
nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END());
}
- return 1;
+ switch_goto_int(r, 1, end);
}
}
@@ -934,12 +936,12 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
} else {
sofia_reg_auth_challenge(nua, profile, nh, regtype, realm, stale);
}
- return 1;
+ switch_goto_int(r, 1, end);
}
reg:
if (regtype != REG_REGISTER) {
- return 0;
+ switch_goto_int(r, 0, end);
}
call_id = sip->sip_call_id->i_id;
@@ -959,6 +961,13 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
if (exptime) {
const char *agent = "dunno";
char guess_ip4[256];
+ const char *username = "unknown";
+ const char *realm = reg_host;
+
+ if (auth_params) {
+ username = switch_event_get_header(auth_params, "sip_auth_username");
+ realm = switch_event_get_header(auth_params, "sip_auth_realm");
+ }
if (sip->sip_user_agent) {
agent = sip->sip_user_agent->g_string;
@@ -979,11 +988,12 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_find_local_ip(guess_ip4, sizeof(guess_ip4), AF_INET);
sql = switch_mprintf("insert into sip_registrations "
- "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires,user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port) "
- "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q')",
+ "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires,"
+ "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm) "
+ "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q')",
call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : reg_host,
contact_str, reg_desc, rpid, (long) switch_epoch_time_now(NULL) + (long) exptime * 2,
- agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c);
+ agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm);
if (sql) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
@@ -1006,6 +1016,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", from_host);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip);
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-port", network_port_c);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "username", username);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "realm", realm);
switch_event_fire(&s_event);
}
@@ -1154,10 +1166,17 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
}
- return 1;
+ switch_goto_int(r, 1, end);
}
- return 0;
+
+ end:
+
+ if (auth_params) {
+ switch_event_destroy(&auth_params);
+ }
+
+ return r;
}
@@ -1458,8 +1477,19 @@ void sofia_reg_handle_sip_r_challenge(int status,
}
-auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization, sip_t const *sip, const char *regstr,
- char *np, size_t nplen, char *ip, switch_event_t **v_event, long exptime, sofia_regtype_t regtype, const char *to_user)
+auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile,
+ sip_authorization_t const *authorization,
+ sip_t const *sip,
+ const char *regstr,
+ char *np,
+ size_t nplen,
+ char *ip,
+ switch_event_t **v_event,
+ long exptime,
+ sofia_regtype_t
+ regtype,
+ const char *to_user,
+ switch_event_t **auth_params)
{
int indexnum;
const char *cur;
@@ -1600,6 +1630,10 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "sip_auth_method", (sip && sip->sip_request) ? sip->sip_request->rq_method_name : NULL);
+ if (auth_params) {
+ switch_event_dup(auth_params, params);
+ }
+
if (!switch_strlen_zero(profile->reg_domain)) {
domain_name = profile->reg_domain;