r25446: Merge some changes I made on the way home from SFO:
[jelmer/samba4-debian.git] / source / lib / tls / tls.c
index c3a6047e065aee25eca68c861e893c7759ea6d76..d2f6d6f740606c052bca205aa8ec9bfcdd1b6aad 100644 (file)
@@ -9,7 +9,7 @@
  
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "lib/events/events.h"
 #include "lib/socket/socket.h"
+#include "lib/tls/tls.h"
+#include "param/param.h"
 
-#if HAVE_LIBGNUTLS
+#if ENABLE_GNUTLS
 #include "gnutls/gnutls.h"
 
 #define DH_BITS 1024
 
+#if defined(HAVE_GNUTLS_DATUM) && !defined(HAVE_GNUTLS_DATUM_T)
+typedef gnutls_datum gnutls_datum_t;
+#endif
+
 /* hold persistent tls data */
 struct tls_params {
        gnutls_certificate_credentials x509_cred;
@@ -44,7 +49,7 @@ struct tls_context {
        struct socket_context *socket;
        struct fd_event *fde;
        BOOL tls_enabled;
-#if HAVE_LIBGNUTLS
+#if ENABLE_GNUTLS
        gnutls_session session;
        BOOL done_handshake;
        BOOL have_first_byte;
@@ -74,7 +79,7 @@ BOOL tls_enabled(struct socket_context *sock)
 }
 
 
-#if HAVE_LIBGNUTLS
+#if ENABLE_GNUTLS
 
 static const struct socket_ops tls_socket_ops;
 
@@ -335,7 +340,7 @@ static NTSTATUS tls_socket_send(struct socket_context *sock,
                return STATUS_MORE_ENTRIES;
        }
        if (ret < 0) {
-               DEBUG(0,("gnutls_record_send of %d failed - %s\n", blob->length, gnutls_strerror(ret)));
+               DEBUG(0,("gnutls_record_send of %d failed - %s\n", (int)blob->length, gnutls_strerror(ret)));
                return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
        }
        *sendlen = ret;
@@ -352,10 +357,11 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx)
        struct tls_params *params;
        int ret;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-       const char *keyfile = private_path(tmp_ctx, lp_tls_keyfile());
-       const char *certfile = private_path(tmp_ctx, lp_tls_certfile());
-       const char *cafile = private_path(tmp_ctx, lp_tls_cafile());
-       const char *crlfile = private_path(tmp_ctx, lp_tls_crlfile());
+       const char *keyfile = private_path(tmp_ctx, global_loadparm, lp_tls_keyfile(global_loadparm));
+       const char *certfile = private_path(tmp_ctx, global_loadparm, lp_tls_certfile(global_loadparm));
+       const char *cafile = private_path(tmp_ctx, global_loadparm, lp_tls_cafile(global_loadparm));
+       const char *crlfile = private_path(tmp_ctx, global_loadparm, lp_tls_crlfile(global_loadparm));
+       const char *dhpfile = private_path(tmp_ctx, global_loadparm, lp_tls_dhpfile(global_loadparm));
        void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *);
 
        params = talloc(mem_ctx, struct tls_params);
@@ -364,7 +370,7 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx)
                return NULL;
        }
 
-       if (!lp_tls_enabled() || keyfile == NULL || *keyfile == 0) {
+       if (!lp_tls_enabled(global_loadparm) || keyfile == NULL || *keyfile == 0) {
                params->tls_enabled = False;
                talloc_free(tmp_ctx);
                return params;
@@ -408,12 +414,28 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx)
                goto init_failed;
        }
        
+       
        ret = gnutls_dh_params_init(&params->dh_params);
        if (ret < 0) goto init_failed;
 
-       ret = gnutls_dh_params_generate2(params->dh_params, DH_BITS);
-       if (ret < 0) goto init_failed;
+       if (dhpfile && *dhpfile) {
+               gnutls_datum_t dhparms;
+               size_t size;
+               dhparms.data = (uint8_t *)file_load(dhpfile, &size, mem_ctx);
 
+               if (!dhparms.data) {
+                       DEBUG(0,("Failed to read DH Parms from %s\n", dhpfile));
+                       goto init_failed;
+               }
+               dhparms.size = size;
+                       
+               ret = gnutls_dh_params_import_pkcs3(params->dh_params, &dhparms, GNUTLS_X509_FMT_PEM);
+               if (ret < 0) goto init_failed;
+       } else {
+               ret = gnutls_dh_params_generate2(params->dh_params, DH_BITS);
+               if (ret < 0) goto init_failed;
+       }
+               
        gnutls_certificate_set_dh_params(params->x509_cred, params->dh_params);
 
        params->tls_enabled = True;
@@ -543,7 +565,7 @@ struct socket_context *tls_init_client(struct socket_context *socket,
        }
        new_sock->private_data    = tls;
 
-       cafile = private_path(tls, lp_tls_cafile());
+       cafile = private_path(tls, global_loadparm, lp_tls_cafile(global_loadparm));
        if (!cafile || !*cafile) {
                goto failed;
        }