#!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", 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) ######## 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) ####### 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] { if ($sht(auth_cache=>$Au) != $null) { 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}); if(kazoo_query("callmgr", $var(amqp_routing_key), $var(amqp_payload_request))) { $var(password) = $(kzR{kz.json,Auth-Password}); 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"); } } 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(); save("location"); if(@contact.expires) { $var(expires) = @contact.expires; } else { if($hdr(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; } if($(proto{s.tolower}) == "udp" || $(proto{s.tolower}) == "tcp" || $(proto{s.tolower}) == "tls") { $var(return_port) = $Rp; } else { $var(return_port) = "5060"; } $var(params) = "fs_path="; ## 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) = ""; } $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", "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 + '" ,' + $var(register_contants) + ' }'; $var(amqp_routing_key) = "registration.success." + $(fd{kz.encode}) + "." + $(fU{kz.encode}); kazoo_publish("callmgr", $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