|
|
#!trydef REGISTRAR_NAT_PING_INTERVAL 30
|
|
|
#!trydef REGISTRAR_NAT_PING_WORKERS 5
|
|
|
#!trydef REGISTRAR_MIN_EXPIRES 300
|
|
|
#!trydef REGISTRAR_MAX_EXPIRES 3600
|
|
|
|
|
|
######## Generic Hash Table container in shared memory ########
|
|
|
modparam("htable", "htable", "auth_cache=>size=16;autoexpire=7200;")
|
|
|
|
|
|
####### Authentication Interface module ##########
|
|
|
loadmodule "auth.so"
|
|
|
|
|
|
####### User Location Implementation module ##########
|
|
|
loadmodule "usrloc.so"
|
|
|
modparam("usrloc", "db_update_as_insert", 0)
|
|
|
modparam("usrloc", "use_domain", 1)
|
|
|
modparam("usrloc", "nat_bflag", FLB_NATB)
|
|
|
modparam("usrloc", "db_url", "text:///etc/kazoo/kamailio/dbtext")
|
|
|
modparam("usrloc", "db_mode", 0)
|
|
|
modparam("usrloc", "handle_lost_tcp", 1)
|
|
|
modparam("usrloc", "xavp_contact", "ulattrs")
|
|
|
modparam("usrloc", "db_check_update", 1)
|
|
|
modparam("usrloc", "timer_interval", 30)
|
|
|
modparam("usrloc", "timer_procs", 1)
|
|
|
|
|
|
|
|
|
######## NAT Traversal module - signaling functions ########
|
|
|
#!ifdef NAT-TRAVERSAL-ROLE
|
|
|
#!trydef NATHELPER-LOADED
|
|
|
loadmodule "nathelper.so"
|
|
|
modparam("nathelper", "natping_interval", REGISTRAR_NAT_PING_INTERVAL)
|
|
|
modparam("nathelper", "ping_nated_only", 1)
|
|
|
modparam("nathelper", "natping_processes", REGISTRAR_NAT_PING_WORKERS)
|
|
|
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
|
|
|
#!endif
|
|
|
|
|
|
####### SIP Registrar implementation module ##########
|
|
|
loadmodule "registrar.so"
|
|
|
modparam("registrar", "received_avp", "$avp(AVP_RECV_PARAM)")
|
|
|
modparam("registrar", "min_expires", REGISTRAR_MIN_EXPIRES)
|
|
|
modparam("registrar", "max_expires", REGISTRAR_MAX_EXPIRES)
|
|
|
modparam("registrar", "xavp_cfg", "regcfg")
|
|
|
modparam("registrar", "reg_on_match_flag", 1)
|
|
|
|
|
|
|
|
|
####### Registrar Logic ########
|
|
|
route[HANDLE_REGISTER]
|
|
|
{
|
|
|
if (is_method("REGISTER")) {
|
|
|
|
|
|
#!ifdef NAT-TRAVERSAL-ROLE
|
|
|
if (nat_uac_test("3")) {
|
|
|
xlog("L_INFO", "$ci|log|correcting NATed contact in registration");
|
|
|
force_rport();
|
|
|
fix_nated_register();
|
|
|
}
|
|
|
|
|
|
## KAZOO-1846: Cisco SPA8000 freaks out on options pings
|
|
|
if (!($ua =~ "Linksys/SPA8000")) {
|
|
|
setbflag(FLB_NATB);
|
|
|
setbflag(FLB_NATSIPPING);
|
|
|
}
|
|
|
#!endif
|
|
|
|
|
|
if (is_present_hf("Authorization")) {
|
|
|
route(ATTEMPT_AUTHORIZATION);
|
|
|
} else {
|
|
|
auth_challenge("$fd", "0");
|
|
|
xlog("L_INFO", "$ci|end|issued auth challenge to new registration for $fu $si:$sp");
|
|
|
exit;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
route[ATTEMPT_AUTHORIZATION]
|
|
|
{
|
|
|
$xavp(regcfg=>match_received) = $su;
|
|
|
$xavp(regcfg[0]=>match_contact) = $(ct{nameaddr.uri});
|
|
|
|
|
|
if ($sht(auth_cache=>$Au) != $null && registered("location", "$rz:$Au", 6) == 1) {
|
|
|
xlog("L_INFO", "$ci|log|authenticating $fu via cached SIP creds");
|
|
|
$var(password) = $sht(auth_cache=>$Au);
|
|
|
} else {
|
|
|
$var(amqp_payload_request) = "{'Event-Category' : 'directory' , 'Event-Name' : 'authn_req', 'Method' : 'REGISTER', 'Auth-Realm' : '" + $fd + "', 'Auth-User' : '" + $fU + "', 'From' : '" + $fu + "', 'To' : '" + $tu +"' }";
|
|
|
$var(amqp_routing_key) = "authn.req." + $(fd{kz.encode});
|
|
|
sl_send_reply("100", "Attempting Kazoo query");
|
|
|
if(kazoo_query("callmgr", $var(amqp_routing_key), $var(amqp_payload_request))) {
|
|
|
$var(password) = $(kzR{kz.json,Auth-Password});
|
|
|
$xavp(ulattrs=>custom_channel_vars) = $(kzR{kz.json,Custom-Channel-Vars});
|
|
|
xlog("L_INFO", "$ci|log|authenticating $Au via Kazoo query response");
|
|
|
} else {
|
|
|
xlog("L_INFO", "$ci|log|failed to query Kazoo for authentication credentials for $Au $si:$sp");
|
|
|
append_to_reply("Retry-After: 60\r\n");
|
|
|
sl_send_reply("500", "Retry Later");
|
|
|
exit;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if($var(password) == $null) {
|
|
|
auth_challenge("$fd", "0");
|
|
|
xlog("L_INFO", "$ci|end|issued auth challenge to registration attempt for $Au $si:$sp");
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
if (!pv_auth_check("$fd", "$var(password)", "0", "0")) {
|
|
|
#!ifdef ANTIFLOOD-ROLE
|
|
|
route(ANITFLOOD_FAILED_AUTH);
|
|
|
#!endif
|
|
|
|
|
|
auth_challenge("$fd", "0");
|
|
|
xlog("L_INFO", "$ci|end|issued auth challenge to failed registration attempt for $Au $si:$sp");
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
#!ifdef ANTIFLOOD-ROLE
|
|
|
route(ANTIFLOOD_SUCCESSFUL_AUTH);
|
|
|
#!endif
|
|
|
|
|
|
if ($sht(auth_cache=>$Au) == $null) {
|
|
|
xlog("L_INFO", "$ci|log|caching SIP credentials for $Au");
|
|
|
$sht(auth_cache=>$Au) = $var(password);
|
|
|
}
|
|
|
|
|
|
# user authenticated - remove auth header
|
|
|
consume_credentials();
|
|
|
|
|
|
$var(save_result) = save("location", "0x04");
|
|
|
if($var(save_result) == -1) {
|
|
|
auth_challenge("$fd", "0");
|
|
|
xlog("L_INFO", "$ci|end|issued auth challenge after failed attempt to save contact for $Au $si:$sp");
|
|
|
exit;
|
|
|
} else {
|
|
|
if($var(save_result) == 1) {
|
|
|
$var(new_reg) = "true";
|
|
|
} else {
|
|
|
$var(new_reg) = "false";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if(@contact.expires) {
|
|
|
$var(expires) = @contact.expires;
|
|
|
} else {
|
|
|
if(is_present_hf("Expires")) {
|
|
|
$var(expires) = $hdr(Expires);
|
|
|
} else {
|
|
|
$var(expires) = REGISTRAR_MIN_EXPIRES;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if($var(expires) == 0) {
|
|
|
xlog("L_INFO", "$ci|end|unregister request from $Au $si:$sp");
|
|
|
exit;
|
|
|
} else if($var(expires) < REGISTRAR_MIN_EXPIRES) {
|
|
|
$var(expires) = REGISTRAR_MIN_EXPIRES;
|
|
|
} else if($var(expires) > REGISTRAR_MAX_EXPIRES) {
|
|
|
$var(expires) = REGISTRAR_MAX_EXPIRES;
|
|
|
}
|
|
|
|
|
|
## Fix for wss websockets.
|
|
|
## RFC 7118 says transport MUST be "ws" not "wss"
|
|
|
## http://tools.ietf.org/html/rfc7118#section-5.2
|
|
|
if ($(proto{s.tolower}) == 'wss') {
|
|
|
$var(transport) = "ws";
|
|
|
} else {
|
|
|
$var(transport) = $(proto{s.tolower});
|
|
|
}
|
|
|
|
|
|
if($var(transport) == "udp" ||$var(transport) == "tcp" || $var(transport) == "tls") {
|
|
|
$var(return_port) = $Rp;
|
|
|
} else {
|
|
|
$var(return_port) = "5060";
|
|
|
}
|
|
|
|
|
|
$var(params) = "fs_path=<sip:" + $Ri + ":" + $var(return_port) + ";lr;received='" + $rz + ":" + $si + ":" + $sp + ";transport=" + $var(transport) + "'>";
|
|
|
|
|
|
## TODO: fix escaping, some phones send us -- reg-id=1;+sip.instance="urn:uuid:9b8bd513-0e6e-4660-ad5e-5e35d88cc68f";
|
|
|
## and if we can store it but not use it because it looses the escapes (that weren't there...)
|
|
|
#if($(ct{tobody.params}) != $null) {
|
|
|
# $var(params) = $(ct{tobody.params}{s.escape.common}) + ";" + $var(params);
|
|
|
#}
|
|
|
|
|
|
if ($avp(AVP_RECV_PARAM) == $null) {
|
|
|
$var(fs_contact) = "<" + $(ct{tobody.uri}) + ";" + $var(params) + ">";
|
|
|
} else {
|
|
|
$var(fs_contact) = "<sip:" + $(ct{tobody.user}) + "@" + $si + ":" + $sp + ";transport=" + $var(transport) + ";" + $var(params) + ">";
|
|
|
}
|
|
|
|
|
|
$var(register_contants) = ' "Presence-Hosts" : "n/a", "Profile-Name" : "sipinterface_1", "Status" : "Registered", "Event-Timestamp" : "' + $TS + '", "Expires" : ' + $var(expires);
|
|
|
|
|
|
$var(amqp_payload_request) = '{"Event-Category" : "directory", "Event-Name" : "reg_success", "First-Registration" : $var(new_reg), "Contact" : "$var(fs_contact)", "Call-ID" : "$ci", "Realm" : "$fd", "Username" : "$fU", "From-User" : "$fU", "From-Host" : "$fd", "To-User" : "$tU", "To-Host" : "$td", "User-Agent" : "$ua" , "Custom-Channel-Vars" : $xavp(ulattrs=>custom_channel_vars), $var(register_contants) }';
|
|
|
|
|
|
$var(amqp_routing_key) = "registration.success." + $(fd{kz.encode}) + "." + $(fU{kz.encode});
|
|
|
|
|
|
kazoo_publish("registrar", $var(amqp_routing_key), $var(amqp_payload_request));
|
|
|
|
|
|
xlog("L_INFO", "$ci|end|successful registration with contact $var(fs_contact)");
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
## kazoo event route , {"directory", "reg_flush") => reg-flush by kamailio limitations
|
|
|
## when a Event-Category or Event-Name has a underscore (_) we need to declare it with a dash (-)
|
|
|
event_route[kazoo:consumer-event-directory-reg-flush]
|
|
|
{
|
|
|
$var(user) = $(kzE{kz.json,Username}) + "@" + $(kzE{kz.json,Realm});
|
|
|
if ($sht(auth_cache=>$var(user)) != $null) {
|
|
|
xlog("L_INFO", "log|removing SIP credentials cache for $var(user)");
|
|
|
$sht(auth_cache=>$var(user)) = $null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
|