gnutls: reorder, inline and turn off server-side if !SOUT
authorRémi Denis-Courmont <remi@remlab.net>
Sat, 23 Aug 2014 09:12:56 +0000 (12:12 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Sat, 23 Aug 2014 09:59:31 +0000 (12:59 +0300)
modules/misc/gnutls.c

index bbc0950..7826558 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * gnutls.c
  *****************************************************************************
- * Copyright (C) 2004-2012 Rémi Denis-Courmont
+ * Copyright (C) 2004-2014 Rémi Denis-Courmont
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
 #include <gnutls/x509.h>
 #include "dhparams.h"
 
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-static int  OpenClient  (vlc_tls_creds_t *);
-static void CloseClient (vlc_tls_creds_t *);
-static int  OpenServer  (vlc_tls_creds_t *, const char *, const char *);
-static void CloseServer (vlc_tls_creds_t *);
-
-#define PRIORITIES_TEXT N_("TLS cipher priorities")
-#define PRIORITIES_LONGTEXT N_("Ciphers, key exchange methods, " \
-    "hash functions and compression methods can be selected. " \
-    "Refer to GNU TLS documentation for detailed syntax.")
-static const char *const priorities_values[] = {
-    "PERFORMANCE",
-    "NORMAL",
-    "SECURE128",
-    "SECURE256",
-    "EXPORT",
-};
-static const char *const priorities_text[] = {
-    N_("Performance (prioritize faster ciphers)"),
-    N_("Normal"),
-    N_("Secure 128-bits (exclude 256-bits ciphers)"),
-    N_("Secure 256-bits (prioritize 256-bits ciphers)"),
-    N_("Export (include insecure ciphers)"),
-};
-
-vlc_module_begin ()
-    set_shortname( "GNU TLS" )
-    set_description( N_("GNU TLS transport layer security") )
-    set_capability( "tls client", 1 )
-    set_callbacks( OpenClient, CloseClient )
-    set_category( CAT_ADVANCED )
-    set_subcategory( SUBCAT_ADVANCED_NETWORK )
-
-    add_submodule ()
-        set_description( N_("GNU TLS server") )
-        set_capability( "tls server", 1 )
-        set_category( CAT_ADVANCED )
-        set_subcategory( SUBCAT_ADVANCED_NETWORK )
-        set_callbacks( OpenServer, CloseServer )
-
-        add_string ("gnutls-priorities", "NORMAL", PRIORITIES_TEXT,
-                    PRIORITIES_LONGTEXT, false)
-            change_string_list (priorities_values, priorities_text)
-vlc_module_end ()
-
 static vlc_mutex_t gnutls_mutex = VLC_STATIC_MUTEX;
 
 /**
@@ -202,6 +151,75 @@ static int gnutls_Recv (void *opaque, void *buf, size_t length)
     return (val < 0) ? gnutls_Error (session, val) : val;
 }
 
+/**
+ * Terminates TLS session and releases session data.
+ * You still have to close the socket yourself.
+ */
+static void gnutls_SessionClose (vlc_tls_t *session)
+{
+    vlc_tls_sys_t *sys = session->sys;
+
+    if (sys->handshaked)
+        gnutls_bye (sys->session, GNUTLS_SHUT_WR);
+    gnutls_deinit (sys->session);
+
+    free (sys);
+}
+
+static int gnutls_SessionOpen (vlc_tls_t *tls, int type,
+                               gnutls_certificate_credentials_t x509, int fd)
+{
+    const char *errp;
+    int val;
+
+    vlc_tls_sys_t *sys = malloc (sizeof (*tls->sys));
+    if (unlikely(sys == NULL))
+        return VLC_ENOMEM;
+
+    sys->handshaked = false;
+
+    val = gnutls_init (&sys->session, type);
+    if (val != 0)
+    {
+        msg_Err (tls, "cannot initialize TLS session: %s",
+                 gnutls_strerror (val));
+        free (sys);
+        return VLC_EGENERIC;
+    }
+
+    char *priorities = var_InheritString (tls, "gnutls-priorities");
+    if (unlikely(priorities == NULL))
+        goto error;
+
+    val = gnutls_priority_set_direct (sys->session, priorities, &errp);
+    if (val < 0)
+        msg_Err (tls, "cannot set TLS priorities \"%s\": %s", errp,
+                 gnutls_strerror (val));
+    free (priorities);
+    if (val < 0)
+        goto error;
+
+    val = gnutls_credentials_set (sys->session, GNUTLS_CRD_CERTIFICATE, x509);
+    if (val < 0)
+    {
+        msg_Err (tls, "cannot set TLS session credentials: %s",
+                 gnutls_strerror (val));
+        goto error;
+    }
+
+    gnutls_transport_set_ptr (sys->session,
+                              (gnutls_transport_ptr_t)(intptr_t)fd);
+
+    tls->sys = sys;
+    tls->sock.p_sys = tls;
+    tls->sock.pf_send = gnutls_Send;
+    tls->sock.pf_recv = gnutls_Recv;
+    return VLC_SUCCESS;
+
+error:
+    gnutls_SessionClose (tls);
+    return VLC_EGENERIC;
+}
 
 /**
  * Starts or continues the TLS handshake.
@@ -210,10 +228,9 @@ static int gnutls_Recv (void *opaque, void *buf, size_t length)
  * 1 if more would-be blocking recv is needed,
  * 2 if more would-be blocking send is required.
  */
-static int gnutls_ContinueHandshake (vlc_tls_t *session, const char *host,
-                                     const char *service)
+static int gnutls_ContinueHandshake (vlc_tls_t *tls)
 {
-    vlc_tls_sys_t *sys = session->sys;
+    vlc_tls_sys_t *sys = tls->sys;
     int val;
 
 #ifdef _WIN32
@@ -222,81 +239,134 @@ static int gnutls_ContinueHandshake (vlc_tls_t *session, const char *host,
     do
     {
         val = gnutls_handshake (sys->session);
-        msg_Dbg (session, "TLS handshake: %s", gnutls_strerror (val));
-
-        if ((val == GNUTLS_E_AGAIN) || (val == GNUTLS_E_INTERRUPTED))
-            /* I/O event: return to caller's poll() loop */
-            return 1 + gnutls_record_get_direction (sys->session);
+        msg_Dbg (tls, "TLS handshake: %s", gnutls_strerror (val));
+
+        switch (val)
+        {
+            case GNUTLS_E_SUCCESS:
+                return 0;
+            case GNUTLS_E_AGAIN:
+            case GNUTLS_E_INTERRUPTED:
+                /* I/O event: return to caller's poll() loop */
+                return 1 + gnutls_record_get_direction (sys->session);
+        }
     }
-    while (val < 0 && !gnutls_error_is_fatal (val));
+    while (!gnutls_error_is_fatal (val));
 
-    if (val < 0)
-    {
 #ifdef _WIN32
-        msg_Dbg (session, "Winsock error %d", WSAGetLastError ());
+    msg_Dbg (tls, "Winsock error %d", WSAGetLastError ());
 #endif
-        msg_Err (session, "TLS handshake error: %s", gnutls_strerror (val));
+    msg_Err (tls, "TLS handshake error: %s", gnutls_strerror (val));
+    return -1;
+}
+
+static int gnutls_ClientSessionOpen (vlc_tls_creds_t *crd, vlc_tls_t *tls,
+                                     int fd, const char *hostname)
+{
+    int val = gnutls_SessionOpen (tls, GNUTLS_CLIENT, crd->sys, fd);
+    if (val != VLC_SUCCESS)
+        return val;
+
+    vlc_tls_sys_t *sys = tls->sys;
+
+    /* minimum DH prime bits */
+    gnutls_dh_set_prime_bits (sys->session, 1024);
+
+    if (likely(hostname != NULL))
+        /* fill Server Name Indication */
+        gnutls_server_name_set (sys->session, GNUTLS_NAME_DNS,
+                                hostname, strlen (hostname));
+
+    return VLC_SUCCESS;
+}
+
+static int gnutls_ClientHandshake (vlc_tls_t *tls, const char *host,
+                                   const char *service)
+{
+    int val = gnutls_ContinueHandshake (tls);
+    if (val)
+        return val;
+
+    /* certificates chain verification */
+    vlc_tls_sys_t *sys = tls->sys;
+    unsigned status;
+
+    val = gnutls_certificate_verify_peers3 (sys->session, host, &status);
+    if (val)
+    {
+        msg_Err (tls, "Certificate verification error: %s",
+                 gnutls_strerror (val));
         return -1;
     }
 
-    sys->handshaked = true;
-    (void) host; (void) service;
-    return 0;
-}
+    if (status == 0)
+        goto success; /* Good certificate */
 
+    /* Bad certificate */
+    gnutls_datum_t desc;
 
-/**
- * Looks up certificate in known hosts data base.
- * @return 0 on success, -1 on failure.
- */
-static int gnutls_CertSearch (vlc_tls_t *obj, const char *host,
-                              const char *service,
-                              const gnutls_datum_t *restrict datum)
-{
-    assert (host != NULL);
+    if (gnutls_certificate_verification_status_print(status,
+                   gnutls_certificate_type_get (sys->session), &desc, 0) == 0)
+    {
+        msg_Err (tls, "Certificate verification failure: %s", desc.data);
+        gnutls_free (desc.data);
+    }
+
+    status &= ~GNUTLS_CERT_INVALID; /* always set / catch-all error */
+    status &= ~GNUTLS_CERT_SIGNER_NOT_FOUND; /* unknown CA */
+    status &= ~GNUTLS_CERT_UNEXPECTED_OWNER; /* mismatched hostname */
+
+    if (status != 0 || host == NULL)
+        return -1; /* Really bad certificate */
 
     /* Look up mismatching certificate in store */
-    int val = gnutls_verify_stored_pubkey (NULL, NULL, host, service,
-                                           GNUTLS_CRT_X509, datum, 0);
+    const gnutls_datum_t *datum;
+    unsigned count;
+
+    datum = gnutls_certificate_get_peers (sys->session, &count);
+    if (datum == NULL || count == 0)
+    {
+        msg_Err (tls, "Peer certificate not available");
+        return -1;
+    }
+
+    msg_Dbg (tls, "%u certificate(s) in the list", count);
+    val = gnutls_verify_stored_pubkey (NULL, NULL, host, service,
+                                       GNUTLS_CRT_X509, datum, 0);
     const char *msg;
     switch (val)
     {
         case 0:
-            msg_Dbg (obj, "certificate key match for %s", host);
-            return 0;
+            msg_Dbg (tls, "certificate key match for %s", host);
+            goto success;
         case GNUTLS_E_NO_CERTIFICATE_FOUND:
-            msg_Dbg (obj, "no known certificates for %s", host);
-            msg = N_("You attempted to reach %s. "
-                "However the security certificate presented by the server "
-                "is unknown and could not be authenticated by any trusted "
-                "Certification Authority. "
-                "This problem may be caused by a configuration error "
-                "or an attempt to breach your security or your privacy.\n\n"
-                "If in doubt, abort now.\n");
+            msg_Dbg (tls, "no known certificates for %s", host);
+            msg = N_("However the security certificate presented by the "
+                "server is unknown and could not be authenticated by any "
+                "trusted Certificate Authority.");
             break;
         case GNUTLS_E_CERTIFICATE_KEY_MISMATCH:
-            msg_Dbg (obj, "certificate keys mismatch for %s", host);
-            msg = N_("You attempted to reach %s. "
-                "However the security certificate presented by the server "
-                "changed since the previous visit "
-                "and was not authenticated by any trusted "
-                "Certification Authority. "
-                "This problem may be caused by a configuration error "
-                "or an attempt to breach your security or your privacy.\n\n"
-                "If in doubt, abort now.\n");
+            msg_Dbg (tls, "certificate keys mismatch for %s", host);
+            msg = N_("However the security certificate presented by the "
+                "server changed since the previous visit and was not "
+                "authenticated by any trusted Certificate Authority. ");
             break;
         default:
-            msg_Err (obj, "certificate key match error for %s: %s", host,
+            msg_Err (tls, "certificate key match error for %s: %s", host,
                      gnutls_strerror (val));
             return -1;
     }
 
-    if (dialog_Question (obj, _("Insecure site"), vlc_gettext (msg),
-                         _("Abort"), _("View certificate"), NULL, host) != 2)
+    if (dialog_Question (tls, _("Insecure site"),
+        _("You attempted to reach %s. %s\n"
+          "This problem may be stem from an attempt to breach your security, "
+          "compromise your privacy, or a configuration error.\n\n"
+          "If in doubt, abort now.\n"),
+                         _("Abort"), _("View certificate"), NULL,
+                         vlc_gettext (msg), host) != 2)
         return -1;
 
     gnutls_x509_crt_t cert;
-    gnutls_datum_t desc;
 
     if (gnutls_x509_crt_init (&cert))
         return -1;
@@ -308,7 +378,7 @@ static int gnutls_CertSearch (vlc_tls_t *obj, const char *host,
     }
     gnutls_x509_crt_deinit (cert);
 
-    val = dialog_Question (obj, _("Insecure site"),
+    val = dialog_Question (tls, _("Insecure site"),
          _("This is the certificate presented by %s:\n%s\n\n"
            "If in doubt, abort now.\n"),
                            _("Abort"), _("Accept 24 hours"),
@@ -325,149 +395,65 @@ static int gnutls_CertSearch (vlc_tls_t *obj, const char *host,
             val = gnutls_store_pubkey (NULL, NULL, host, service,
                                        GNUTLS_CRT_X509, datum, expiry, 0);
             if (val)
-                msg_Err (obj, "cannot store X.509 certificate: %s",
+                msg_Err (tls, "cannot store X.509 certificate: %s",
                          gnutls_strerror (val));
-            return 0;
-    }
-    return -1;
-}
-
-
-static int gnutls_HandshakeAndValidate (vlc_tls_t *session, const char *host,
-                                        const char *service)
-{
-    vlc_tls_sys_t *sys = session->sys;
-
-    int val = gnutls_ContinueHandshake (session, host, service);
-    if (val)
-        return val;
-
-    /* certificates chain verification */
-    unsigned status;
-
-    val = gnutls_certificate_verify_peers3 (sys->session, host, &status);
-    if (val)
-    {
-        msg_Err (session, "Certificate verification error: %s",
-                 gnutls_strerror (val));
-        return -1;
-    }
-
-    if (status == 0)
-        return 0; /* good certificate */
-
-    gnutls_datum_t datum;
-
-    if (gnutls_certificate_verification_status_print(status,
-                   gnutls_certificate_type_get (sys->session), &datum, 0) == 0)
-    {
-        msg_Err (session, "Certificate verification failure: %s", datum.data);
-        gnutls_free (datum.data);
-    }
-
-    status &= ~GNUTLS_CERT_INVALID; /* always set / catch-all error */
-    status &= ~GNUTLS_CERT_SIGNER_NOT_FOUND; /* unknown CA */
-    status &= ~GNUTLS_CERT_UNEXPECTED_OWNER; /* mismatched hostname */
-
-    if (status != 0 || host == NULL)
-        return -1; /* really bad certificate */
-
-    /* manual verification */
-    const gnutls_datum_t *data;
-    unsigned count;
-
-    data = gnutls_certificate_get_peers (sys->session, &count);
-    if (data == NULL || count == 0)
-    {
-        msg_Err (session, "Peer certificate not available");
-        return -1;
+            break;
+        default:
+            return -1;
     }
-    msg_Dbg (session, "%u certificate(s) in the list", count);
-
-    return gnutls_CertSearch (session, host, service, data);
-}
-
-static int
-gnutls_SessionPrioritize (vlc_object_t *obj, gnutls_session_t session)
-{
-    char *priorities = var_InheritString (obj, "gnutls-priorities");
-    if (unlikely(priorities == NULL))
-        return VLC_ENOMEM;
 
-    const char *errp;
-    int val = gnutls_priority_set_direct (session, priorities, &errp);
-    if (val < 0)
-    {
-        msg_Err (obj, "cannot set TLS priorities \"%s\": %s", errp,
-                 gnutls_strerror (val));
-        val = VLC_EGENERIC;
-    }
-    else
-        val = VLC_SUCCESS;
-    free (priorities);
-    return val;
+success:
+    sys->handshaked = true;
+    return 0;
 }
 
-
 /**
- * Terminates TLS session and releases session data.
- * You still have to close the socket yourself.
+ * Initializes a client-side TLS credentials.
  */
-static void gnutls_SessionClose (vlc_tls_t *session)
-{
-    vlc_tls_sys_t *sys = session->sys;
-
-    if (sys->handshaked)
-        gnutls_bye (sys->session, GNUTLS_SHUT_WR);
-    gnutls_deinit (sys->session);
-
-    free (sys);
-}
-
-
-static int gnutls_SessionOpen (vlc_tls_t *tls, int type,
-                               gnutls_certificate_credentials_t x509, int fd)
+static int OpenClient (vlc_tls_creds_t *crd)
 {
-    vlc_tls_sys_t *sys = malloc (sizeof (*tls->sys));
-    if (unlikely(sys == NULL))
-        return VLC_ENOMEM;
+    gnutls_certificate_credentials_t x509;
 
-    sys->handshaked = false;
+    if (gnutls_Init (VLC_OBJECT(crd)))
+        return VLC_EGENERIC;
 
-    int val = gnutls_init (&sys->session, type);
+    int val = gnutls_certificate_allocate_credentials (&x509);
     if (val != 0)
     {
-        msg_Err (tls, "cannot initialize TLS session: %s",
+        msg_Err (crd, "cannot allocate credentials: %s",
                  gnutls_strerror (val));
-        free (sys);
+        gnutls_Deinit (VLC_OBJECT(crd));
         return VLC_EGENERIC;
     }
 
-    if (gnutls_SessionPrioritize (VLC_OBJECT (tls), sys->session))
-        goto error;
-
-    val = gnutls_credentials_set (sys->session, GNUTLS_CRD_CERTIFICATE, x509);
+    val = gnutls_certificate_set_x509_system_trust (x509);
     if (val < 0)
-    {
-        msg_Err (tls, "cannot set TLS session credentials: %s",
+        msg_Err (crd, "cannot load trusted Certificate Authorities: %s",
                  gnutls_strerror (val));
-        goto error;
-    }
+    else
+        msg_Dbg (crd, "loaded %d trusted CAs", val);
 
-    gnutls_transport_set_ptr (sys->session,
-                              (gnutls_transport_ptr_t)(intptr_t)fd);
+    gnutls_certificate_set_verify_flags (x509,
+                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
+
+    crd->sys = x509;
+    crd->open = gnutls_ClientSessionOpen;
+    crd->handshake = gnutls_ClientHandshake;
+    crd->close = gnutls_SessionClose;
 
-    tls->sys = sys;
-    tls->sock.p_sys = tls;
-    tls->sock.pf_send = gnutls_Send;
-    tls->sock.pf_recv = gnutls_Recv;
     return VLC_SUCCESS;
+}
 
-error:
-    gnutls_SessionClose (tls);
-    return VLC_EGENERIC;
+static void CloseClient (vlc_tls_creds_t *crd)
+{
+    gnutls_certificate_credentials_t x509 = crd->sys;
+
+    gnutls_certificate_free_credentials (x509);
+
+    gnutls_Deinit (VLC_OBJECT(crd));
 }
 
+#ifdef ENABLE_SOUT
 /**
  * Server-side TLS credentials private data
  */
@@ -489,27 +475,17 @@ static int gnutls_ServerSessionOpen (vlc_tls_creds_t *crd, vlc_tls_t *tls,
     return gnutls_SessionOpen (tls, GNUTLS_SERVER, sys->x509_cred, fd);
 }
 
-static int gnutls_ClientSessionOpen (vlc_tls_creds_t *crd, vlc_tls_t *tls,
-                                     int fd, const char *hostname)
+static int gnutls_ServerHandshake (vlc_tls_t *tls, const char *host,
+                                   const char *service)
 {
-    int val = gnutls_SessionOpen (tls, GNUTLS_CLIENT, crd->sys, fd);
-    if (val != VLC_SUCCESS)
-        return val;
+    int val = gnutls_ContinueHandshake (tls);
+    if (val == 0)
+        tls->sys->handshaked = true;
 
-    vlc_tls_sys_t *sys = tls->sys;
-
-    /* minimum DH prime bits */
-    gnutls_dh_set_prime_bits (sys->session, 1024);
-
-    if (likely(hostname != NULL))
-        /* fill Server Name Indication */
-        gnutls_server_name_set (sys->session, GNUTLS_NAME_DNS,
-                                hostname, strlen (hostname));
-
-    return VLC_SUCCESS;
+    (void) host; (void) service;
+    return val;
 }
 
-
 /**
  * Allocates a whole server's TLS credentials.
  */
@@ -594,7 +570,7 @@ static int OpenServer (vlc_tls_creds_t *crd, const char *cert, const char *key)
 
     crd->sys = sys;
     crd->open = gnutls_ServerSessionOpen;
-    crd->handshake = gnutls_ContinueHandshake;
+    crd->handshake = gnutls_ServerHandshake;
     crd->close = gnutls_SessionClose;
 
     return VLC_SUCCESS;
@@ -619,49 +595,43 @@ static void CloseServer (vlc_tls_creds_t *crd)
 
     gnutls_Deinit (VLC_OBJECT(crd));
 }
+#endif
 
-/**
- * Initializes a client-side TLS credentials.
- */
-static int OpenClient (vlc_tls_creds_t *crd)
-{
-    gnutls_certificate_credentials_t x509;
-
-    if (gnutls_Init (VLC_OBJECT(crd)))
-        return VLC_EGENERIC;
-
-    int val = gnutls_certificate_allocate_credentials (&x509);
-    if (val != 0)
-    {
-        msg_Err (crd, "cannot allocate credentials: %s",
-                 gnutls_strerror (val));
-        gnutls_Deinit (VLC_OBJECT(crd));
-        return VLC_EGENERIC;
-    }
-
-    val = gnutls_certificate_set_x509_system_trust (x509);
-    if (val < 0)
-        msg_Err (crd, "cannot load trusted Certificate Authorities: %s",
-                 gnutls_strerror (val));
-    else
-        msg_Dbg (crd, "loaded %d trusted CAs", val);
-
-    gnutls_certificate_set_verify_flags (x509,
-                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
-
-    crd->sys = x509;
-    crd->open = gnutls_ClientSessionOpen;
-    crd->handshake = gnutls_HandshakeAndValidate;
-    crd->close = gnutls_SessionClose;
-
-    return VLC_SUCCESS;
-}
-
-static void CloseClient (vlc_tls_creds_t *crd)
-{
-    gnutls_certificate_credentials_t x509 = crd->sys;
-
-    gnutls_certificate_free_credentials (x509);
+#define PRIORITIES_TEXT N_("TLS cipher priorities")
+#define PRIORITIES_LONGTEXT N_("Ciphers, key exchange methods, " \
+    "hash functions and compression methods can be selected. " \
+    "Refer to GNU TLS documentation for detailed syntax.")
+static const char *const priorities_values[] = {
+    "PERFORMANCE",
+    "NORMAL",
+    "SECURE128",
+    "SECURE256",
+    "EXPORT",
+};
+static const char *const priorities_text[] = {
+    N_("Performance (prioritize faster ciphers)"),
+    N_("Normal"),
+    N_("Secure 128-bits (exclude 256-bits ciphers)"),
+    N_("Secure 256-bits (prioritize 256-bits ciphers)"),
+    N_("Export (include insecure ciphers)"),
+};
 
-    gnutls_Deinit (VLC_OBJECT(crd));
-}
+vlc_module_begin ()
+    set_shortname( "GNU TLS" )
+    set_description( N_("GNU TLS transport layer security") )
+    set_capability( "tls client", 1 )
+    set_callbacks( OpenClient, CloseClient )
+    set_category( CAT_ADVANCED )
+    set_subcategory( SUBCAT_ADVANCED_NETWORK )
+    add_string ("gnutls-priorities", "NORMAL", PRIORITIES_TEXT,
+                PRIORITIES_LONGTEXT, false)
+        change_string_list (priorities_values, priorities_text)
+#ifdef ENABLE_SOUT
+    add_submodule ()
+        set_description( N_("GNU TLS server") )
+        set_capability( "tls server", 1 )
+        set_category( CAT_ADVANCED )
+        set_subcategory( SUBCAT_ADVANCED_NETWORK )
+        set_callbacks( OpenServer, CloseServer )
+#endif
+vlc_module_end ()