signalwire / freeswitch

FreeSWITCH is a Software Defined Telecom Stack enabling the digital transformation from proprietary telecom switches to a versatile software implementation that runs on any commodity hardware. From a Raspberry PI to a multi-core server, FreeSWITCH can unlock the telecommunications potential of any device.
https://freeswitch.com/#getting-started
Other
3.62k stars 1.43k forks source link

receive '401 Unauthorized', without 'WWW-Authenticate' header #1779

Open dkokov opened 2 years ago

dkokov commented 2 years ago

Describe the bug When I'm trying to send a MESSAGE to the FreeSWITCH after more 1min from SMS session starting, I receive 401 without WWW-Authenticate . This MESSAGE is not received by other subscriber.

To Reproduce Steps to reproduce the behavior:

  1. Sent message and after 1-2 mins, try to send again - second message in same session(Call ID)
  2. A FreeSWITCH responses with '401 Unauthorized' but without 'WWW-Authenticate'

Expected behavior In a normally case, the FreeSWITCH uses 407. If it uses 401,it has to send WWW-Authenticate

Package version or git hash

Trace logs In this case, there aren't anything in the log.

briankwest commented 2 years ago

Do you have auth-messages set on your sofia profile?

Len-PGH commented 2 years ago

Check to see the uptime of FreeSWITCH. I crashed FreesSWITCH in the process of replicating the issue

#0  0x00007fd89e8db7bb in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007fd89e8c6535 in __GI_abort () at abort.c:79
#2  0x00007fd89e8c640f in __assert_fail_base (fmt=0x7fd89ea27ee0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x7fd89f2ad795 "channel != ((void *)0)", file=0x7fd89f27a8c7 "src/switch_channel.c", line=986, function=<optimized out>) at assert.c:92
#3  0x00007fd89e8d4102 in __GI___assert_fail (assertion=assertion@entry=0x7fd89f2ad795 "channel != ((void *)0)", file=file@entry=0x7fd89f27a8c7 "src/switch_channel.c", line=line@entry=986, function=function@entry=0x7fd89f27daa0 <__PRETTY_FUNCTION__.24252> "switch_channel_get_variable_dup") at assert.c:101
#4  0x00007fd89eecd63c in switch_channel_get_variable_dup (channel=channel@entry=0x0, varname=varname@entry=0x7fd896c644e6 "inbound_sip_headers_as_arrays", dup=dup@entry=SWITCH_FALSE, idx=idx@entry=-1) at src/switch_channel.c:1007
#5  0x00007fd896c49339 in switch_channel_var_true (variable=0x7fd896c644e6 "inbound_sip_headers_as_arrays", channel=0x0) at ../../../../src/include/switch_channel.h:338
#6  0x00007fd896c49339 in sofia_presence_handle_sip_i_message (status=status@entry=100, phrase=phrase@entry=0x7fd86402daa0 "Trying", nua=nua@entry=0x7fd874035500, profile=profile@entry=0x55d3d20648d0, nh=nh@entry=0x7fd86402ccc0, session=session@entry=0x0, sofia_private=0x0, sip=0x7fd86402b248, de=0x7fd874029de0, tags=0x7fd86402da90) at sofia_presence.c:4893
#7  0x00007fd896c276ee in our_sofia_event_callback (event=nua_i_message, status=100, phrase=0x7fd86402daa0 "Trying", nua=0x7fd874035500, profile=0x55d3d20648d0, nh=0x7fd86402ccc0, sofia_private=<optimized out>, sip=0x7fd86402b248, de=0x7fd874029de0, tags=0x7fd86402da90) at sofia.c:1836
#8  0x00007fd896c2ea16 in sofia_process_dispatch_event (dep=0x7fd896a5cbd8) at sofia.c:2257
#9  0x00007fd896c2ebeb in sofia_msg_thread_run (thread=<optimized out>, obj=0x7fd896b76ad8) at sofia.c:2306
#10 0x00007fd896c2ebeb in sofia_msg_thread_run (thread=<optimized out>, obj=0x7fd896b76ad8) at sofia.c:2277
#11 0x00007fd89f26bc52 in dummy_worker (opaque=0x55d3d20586e0) at threadproc/unix/thread.c:159
#12 0x00007fd89edeafa3 in start_thread (arg=<optimized out>) at pthread_create.c:486
#13 0x00007fd89e99ceff in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
dkokov commented 2 years ago

Brian, I don't know which auth-messages I have to set but I have first or some successful messages with auth . When I'm waiting more 1 min,then happen this problem - 401 without WWW-Authenticate . See attached picture from the SNGREP. Screenshot from 2022-08-30 09-21-54 .

a13r commented 11 months ago

I'm sorry to dig out this old issue, but I have the exact same problem with Snom desk phones, both with MESSAGE and SUBSCRIBE. I'm currently using Freeswitch version 1.10.10-release-24-4cb05e7f4a and I think I found out what happens.

Analyzing the SIP trace, I noticed that the WWW-Authenticate header is missing in the 401 response:

Sent to Udp:172.22.210.3:5060 from Udp:172.22.210.153:5060 at Nov 21 11:28:35.878 (685 bytes):

SUBSCRIBE sip:207@172.22.210.3:5060 SIP/2.0
Via: SIP/2.0/UDP 172.22.210.153:5060;branch=z9hG4bK-jyhxsogbec4d;rport
From: <sip:201@172.22.210.3>;tag=z0kw85uxgt
To: <sip:207@172.22.210.3>;tag=qiK2RIRcAd9E
Call-ID: c8755c65dbcf-inmkmv2eaxxs
CSeq: 76 SUBSCRIBE
Max-Forwards: 70
User-Agent: snomD345/10.1.159.12
Contact: <sip:201@172.22.210.153:5060>;reg-id=1
Event: dialog
Accept: application/dialog-info+xml
Authorization: Digest username="201",realm="172.22.210.3",nonce="2594c90e-d132-419f-a598-74b9ce0c773e",uri="sip:207@172.22.210.3:5060",qop=auth,nc=00000009,cnonce="102b01ae",response="88605665b71bdd4074d41d4203915676",algorithm=MD5
Expires: 3600
Content-Length: 0

Received from Udp:172.22.210.3:5060 on Udp:172.22.210.153:5060 at Nov 21 11:28:35.880 (655 bytes):

SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 172.22.210.153:5060;branch=z9hG4bK-jyhxsogbec4d;rport=5060
From: <sip:201@172.22.210.3>;tag=z0kw85uxgt
To: <sip:207@172.22.210.3>;tag=qiK2RIRcAd9E
Call-ID: c8755c65dbcf-inmkmv2eaxxs
CSeq: 76 SUBSCRIBE
User-Agent: FreeSWITCH-mod_sofia/1.10.10-release-24-4cb05e7f4a~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Allow-Events: talk, hold, conference, presence, as-feature-event, dialog, line-seize, call-info, sla, include-session-description, presence.winfo, message-summary, refer
Content-Length: 0

In the SUBSCRIBE request, the client re-uses the nonce from the initial authentication during REGISTER, indicated by a non-zero nonce counter nc=00000009. This mechanism is specified in RFC 2617, section 3.3:

A client should remember the username, password, nonce, nonce count and opaque values associated with an authentication session to use to construct the Authorization header in future requests within that protection space. The Authorization header may be included preemptively; doing so improves server efficiency and avoids extra round trips for authentication challenges. The server may choose to accept the old Authorization header information, even though the nonce value included might not be fresh. Alternatively, the server may return a 401 response with a new nonce value, causing the client to retry the request; by specifying stale=TRUE with this response, the server tells the client to retry with the new nonce, but without prompting for a new username and password.

I think Freeswitch does not handle this correctly and simply replies with a 401 response, not including any authentication related response headers.

As a workaround, I could configure the phones not to send another digest authentication preemtively (by setting cache_sip_authorization to off). As a result, the phones send an unauthenticated request at first and Freeswitch responds with a 407 including WWW-Authenticate as expected.

I think there are two possible solutions to this problem:

What do you think?

Regards, Andreas

dkokov commented 11 months ago

I have forgotten this issue.Sorry

На вт, 21.11.2023 г. в 15:23 ч. Andreas Bruckner @.***> написа:

I'm sorry to dig out this old issue, but I have the exact same problem with Snom desk phones, both with MESSAGE and SUBSCRIBE. I'm currently using Freeswitch version 1.10.10-release-24-4cb05e7f4a and I think I found out what happens.

Analyzing the SIP trace, I noticed that the WWW-Authenticate header is missing in the 401 response:

Sent to Udp:172.22.210.3:5060 from Udp:172.22.210.153:5060 at Nov 21 11:28:35.878 (685 bytes):

SUBSCRIBE @.:5060 SIP/2.0 Via: SIP/2.0/UDP 172.22.210.153:5060;branch=z9hG4bK-jyhxsogbec4d;rport From: @.>;tag=z0kw85uxgt To: @.>;tag=qiK2RIRcAd9E Call-ID: c8755c65dbcf-inmkmv2eaxxs CSeq: 76 SUBSCRIBE Max-Forwards: 70 User-Agent: snomD345/10.1.159.12 Contact: @.:5060>;reg-id=1 Event: dialog Accept: application/dialog-info+xml Authorization: Digest @.***:5060",qop=auth,nc=00000009,cnonce="102b01ae",response="88605665b71bdd4074d41d4203915676",algorithm=MD5 Expires: 3600 Content-Length: 0

Received from Udp:172.22.210.3:5060 on Udp:172.22.210.153:5060 at Nov 21 11:28:35.880 (655 bytes):

SIP/2.0 401 Unauthorized Via: SIP/2.0/UDP 172.22.210.153:5060;branch=z9hG4bK-jyhxsogbec4d;rport=5060 From: @.>;tag=z0kw85uxgt To: @.>;tag=qiK2RIRcAd9E Call-ID: c8755c65dbcf-inmkmv2eaxxs CSeq: 76 SUBSCRIBE User-Agent: FreeSWITCH-mod_sofia/1.10.10-release-24-4cb05e7f4a~64bit Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE Supported: timer, path, replaces Allow-Events: talk, hold, conference, presence, as-feature-event, dialog, line-seize, call-info, sla, include-session-description, presence.winfo, message-summary, refer Content-Length: 0

In the SUBSCRIBE request, the client re-uses the nonce from the initial authentication during REGISTER, indicated by a non-zero nonce counter nc=00000009. This mechanism is specified in RFC 2617, section 3.3 https://datatracker.ietf.org/doc/html/rfc2617#section-3.3:

A client should remember the username, password, nonce, nonce count and opaque values associated with an authentication session to use to construct the Authorization header in future requests within that protection space. The Authorization header may be included preemptively; doing so improves server efficiency and avoids extra round trips for authentication challenges. The server may choose to accept the old Authorization header information, even though the nonce value included might not be fresh. Alternatively, the server may return a 401 response with a new nonce value, causing the client to retry the request; by specifying stale=TRUE with this response, the server tells the client to retry with the new nonce, but without prompting for a new username and password.

I think Freeswitch does not handle this correctly and simply replies with a 401 response, not including any authentication related response headers.

As a workaround, I could configure the phones not to send another digest authentication preemtively. As a result, the phones send an unauthenticated request at first and Freeswitch responds with a 401 including WWW-Authenticate as expected.

I think there are two possible solutions to this problem:

  • implement this aspect of digest authentication correctly
  • do not accept re-used nonce values and reply with a WWW-Authenticate header

What do you think?

Regards, Andreas

— Reply to this email directly, view it on GitHub https://github.com/signalwire/freeswitch/issues/1779#issuecomment-1820920246, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEWLQJAPXBQNUAGZ43QF3DTYFSTOTAVCNFSM575BG7QKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBSGA4TEMBSGQ3A . You are receiving this because you authored the thread.Message ID: @.***>

BrianMiller793 commented 10 months ago

I am experiencing this issue currently with a few different phone models. What I am seeing is that the first SUBSCRIBE has a user@realm, and the failing request is using a cached nonce with user@ip.address.

Proxy-Authorization: Digest username="1234",realm="foobar",uri="sip:1234@foobar" Proxy-Authorization: Digest username="1234",realm="foobar",uri="sip:1234@192.168.0.123:5066"

In the above example from a13r, Authorization: Digest username="201",realm="172.22.210.3",uri="sip:207@172.22.210.3:5060", the username, realm, and URI are all different.

The subsequent 401 does not have a Proxy-Authenticate or WWW-Authenticate header.

In my configuration, I have <param name="auth-all-packets" value="false"/>

BrianMiller793 commented 9 months ago

The 401 for a SUBSCRIBE renewal is happening because the renewal comes after the Sofia nonce-ttl timer has expired. If the renewal comes in before the nonce-ttl timer expires, the UC returns 202. According to RFC 3261, "The WWW-Authenticate response-header field MUST be included in 401 (Unauthorized) response messages."