Hello,

I found an issue with checking the Host: header when you are using a non-default port (that is not 80 or 443) for WebSockets.

I have updated the WebSockets example kamailio.cfg in git master with a fix.

Regards,

Peter

On Fri, 2012-09-14 at 11:55 +0200, Jesús Pérez Rubio wrote:
Hi, I had the same problem and I solve it changing this line on my kamailio.cfg:

# DIRTY WORKARROUND :P   
#if ($hdr(Host) == $null || !is_myself($hdr(Host))) {   
if ($hdr(Host) == $null) {
      xlog("L_WARN", "Bad host $hdr(Host)\n");
      xhttp_reply("403", "Forbidden", "", "");
      exit;
}

Could anybode confirm me if this solution is correct (and secure) please?

Thanks in advance :).

2012/8/8 Carlos Ruiz Díaz <carlos.ruizdiaz@gmail.com>
Thank you for your time Peter. 


I'll setup a VM with Windows to continue with my tests and I'll come back later with more feedback.


Regards.


Carlos.


On Wed, Aug 8, 2012 at 12:22 PM, Peter Dunkley <peter.dunkley@crocodile-rcs.com> wrote:
Hi,

I have added some comments in-line below.

Regards,

Peter

> 1. After setting up the proxy ip:port in the call.htm file (of sipml5) to

> *
> 127.0.0.1:5060* the client started to work but kamailio script refused to
> establish my connection because the following condition was not satisfied:
>
>

> *if ($Rp != MY_WS_PORT && $Rp != MY_WSS_PORT) {*
> *                xlog("L_WARN", "HTTP request received on $Rp\n");*
> *                xhttp_reply("403", "Forbidden", "", "");*
> *                exit;*
> *}*
>
> *MY_WS_PORT* and *MY_WSS_PORT *are set to 80 and 443 respectively, as the
> default config example of websocket module says so.
>

> Then, I decided to change the ip:port to *127.0.0.1:80*, always in the
> call.htm file and afterwards the condition was satisfied but sipml5 dies
> with
>
>  SIP stack start: proxy='127.0.0.1:80', realm='<sip:127.0.0.1>',
> impi='2000', impu='<sip:2000@127.0.0.1>'

> tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>  Connecting to 'ws://127.0.0.1:80'

> tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>  Stack starting
> tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>  Unexpected response code: 200 :1 <http://127.0.0.1/>
>  __tsip_transport_ws_onerror
> tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>  __tsip_transport_ws_onclose
> tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>  Failed to connet to the server
>
> Finally, I ended up commenting the condition block and restored the

> original values of ip:port to *127.0.0.1:5060* .
>
> Having done that, I tried again and another error was thrown but this
> time,

> in the next condition block: * if ($hdr(Host) == $null ||
> !is_myself($hdr(Host))) *
>
> <script>: WebSocket
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <script>:
> Host:
> 127.0.0.1:5060
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <script>:
>  Origin: http://127.0.0.1
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==9 && [
> 127.0.0.1:5060] == [127.0.0.1]
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==9 && [
> 127.0.0.1:5060] == [127.0.0.2]
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==13 && [
> 127.0.0.1:5060] == [192.168.10.95]
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==13 && [
> 127.0.0.1:5060] == [192.168.10.55]
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==9 && [
> 127.0.0.1:5060] == [127.0.0.1]
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==9 && [
> 127.0.0.1:5060] == [127.0.0.2]
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==13 && [
> 127.0.0.1:5060] == [192.168.10.95]
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==13 && [
> 127.0.0.1:5060] == [192.168.10.55]
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core>

> [forward.c:462]: *check_self: host != me*
> Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]: WARNING: <script>: Bad
> host 127.0.0.1:5060
>
> I commented the block too and only then sipml5 was able to register
> itself.
>
> What am I doing wrong here?
>


When I tested this I was hosting sipml5 on a web-server on a separate
machine from Kamailio, and my web-browser was on a separate machine from
both Kamailio and the web-server.  The example configuration works for
that scenario (which is likely to be the way it would be deployed in a
real system).  I suspect that the Kamailio listen directives (or something
else related) aren't set-up quite right for your environment.

Host: is a required header when establishing a WebSocket connection.  The
Host: header added by the client should indicate the name of the server
the client is trying to connect to as indicated in the WebSocket URI (so
if you put an IP address in the URI that will be in the Host: header, if
you put a hostname in the URI then it will be in the Host: header).  The
WebSocket server (in this case Kamailio) should check that this header
matches what it believes it's externally visible name is before accepting
the connection.

This check needs to be performed in kamailio.cfg instead of the WebSocket
module in order for the check to be flexible.  The check in the example
kamailio.cfg is:
- Making sure the Host: header is present
- Making sure the name in the Host: header is an IP address (as defined in
the listen directives) or alias (for example a domain name) that the
Kamailio instance believes it is authoritative for.

As the WebSocket stack in a web-browser will add the Host: header
automatically, any problem with this suggests that the WebSocket URI set
in sipml5 and the listen/alias directives in kamailio.cfg don't match -
which would be consistent with the first part your connection
establishment problem too.

I would suggest that you should re-instate these lines as, by commenting
them out (rather than fixing the underlying problems in the test set-up),
you may be moving the issues down-stream.

> 2. I registered a legacy softphone (twinkle) to attempt to initiate a call
> in both ways, but the was something wrong with the signaling, probably
> some
> frame decoding garbage in the buffer of the SIP message. Perhaps these
> bytes are part of the frame control header but since I haven't read the
> RFC
> (yet) I am mentioning it anyway.
>

> tcp_send: buf=*#012�~#003�*INVITE
> sip:2000@df7jal23ls0d.invalid;transport=ws
> SIP/2.0#015#012Record-Route:
> <sip:127.0.0.1;transport=ws;r2=on;lr=on>#015#012Record-Route:
> <sip:127.0.0.1;r2=on;lr=on>#015#012Via: SIP/2.0/WS
>  127.0.0.1;branch=z9hG4bK90a8.b1a7035e13ed19880dd12a1f4c86adbb.0#015#012Via:
> SIP/2.0/UDP
> 127.0.0.1:5062;rport=5062;branch=z9hG4bKimixlbyp#015#012Max-Forwards:
> 69#015#012To: <sip:2000@127.0.0.1>#015#012From: "1000"
> <sip:1000@127.0.0.1>;tag=lrtfz#015#012Call-ID:
> gxsqobolphfchfq@carlosrdcnx-laptop.site#015#012CSeq: 654
> INVITE#015#012Contact: <sip:1000@127.0.0.1:5062>#015#012Content-Type:
> application/sdp#015#012Allow:
> INVITE,ACK,BYE,CANCEL,OPTIONS,PRACK,REFER,NOTIFY,SUBSCRIBE,INFO,MESSAGE#015#012Supported:
> replaces,norefersub,100rel#015#012User-Agent:
> Twinkle/1.4.2#015#012Content-Length:
> 302#015#012#015#012v=0#015#012o=twinkle 391470222 1383232165 IN IP4
> 127.0.0.1#015#012s=-#015#012c=IN IP4 127.0.0.1#015#012t=0 0#015#012m=audio
> 8008 RTP/AVP 98 97 8 0 3 101#015#012a=rtpmap:98
> speex/16000#015#012a=rtpmap:97 speex/8000#015#012a=rtpmap:8
> PCMA/8000#015#012a=rtpmap:0 PCMU/8000#015#012a=rtpmap:3
> GSM/8000#015#012a=rtpmap:101 telephone-event/8000#015#012a=fmtp:101
> 0-15#015#012a=ptime:20#015#012
>


That INVITE is for a call towards sipml5 on a WebSocket connection.  So
this isn't a SIP message over TCP, it is a SIP message over WebSockets
over TCP - and those are not the same thing.  The stuff at the start of
the TCP buffer is the WebSocket framing and it is meant to be there.

The WebSocket framing will not be present on the connection to Twinkle.

> 3. Does Twinkle support the minimum media requirements for testing? If
> not,
> what (Linux) softphone is suitable for this purpose?
>


When using an up-to-date Google Chrome you need to use a client that
supports RTP/SAVPF.  Boghe (from Doubango) is a Windows client that
supports this.  I don't know which (if any) Linux clients support this
feature.

--
Peter Dunkley
Technical Director
Crocodile RCS Ltd


_______________________________________________
sr-dev mailing list
sr-dev@lists.sip-router.org
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev



_______________________________________________
sr-dev mailing list
sr-dev@lists.sip-router.org
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev




--
Jesús Pérez
VoIP Engineer at Quobis

Fixed: +34 902 999 465
Site: http://www.quobis.com

_______________________________________________
sr-dev mailing list
sr-dev@lists.sip-router.org
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

-- 
Peter Dunkley
Technical Director
Crocodile RCS Ltd