Hello,
our voip provider requires autentication to voip services. Trying to use UAC module, I get "401 Unauthorized" packet, but looks like all ser based programs have problems to parse this packet. Can somebody make a patch to fix this?
Here is message from logs:
Jun 17 15:01:42 kamailio /usr/sbin/kamailio[1291]: ERROR: uac [auth_hdr.c:267]: parse error in <DIGEST realm="BroadWorks",qop="auth",algorithm=MD5,nonce="BroadWorksXgajlo4shTqsrkgdBW"> around 0
And ngrep sniffed packet:
SIP/2.0 401 Unauthorized. Via: SIP/2.0/UDP 100.100.242.20;branch=z9hG4bK119f.8a41a626.0. Via: SIP/2.0/UDP 100.100.16.77;branch=z9hG4bK119f.7cc235e.0. Via: SIP/2.0/UDP 100.100.10.10;branch=z9hG4bK8ec5c892A88F71C9. From: "Ondrej Jan" sip:556807505@as.vvn.t-com.sk;tag=89D71D23-32F3D9BC. To: sip:0248213335@as.vvn.t-com.sk;user=phone;tag=1621075049-1276779704129. CSeq: 2 INVITE. Call-ID: 41c7437-58259a9d-d157be06@100.100.10.10. WWW-Authenticate: DIGEST realm="BroadWorks",qop="auth",algorithm=MD5,nonce="BroadWorksXgajlo4shTqsrkgdBW". Content-Length: 0.
I tryed to look at sources, but this "C" code is too complicated for me. :-(
SAL
Am 17.06.2010 15:51, schrieb Ján ONDREJ (SAL):
WWW-Authenticate: DIGEST realm="BroadWorks",qop="auth",algorithm=MD5,nonce="BroadWorksXgajlo4shTqsrkgdBW".
looks like the header is buggy, it should be "Digest":
challenge = ("Digest" LWS digest-cln *(COMMA digest-cln))
In modules_k/uac/auth_hdr.c try to change
if (strncmp(p,AUTHENTICATE_DIGEST_S,AUTHENTICATE_DIGEST_LEN)!=0)
to use strncasecmp()
regards klaus
2010/6/17 Klaus Darilion klaus.mailinglists@pernau.at:
looks like the header is buggy, it should be "Digest":
challenge = ("Digest" LWS digest-cln *(COMMA digest-cln))
The header is not buggy as 99.9% of SIP ABNF grammar is case insensitive. In fact the only case sensitive are the SIP methods (INVITE, REGISTER...).
2010/6/18 Iñaki Baz Castillo ibc@aliax.net:
2010/6/17 Klaus Darilion klaus.mailinglists@pernau.at:
looks like the header is buggy, it should be "Digest":
challenge = ("Digest" LWS digest-cln *(COMMA digest-cln))
The header is not buggy as 99.9% of SIP ABNF grammar is case insensitive. In fact the only case sensitive are the SIP methods (INVITE, REGISTER...).
So yes, the bug is in auth_hdr.c as it should use strncasecmp().
On Friday 18 June 2010, Iñaki Baz Castillo wrote:
2010/6/18 Iñaki Baz Castillo ibc@aliax.net:
2010/6/17 Klaus Darilion klaus.mailinglists@pernau.at:
looks like the header is buggy, it should be "Digest":
challenge = ("Digest" LWS digest-cln *(COMMA digest-cln))
The header is not buggy as 99.9% of SIP ABNF grammar is case insensitive. In fact the only case sensitive are the SIP methods (INVITE, REGISTER...).
So yes, the bug is in auth_hdr.c as it should use strncasecmp().
Hi Iñaki,
ok, i'll change it in the code.
Cheers,
Henning
On Tue, Jun 29, 2010 at 12:24:03PM +0200, Henning Westerholt wrote:
On Friday 18 June 2010, Iñaki Baz Castillo wrote:
2010/6/18 Iñaki Baz Castillo ibc@aliax.net:
2010/6/17 Klaus Darilion klaus.mailinglists@pernau.at:
looks like the header is buggy, it should be "Digest":
challenge = ("Digest" LWS digest-cln *(COMMA digest-cln))
The header is not buggy as 99.9% of SIP ABNF grammar is case insensitive. In fact the only case sensitive are the SIP methods (INVITE, REGISTER...).
So yes, the bug is in auth_hdr.c as it should use strncasecmp().
Hi Iñaki,
ok, i'll change it in the code.
Thank you.
Even if it's better, it still don't work for me.
Here is what is logged in log:
0(1515) DEBUG: uac [auth_hdr.c:409]: hdr is <Authorization: Digest username="xxxx07500", realm="BroadWorks", nonce="BroadWorksXgb3lz7xdT18h03wBW", uri="sip:09xxxxxxxx@as.vvn.xxxxxx;user=phone", qop=auth, nc=00000001, cnonce="629288560", response="96cc89eca0eb44624e6572e6f6545dcc", algorithm=MD5
But I con't find any response in ACK packet send to our provider:
U xxx.xxx.137.250:5060 -> xxx.xxx.xxx.20:5060 SIP/2.0 401 Unauthorized. Via: SIP/2.0/UDP xxx.xxx.xxx.20;branch=z9hG4bK2e5.758ec977.0. Via: SIP/2.0/UDP xxx.xxx.10.10;branch=z9hG4bK9270d540C0C4209D. From: "Ondrej Jan" sip:xxxxxxx@as.vvn.xxxxxxx;tag=56FAB897-DD2E3AD2. To: sip:09xxxxxxxxx@as.vvn.xxxxxx;user=phone;tag=860899010-1277989544929. CSeq: 2 INVITE. Call-ID: 754f437b-41f09f61-7b255ff4@xxx.xxx.10.10. WWW-Authenticate: DIGEST realm="BroadWorks",qop="auth",algorithm=MD5,nonce="BroadWorksXgb3lz7xdT18h03wBW". Content-Length: 0. .
# U xxx.xxx.xxx.20:5060 -> xxx.xxx.137.250:5060 ACK sip:09xxxxxxxx@as.vvn.xxxxxxx;user=phone SIP/2.0. Via: SIP/2.0/UDP xxx.xxx.xxx.20;branch=z9hG4bK2e5.758ec977.0. From: "Ondrej Jan" sip:xxxxxx505@as.vvn.xxxxxx;tag=56FAB897-DD2E3AD2. To: sip:09xxxxxxxx@as.vvn.xxxxx;user=phone;tag=860899010-1277989544929. CSeq: 2 ACK. Call-ID: 754f437b-41f09f61-7b255ff4@xxx.xxx.10.10. Max-Forwards: 68. Content-Length: 0. .
Is something wrong in my configuration? How these authenticate packets should look?
May be problem is, that I need to subst some strings in routed packets, because they need special username and they require to send their domain in From and To headers. Is this my problem? What should I search for in my logs?
Thank you.
SAL
On Thursday 01 July 2010, Ján ONDREJ (SAL) wrote:
ok, i'll change it in the code.
Thank you.
Hello Jan,
Even if it's better, it still don't work for me.
Here is what is logged in log:
0(1515) DEBUG: uac [auth_hdr.c:409]: hdr is <Authorization: Digest username="xxxx07500", realm="BroadWorks", nonce="BroadWorksXgb3lz7xdT18h03wBW", uri="sip:09xxxxxxxx@as.vvn.xxxxxx;user=phone", qop=auth, nc=00000001, cnonce="629288560", response="96cc89eca0eb44624e6572e6f6545dcc", algorithm=MD5
But I con't find any response in ACK packet send to our provider:
the response should be included in the second INVITE (or the message that was challenged).
U xxx.xxx.137.250:5060 -> xxx.xxx.xxx.20:5060 SIP/2.0 401 Unauthorized. Via: SIP/2.0/UDP xxx.xxx.xxx.20;branch=z9hG4bK2e5.758ec977.0. Via: SIP/2.0/UDP xxx.xxx.10.10;branch=z9hG4bK9270d540C0C4209D. From: "Ondrej Jan" sip:xxxxxxx@as.vvn.xxxxxxx;tag=56FAB897-DD2E3AD2. To: sip:09xxxxxxxxx@as.vvn.xxxxxx;user=phone;tag=860899010-1277989544929. CSeq: 2 INVITE. Call-ID: 754f437b-41f09f61-7b255ff4@xxx.xxx.10.10. WWW-Authenticate: DIGEST realm="BroadWorks",qop="auth",algorithm=MD5,nonce="BroadWorksXgb3lz7xdT18h0 3wBW". Content-Length: 0. .
# U xxx.xxx.xxx.20:5060 -> xxx.xxx.137.250:5060 ACK sip:09xxxxxxxx@as.vvn.xxxxxxx;user=phone SIP/2.0. Via: SIP/2.0/UDP xxx.xxx.xxx.20;branch=z9hG4bK2e5.758ec977.0. From: "Ondrej Jan" sip:xxxxxx505@as.vvn.xxxxxx;tag=56FAB897-DD2E3AD2. To: sip:09xxxxxxxx@as.vvn.xxxxx;user=phone;tag=860899010-1277989544929. CSeq: 2 ACK. Call-ID: 754f437b-41f09f61-7b255ff4@xxx.xxx.10.10. Max-Forwards: 68. Content-Length: 0. .
Is something wrong in my configuration? How these authenticate packets should look?
I never used uac_auth() so far, but normally you send a request like an INVITE to the host, its then challenged with e.g. a 401 including a nonce and some other parameters, you ACK it, and then you re-send the request with the added credentials.
May be problem is, that I need to subst some strings in routed packets, because they need special username and they require to send their domain in From and To headers. Is this my problem? What should I search for in my logs?
Maybe the target do some comparisons on the credentials (like username, realm) and the From header? Are you able to login with a normal user agent (e.g. softphone) on the target if you just route the request through your proxy and do the same header modifications?
Regards,
Henning
Is something wrong in my configuration? How these authenticate packets should look?
I never used uac_auth() so far, but normally you send a request like an INVITE to the host, its then challenged with e.g. a 401 including a nonce and some other parameters, you ACK it, and then you re-send the request with the added credentials.
May be problem is, that I need to subst some strings in routed packets, because they need special username and they require to send their domain in From and To headers. Is this my problem? What should I search for in my logs?
Maybe the target do some comparisons on the credentials (like username, realm) and the From header? Are you able to login with a normal user agent (e.g. softphone) on the target if you just route the request through your proxy and do the same header modifications?
I can't login with my softphone using same rewrites. Without rewrites if client is set to proper setting and my kamailio is used only as proxy, it works.
I need at least this rewrite:
route[6] { subst('/^(From.*sip:)[0-9]+@xxx.xxx.xxx.20(.*)$/\1xxxx07505@as.vvn.xxxxx.xx\2/i'); rewritehostport("as.vvn.xxxxx.xx"); t_on_failure("6"); route(5); }
My target is checking for their domain in From: header. Can I use some transactional rewrite, which can automatically rewrite this change back? I tryed to use t_on_reply without success yet.
Is it normal behaviour to check for existence of From header and only allow target's domain? I need to make a trunk between our voip site and target's, so I think it's normal, that our domains are different.
Thank you.
SAL
On 07/02/2010 02:54 AM, Ján ONDREJ (SAL) wrote:
My target is checking for their domain in From: header. Can I use some transactional rewrite, which can automatically rewrite this change back? I tryed to use t_on_reply without success yet.
It is not something a proxy is supposed to be able to do, but the 'uac' module provides this functionality in the form of uac_replace_from(). Check out the first three module parameters; they relate to various aspects of statefully rewriting the From header between endpoints A and B in such a way that A does not know about it.
Is it normal behaviour to check for existence of From header and only allow target's domain? I need to make a trunk between our voip site and target's, so I think it's normal, that our domains are different.
It varies. It is a common practice, though.
On Fri, Jul 02, 2010 at 03:05:40AM -0400, Alex Balashov wrote:
On 07/02/2010 02:54 AM, Ján ONDREJ (SAL) wrote:
My target is checking for their domain in From: header. Can I use some transactional rewrite, which can automatically rewrite this change back? I tryed to use t_on_reply without success yet.
It is not something a proxy is supposed to be able to do, but the 'uac' module provides this functionality in the form of uac_replace_from(). Check out the first three module parameters;
No change. Still unable to route calls.
they relate to various aspects of statefully rewriting the From header between endpoints A and B in such a way that A does not know about it.
I use defaults, so looks like I use automatic restore. I don't know, how to send it manually, so auto looks to be a good choice. uac_restore_from can't be used from reply route.
Now looking at uac_auth() documentation again:
------------------------- 4.4. uac_auth()
This function can be called only from failure route and will build the authentication response header and insert it into the request without sending anything.
This function can be used from FAILURE_ROUTE.
Example 1.11. uac_auth usage
... uac_auth(); ...
------------------------
Looks like uac_auth() does not send another request. Can somebody give me a more complete example, how to use uac_auth()? Do I need to use uac_req_send or call some route to do it? May be it is my problem, because second INVITE is not sent.
SAL
On 07/02/2010 03:22 AM, "Ján ONDREJ (SAL)" wrote:
I use defaults, so looks like I use automatic restore. I don't know, how to send it manually, so auto looks to be a good choice. uac_restore_from can't be used from reply route.
If you are using the "auto" restore mode, it is not necessary to call uac_restore_from().
Looks like uac_auth() does not send another request. Can somebody give me a more complete example, how to use uac_auth()? Do I need to use uac_req_send or call some route to do it? May be it is my problem, because second INVITE is not sent.
The uac_auth() function is intended to be called from a failure route when catching a 407 Proxy Authorization Required challenge.
You will need to use serial forking ("branching") to re-send the request with the appropriate digest authentication headers:
I would use it like this:
route { ... t_on_failure("MAYBE_AUTH_CHALLENGE");
if(!t_relay()) sl_reply_error(); }
...
failure_route[MAYBE_AUTH_CHALLENGE] { if(t_is_canceled()) exit;
if(t_check_status("407")) { append_branch();
if(!uac_auth()) { xlog("L_ERR", "Something went wrong with uac_auth()!\n"); t_reply("500", "Internal Server Error"); return; }
if(!t_relay()) { t_reply("500", "Internal Server Error"); return; } }
Keep in mind that uac_auth() will silently fail to add the right headers, without explanation, if the realm you provide it (whether by AVP or via the "credential" modparam to 'uac') does not match the realm requested in the challenge from the provider, but you won't know that unless you turn up debug verbosity.