lib/tls: Add new 'tls priority' option
authorAndrew Bartlett <abartlet@samba.org>
Sun, 19 Jul 2015 23:22:46 +0000 (11:22 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 20 Jul 2015 01:08:26 +0000 (03:08 +0200)
This adds a new option to the smb.conf to allow administrators to disable
TLS protocols in GnuTLS without changing the code.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11076
Pair-programmed-with: Garming Sam <garming@catalyst.net.nz>
Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
docs-xml/smbdotconf/security/tlspriority.xml [new file with mode: 0644]
lib/param/loadparm.c
lib/param/param_table.c
source3/param/loadparm.c
source4/ldap_server/ldap_server.c
source4/lib/tls/tls.h
source4/lib/tls/tls_tstream.c
source4/libcli/ldap/ldap_client.c
source4/librpc/rpc/dcerpc_roh.c

diff --git a/docs-xml/smbdotconf/security/tlspriority.xml b/docs-xml/smbdotconf/security/tlspriority.xml
new file mode 100644 (file)
index 0000000..345f030
--- /dev/null
@@ -0,0 +1,18 @@
+<samba:parameter name="tls priority"
+                 type="string"
+                 context="G"
+                 constant="1"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+ <description>
+   <para>This option can be set to a string describing the TLS protocols
+   to be supported in the parts of Samba that use GnuTLS, specifically
+   the AD DC.
+   </para>
+   <para>The valid options are described in the
+   <ulink url="http://gnutls.org/manual/html_node/Priority-Strings.html">GNUTLS
+   Priority-Strings documentation at http://gnutls.org/manual/html_node/Priority-Strings.html</ulink>
+   </para>
+ </description>
+
+ <value type="default">NORMAL</value>
+</samba:parameter>
index 0e114288e2202cf9aecc95ea0b96439160230049..1a0d45908d63c422898c06d8da24966470190b63 100644 (file)
@@ -2541,6 +2541,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
        lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
        lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
        lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
+       lpcfg_do_global_parameter(lp_ctx, "tls priority", "NORMAL");
        lpcfg_do_global_parameter(lp_ctx, "prefork children:smb", "4");
 
        lpcfg_do_global_parameter(lp_ctx, "rndc command", "/usr/sbin/rndc");
index 0fdd50dad192976a705b4ec062579732088764b9..3a0247c066f4c9738d3bb64ccbacc92597e3b61a 100644 (file)
@@ -3997,6 +3997,14 @@ struct parm_struct parm_table[] = {
                .special        = NULL,
                .enum_list      = NULL
        },
+       {
+               .label          = "tls priority",
+               .type           = P_STRING,
+               .p_class        = P_GLOBAL,
+               .offset         = GLOBAL_VAR(tls_priority),
+               .special        = NULL,
+               .enum_list      = NULL
+       },
 
        {NULL,  P_BOOL,  P_NONE,  0,  NULL,  NULL,  0}
 };
index 7dd8786ae392c51b34e22e54e20d236ff15bb9c5..fb66eaa39a92fbb9480815587cfd2d1727f8be16 100644 (file)
@@ -872,6 +872,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
        string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
        string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
+       string_set(Globals.ctx, &Globals.tls_priority, "NORMAL");
 
        string_set(Globals.ctx, &Globals.share_backend, "classic");
 
index 691266cfabf0b852b7108510811c5779f1864516..d849ed30bccfdc20b4ccf410aed6a7c77f1dbb8a 100644 (file)
@@ -934,6 +934,7 @@ static void ldapsrv_task_init(struct task_server *task)
                                           lpcfg_tls_cafile(ldap_service, task->lp_ctx),
                                           lpcfg_tls_crlfile(ldap_service, task->lp_ctx),
                                           lpcfg_tls_dhpfile(ldap_service, task->lp_ctx),
+                                          lpcfg_tls_priority(task->lp_ctx),
                                           &ldap_service->tls_params);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("ldapsrv failed tstream_tls_params_server - %s\n",
index 3ff009d1ee6130a1c34937e2b28312a55ec3a237..e6c27f3e6f519ef2e63d28d789a853114b109bc4 100644 (file)
@@ -71,6 +71,7 @@ struct tstream_tls_params;
 NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx,
                                   const char *ca_file,
                                   const char *crl_file,
+                                  const char *tls_priority,
                                   struct tstream_tls_params **_tlsp);
 
 NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx,
@@ -81,6 +82,7 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx,
                                   const char *ca_file,
                                   const char *crl_file,
                                   const char *dhp_file,
+                                  const char *tls_priority,
                                   struct tstream_tls_params **_params);
 
 bool tstream_tls_params_enabled(struct tstream_tls_params *params);
index 9dea4f23c77a0517d2dd3582d1870cbee8b8d29b..188a3b801bf942b405499d540a2cd7ee463dc7f8 100644 (file)
@@ -868,6 +868,7 @@ struct tstream_tls_params {
 #if ENABLE_GNUTLS
        gnutls_certificate_credentials x509_cred;
        gnutls_dh_params dh_params;
+       const char *tls_priority;
 #endif /* ENABLE_GNUTLS */
        bool tls_enabled;
 };
@@ -895,6 +896,7 @@ bool tstream_tls_params_enabled(struct tstream_tls_params *tlsp)
 NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx,
                                   const char *ca_file,
                                   const char *crl_file,
+                                  const char *tls_priority,
                                   struct tstream_tls_params **_tlsp)
 {
 #if ENABLE_GNUTLS
@@ -943,6 +945,12 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx,
                }
        }
 
+       tlsp->tls_priority = talloc_strdup(tlsp, tls_priority);
+       if (tlsp->tls_priority == NULL) {
+               talloc_free(tlsp);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        tlsp->tls_enabled = true;
 
        *_tlsp = tlsp;
@@ -964,6 +972,7 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx,
 {
        struct tevent_req *req;
        struct tstream_tls_connect_state *state;
+       const char *error_pos;
 #if ENABLE_GNUTLS
        struct tstream_tls *tlss;
        int ret;
@@ -1002,9 +1011,12 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       ret = gnutls_set_default_priority(tlss->tls_session);
+       ret = gnutls_priority_set_direct(tlss->tls_session,
+                                        tls_params->tls_priority,
+                                        &error_pos);
        if (ret != GNUTLS_E_SUCCESS) {
-               DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+               DEBUG(0,("TLS %s - %s.  Check 'tls priority' option at '%s'\n",
+                        __location__, gnutls_strerror(ret), error_pos));
                tevent_req_error(req, EINVAL);
                return tevent_req_post(req, ev);
        }
@@ -1070,6 +1082,7 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx,
                                   const char *ca_file,
                                   const char *crl_file,
                                   const char *dhp_file,
+                                  const char *tls_priority,
                                   struct tstream_tls_params **_tlsp)
 {
        struct tstream_tls_params *tlsp;
@@ -1200,6 +1213,12 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx,
 
        gnutls_certificate_set_dh_params(tlsp->x509_cred, tlsp->dh_params);
 
+       tlsp->tls_priority = talloc_strdup(tlsp, tls_priority);
+       if (tlsp->tls_priority == NULL) {
+               talloc_free(tlsp);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        tlsp->tls_enabled = true;
 
 #else /* ENABLE_GNUTLS */
@@ -1226,6 +1245,7 @@ struct tevent_req *_tstream_tls_accept_send(TALLOC_CTX *mem_ctx,
        struct tevent_req *req;
        struct tstream_tls_accept_state *state;
        struct tstream_tls *tlss;
+       const char *error_pos;
 #if ENABLE_GNUTLS
        int ret;
 #endif /* ENABLE_GNUTLS */
@@ -1263,9 +1283,12 @@ struct tevent_req *_tstream_tls_accept_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       ret = gnutls_set_default_priority(tlss->tls_session);
+       ret = gnutls_priority_set_direct(tlss->tls_session,
+                                        tlsp->tls_priority,
+                                        &error_pos);
        if (ret != GNUTLS_E_SUCCESS) {
-               DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
+               DEBUG(0,("TLS %s - %s.  Check 'tls priority' option at '%s'\n",
+                        __location__, gnutls_strerror(ret), error_pos));
                tevent_req_error(req, EINVAL);
                return tevent_req_post(req, ev);
        }
index 68ebfcf1b5672c4d68a27983794bb6ef5b970bbf..94367a17c04eec413e8bf9ec4593eae1ea932cc4 100644 (file)
@@ -464,7 +464,7 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con
                if (conn->ldaps) {
                        char *ca_file = lpcfg_tls_cafile(state, conn->lp_ctx);
                        char *crl_file = lpcfg_tls_crlfile(state, conn->lp_ctx);
-
+                       const char *tls_priority = lpcfg_tls_priority(conn->lp_ctx);
                        if (!ca_file || !*ca_file) {
                                composite_error(result,
                                                NT_STATUS_INVALID_PARAMETER_MIX);
@@ -474,6 +474,7 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con
                        status = tstream_tls_params_client(state,
                                                           ca_file,
                                                           crl_file,
+                                                          tls_priority,
                                                           &state->tls_params);
                        if (!NT_STATUS_IS_OK(status)) {
                                composite_error(result, status);
index 09072940f90fc4c0c20b1d1e7aa930f8a46fcdb2..61a22a799444d26f433c53912c7a67c323e1917d 100644 (file)
@@ -31,6 +31,7 @@
 #include "librpc/rpc/dcerpc.h"
 #include "librpc/rpc/dcerpc_roh.h"
 #include "librpc/rpc/dcerpc_proto.h"
+#include "lib/param/param.h"
 
 static ssize_t tstream_roh_pending_bytes(struct tstream_context *stream);
 static struct tevent_req * tstream_roh_readv_send(
@@ -185,6 +186,7 @@ struct tevent_req *dcerpc_pipe_open_roh_send(struct dcecli_connection *conn,
        /* Initialize TLS */
        if (use_tls) {
                status = tstream_tls_params_client(state->roh, NULL, NULL,
+                                                  lpcfg_tls_priority(lp_ctx),
                                                   &state->tls_params);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0,("%s: Failed tstream_tls_params_client - %s\n",