summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-05-28 03:50:13 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:17:08 -0500
commitc22d20edb4ee9c57f4bdd304034c18ace8e8e99e (patch)
treecf662b9fe5e9befab5569359a05a10f77fbb0c01
parent2b0607248aceebd80938eb5ffad309aa7b47472e (diff)
downloadsamba-c22d20edb4ee9c57f4bdd304034c18ace8e8e99e.tar.gz
samba-c22d20edb4ee9c57f4bdd304034c18ace8e8e99e.tar.bz2
samba-c22d20edb4ee9c57f4bdd304034c18ace8e8e99e.zip
r7048: added auto-generation of TLS self-signed certificates if none exist already
This allows smbd to be setup from scratch over ssl without having to know how to create valid certificates (which can be quite tricky unless you've done it before) Of course, a good admin will provide real certificates, and smbd will use them if specified (This used to be commit 00b67efc99eac7bca386dea03f03bbb9470ab002)
-rw-r--r--source4/web_server/config.mk3
-rw-r--r--source4/web_server/tls.c20
-rw-r--r--source4/web_server/tlscert.c149
3 files changed, 164 insertions, 8 deletions
diff --git a/source4/web_server/config.mk b/source4/web_server/config.mk
index 00ae2ea8a0..4915129919 100644
--- a/source4/web_server/config.mk
+++ b/source4/web_server/config.mk
@@ -35,7 +35,8 @@ INIT_OBJ_FILES = \
ADD_OBJ_FILES = \
web_server/http.o \
web_server/calls.o \
- web_server/tls.o
+ web_server/tls.o \
+ web_server/tlscert.o
REQUIRED_SUBSYSTEMS = ESP
# End SUBSYSTEM WEB
#######################
diff --git a/source4/web_server/tls.c b/source4/web_server/tls.c
index 656c5ee6d6..13fc6e805b 100644
--- a/source4/web_server/tls.c
+++ b/source4/web_server/tls.c
@@ -240,17 +240,23 @@ void tls_initialise(struct task_server *task)
tls = talloc_zero(edata, struct tls_data);
edata->tls_data = tls;
+ if (!file_exist(cafile)) {
+ tls_cert_generate(tls, keyfile, certfile, cafile);
+ }
+
ret = gnutls_global_init();
if (ret < 0) goto init_failed;
gnutls_certificate_allocate_credentials(&tls->x509_cred);
if (ret < 0) goto init_failed;
- ret = gnutls_certificate_set_x509_trust_file(tls->x509_cred, cafile,
- GNUTLS_X509_FMT_PEM);
- if (ret < 0) {
- DEBUG(0,("TLS failed to initialise cafile %s\n", cafile));
- goto init_failed;
+ if (cafile && *cafile) {
+ ret = gnutls_certificate_set_x509_trust_file(tls->x509_cred, cafile,
+ GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ DEBUG(0,("TLS failed to initialise cafile %s\n", cafile));
+ goto init_failed;
+ }
}
if (crlfile && *crlfile) {
@@ -258,7 +264,7 @@ void tls_initialise(struct task_server *task)
crlfile,
GNUTLS_X509_FMT_PEM);
if (ret < 0) {
- DEBUG(0,("TLS failed to initialise crlfile %s\n", cafile));
+ DEBUG(0,("TLS failed to initialise crlfile %s\n", crlfile));
goto init_failed;
}
}
@@ -268,7 +274,7 @@ void tls_initialise(struct task_server *task)
GNUTLS_X509_FMT_PEM);
if (ret < 0) {
DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s\n",
- lp_web_certfile(), lp_web_keyfile()));
+ certfile, keyfile));
goto init_failed;
}
diff --git a/source4/web_server/tlscert.c b/source4/web_server/tlscert.c
new file mode 100644
index 0000000000..81b2a0ab45
--- /dev/null
+++ b/source4/web_server/tlscert.c
@@ -0,0 +1,149 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ auto-generate self signed TLS certificates
+
+ Copyright (C) Andrew Tridgell 2005
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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.
+*/
+
+#include "includes.h"
+
+#if HAVE_LIBGNUTLS
+#include "gnutls/gnutls.h"
+#include "gnutls/x509.h"
+
+#define ORGANISATION_NAME "Samba Web Administration"
+#define UNIT_NAME "SWAT - temporary autogenerated certificate"
+#define COMMON_NAME "Samba SWAT"
+#define LIFETIME 700*24*60*60
+
+/*
+ auto-generate a set of self signed certificates
+*/
+void tls_cert_generate(TALLOC_CTX *mem_ctx,
+ const char *keyfile, const char *certfile,
+ const char *cafile)
+{
+ gnutls_x509_crt cacrt, crt;
+ gnutls_x509_privkey key, cakey;
+ uint32_t serial = (uint32_t)time(NULL);
+ char keyid[100];
+ char buf[4096];
+ size_t bufsize;
+ size_t keyidsize = sizeof(keyid);
+ time_t activation = time(NULL), expiry = activation + LIFETIME;
+ int ret;
+
+ if (file_exist(keyfile) || file_exist(certfile) || file_exist(cafile)) {
+ DEBUG(0,("TLS autogeneration skipped - some TLS files already exist\n"));
+ return;
+ }
+
+#define TLSCHECK(call) do { \
+ ret = call; \
+ if (ret < 0) { \
+ DEBUG(0,("TLS %s - %s\n", #call, gnutls_strerror(ret))); \
+ goto failed; \
+ } \
+} while (0)
+
+ TLSCHECK(gnutls_global_init());
+
+ DEBUG(0,("Attempting to autogenerate TLS self-signed keys for https\n"));
+
+ DEBUG(3,("Generating private key\n"));
+ TLSCHECK(gnutls_x509_privkey_init(&key));
+ TLSCHECK(gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 1024, 0));
+
+ DEBUG(3,("Generating CA private key\n"));
+ TLSCHECK(gnutls_x509_privkey_init(&cakey));
+ TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, 1024, 0));
+
+ DEBUG(3,("Generating CA certificate\n"));
+ TLSCHECK(gnutls_x509_crt_init(&cacrt));
+ TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt,
+ GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
+ ORGANISATION_NAME, strlen(ORGANISATION_NAME)));
+ TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt,
+ GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
+ UNIT_NAME, strlen(UNIT_NAME)));
+ TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt,
+ GNUTLS_OID_X520_COMMON_NAME, 0,
+ COMMON_NAME, strlen(COMMON_NAME)));
+ TLSCHECK(gnutls_x509_crt_set_key(cacrt, cakey));
+ TLSCHECK(gnutls_x509_crt_set_serial(cacrt, &serial, sizeof(serial)));
+ TLSCHECK(gnutls_x509_crt_set_activation_time(cacrt, activation));
+ TLSCHECK(gnutls_x509_crt_set_expiration_time(cacrt, expiry));
+ TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 0));
+ TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(cacrt, GNUTLS_KP_TLS_WWW_SERVER, 0));
+ TLSCHECK(gnutls_x509_crt_set_version(cacrt, 3));
+ TLSCHECK(gnutls_x509_crt_get_key_id(cacrt, 0, keyid, &keyidsize));
+ TLSCHECK(gnutls_x509_crt_set_subject_key_id(cacrt, keyid, keyidsize));
+ TLSCHECK(gnutls_x509_crt_sign(cacrt, cacrt, cakey));
+
+ DEBUG(3,("Generating TLS certificate\n"));
+ TLSCHECK(gnutls_x509_crt_init(&crt));
+ TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt,
+ GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
+ ORGANISATION_NAME, strlen(ORGANISATION_NAME)));
+ TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt,
+ GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
+ UNIT_NAME, strlen(UNIT_NAME)));
+ TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt,
+ GNUTLS_OID_X520_COMMON_NAME, 0,
+ COMMON_NAME, strlen(COMMON_NAME)));
+ TLSCHECK(gnutls_x509_crt_set_key(crt, key));
+ TLSCHECK(gnutls_x509_crt_set_serial(crt, &serial, sizeof(serial)));
+ TLSCHECK(gnutls_x509_crt_set_activation_time(crt, activation));
+ TLSCHECK(gnutls_x509_crt_set_expiration_time(crt, expiry));
+ TLSCHECK(gnutls_x509_crt_set_ca_status(crt, 0));
+ TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0));
+ TLSCHECK(gnutls_x509_crt_set_version(crt, 3));
+ TLSCHECK(gnutls_x509_crt_get_key_id(crt, 0, keyid, &keyidsize));
+ TLSCHECK(gnutls_x509_crt_set_subject_key_id(crt, keyid, keyidsize));
+ TLSCHECK(gnutls_x509_crt_sign(crt, crt, key));
+
+ DEBUG(3,("Exporting TLS keys\n"));
+
+ bufsize = sizeof(buf);
+ TLSCHECK(gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
+ file_save(certfile, buf, bufsize);
+
+ bufsize = sizeof(buf);
+ TLSCHECK(gnutls_x509_crt_export(cacrt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
+ file_save(cafile, buf, bufsize);
+
+ bufsize = sizeof(buf);
+ TLSCHECK(gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &bufsize));
+ file_save(keyfile, buf, bufsize);
+
+ gnutls_x509_privkey_deinit(key);
+ gnutls_x509_privkey_deinit(cakey);
+ gnutls_x509_crt_deinit(cacrt);
+ gnutls_x509_crt_deinit(crt);
+ gnutls_global_deinit();
+
+ DEBUG(0,("TLS self-signed keys generated OK\n"));
+ return;
+
+failed:
+ DEBUG(0,("TLS certificate generation failed\n"));
+}
+
+#else
+ void tls_cert_dummy(void) {}
+#endif