Dear all!
Please help. I have problem dealing with recursive call in failure route.
this route happen first time for authentication to external SIP provider
(react on code 401), then it have response 480 i want to direct traffic
to another operator via cr_route.
First i relay INVITE and getting 401, then sending authentication, but
provider gives 480. I can see it in a dump of SIP session. But my
failure_route still thinking that reply code is 401 on second reply.
Maybe because i dont understand well how branches concept work here? Or
using kamailio 3.0? ;) Looks like it give me status code of first reply
and ignoring actual code in reply. :( I don't know if it something with
development version or my own misunderstanding. sorry
route[PSTN_RELAY] {
# open trans or it will complain on uac_replace_from
if (!t_check_trans()) t_newtran();
#!ifdef WITH_NAT
if (check_route_param("nat=yes")) {
setbflag("6");
}
if (isflagset(5) || isbflagset("6")) {
route(RTPPROXY);
}
#!endif
cr_user_carrier("$fU", "$fd", "$avp(s:carrier)");
xlog ("L_INFO","carrier $avp(s:carrier) selected for $fU at $fd\n");
$avp(s:domain)="route_domain1";
if( !cr_route("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rU",
"call_id") ){
sl_send_reply("403", "Not allowed");
xlog ("cr_route failed for $rU from $fU@$fd\n");
t_release();
exit;
}
#loading auth information for $rd (ruri domain) and replace "From"
header
route (LOAD_AUTH);
xlog ("L_INFO","relaying to $rd\n");
#reducing size to fit MTU
remove_hf("User-Agent");
remove_hf("P-Preferred-Identity");
remove_hf("Record-route");
remove_hf("a=nortpproxy");
# setflag(11); # so failroute can procees carrierroute backup
# we do all in one failure block;
t_on_failure("FAIL_ONE");
if (!t_relay()) {
sl_reply_error();
}
exit;
}
##### LOAD_AUTH ##########
# loading authentication information from carrierauth table
# set From field according to carrierauth information
# arguments:
# $rd - request uri doamin, sip provider carrier
# returns:
# avp(i:20) - rewrited host = $rd
# avp(i:21) - auth user
# avp(i:22) - auth pass
# avp(i:23) - auth realm
# avp(i:24) - auth domain
route[LOAD_AUTH]{
xlog ("L_INFO","searching authentication for $rd host");
$avp(i:20)=$rd;
if ( avp_db_query(
"SELECT username, password, realm, domain FROM carrierauth WHERE
hostname='$rd'",
"$avp(i:21);$avp(i:22);$avp(i:23);$avp(i:24)") > 0 ) {
xlog ("L_INFO"," for $rd got user: $avp(i:21) pass: $avp(i:22)
realm: $avp(i:23) domain: $avp(i:24)");
# replace from_user@from_domain
xlog("L_INFO","changing from -> sip:$avp(i:21)@$avp(i:24)");
uac_replace_from("sip:$avp(i:21)@$avp(i:24)");
}
# we are not relaying authentications :)
remove_hf("Authorization"); # remove client authentication
# reset flag to mark no authentication yet performed
resetflag(10); # let's use 10 to know uac authentication was sent
return(1);
}
failure_route[FAIL_ONE] {
xlog("L_INFO","failure reply: $T_rpl($rr) $T_rpl($rs) $T_reply_code
$branch(count) $rb\n");
#######
####### Here is a problem. Error code $T_reply_code is always 401 even
for second time... I have 480 on ngrep
#######
if ( t_check_status("401|407") ) # Unathorised reply
{ xlog("Authentication required \n");
# have we already tried to authenticate? do we have auth
information loaded?
if (isflagset(10) || $avp(i:21)==$null ) # auth was already sent
or we don't have auth info
{
xlog("Authentication to $avp(i:20) provider as
$avp(i:21)@$avp(i:24) failed\n");
t_reply("503","Authentication failed");
avp_delete("$avp(i:20)");
avp_delete("$avp(i:21)");
avp_delete("$avp(i:22)");
avp_delete("$avp(i:23)");
avp_delete("$avp(i:24)");
exit(); # :(
}
# if call from here LOAD_AUTH will look for original uri, not
rewriten before
if( !is_avp_set("$avp(i:20)") || $avp(i:20)=='') # if LAOD_AUTH
was not done yet
route (LOAD_AUTH); # loads auth avps and rewrite 'from' field
# this avps loaded before by LOAD_AUTH
# avp(i:20) - rewrited host
# avp(i:21) - auth user
# avp(i:22) - auth pass
# avp(i:23) - auth realm
# avp(i:24) - auth domain
remove_hf("Authorization"); # remove client authentication
if (uac_auth()) # adding auth header
{
xlog("L_INFO","Authorization header set, sending...");
# mark that auth was performed
setflag(10);
# trigger again the failure route
t_on_failure("FAIL_ONE");
# repeat the request with auth response this time
append_branch(); # ?
t_relay();
exit;
}
}
# In case of failure on PSTN provider, send it to an alternative route:
if ( t_check_status("408|5[0-9][0-9]")) {
# if ( isflagset(11) && t_check_status("408|5[0-9][0-9]")) {
revert_uri();
if (!cr_next_domain("$avp(s:carrier)", "$avp(s:domain)", "$rU",
"$rd", "$T_reply_code", "$avp(s:domain)")) {
xlog("L_ERR", "cr_next_domain failed\n");
exit;
}
if (!cr_route("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rU",
"call_id")) {
xlog("L_ERR", "cr_route failed\n");
exit;
}
route(LOAD_AUTH);
t_on_failure("FAIL_ONE");
append_branch();
if (!t_relay()) {
xlog("L_ERR", "t_relay to $rd failed\n");
exit;
}
}
#!ifdef WITH_NAT
if (is_method("INVITE")
&& (isbflagset("6") || isflagset(5))) {
unforce_rtp_proxy();
}
#!endif
if (t_is_canceled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply("404","Not found");
## exit;
##}
# uncomment the following lines if you want to redirect the failed
# calls to a different new destination
##if (t_check_status("486|408")) {
## sethostport("192.168.2.100:5060");
## append_branch();
## # do not set the missed call flag again
## t_relay();
##}
}
Revision: 5957
http://openser.svn.sourceforge.net/openser/?rev=5957&view=rev
Author: mariuszbihlei
Date: 2009-11-20 13:59:26 +0000 (Fri, 20 Nov 2009)
Log Message:
-----------
Correct description for TMCB_REQUEST_BUILT callback: It is not called
before but after a new request has been sent.
Patch by Timo Reimann (timo.reimann AT 1und1.de)
Modified Paths:
--------------
branches/1.5/modules/tm/t_hooks.h
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Bugs item #2901127, was opened at 2009-11-20 08:14
Message generated for change (Tracker Item Submitted) made by ttrask01
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=743020&aid=2901127&group_…
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: ver 1.5.x
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Ted Trask (ttrask01)
Assigned to: Nobody/Anonymous (nobody)
Summary: Kamctl cannot add user to dbtext
Initial Comment:
Running kamailio 1.5.2 on alpine linux. Same problem applies to 1.5.3.
"kamctl add user password" fails with result:
email_address cannot be empty or null
\E[37;31mERROR: introducing the new user 'user' to the database failed
The kamctl script does not accept an email-address on the command line, showing usage (too many command-line parameters).
The problem is in the database definition. Here is the 'subscriber' definition for the various DB types:
scripts/db_berkeley/kamailio/subscriber:id(int) username(str) domain(str) password(str) email_address(str) ha1(str) ha1b(str) rpid(str)
scripts/postgres/auth_db-create.sql: email_address VARCHAR(64) DEFAULT '' NOT NULL,
scripts/mysql/auth_db-create.sql: email_address VARCHAR(64) DEFAULT '' NOT NULL,
scripts/oracle/auth_db-create.sql: email_address VARCHAR2(64) DEFAULT '',
scripts/dbtext/kamailio/subscriber:id(int,auto) username(string) domain(string) password(string) email_address(string) ha1(string) ha1b(string) rpid(string,null)
Ok, all of the databases have the email_address column, most saying non-null and default to "". The problem comes because kamctl doesn't take a parameter for email_address and tries to set it to null. For postgres it works just fine, because there's a default defined. Not true for dbtext. It says non-null, but doesn't define a default.
Further, it appears the dbtext does not differentiate between "" and null. So, if we remove the non-null restriction, it will allow it to be set to null, which is actually "", which is what the default should be!
So, to make this as clear as mud, the one line in scripts/dbtext/kamailio/subscriber (/usr/share/kamailio/dbtext/kamailio/subscriber on my device) should be changed from:
id(int,auto) username(string) domain(string) password(string) email_address(string) ha1(string) ha1b(string) rpid(string,null)
to (adding the word 'null' in the email_address column definition):
id(int,auto) username(string) domain(string) password(string) email_address(string,null) ha1(string) ha1b(string) rpid(string,null)
And that should fix the problem.
Ted Trask
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=743020&aid=2901127&group_…
Hi All,
Has anyone else noticed the significant inaccuracy of the timeout in the
dialog module?
We are using:
modparam("dialog", "timeout_avp", "$avp(i:10)")
However, the actual call is torn down a NUMBER of seconds past the timeout
supplied. In some instances, for long calls, it is out by 30seconds or
more....? For shorter calls it is accurate with a second or so.
Anyone have any input, ideas?
Cheers
Jason
Hi All,
I have updated the pkg/kamailio/debian-lenny packaging files to work with 3.0.0-rc2. Patch is attached if someone would like to look over it and commit it.
Cheers,
Jonas
Jan,
On Tuesday 17 November 2009, you wrote:
> On Tue, Nov 17, 2009 at 4:13 PM, Alex Hermann <alex(a)speakup.nl> wrote:
> > Hello,
> >
> > Why is the nonce expiry checked in post_auth instead of pre_auth? Now the
> > expiry is checked after the username/password is checked against the DB.
> > That seems a bit odd.
> >
> > I moved the check to check_nonce (which is called from pre_auth) and it
> > seems to work fine. Did I miss something? Security issue?
>
> There are two major reasons for this:
>
> The server sends back stale=true in digest credentials if the nonce
> has expired, but only if the credentials are otherwise valid (i.e. the
> username and the password are correct). The parameter stale=true
> indicates to the user agent that there is no need to ask the user for
> username and password again, it can just generate a new authorization
> header with ca> ched username and password and a new nonce string from
> the server.
The server can just as well generate a stale=true response immediately,
independent of the credentials check. If later on a non-expired nonce
arrives, it can do the credentials check and send a response without
stale=true if necessary.
> The second reason is that we need to accept credentials with old nonce
> string for ACK and CANCEL requests. Those two requests cannot be
> challenged (There is no reply for ACK and CANCEL must have the same
> CSeq as the request being canceled), thus we cannot ask the user agent
> to resubmit them again with a new nonce.
This reason is invalid because of the following existing code in pre_auth:
if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL))
return AUTHORIZED;
--
Met vriendelijke groet,
Alex Hermann
SpeakUp BV
T: 088-SPEAKUP (088-7732587)
F: 088-7732588