[Home]

Summary:ASTERISK-24646: PJSIP changeset 4899 breaks TLS
Reporter:Stephan Eisvogel (eisvogel)Labels:
Date Opened:2014-12-27 15:40:52.000-0600Date Closed:2015-01-29 14:41:21.000-0600
Priority:MajorRegression?Yes
Status:Closed/CompleteComponents:Channels/chan_sip/Interoperability
Versions:11.15.0 Frequency of
Occurrence
Constant
Related
Issues:
Environment:Linux; hostileAttachments:( 0) ASTERISK-24646.patch
( 1) ASTERISK-24646-chan_sip.patch
( 2) sip-trace.txt
Description:PJSIP as of changeset 4899 (https://trac.pjsip.org/repos/changeset/4899) has started verifying the Contact-header sent by the server to be of the SIPS scheme if transport is TLS. It will not check the Contact-header for ";transport=TLS" as sent by Asterisk.

As a result, registration by a client using this well-known stack will succeed, but any call attempt will terminate. A SIP trace will show the message "Warning: 381 localhost SIPS Required" going from the client to the server.

This was found using CSipSimple-trunk, other clients e.g. MicroSIP will likely follow, once this change has crept into their code bases.

The issue has previously been discussed last year here http://lists.digium.com/pipermail/asterisk-dev/2013-September/062567.html Asterisk developers were of the opinion that using SIPS in Contact-header will break proxying up a chain. PJSIP developers seem to be of the opinion they are following RFCs. And I am puzzled, looking for a resolution.

Workarounds/fixes I could identify:

1. Set disable_secure_dlg_check = PJ_TRUE on clients using PJSIP
2. Modify PJSIP's pjsip_inv_verify_request3 to check for ;transport=TLS not only in Record-Route-header but also in Contact-header.
3. Patch Asterisk to emit SIPS scheme when transport is TLS

I suggest identifying first, if this should be an Asterisk issue at all, or be brought up with PJSIP developers to change the default behaviour.
Comments:By: Mark Michelson (mmichelson) 2015-01-09 15:09:14.000-0600

Setting disable_secure_dialog_check to PJ_TRUE is a good workaround to start with, but I don't think that it's a good long-term solution. The Asterisk-dev thread you linked to seemed to have a bit of an ambiguous resolution, and I'm not sure what action actually came from it. I think this needs another look, and I may need to get in touch with the PJSIP devs to find out what the best move forward is here.

By: Mark Michelson (mmichelson) 2015-01-09 16:18:15.083-0600

So before I take any further action, I want to make sure I understand exactly what the problem is you're seeing. Here's how I'm interpreting the problem:

* CSipSimple registers to Asterisk.
* CSipSimple places a call over TLS to Asterisk. The Request URI of the incoming call to Asterisk has a sips: URI scheme.
* Asterisk sends a response to the INVITE with a Contact header that does not have a sips: URI scheme. Instead, the Contact header that Asterisk sends has a sip: URI scheme with ;transport=tls appended.
* CSipSimple, which uses PJSIP under the hood, checks the 200 OK and complains that the Contact header in the 200 OK from Asterisk is not a sips: URI, so after ACKing the 200 OK, CSipSimple sends a BYE to end the dialog.

Do I have the scenario correct, or does it go differently from that?

Edit: Just to be on the safe side, it's probably best if you could provide a pcap of the scenario. Thanks!

By: Stephan Eisvogel (eisvogel) 2015-01-09 16:32:49.253-0600

A pcap of what, encrypted TLS? Not sure you would see much in that.
It's encrypted. ;-) It's also ephemeral DHE so even if I supplied the
server's secret key, it can't be decrypted for analysis.

May I suggest a SIP trace using Asterisk debug level from the console.

By: Mark Michelson (mmichelson) 2015-01-09 16:47:09.851-0600

Yes, much better idea :)

By: Stephan Eisvogel (eisvogel) 2015-01-10 05:10:59.193-0600

SIP debug trace from console

By: Stephan Eisvogel (eisvogel) 2015-01-10 05:12:04.054-0600

I attached a SIP debug log of a TLS/SRTP-call from subscriber 2004 to 2000 using
a very recent Asterisk and PJSIP-stack client. Of note:

- I sanitized domain and authentication data, so this can be transmitted publicly
- The troublesome reply by Asterisk can be found in line 189
- The PJSIP-stack-based client BYE and error message is found in line 213 right behind it
- The call is terminated as soon as 2000 picks up
- PJSIP stacks before changeset 4899 ignore line 189 being sip: instead of sips:


By: Stephan Eisvogel (eisvogel) 2015-01-12 07:14:16.287-0600

CSipSimple issue 2776 is tracked here: https://code.google.com/p/csipsimple/issues/detail?id=2776


By: Mark Michelson (mmichelson) 2015-01-12 13:08:24.513-0600

After doing a lot of reading on the topic, I'm convinced that the party at fault here is Asterisk. We're not being compliant with RFC 3261's text, and in order to be compatible with clients, we need to alter our behavior. The way forward seems pretty straight-forward, but I also sent out an e-mail to Olle Johansson since he is much more knowledgeable on the subject than I am.

What I am comfortable doing for now is providing a temporary patch that should resolve your issue. I will attach the patch once I have it finished. I will also await a response from Olle in case he has further suggestions on how to go about fixing the issue.

By: Mark Michelson (mmichelson) 2015-01-12 13:33:14.894-0600

I have added ASTERISK-24646.patch. This patch follows the guidelines in RFC 3261 section 12.1.1 to determine whether the Contact header we generate should be a sips: URI or not. For the time being, I have also left the ;transport parameter on our Contact header, since I feel like there are clients that rely on that and removing it could cause problems.

Please try this with CSipSimple and let me know if the issue you reported is fixed or if this causes any further issues.

By: Stephan Eisvogel (eisvogel) 2015-01-12 14:09:49.759-0600

Thanks Mark, but the patch will not work for Asterisk 11, against which I have reported this issue.
I do not have any Asterisk 13 instances running.

Quickly browsing through channels/chan_sip.c I think the function needing a similar fix might be
static void build_contact(struct sip_pvt *p) around line 13685. Then I got lost in struct sip_pvt's
5000 lines, while looking up parse_uri.


By: Mark Michelson (mmichelson) 2015-01-12 14:20:03.917-0600

Ah, my mistake. I instictively start patching our PJSIP implementation these days by default, I'll provide a similar chan_sip.c patch for you.

By: Stephan Eisvogel (eisvogel) 2015-01-12 14:39:28.496-0600

For reference

In addition to ​responses http://tools.ietf.org/html/rfc3261#section-12.1.1
- If the request that initiated the dialog contained a SIPS URI in the Request-URI or in the top Record-Route header field value, if there was any, or the Contact header field if there was no Record-Route header field, the Contact header field in the response MUST be a SIPS URI.

also relevant is requests http://tools.ietf.org/html/rfc5630#section-5.1.1
- As mandated by RFC3261, Section 8.1.1.8, in a request, "if the Request-URI or top Route header field value contains a SIPS URI, the Contact header field MUST contain a SIPS URI as well".

and target refreshes as well ​http://tools.ietf.org/html/rfc5630#section-5.1.1.2
- When a target refresh occurs within a dialog (e.g., re-INVITE request, UPDATE request), the UAC MUST include a Contact header field with a SIPS URI if the original request used a SIPS Request-URI.


By: Mark Michelson (mmichelson) 2015-01-12 15:43:59.149-0600

I'm attaching ASTERISK-24646-chan_sip.patch. This addresses the issue you were having and also generates SIPS Contact URIs when Asterisk is the UAC as well. As far as target refreshes are concerned, Asterisk does not send target refreshes with different request URIs from what was originally sent, so they should be properly covered by the chan_sip patch here.

By: Stephan Eisvogel (eisvogel) 2015-01-12 17:07:22.243-0600

Applied second patch with 11-trunk, now working with latest CSipSimple 1.02.03 r2456 nightly.
Good job, you are a fast programmer. ;-) This should be reviewed and verified by other people now.

Typo/cosmetic fixes I found looking through the patch:

--- ASTERISK-24646-chan_sip.patch.txt.orig      2015-01-12 23:56:16.139299682 +0100
+++ ASTERISK-24646-chan_sip.patch.txt   2015-01-12 23:43:06.712679189 +0100
@@ -18,7 +18,7 @@
+}
 
+/*!
-+ * \brief Determine if, as a UAS, we need to use a SIPS contact.
++ * \brief Determine if, as a UAS, we need to use a SIPS Contact.
+ *
+ * This uses the rules defined in RFC 3261 section 12.1.1 to
+ * determine if a SIPS URI should be used as the Contact header
@@ -53,7 +53,7 @@
+/*!
+ * \brief Determine if, as a UAC, we need to use a SIPS Contact.
+ *
-+ * This uses the rules defined in RFC 3621 sectcion 8.1.1.8 to
++ * This uses the rules defined in RFC 3621 section 8.1.1.8 to
+ * determine if a SIPS URI should be used as the Contact header
+ * on our outgoing request.
+ *
@@ -91,7 +91,7 @@
+ *
+ * \param p The sip_pvt where the built Contact will be saved.
+ * \param req The request that triggered the creation of a Contact header.
-+ * \praram incoming Indicates if the Contact header is being created for a response to an incoming request
++ * \param incoming Indicates if the Contact header is being created for a response to an incoming request
+ */
+static void build_contact(struct sip_pvt *p, struct sip_request *req, int incoming)
 {


By: Mark Michelson (mmichelson) 2015-01-13 10:26:21.731-0600

Thanks for editing my patch.

We're at a point where you have a patch that fixes the issue for you, but when it comes to things like guaranteeing SIPS support in a Contact header, I defer to people who are more knowledgeable than me before I will actually commit the patch. I mentioned before that I sent an e-mail to Olle Johansson, a SIP expert and contributor to Asterisk and Kamailio, for some advice on this issue. He's let me know that he will get back to me soon.

In the meantime, I'm going to leave this issue open until I get confirmation from Olle that the approach being taken here is correct. I will post back here once I have more information.

By: Stephan Eisvogel (eisvogel) 2015-02-21 13:48:52.739-0600

Not sure how to deal with closed tickets, but here it goes. I think I have identified another
scenario not fixed with this patch. I checked out SVN-branch-11-r432098M and the problem
does exist there still. I also tried revision r431423 to exclude possibility of introduced regression
since that patch, but it ain't. Scenario:

SIP phone (unencrypted) <---> Asterisk <---> Newer PJSIP client (encrypted, IP 192.168.129.114 in below example)

In sip.conf peer definitions only the pjsip client has the entries transport=tls and encryption=yes. The initiating SIP
phone on the left doesn't and therefore talks plaintext with Asterisk. Here is what happens on right side:

-----------------------------------------------------------------------------------------------------------------
Reliably Transmitting (NAT) to 192.168.129.114:53854:
INVITE sips:2004@192.168.129.114:53854;transport=TLS;ob SIP/2.0
Via: SIP/2.0/TLS 192.168.129.1:5061;branch=z9hG4bK6327ac34;rport
Max-Forwards: 70
From: "Test" <sip:2000@192.168.129.1>;tag=as49504738
To: <sips:2004@192.168.129.114:53854;transport=TLS;ob>
Contact: <sip:2000@192.168.129.1:5061;transport=TLS>
Call-ID: 0170dac0676a490200fee7c13f1b8609@192.168.129.1:5061
CSeq: 102 INVITE
Date: Sat, 21 Feb 2015 17:47:53 GMT
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Content-Type: application/sdp
Content-Length: 523
...

<--- SIP read from TLS:192.168.129.114:53854 --->
SIP/2.0 480 Temporarily Unavailable
Via: SIP/2.0/TLS 192.168.129.1:5061;rport=5061;received=192.168.129.1;branch=z9hG4bK6327ac34
Call-ID: 0170dac0676a490200fee7c13f1b8609@192.168.129.1:5061
From: "Test" <sip:2000@192.168.129.1>;tag=as49504738
To: <sips:2004@192.168.129.114;ob>;tag=z9hG4bK6327ac34
CSeq: 102 INVITE
Warning: 381 localhost "SIPS Required"
Content-Length: 0

Transmitting (NAT) to 192.168.129.114:53854:
ACK sips:2004@192.168.129.114:53854;transport=TLS;ob SIP/2.0
Via: SIP/2.0/TLS 192.168.129.1:5061;branch=z9hG4bK6327ac34;rport
Max-Forwards: 70
From: "Test" <sip:2000@192.168.129.1>;tag=as49504738
To: <sips:2004@192.168.129.114:53854;transport=TLS;ob>;tag=z9hG4bK6327ac34
Contact: <sip:2000@192.168.129.1:5061;transport=TLS>
Call-ID: 0170dac0676a490200fee7c13f1b8609@192.168.129.1:5061
CSeq: 102 ACK
Content-Length: 0
-----------------------------------------------------------------------------------------------------------------

In the very first invite, the line Contact: <sip:2000@192.168.129.1:5061;transport=TLS> is
imho the problem. Asterisk fails to determine if called party requires TLS and does not set
contact header of invite packet to sips if that's the case.

By: Matt Jordan (mjordan) 2015-02-21 16:55:40.252-0600

[~eisvogel]: Please open a new issue, providing both the {{sip.conf}} and the {{pjsip.conf}} for the new scenario. This doesn't feel like exactly the same problem, and depending on the configuration, may be expected behaviour. Thanks!

By: Stephan Eisvogel (eisvogel) 2015-02-21 19:20:36.110-0600

[~mjordan]: Thanks for taking the time to comment, Matt. Appreciate it very much. My working production setup at home with handcrafted config files from scratch has grown to a whopping 1200 lines and I don't want to mess with it too much for testing. Let me try to build a stripped down installation for that ticket. Just give me a couple of weeks. ;-)