diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-05-28 03:50:13 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:17:08 -0500 |
commit | c22d20edb4ee9c57f4bdd304034c18ace8e8e99e (patch) | |
tree | cf662b9fe5e9befab5569359a05a10f77fbb0c01 | |
parent | 2b0607248aceebd80938eb5ffad309aa7b47472e (diff) | |
download | samba-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.mk | 3 | ||||
-rw-r--r-- | source4/web_server/tls.c | 20 | ||||
-rw-r--r-- | source4/web_server/tlscert.c | 149 |
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 |