You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

365 lines
12 KiB

#!trydef REGISTRAR_NAT_PING_INTERVAL 30
#!trydef REGISTRAR_NAT_PING_WORKERS 5
#!trydef REGISTRAR_MIN_EXPIRES 300
#!trydef REGISTRAR_MAX_EXPIRES 3600
#!trydef REGISTRAR_CONTACT_MAX_SIZE 2048
######## Generic Hash Table container in shared memory ########
modparam("htable", "htable", "auth_cache=>size=16;autoexpire=7200;")
####### Authentication Interface module ##########
loadmodule "auth.so"
#!ifdef OPENBTS_AUTH_ROLE
loadmodule "auth_openbts.so"
modparam("auth", "qop", "")
modparam("auth", "secret", "OPENBTS_AUTH_SECRET")
modparam("auth_openbts", "challenge_attr", "$avp(digest_challenge)")
#!endif
####### 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", "KAZOO_DB_URL")
modparam("usrloc", "db_mode", 1)
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)
modparam("usrloc", "db_timer_clean", 1)
modparam("usrloc", "fetch_rows", 400)
######## 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", 0)
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", "gruu_enabled", 1)
modparam("registrar", "outbound_mode", 1)
modparam("registrar", "regid_mode", 1)
modparam("registrar", "path_mode", 1)
modparam("registrar", "use_path", 1)
modparam("registrar", "received_param", "")
##modparam("registrar", "xavp_rcd", "ulrcd")
modparam("registrar", "contact_max_size", REGISTRAR_CONTACT_MAX_SIZE)
####### 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\n");
force_rport();
}
fix_nated_register();
## KAZOO-1846: Cisco SPA8000 freaks out on options pings
if (!($ua =~ "Linksys/SPA8000"
|| $ua =~ "OpenBTS"
|| $ua =~ "SIPp"
|| (af==INET6)
)) {
setbflag(FLB_NATB);
setbflag(FLB_NATSIPPING);
}
#!endif
route(ATTEMPT_AUTHORIZATION);
}
}
route[AUTHORIZATION_CHECK]
{
if (!is_method("MESSAGE|NOTIFY|SUBSCRIBE|PUBLISH"))
return;
if(has_totag())
return;
if (isflagset(FLAG_INTERNALLY_SOURCED))
return;
if (isflagset(FLAG_TRUSTED_SOURCE))
return;
$xavp(regcfg=>match_received) = $su;
if(!(registered("location", "$fu", 2, 1) == 1 && $(xavp(ulattrs=>custom_channel_vars){s.len}) > 1)) {
xlog("L_INFO", "$ci|log|not authorized $fu from $si:$sp\n");
send_reply("503", "Not Registered");
exit;
# route(ATTEMPT_AUTHORIZATION);
}
}
route[ATTEMPT_AUTHORIZATION]
{
$var(nonce) = $(uuid(g){s.rm,-});
#!ifdef OPENBTS_AUTH_ROLE
if($ua =~ "OpenBTS" && $sht(auth_cache=>$Au::nonce) != $null ) {
$var(nonce) = $sht(auth_cache=>$Au::nonce);
}
#!endif
$xavp(regcfg=>match_received) = $su;
if($sht(auth_cache=>$Au) != $null && registered("location", "$rz:$Au", 2, 1) == 1 && $(xavp(ulattrs=>custom_channel_vars){s.len}) > 1) {
$var(password) = $sht(auth_cache=>$Au);
route(SAVE_LOCATION);
}
if( is_present_hf("Authorization")) {
route(KAZOO_AUTHORIZATION);
}
#!ifdef OPENBTS_AUTH_ROLE
if($ua =~ "OpenBTS") {
openbts_auth_challenge("$fd", "$var(nonce)");
} else {
#!endif
auth_challenge("$fd", "0");
#!ifdef OPENBTS_AUTH_ROLE
}
#!endif
xlog("L_INFO", "$ci|end|issued auth challenge to new registration for $fu $si:$sp\n");
exit;
}
route[KAZOO_AUTHORIZATION]
{
$var(nonce) = $adn;
$var(amqp_payload_request) = $_s({"Event-Category" : "directory" , "Event-Name" : "authn_req", "Method" : "REGISTER", "Auth-Nonce" : "$adn", "Auth-Realm" : "$fd", "Auth-User" : "$fU", "From" : "$fu", "To" : "$tu", "Orig-IP" : "$si", "Orig-Port" : "$sp", "User-Agent" : "$(ua{s.escape.common}{s.replace,\','}{s.replace,$$,})", "Contact" : "$(ct{s.escape.common}{s.replace,\','}{s.replace,$$,})", "Call-ID" : "$ci" });
$var(amqp_routing_key) = "authn.req." + $(fd{kz.encode});
$avp(kz_timeout) = 2500;
if (!t_newtran()) {
sl_reply_error();
exit();
}
if(kazoo_async_query("callmgr", $var(amqp_routing_key), $var(amqp_payload_request), "KAZOO_AUTHORIZATION_OK", "KAZOO_AUTHORIZATION_ERROR") != 1) {
xlog("L_INFO", "$ci|log|failed to send Kazoo query for authentication credentials for $Au $si:$sp\n");
append_to_reply("Retry-After: 60\r\n");
send_reply("503", "Retry Later");
exit;
}
}
route[KAZOO_AUTHORIZATION_OK]
{
$var(password) = $(kzR{kz.json,Auth-Password});
$var(nonce) = $adn;
#!ifdef OPENBTS_AUTH_ROLE
if( $(kzR{kz.json,Auth-Nonce}) != "" && $var(nonce) != $(kzR{kz.json,Auth-Nonce})) {
xlog("L_INFO", "$ci|log|nonce replace $var(nonce) with $(kzR{kz.json,Auth-Nonce})\n");
$var(nonce) = $(kzR{kz.json,Auth-Nonce});
$sht(auth_cache=>$Au::nonce) = $var(nonce);
}
#!endif
if( $(kzR{kz.json,Event-Name}) == "authn_err" ) {
auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|end|issued auth challenge to registration attempt for $Au $si:$sp\n");
exit;
} else {
$xavp(ulattrs=>custom_channel_vars) = $(kzR{kz.json,Custom-Channel-Vars});
xlog("L_INFO", "$ci|log|authenticating $Au via Kazoo query response\n");
route(CHECK_AUTHORIZATION);
}
}
route[KAZOO_AUTHORIZATION_ERROR]
{
xlog("L_INFO", "$ci|log|failed to query Kazoo for authentication credentials for $Au $si:$sp\n");
append_to_reply("Retry-After: 60\r\n");
send_reply("503", "Retry Later");
exit;
}
route[CHECK_AUTHORIZATION]
{
if($ua =~ "OpenBTS") {
xlog("L_INFO", "$ci|end|OPENBTS attempt for $Au $si:$sp\n");
} else {
if($var(password) == $null || $var(password) == "") {
auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|end|issued auth challenge to registration attempt for $Au $si:$sp\n");
exit;
}
if (!pv_auth_check("$fd", "$var(password)", "0", "0")) {
#!ifdef ANTIFLOOD_ROLE
route(ANITFLOOD_FAILED_AUTH);
#!endif
auth_challenge("$fd", "0");
xlog("L_WARNING", "$ci|end|issued auth challenge to failed registration attempt for $Au from IP $si:$sp\n");
exit;
}
}
#!ifdef ANTIFLOOD_ROLE
route(ANTIFLOOD_SUCCESSFUL_AUTH);
#!endif
# user authenticated - remove auth header
consume_credentials();
route(SAVE_LOCATION);
}
route[SAVE_LOCATION]
{
if ($sht(auth_cache=>$Au) == $null) {
xlog("L_INFO", "$ci|log|caching sip credentials for $Au\n");
};
$sht(auth_cache=>$Au) = $var(password);
#!ifdef OPENBTS_AUTH_ROLE
if($ua =~ "OpenBTS") {
$sht(auth_cache=>$Au::nonce) = $var(nonce);
}
#!endif
$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\n");
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;
}
}
## this is what we should be using
## but ulrcd seems to have a weird leak
## if($var(save_result) == 3) {
## $var(expires) = 0;
## } else {
## $var(expires) = $xavp(ulrcd=>expires);
## }
if($var(expires) == 0) {
xlog("L_INFO", "$ci|end|unregister request from $Au $si:$sp\n");
$var(Status) = "Unregistered";
} else {
$var(Status) = "Registered";
if($var(expires) < REGISTRAR_MIN_EXPIRES) {
$var(expires) = REGISTRAR_MIN_EXPIRES;
} else if($var(expires) > REGISTRAR_MAX_EXPIRES) {
$var(expires) = REGISTRAR_MAX_EXPIRES;
}
}
$var(ip) = $Ri;
if(af==INET6) {
$var(ip) = "[" + $Ri + "]";
}
#!ifndef KZ_DISABLE_REGISTRAR_PORT
$var(port) = KZ_REGISTRAR_PORT;
#!else
$var(port) = $Rp;
#!endif
$var(AdvIP) = $RAi;
if(af==INET6) {
$var(AdvIP) = "[" + $RAi + "]";
}
$var(amqp_payload_request) = $_s({"Event-Category" : "directory", "Event-Name" : "reg_success", "Status" : "$var(Status)", "Event-Timestamp" : $TS, "Expires" : $(var(expires){s.int}), "First-Registration" : $var(new_reg), "Contact" : "$(ct{s.escape.common}{s.replace,\','}{s.replace,$$,})", "Call-ID" : "$ci", "Realm" : "$fd", "Username" : "$fU", "From-User" : "$fU", "From-Host" : "$fd", "To-User" : "$tU", "To-Host" : "$td", "User-Agent" : "$(ua{s.escape.common}{s.replace,\','}{s.replace,$$,})" , "Custom-Channel-Vars" : $xavp(ulattrs=>custom_channel_vars), "Proxy-Path" : "sip:$var(ip):$var(port)", "Proxy-Protocol" : "$proto", "Proxy-IP" : "$var(AdvIP)", "Proxy-Port" : "$RAp", "Source-IP": "$si", "Source-Port": "$sp" });
$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 $(var(Status){s.tolower}) with contact : $ct\n");
#!ifdef PUSHER_ROLE
route(PUSHER_ON_REGISTRATION);
#!endif
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});
xlog("L_INFO", "$(kzE{kz.json,Msg-ID})|log|received directory flush for $var(user)\n");
if ($sht(auth_cache=>$var(user)) != $null) {
$sht(auth_cache=>$var(user)) = $null;
}
if(reg_fetch_contacts("location", "sip:$var(user)", "caller")) {
$var(i) = 0;
while($var(i) < $(ulc(caller=>count))) {
unregister("location", "sip:$(ulc(caller=>aor))", "$(ulc(caller=>ruid)[$var(i)])");
$var(i) = $var(i) + 1;
}
reg_free_contacts("caller");
}
#!ifdef ANTIFLOOD_ROLE
route(ANTIFLOOD_RESET_AUTH);
#!endif
}
route[REGISTRAR_BINDINGS]
{
#!import_file "registrar-custom-bindings.cfg"
#!ifndef REGISTRAR_CUSTOM_BINDINGS
$var(payload) = "{ 'exchange' : 'registrar' , 'type' : 'topic', 'queue' : 'registrar-flush-MY_HOSTNAME', 'routing' : 'registration.flush.*', 'federate' : 1 }";
kazoo_subscribe("$var(payload)");
#!endif
#!ifdef REGISTRAR_SYNC_ROLE
route(REGISTRAR_SYNC_BINDINGS);
#!endif
}
#!ifdef REGISTRAR_SYNC_ROLE
#!include_file "registrar-sync-role.cfg"
#!endif
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab