Module: sip-router
Branch: master
Commit: 84563257d6c174c7ef3c7ee9b931e64a0b5a95c2
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=8456325…
Author: Peter Dunkley <peter.dunkley(a)crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley(a)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] {