Module: sip-router Branch: master Commit: 84563257d6c174c7ef3c7ee9b931e64a0b5a95c2 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=84563257...
Author: Peter Dunkley peter.dunkley@crocodile-rcs.com Committer: Peter Dunkley peter.dunkley@crocodile-rcs.com Date: Tue Sep 18 19:29:36 2012 +0100
modules/websocket: Updated example kamailio.cfg
- Now using corex and alias_subdomains.
It is quite likely that a WebSocket server will be running on a host within the domain it is authoritative for and that the WebSocket client will address that host directly. This means that the alias_subdomains modparam is a good way to get a domain and all of its sub-domains to match "myself".
This is very useful for checking the Host: header in the WebSocket handshake.
- Added handling of OPTIONS pings.
- Fixed a problem with the Host: header check.
When you connect to a WS or WSS socket in Google Chrome on the default ports (80 and 443 respectively) the Host: header will contain just a hostname (for example, "proxy.example.com") which works with is_myself().
When you connect to a WS or WSS socket in Google Chrome on a non-default port (for example, 8080 or 8443 respectively) the Host: header will contain a hostname and port (for example, "proxy.example.com:8080") whoch does not work with is_myself().
However, both "sip:proxy.example.com" and "sip:proxy.example.com:8080" will work, so simply adding "sip:" to the start of the contents of the Host: header before checking fixes the problem.
- Tidied up response reason texts.
- Tidied up some of the TLS specific checks in event_route[xhttp:request].
- Removed some DBG level log messages.
- Added a (commented out) example for checking the Origin: header in the WebSocket handshake.
---
modules/websocket/example/kamailio.cfg | 44 +++++++++++++++++++++++-------- 1 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/modules/websocket/example/kamailio.cfg b/modules/websocket/example/kamailio.cfg index 5cc76ab..17ae075 100644 --- a/modules/websocket/example/kamailio.cfg +++ b/modules/websocket/example/kamailio.cfg @@ -5,6 +5,7 @@
#!substdef "!DBURL!sqlite:///etc/kamailio/db.sqlite!g" #!substdef "!MY_IP_ADDR!a.b.c.d!g" +#!substdef "!MY_DOMAIN!example.com!g" #!substdef "!MY_WS_PORT!80!g" #!substdef "!MY_WSS_PORT!443!g" #!substdef "!MY_WS_ADDR!tcp:MY_IP_ADDR:MY_WS_PORT!g" @@ -20,8 +21,6 @@ fork=yes children=4
-alias="example.com" - #!ifdef WITH_TLS enable_tls=1 #!endif @@ -65,6 +64,7 @@ loadmodule "auth.so" loadmodule "auth_db.so" loadmodule "kex.so" loadmodule "mi_rpc.so" +loadmodule "corex.so" #!ifdef WITH_TLS loadmodule "tls.so" #!endif @@ -105,6 +105,9 @@ modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password") modparam("auth_db", "load_credentials", "")
+# ----- corex params ----- +modparam("corex", "alias_subdomains", "MY_DOMAIN") + #!ifdef WITH_TLS # ----- tls params ----- modparam("tls", "tls_method", "SSLv23") @@ -203,10 +206,15 @@ route[REQINIT] { exit; }
- if(!sanity_check("1511", "7")) { + if (!sanity_check("1511", "7")) { xlog("Malformed SIP message from $si:$sp\n"); exit; } + + if (uri == myself && is_method("OPTIONS") && !(uri=~"sip:.*[@]+.*")) { + options_reply(); + exit; + } }
# Handle requests within SIP dialogs @@ -239,7 +247,7 @@ route[WITHINDLG] { exit; } } - sl_send_reply("404","Not here"); + sl_send_reply("404","Not Found"); } exit; } @@ -287,7 +295,7 @@ route[AUTH] { # if caller is not local subscriber, then check if it calls # a local destination, otherwise deny, not an open relay here if (from_uri!=myself && uri!=myself) { - sl_send_reply("403","Not relaying"); + sl_send_reply("403","Forbidden"); exit; } } @@ -307,7 +315,11 @@ event_route[xhttp:request] { set_reply_close(); set_reply_no_connect(); - if ($Rp != MY_WS_PORT && $Rp != MY_WSS_PORT) { + if ($Rp != MY_WS_PORT +#!ifdef WITH_TLS + && $Rp != MY_WSS_PORT +#!endif + ) { xlog("L_WARN", "HTTP request received on $Rp\n"); xhttp_reply("403", "Forbidden", "", ""); exit; @@ -318,17 +330,25 @@ event_route[xhttp:request] { if ($hdr(Upgrade)=~"websocket" && $hdr(Connection)=~"Upgrade" && $rm=~"GET") { - xlog("L_DBG", "WebSocket\n"); - xlog("L_DBG", " Host: $hdr(Host)\n"); - xlog("L_DBG", " Origin: $hdr(Origin)\n");
- if ($hdr(Host) == $null || !is_myself($hdr(Host))) { + # Validate Host - make sure the client is using the correct + # alias for WebSockets + if ($hdr(Host) == $null || !is_myself("sip:" + $hdr(Host))) { xlog("L_WARN", "Bad host $hdr(Host)\n"); xhttp_reply("403", "Forbidden", "", ""); exit; }
- # Optional... validate Origin + # Optional... validate Origin - make sure the client is from an + # authorised website. For example, + # + # if ($hdr(Origin) != "http://communicator.MY_DOMAIN" + # && $hdr(Origin) != "https://communicator.MY_DOMAIN") { + # xlog("L_WARN", "Unauthorised client $hdr(Origin)\n"); + # xhttp_reply("403", "Forbidden", "", ""); + # exit; + # } + # Optional... perform HTTP authentication
# ws_handle_handshake() exits (no further configuration file @@ -341,7 +361,7 @@ event_route[xhttp:request] { } }
- xhttp_reply("404", "Not found", "", ""); + xhttp_reply("404", "Not Found", "", ""); }
event_route[websocket:closed] {