Browse Source

start to support authentication for other methods

master
lazedo 6 years ago
parent
commit
082ecbfc40
3 changed files with 242 additions and 195 deletions
  1. +0
    -172
      kamailio/auth.cfg
  2. +0
    -23
      kamailio/authorization-role.cfg
  3. +242
    -0
      kamailio/authorization.cfg

+ 0
- 172
kamailio/auth.cfg View File

@ -1,172 +0,0 @@
#!trydef KZ_STRICT_AUTH 1
kazoo.strict_auth = KZ_STRICT_AUTH descr "only allow requests from registered or trusted sources"
route[AUTH]
{
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
$avp(auth_allowed) = "true";
return;
}
if (!is_method("INVITE|MESSAGE|REFER")) {
$avp(auth_allowed) = "true";
return;
}
#!ifdef DISPATCHER_ROLE
route(SETUP_AUTH_HEADERS);
#!endif
}
route[AUTH_HEADERS]
{
remove_hf_re("^X-");
if (!is_method("INVITE|MESSAGE|REFER")) {
return;
}
xavp_params_implode("hf", "$var(outx)");
$var(out) = $(var(outx){re.subst,/^(.*);$$/\1/});
$var(c) = $(var(out){param.count});
xlog("L_DEBUG", "$ci|auth|headers $var(c) => $var(out) => $var(outx)\n");
while($var(c) > 0) {
$var(idx) = $var(c) - 1;
xlog("L_DEBUG", "$ci|auth|adding $(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\n");
append_hf("$(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\r\n");
$var(c) = $var(c) - 1;
}
}
route[AUTH_HEADERS_JSON]
{
xavp_params_implode("hf", "$var(outx)");
$var(out) = $(var(outx){re.subst,/^(.*);$$/\1/});
$var(c) = $(var(out){param.count});
$var(headers_json) = "";
$var(sep) = "";
xlog("L_DEBUG", "$ci|auth|headers $var(c) => $var(out) => $var(outx)\n");
while($var(c) > 0) {
$var(idx) = $var(c) - 1;
xlog("L_DEBUG", "$ci|auth|adding $(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\n");
append_hf("$(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\r\n");
$var(headers_json) = $_s($var(headers_json)$var(sep)"$(var(out){param.name,$var(idx)})" : "$(var(out){param.valueat,$var(idx)}{s.unescape.param})");
$var(c) = $var(c) - 1;
$var(sep) = " , ";
}
$var(headers_json) = $_s({ $var(headers_json) });
}
route[SETUP_AUTH_HEADERS]
{
$avp(auth_allowed) = "false";
$xavp(hf=>X-AUTH-IP) = $si;
$xavp(hf[0]=>X-AUTH-PORT) = $sp;
#!ifdef REGISTRAR_ROLE
$avp(is_registered) = "false";
$xavp(regcfg=>match_received) = $su;
if (registered("location","sip:$Au", 2, 1) == 1) {
$avp(is_registered) = "true";
$avp(auth_allowed) = "true";
route(AUTH_XAVP_TOKEN);
return;
} else if(is_present_hf("Proxy-Authorization")) {
if(registered("location", "sip:$au@$ar", 2, 1) == 1) {
xlog("L_INFO", "$ci|auth|from sip:$au@$ar\n");
$avp(is_registered) = "true";
$avp(auth_allowed) = "true";
route(AUTH_XAVP_TOKEN);
return;
}
}
#!endif
if (allow_source_address()) {
$avp(auth_allowed) = "true";
$xavp(hf[0]=>X-AUTH-Token) = $avp(trusted_x_header);
$xavp(hf[0]=>X-AUTH-URI-User) = $rU;
$xavp(hf[0]=>X-AUTH-URI-Realm) = $rd;
if(is_present_hf("P-Asserted-Identity") && $(ai{uri.user}) != "") {
$xavp(hf[0]=>X-AUTH-From-User) = $(ai{uri.user});
} else if(is_present_hf("P-Preferred-Identity") && $pU != "") {
$xavp(hf[0]=>X-AUTH-From-User) = $pU;
} else if(is_present_hf("Remote-Party-ID") && $(re{uri.user}) != "") {
$xavp(hf[0]=>X-AUTH-From-User) = $(re{uri.user});
} else {
$xavp(hf[0]=>X-AUTH-From-User) = $fU;
}
if($xavp(hf=>X-AUTH-From-User) =~ "^\+?00+$") {
$xavp(hf[0]=>X-AUTH-From-Is-Anonymous) = "true";
$xavp(hf[0]=>X-AUTH-From-User) = $null;
} else if($(xavp(hf=>X-AUTH-From-User){s.tolower}) =~ "^anonymous$") {
$xavp(hf[0]=>X-AUTH-From-Is-Anonymous) = "true";
$xavp(hf[0]=>X-AUTH-From-User) = $null;
}
return;
}
}
#!ifdef REGISTRAR_ROLE
route[AUTH_XAVP_TOKEN]
{
#!ifdef WITH_AUTH_TOKEN
route(AUTH_TOKEN);
#!else
route(AUTH_CCVS)
#!endif
}
route[AUTH_TOKEN]
{
if($(xavp(ulattrs=>token){s.len}) > 0) {
$xavp(hf[0]=>X-AUTH-Token) = $xavp(ulattrs=>token);
} else {
if($(xavp(ulattrs=>Authorizing-ID){s.len}) > 0 && $(xavp(ulattrs=>Account-ID){s.len})) {
$xavp(hf[0]=>X-AUTH-Token) = $_s($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID})@$(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}));
}
}
}
route[AUTH_CCVS]
{
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}{s.len}) > 0 && $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type}{s.len}) > 0)
$xavp(hf[0]=>X-AUTH-Token) = $_s($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID})@$(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}));
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Account-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Authorizing-Type) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Authorizing-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Username}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Username) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Username});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Realm}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Realm) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Realm});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Realm}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Account-Realm) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Realm});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Name}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Account-Name) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Name}{s.escape.param});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Presence-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Presence-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Presence-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Owner-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Owner-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Owner-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Hotdesk-Current-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Hotdesk-Current-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Hotdesk-Current-ID});
}
#!endif

+ 0
- 23
kamailio/authorization-role.cfg View File

@ -1,23 +0,0 @@
## to be enhanced
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;
}
}

+ 242
- 0
kamailio/authorization.cfg View File

@ -0,0 +1,242 @@
modparam("statistics","variable", "auth:amqp_not_available")
modparam("statistics","variable", "auth:new_tran")
modparam("statistics","variable", "auth:challenge")
modparam("statistics","variable", "auth:amqp_async_error")
modparam("statistics","variable", "auth:amqp_returned")
modparam("statistics","variable", "auth:amqp_timeout")
modparam("statistics","variable", "auth:authn_perm_err")
modparam("statistics","variable", "auth:authn_err")
modparam("statistics","variable", "auth:authn_resp")
modparam("statistics","variable", "auth:authn_unknown")
route[AUTHORIZATION]
{
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
return;
}
if (isflagset(FLAG_AUTHORIZED)) {
return;
}
if (!is_method("INVITE|REFER|MESSAGE|NOTIFY|SUBSCRIBE|PUBLISH")) {
setflag(FLAG_AUTHORIZED);
return;
}
route(AUTHORIZATION_CHECK);
if (!isflagset(FLAG_AUTHORIZED)) {
xlog("L_INFO", "$ci|auth|challenging $rm from $Au $si:$sp\n");
$var(auth) = auth_challenge("$fd", "4");
update_stat("auth:challenge", "+1");
if($var(auth) != 1) {
xlog("L_ERROR", "$ci|register|error creating or sending challenge to $rm attempt for $fu from $si:$sp\n");
send_reply("403", "Forbidden");
}
exit;
}
}
route[AUTHORIZATION_CHECK]
{
route(AUTHORIZATION_CHECK_TRUSTED);
route(AUTHORIZATION_CHECK_REGISTERED);
}
route[AUTHORIZATION_CHECK_TRUSTED]
{
if (isflagset(FLAG_AUTHORIZED)) return;
if (isflagset(FLAG_TRUSTED_SOURCE)) {
route(SETUP_AUTH_ORIGIN);
route(SETUP_AUTH_TRUSTED);
setflag(FLAG_AUTHORIZED);
}
}
route[AUTHORIZATION_CHECK_REGISTERED]
{
if (isflagset(FLAG_AUTHORIZED)) return;
#!ifdef REGISTRAR_ROLE
$xavp(regcfg=>match_received) = $su;
if (registered("location","sip:$Au", 2, 1) == 1) {
route(SETUP_AUTH_ORIGIN);
$xavp(hf[0]=>X-AUTH-Token) = $xavp(ulattrs=>token);
setflag(FLAG_AUTHORIZED);
}
#!endif
}
route[HANDLE_AUTHORIZATION]
{
if(!is_present_hf("Proxy-Authorization")) {
route(MAIN);
exit;
}
$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) = $_s($def(REGISTRAR_AMQP_RK_PREFIX)$(fd{kz.encode}));
$avp(kz_timeout) = $sel(cfg_get.kazoo.registrar_query_timeout_ms);
$xavp(deltas=>query) = $(TV(Sn){s.replace,.,});
xlog("L_DEBUG", "$ci|amqp|publishing to $def(REGISTRAR_AMQP_EXCHANGE) => $var(amqp_routing_key) : $def(REGISTRAR_AMQP_FLAGS) : $var(amqp_payload_request)\n");
if(kazoo_async_query("$def(REGISTRAR_AMQP_EXCHANGE)", $var(amqp_routing_key), $var(amqp_payload_request), "KZ_AUTHORIZATION_CHECK_REPLY", "KZ_AUTHORIZATION_CHECK_TIMEOUT", "$def(REGISTRAR_AMQP_FLAGS)") != 1) {
xlog("L_INFO", "$ci|log|failed to send registrar query for authentication credentials for $Au $si:$sp\n");
update_stat("auth:amqp_async_error", "+1");
send_reply("403", "Forbidden");
exit;
}
}
failure_route[KZ_AUTHORIZATION_CHECK_TIMEOUT]
{
if($(kzR{kz.json,Event-Name}) == "message_returned" ) {
xlog("L_WARNING", "$ci|amqp|message was returned by broker $(kzR{kz.json,Error-Code}) $(kzR{kz.json,Error-Reason})\n");
update_stat("auth:amqp_returned", "+1");
} else {
xlog("L_WARNING", "$ci|end|failed $T_reply_code $T_reply_reason [$T(id_index):$T(id_label)] querying directory for authentication credentials for $Au $si:$sp\n");
update_stat("auth:amqp_timeout", "+1");
}
t_reply("403", "Forbidden");
exit;
}
onreply_route[KZ_AUTHORIZATION_CHECK_REPLY]
{
$var(StartRoute) = $(TV(Sn){s.replace,.,});
$var(delta_to_start) = $var(StartRoute) - $(kzR{kz.json,AMQP-Received});
$var(delta_from_query) = $(kzR{kz.json,AMQP-Received}) - $xavp(deltas=>query);
xlog("L_INFO", "$ci|log|received $(kzR{kz.json,Event-Category}) $(kzR{kz.json,Event-Name}) reply from $(kzR{kz.json,App-Name})-$(kzR{kz.json,App-Version}) (Δ1 $(kzR{kz.json,AMQP-Elapsed-Micro}) μs , Δ2 $var(delta_to_start) μs, Δ3 $var(delta_from_query) μs)\n");
$var(password) = $(kzR{kz.json,Auth-Password});
if( $(kzR{kz.json,Event-Name}) == "authn_err" ) {
update_stat("auth:authn_err", "+1");
t_reply("403", "Forbidden");
exit;
} else if( $(kzR{kz.json,Event-Name}) == "authn_resp" ) {
update_stat("auth:authn_resp", "+1");
route(KZ_AUTHORIZATION_CHECK_RESPONSE);
} else {
update_stat("auth:authn_unknown", "+1");
xlog("L_INFO", "$ci|log|unhandle response from directory $Au via $(kzR{kz.json,App-Name})-$(kzR{kz.json,App-Version})\n");
t_reply("403", "Forbidden");
exit;
}
}
route[KZ_AUTHORIZATION_CHECK_RESPONSE]
{
if (!pv_auth_check("$fd", "$var(password)", "0", "0")) {
#!ifdef ANTIFLOOD_ROLE
route(ANITFLOOD_FAILED_AUTH);
#!endif
xlog("L_WARNING", "$ci|end|auth|$mbu\n");
send_reply("403", "Forbidden");
exit;
}
consume_credentials();
route(SETUP_AUTH_ORIGIN);
$xavp(ulattrs=>custom_channel_vars) = $(kzR{kz.json,Custom-Channel-Vars});
$xavp(ulattrs[0]=>token) = $_s($(kzR{kz.json,Custom-Channel-Vars.Authorizing-ID})@$(kzR{kz.json,Custom-Channel-Vars.Account-ID}));
setflag(FLAG_AUTHORIZED);
route(MAIN);
exit;
}
route[SETUP_AUTH_ORIGIN]
{
$xavp(hf=>X-AUTH-IP) = $si;
$xavp(hf[0]=>X-AUTH-PORT) = $sp;
}
route[SETUP_AUTH_AOR]
{
if ($avp(is_registered) == "true") return;
#!ifdef REGISTRAR_ROLE
$xavp(regcfg=>match_received) = $su;
if (registered("location","sip:$Au", 2, 1) == 1) {
$avp(is_registered) = "true";
}
#!endif
}
route[SETUP_AUTH_TRUSTED]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
$xavp(hf[0]=>X-AUTH-Token) = $avp(trusted_x_header);
$xavp(hf[0]=>X-AUTH-URI-User) = $rU;
$xavp(hf[0]=>X-AUTH-URI-Realm) = $rd;
if(is_present_hf("P-Asserted-Identity") && $(ai{uri.user}) != "") {
$xavp(hf[0]=>X-AUTH-From-User) = $(ai{uri.user});
} else if(is_present_hf("P-Preferred-Identity") && $pU != "") {
$xavp(hf[0]=>X-AUTH-From-User) = $pU;
} else if(is_present_hf("Remote-Party-ID") && $(re{uri.user}) != "") {
$xavp(hf[0]=>X-AUTH-From-User) = $(re{uri.user});
} else {
$xavp(hf[0]=>X-AUTH-From-User) = $fU;
}
if($xavp(hf=>X-AUTH-From-User) =~ "^\+?00+$") {
$xavp(hf[0]=>X-AUTH-From-Is-Anonymous) = "true";
$xavp(hf[0]=>X-AUTH-From-User) = $null;
} else if($(xavp(hf=>X-AUTH-From-User){s.tolower}) =~ "^anonymous$") {
$xavp(hf[0]=>X-AUTH-From-Is-Anonymous) = "true";
$xavp(hf[0]=>X-AUTH-From-User) = $null;
}
setflag(FLAG_AUTHORIZED);
}
}
route[AUTH_HEADERS_JSON]
{
xavp_params_implode("hf", "$var(outx)");
$var(out) = $(var(outx){re.subst,/^(.*);$$/\1/});
$var(c) = $(var(out){param.count});
$var(headers_json) = "";
$var(sep) = "";
xlog("L_DEBUG", "$ci|auth|headers $var(c) => $var(out) => $var(outx)\n");
while($var(c) > 0) {
$var(idx) = $var(c) - 1;
xlog("L_DEBUG", "$ci|auth|adding $(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\n");
append_hf("$(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\r\n");
$var(headers_json) = $_s($var(headers_json)$var(sep)"$(var(out){param.name,$var(idx)})" : "$(var(out){param.valueat,$var(idx)}{s.unescape.param})");
$var(c) = $var(c) - 1;
$var(sep) = " , ";
}
$var(headers_json) = $_s({ $var(headers_json) });
}
route[AUTH_HEADERS]
{
remove_hf_re("^X-");
if (!is_method("INVITE|MESSAGE|REFER")) {
return;
}
xavp_params_implode("hf", "$var(outx)");
$var(out) = $(var(outx){re.subst,/^(.*);$$/\1/});
$var(c) = $(var(out){param.count});
xlog("L_DEBUG", "$ci|auth|headers $var(c) => $var(out) => $var(outx)\n");
while($var(c) > 0) {
$var(idx) = $var(c) - 1;
xlog("L_DEBUG", "$ci|auth|adding $(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\n");
append_hf("$(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\r\n");
$var(c) = $var(c) - 1;
}
}

Loading…
Cancel
Save