changeset 1814:daf7dcc635d6

Improve SSL/TLS support by adding vhost name to the SSL listener spec and set the libwebsocket stuff accordingly. This fixes problems with SNI.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 30 Oct 2017 01:45:23 +0200
parents d7deea635463
children 7ac487466456
files mapsearch.c
diffstat 1 files changed, 42 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/mapsearch.c	Mon Oct 30 01:14:51 2017 +0200
+++ b/mapsearch.c	Mon Oct 30 01:45:23 2017 +0200
@@ -39,6 +39,7 @@
 typedef struct
 {
     char *interface;         // Listen interface (* = listen all)
+    char *vhostname;         // Vhost name
     int port;                // Port number
 
     BOOL useIPv6;
@@ -112,7 +113,7 @@
         "To force IPv6, use IPv6 address [] or prefix spec with @. In order to\n"
         "listen to all interfaces, you can specify an asterisk (*) as host. Example:\n"
         "\n"
-        "-l *:3491 -l *:3492=<ssl_cert_file.crt>:<ssl_key_file.key>:<ca_file.crt>\n"
+        "-l *:3491 -l *:3492=<vhostname for SNI>:<ssl_cert_file.crt>:<ssl_key_file.key>:<ca_file.crt>\n"
         "\n"
         "Would listen for normal WebSocket (ws://) connections on port 3491 and for\n"
         "secure SSL/TLS WebSocket (wss://) connections on port 3492 of all interfaces.\n"
@@ -278,7 +279,10 @@
     // Parse the SSL/TLS spec, if any
     if (flags != NULL)
     {
-        char *cstart = flags, *cend;
+        char *cstart, *cend;
+
+        // Check for separator
+        cstart = flags;
         if ((cend = strchr(cstart, ':')) == NULL)
         {
             THERR("Invalid SSL/TLS spec '%s'\n", flags);
@@ -286,16 +290,36 @@
         }
         *cend++ = 0;
 
-        ctx->sslCertFile = th_strdup_trim(cstart, TH_TRIM_BOTH);
+        // Get the vhost name
+        ctx->vhostname = th_strdup_trim(cstart, TH_TRIM_BOTH);
+        if (strlen(ctx->vhostname) == 0)
+        {
+            th_free(ctx->vhostname);
+            ctx->vhostname = NULL;
+        }
+
+        // Check for separator
         cstart = cend;
-
         if ((cend = strchr(cend, ':')) == NULL)
         {
-            THERR("Invalid SSL/TLS spec '%s'\n", flags);
+            THERR("Invalid SSL/TLS spec, missing certificate file.\n");
             goto out;
         }
         *cend++ = 0;
 
+        // Get certificate file path
+        ctx->sslCertFile = th_strdup_trim(cstart, TH_TRIM_BOTH);
+
+        // Check for separator
+        cstart = cend;
+        if ((cend = strchr(cend, ':')) == NULL)
+        {
+            THERR("Invalid SSL/TLS spec, missing key file.\n");
+            goto out;
+        }
+        *cend++ = 0;
+
+        // Get the rest
         ctx->sslKeyFile = th_strdup_trim(cstart, TH_TRIM_BOTH);
         ctx->sslCAFile = th_strdup_trim(cend, TH_TRIM_BOTH);
         ctx->useSSL = TRUE;
@@ -1006,8 +1030,8 @@
 
     info.protocols = mapLWSProtocols;
     info.extensions = mapLWSExtensions;
+    info.ssl_cipher_list = optSSLCipherList;
     info.timeout_secs = 5;
-    info.ssl_cipher_list = optSSLCipherList;
 
     if ((setLWSContext = lws_create_context(&info)) == NULL)
     {
@@ -1022,21 +1046,29 @@
 
         if (ctx->useSSL)
         {
-            THMSG(1, "Listen to %s:%d (wss) [cert='%s', key='%s', ca='%s']\n",
+            THMSG(1, "Listen to %s:%d (wss) [vhost='%s', cert='%s', key='%s', ca='%s']\n",
                 ctx->interface != NULL ? ctx->interface : "*", ctx->port,
+                ctx->vhostname,
                 ctx->sslCertFile, ctx->sslKeyFile, ctx->sslCAFile);
+
+            info.vhost_name = ctx->vhostname;
+            info.ssl_cert_filepath = ctx->sslCertFile;
+            info.ssl_private_key_filepath = ctx->sslKeyFile;
+            info.ssl_ca_filepath = ctx->sslCAFile[0] ? ctx->sslCAFile : NULL;
         }
         else
         {
             THMSG(1, "Listen to %s:%d (ws)\n",
                 ctx->interface != NULL ? ctx->interface : "*", ctx->port);
+
+            info.vhost_name = NULL;
+            info.ssl_cert_filepath = NULL;
+            info.ssl_private_key_filepath = NULL;
+            info.ssl_ca_filepath = NULL;
         }
 
         info.port = ctx->port;
         info.iface = ctx->interface;
-        info.ssl_cert_filepath = ctx->sslCertFile;
-        info.ssl_private_key_filepath = ctx->sslKeyFile;
-        info.ssl_ca_filepath = ctx->sslCAFile[0] ? ctx->sslCAFile : NULL;
 
         if ((ctx->vhost = lws_create_vhost(setLWSContext, &info)) == NULL)
         {