Summary:ASTERISK-02651: dialog matching problems
Reporter:klaus3000 (klaus3000)Labels:
Date Opened:2004-10-22 05:42:37Date Closed:2011-06-07 14:11:57
Versions:Frequency of
Environment:Attachments:( 0) chan_sip.c_example_frag_for_tag_matching.txt
( 1) patch_chan_sip_tagfix_for_register.txt
Description:Asterisk does not respond to SIP messages with wrong tags like it should do. Generally I think the matching of from-tags and to-tags in asterisk is freaky. I will explain the problems on several examples ("pedantic=yes"):

1. I send an INVITE with a tag in the To: header. Asterisk accepts the INVITE although there is no active dialog with this dialog-id (call-id, to-tag, from-tag). Usually, a UAS responses with a "481 Call leg does not exist". According to RFC 3261 it is allowed to create a dialog like asterisk does, but only if the UAS (in this case asterisk) can retrieve from the to-tag that this request belongs to him (e.g. in case of the UAS crashed and dialog recovery).
This behaviour causes problems and security problems. If for example there is a front-end ser with user authentication and an asterisk as PSTN-Gateway: ser is only transaction statefull and therefore will forwarded in-dialog requests (with to-tag) without authentication. If asterisk accepts faked in-dialog INVITES a call to the PSTN will be established without authentication checks.

2. The following scenario: I send an INVITE with callid I, from-tag FT1 and to-tag TT1. --> asterisk creates the call.
Then I send a second INVITE with same call-id and from-tag, but different to-tag: I, FT1, TT2. This will be matched by asterisk to the existing dialog. This is wrong because the dialog-id is not the same.

3. I send an INVITE to asterisk and the session will be established. Then I send a BYE message with the same call-id but wrong tags. Asterisk replies with 200 Ok (?) and keeps the established call (this is ok). Asterisk should reply with a "481 Call leg does not exist".

Problem guess: In chan_sip will only be checked against the remote-tag in find_call(). Here should be added checks against the local tag and any non-matching request (except initial requests without to-tag) should be rejected with "481 ...".

Furthermore I think the tags-matching should be done always, not only if "pedantic=yes".



References to RFC3261.
tag creation: section 19.3
UAS Behavior: section 12.2.2 (to-tag matching and recovery)
Comments:By: khb (khb) 2004-11-03 22:59:11.000-0600

Some thoughts on this:

I think you are in principle correct in your observation and suggestion.
However, to implement complete tag matching isn't a quick fix since it requires perfect behavior in Asterisk and remote UAs.  Asterisk doesn't generate tags correctly in all circumstances and strict checking unveils some bugs. I have been running with complete matching and found it useful to turn off the tag matching for dialogs with certain proxy hosts with a peer specific config option. The tag matching certainly needs to be decoupled from the pedantic option, which has other side effects.  Making it peer specific was not straight forward since the tags need checking when we don't have an association of an incoming message with a configured peer yet (in find_call())

And it's not all ASterisk's fault, other devices and proxies add their own share of confusion.  Rejecting all mis-matched tags results in undesired behavior as well, such as perfectly good and honest dialogs being needlessly dropped.

Does anyone here know definitively, whether Asterisk should create a new from-tag for sending the authenticated re-transmission of a REGISTER call, after the  registrar returned a 401 response and whether the registrar in turn should use a new tag as well for the 200 OK?  I assumed the answer is yes (looking at RFC 3665 examples), and therefore I fixed Asterisks behavior of remembering the remote tag from the first attempt in a REGISTER dialog--which then fails to match the call when receiving the 200 OK with a new tag.  THis happens with some proxies but not others,  for example domains sipgate.at vs. sipgate.de (both hosted on the same proxy server actually, strange)
The concise question of this is:  Is the authenticated re-transmission of a REGISTER a new 'dialog' or not?

By: klaus3000 (klaus3000) 2004-11-04 03:09:47.000-0600

From my understandings the 2nd REGISTER is a new transaction outside a dialog (because a REGISTER does not creates dialogs) - therefore the from-tag may/must be a new one. I've checked with xlite and Cisco7960(ver.3-06-2): xlite uses the same from-tag for the second REGISTER and Cisco does not use a from-tag at all.

Anyway, the 200 OK must include a different to-tag than the 401/407.

For INVITE messages, things are different, e.g. reINVITEs are always in-dialog, therefore the tags in the INVITE message with the credential must be the same as in the previous INVITE message. I'm unsure for the initial INVITE as there is no dialog yet - example RFC3665 (p. 15-) uses the same from-tag.

IMO it will be fine to use the same from-tag in the second REGISTER message and it will be less complicated if the tag creation rules are the same for INVITE and REGISTER messages.
Nevertheless, a UAS should also accept a new from-tag in the second REGISTER message.

By: Olle Johansson (oej) 2004-11-04 07:38:24.000-0600

"Asterisk does not respond to SIP messages with wrong tags like it should do."

Hmm. Should we respond with wrong tags? :-)

Nevertheless, you are right and Asterisk chan_sip does it the wrong way. I did not realise how wrong, but this needs to be fixed.

By: Olle Johansson (oej) 2004-11-04 07:40:15.000-0600

khb:"I have been running with complete matching". Do you want to share that code?

By: khb (khb) 2004-11-04 13:32:48.000-0600

Attached is a code fragment from my modifications.  Should probably be discussed not here but on dev-list.
The important part is routine call_find and how it's called in sip_sock_read.
I think it essentially does what Klaus wanted, wrt the 481. But it lets you
detect the various tag matches that could occur. Needs to be expanded still
for various cases.
If you want to use this code you need to back port it to chan_sip.  THere are
a lot of changes in the req structures and the messsage parsing is done upfront elsewhere.

By: khb (khb) 2004-11-04 13:36:59.000-0600

Attached a trivial patch (patch_chan_sip_tagfix_for_register.txt) which should go into CVS. This fixes the above described match against old remote tag in an authenticated register and creates a new from-tag for every outgoing REGISTER request.

By: Mark Spencer (markster) 2004-11-16 18:18:02.000-0600

Fixed in CVS

By: klaus3000 (klaus3000) 2004-11-17 05:25:40.000-0600

I tried current CVS (Asterisk CVS-HEAD-11/17/04-12:03:21 ) and the bug is still in there - asterisk still does not check the To-tag for incoming initial requests.

If send an INVITE with To-tag present (re-INVITE) and asterisk does not find a matching dialog/call (match = callid + fromtag + totag) it has to reject the INVITE with "481 Call leg does not exist" instead of accepting it.

Furthermore, a BYE with non matching dialog should also raise an "481" instead of sending "200 OK".

By: khb (khb) 2004-11-17 12:19:49.000-0600

Yes. It's not your problem that's been fixed, the CVS update was for REGISTER.
If I find time, I will try to back-port my code to current distribution.

edited on: 11-17-04 12:22

By: twisted (twisted) 2004-12-15 20:34:43.000-0600

Where do we stand here? It's been close to a month with nothing going on...


By: twisted (twisted) 2004-12-28 10:38:11.000-0600

Closed due to lack of interest from all parties.  Feel free to reopen if this is not the case.

By: Digium Subversion (svnbot) 2008-01-15 15:13:59.000-0600

Repository: asterisk
Revision: 4266

U   trunk/channels/chan_sip.c

r4266 | markster | 2008-01-15 15:13:58 -0600 (Tue, 15 Jan 2008) | 2 lines

Make sure we use new tags for sip register calls (bug ASTERISK-2651)