diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-06-19 04:21:45 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:18:30 -0500 |
commit | 822498b7f536e4c4e552c524b14d6cb691ec5b62 (patch) | |
tree | 35b8a7423c7e2454e744e9283d9fa3cbccac6706 /source4 | |
parent | e485e80b512f17aba0b6b1dd5acc3f738f4189c1 (diff) | |
download | samba-822498b7f536e4c4e552c524b14d6cb691ec5b62.tar.gz samba-822498b7f536e4c4e552c524b14d6cb691ec5b62.tar.bz2 samba-822498b7f536e4c4e552c524b14d6cb691ec5b62.zip |
r7744: converted the web server to use the lib/tls/ generic tls code
(This used to be commit 023fc567badba38b87895ea73515b2ce0b703a8c)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/config.list | 1 | ||||
-rw-r--r-- | source4/param/loadparm.c | 38 | ||||
-rw-r--r-- | source4/web_server/config.mk | 6 | ||||
-rw-r--r-- | source4/web_server/http.c | 12 | ||||
-rw-r--r-- | source4/web_server/tls.c | 376 | ||||
-rw-r--r-- | source4/web_server/tlscert.c | 153 | ||||
-rw-r--r-- | source4/web_server/web_server.c | 16 | ||||
-rw-r--r-- | source4/web_server/web_server.h | 4 |
8 files changed, 41 insertions, 565 deletions
diff --git a/source4/config.list b/source4/config.list index 69b79c11b0..d52b892ab7 100644 --- a/source4/config.list +++ b/source4/config.list @@ -12,6 +12,7 @@ lib/socket/config.mk lib/ldb/config.mk lib/talloc/config.mk lib/tdb/config.mk +lib/tls/config.mk lib/registry/config.mk lib/messaging/config.mk lib/events/config.mk diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 92e98dcf7d..26466797ad 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -180,11 +180,11 @@ typedef struct char *szIDMapBackend; char *szGuestaccount; char *swat_directory; - BOOL web_tls; - char *web_keyfile; - char *web_certfile; - char *web_cafile; - char *web_crlfile; + BOOL tls_enabled; + char *tls_keyfile; + char *tls_certfile; + char *tls_cafile; + char *tls_crlfile; int max_mux; int max_xmit; int pwordlevel; @@ -599,11 +599,11 @@ static struct parm_struct parm_table[] = { {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"web tls", P_BOOL, P_GLOBAL, &Globals.web_tls, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"web tls keyfile", P_STRING, P_GLOBAL, &Globals.web_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"web tls certfile", P_STRING, P_GLOBAL, &Globals.web_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"web tls cafile", P_STRING, P_GLOBAL, &Globals.web_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"web tls crlfile", P_STRING, P_GLOBAL, &Globals.web_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"tls enabled", P_BOOL, P_GLOBAL, &Globals.tls_enabled, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"tls keyfile", P_STRING, P_GLOBAL, &Globals.tls_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"tls certfile", P_STRING, P_GLOBAL, &Globals.tls_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"tls cafile", P_STRING, P_GLOBAL, &Globals.tls_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"tls crlfile", P_STRING, P_GLOBAL, &Globals.tls_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER}, {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER}, @@ -1051,10 +1051,10 @@ static void init_globals(void) do_parameter("max wins ttl", "432000"); do_parameter("min wins ttl", "10"); - do_parameter("web tls", "True"); - do_parameter_var("web tls keyfile", "%s/tls/key.pem", dyn_PRIVATE_DIR); - do_parameter_var("web tls certfile", "%s/tls/cert.pem", dyn_PRIVATE_DIR); - do_parameter_var("web tls cafile", "%s/tls/ca.pem", dyn_PRIVATE_DIR); + do_parameter("tls enabled", "True"); + do_parameter_var("tls keyfile", "%s/tls/key.pem", dyn_PRIVATE_DIR); + do_parameter_var("tls certfile", "%s/tls/cert.pem", dyn_PRIVATE_DIR); + do_parameter_var("tls cafile", "%s/tls/ca.pem", dyn_PRIVATE_DIR); } static TALLOC_CTX *lp_talloc; @@ -1157,11 +1157,11 @@ FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port) FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port) FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset) FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory) -FN_GLOBAL_BOOL(lp_web_tls, &Globals.web_tls) -FN_GLOBAL_STRING(lp_web_keyfile, &Globals.web_keyfile) -FN_GLOBAL_STRING(lp_web_certfile, &Globals.web_certfile) -FN_GLOBAL_STRING(lp_web_cafile, &Globals.web_cafile) -FN_GLOBAL_STRING(lp_web_crlfile, &Globals.web_crlfile) +FN_GLOBAL_BOOL(lp_tls_enabled, &Globals.tls_enabled) +FN_GLOBAL_STRING(lp_tls_keyfile, &Globals.tls_keyfile) +FN_GLOBAL_STRING(lp_tls_certfile, &Globals.tls_certfile) +FN_GLOBAL_STRING(lp_tls_cafile, &Globals.tls_cafile) +FN_GLOBAL_STRING(lp_tls_crlfile, &Globals.tls_crlfile) FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset) FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset) FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile) diff --git a/source4/web_server/config.mk b/source4/web_server/config.mk index 2398c11d98..cf7dd24afa 100644 --- a/source4/web_server/config.mk +++ b/source4/web_server/config.mk @@ -19,9 +19,7 @@ NOPROTO=YES INIT_OBJ_FILES = \ web_server/web_server.o ADD_OBJ_FILES = \ - web_server/http.o \ - web_server/tls.o \ - web_server/tlscert.o -REQUIRED_SUBSYSTEMS = ESP EXT_LIB_GNUTLS SMBCALLS + web_server/http.o +REQUIRED_SUBSYSTEMS = ESP LIBTLS SMBCALLS # End SUBSYSTEM WEB ####################### diff --git a/source4/web_server/http.c b/source4/web_server/http.c index b0001068c4..314d919357 100644 --- a/source4/web_server/http.c +++ b/source4/web_server/http.c @@ -30,6 +30,7 @@ #include "system/time.h" #include "web_server/esp/esp.h" #include "dlinklist.h" +#include "lib/tls/tls.h" #define SWAT_SESSION_KEY "SwatSessionId" #define HTTP_PREAUTH_URI "/scripting/preauth.esp" @@ -245,12 +246,12 @@ static void http_redirect(EspHandle handle, int code, char *url) char *p = strrchr(web->input.url, '/'); if (p == web->input.url) { url = talloc_asprintf(web, "http%s://%s/%s", - web->tls_session?"s":"", + tls_enabled(web->tls)?"s":"", host, url); } else { int dirlen = p - web->input.url; url = talloc_asprintf(web, "http%s://%s%*.*s/%s", - web->tls_session?"s":"", + tls_enabled(web->tls)?"s":"", host, dirlen, dirlen, web->input.url, url); @@ -450,10 +451,10 @@ static void http_setup_arrays(struct esp_state *esp) SETVAR(ESP_SERVER_OBJ, "DOCUMENT_ROOT", lp_swat_directory()); SETVAR(ESP_SERVER_OBJ, "SERVER_PORT", talloc_asprintf(esp, "%u", socket_get_my_port(web->conn->socket))); - SETVAR(ESP_SERVER_OBJ, "SERVER_PROTOCOL", web->tls_session?"https":"http"); + SETVAR(ESP_SERVER_OBJ, "SERVER_PROTOCOL", tls_enabled(web->tls)?"https":"http"); SETVAR(ESP_SERVER_OBJ, "SERVER_SOFTWARE", "SWAT"); SETVAR(ESP_SERVER_OBJ, "GATEWAY_INTERFACE", "CGI/1.1"); - SETVAR(ESP_SERVER_OBJ, "TLS_SUPPORT", edata->tls_data?"True":"False"); + SETVAR(ESP_SERVER_OBJ, "TLS_SUPPORT", tls_support(edata->tls_params)?"True":"False"); } #if HAVE_SETJMP_H @@ -948,5 +949,8 @@ NTSTATUS http_setup_esp(struct task_server *task) task->private = edata; + edata->tls_params = tls_initialise(edata); + NT_STATUS_HAVE_NO_MEMORY(edata->tls_params); + return NT_STATUS_OK; } diff --git a/source4/web_server/tls.c b/source4/web_server/tls.c deleted file mode 100644 index 13fc6e805b..0000000000 --- a/source4/web_server/tls.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - transport layer security handling code - - 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" -#include "smbd/service_task.h" -#include "smbd/service_stream.h" -#include "web_server/web_server.h" -#include "lib/events/events.h" -#include "system/network.h" - -#if HAVE_LIBGNUTLS -#include "gnutls/gnutls.h" - -#define DH_BITS 1024 - -/* hold per connection tls data */ -struct tls_session { - gnutls_session session; - BOOL done_handshake; -}; - -/* hold persistent tls data */ -struct tls_data { - gnutls_certificate_credentials x509_cred; - gnutls_dh_params dh_params; -}; - -/* - callback for reading from a socket -*/ -static ssize_t tls_pull(gnutls_transport_ptr ptr, void *buf, size_t size) -{ - struct websrv_context *web = talloc_get_type(ptr, struct websrv_context); - NTSTATUS status; - size_t nread; - - if (web->input.tls_first_char) { - *(uint8_t *)buf = web->input.first_byte; - web->input.tls_first_char = False; - return 1; - } - - status = socket_recv(web->conn->socket, buf, size, &nread, 0); - if (!NT_STATUS_IS_OK(status)) { - EVENT_FD_READABLE(web->conn->event.fde); - EVENT_FD_NOT_WRITEABLE(web->conn->event.fde); - return -1; - } - if (web->output.output_pending) { - EVENT_FD_WRITEABLE(web->conn->event.fde); - } - if (size != nread) { - EVENT_FD_READABLE(web->conn->event.fde); - } - return nread; -} - -/* - callback for writing to a socket -*/ -static ssize_t tls_push(gnutls_transport_ptr ptr, const void *buf, size_t size) -{ - struct websrv_context *web = talloc_get_type(ptr, struct websrv_context); - NTSTATUS status; - size_t nwritten; - DATA_BLOB b; - - if (web->tls_session == NULL) { - return size; - } - - b.data = discard_const(buf); - b.length = size; - - status = socket_send(web->conn->socket, &b, &nwritten, 0); - if (!NT_STATUS_IS_OK(status)) { - EVENT_FD_WRITEABLE(web->conn->event.fde); - return -1; - } - if (size != nwritten) { - EVENT_FD_WRITEABLE(web->conn->event.fde); - } - return nwritten; -} - -/* - destroy a tls session - */ -static int tls_destructor(void *ptr) -{ - struct tls_session *tls_session = talloc_get_type(ptr, struct tls_session); - int ret; - ret = gnutls_bye(tls_session->session, GNUTLS_SHUT_WR); - if (ret < 0) { - DEBUG(0,("TLS gnutls_bye failed - %s\n", gnutls_strerror(ret))); - } - return 0; -} - - -/* - possibly continue the handshake process -*/ -static NTSTATUS tls_handshake(struct tls_session *tls_session) -{ - int ret; - - if (tls_session->done_handshake) { - return NT_STATUS_OK; - } - - ret = gnutls_handshake(tls_session->session); - if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { - return STATUS_MORE_ENTRIES; - } - if (ret < 0) { - DEBUG(0,("TLS gnutls_handshake failed - %s\n", gnutls_strerror(ret))); - return NT_STATUS_UNEXPECTED_NETWORK_ERROR; - } - tls_session->done_handshake = True; - return NT_STATUS_OK; -} - - -/* - receive data either by tls or normal socket_recv -*/ -NTSTATUS tls_socket_recv(struct websrv_context *web, void *buf, size_t wantlen, - size_t *nread) -{ - int ret; - NTSTATUS status; - struct tls_session *tls_session = talloc_get_type(web->tls_session, - struct tls_session); - - if (web->tls_session != NULL && web->input.tls_detect) { - status = socket_recv(web->conn->socket, &web->input.first_byte, - 1, nread, 0); - NT_STATUS_NOT_OK_RETURN(status); - if (*nread == 0) return NT_STATUS_OK; - web->input.tls_detect = False; - /* look for the first byte of a valid HTTP operation */ - if (strchr("GPHO", web->input.first_byte)) { - /* not a tls link */ - web->tls_session = NULL; - talloc_free(tls_session); - *(uint8_t *)buf = web->input.first_byte; - return NT_STATUS_OK; - } - web->input.tls_first_char = True; - } - - if (web->tls_session == NULL) { - return socket_recv(web->conn->socket, buf, wantlen, nread, 0); - } - - status = tls_handshake(tls_session); - NT_STATUS_NOT_OK_RETURN(status); - - ret = gnutls_record_recv(tls_session->session, buf, wantlen); - if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { - return STATUS_MORE_ENTRIES; - } - if (ret < 0) { - DEBUG(0,("gnutls_record_recv failed - %s\n", gnutls_strerror(ret))); - return NT_STATUS_UNEXPECTED_NETWORK_ERROR; - } - *nread = ret; - return NT_STATUS_OK; -} - - -/* - send data either by tls or normal socket_recv -*/ -NTSTATUS tls_socket_send(struct websrv_context *web, const DATA_BLOB *blob, - size_t *sendlen) -{ - NTSTATUS status; - int ret; - struct tls_session *tls_session = talloc_get_type(web->tls_session, - struct tls_session); - - if (web->tls_session == NULL) { - return socket_send(web->conn->socket, blob, sendlen, 0); - } - - status = tls_handshake(tls_session); - NT_STATUS_NOT_OK_RETURN(status); - - ret = gnutls_record_send(tls_session->session, blob->data, blob->length); - if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { - return STATUS_MORE_ENTRIES; - } - if (ret < 0) { - DEBUG(0,("gnutls_record_send failed - %s\n", gnutls_strerror(ret))); - return NT_STATUS_UNEXPECTED_NETWORK_ERROR; - } - *sendlen = ret; - return NT_STATUS_OK; -} - - -/* - initialise global tls state -*/ -void tls_initialise(struct task_server *task) -{ - struct esp_data *edata = talloc_get_type(task->private, struct esp_data); - struct tls_data *tls; - int ret; - const char *keyfile = lp_web_keyfile(); - const char *certfile = lp_web_certfile(); - const char *cafile = lp_web_cafile(); - const char *crlfile = lp_web_crlfile(); - - if (!lp_web_tls() || keyfile == NULL || *keyfile == 0) { - return; - } - - 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; - - 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) { - ret = gnutls_certificate_set_x509_crl_file(tls->x509_cred, - crlfile, - GNUTLS_X509_FMT_PEM); - if (ret < 0) { - DEBUG(0,("TLS failed to initialise crlfile %s\n", crlfile)); - goto init_failed; - } - } - - ret = gnutls_certificate_set_x509_key_file(tls->x509_cred, - certfile, keyfile, - GNUTLS_X509_FMT_PEM); - if (ret < 0) { - DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s\n", - certfile, keyfile)); - goto init_failed; - } - - ret = gnutls_dh_params_init(&tls->dh_params); - if (ret < 0) goto init_failed; - - ret = gnutls_dh_params_generate2(tls->dh_params, DH_BITS); - if (ret < 0) goto init_failed; - - gnutls_certificate_set_dh_params(tls->x509_cred, tls->dh_params); - return; - -init_failed: - DEBUG(0,("GNUTLS failed to initialise - %s\n", gnutls_strerror(ret))); - talloc_free(tls); - edata->tls_data = NULL; -} - - -/* - setup for a new connection -*/ -NTSTATUS tls_init_connection(struct websrv_context *web) -{ - struct esp_data *edata = talloc_get_type(web->task->private, struct esp_data); - struct tls_data *tls_data = talloc_get_type(edata->tls_data, struct tls_data); - struct tls_session *tls_session; - int ret; - - if (edata->tls_data == NULL) { - web->tls_session = NULL; - return NT_STATUS_OK; - } - -#define TLSCHECK(call) do { \ - ret = call; \ - if (ret < 0) { \ - DEBUG(0,("TLS %s - %s\n", #call, gnutls_strerror(ret))); \ - goto failed; \ - } \ -} while (0) - - tls_session = talloc_zero(web, struct tls_session); - web->tls_session = tls_session; - - TLSCHECK(gnutls_init(&tls_session->session, GNUTLS_SERVER)); - - talloc_set_destructor(tls_session, tls_destructor); - - TLSCHECK(gnutls_set_default_priority(tls_session->session)); - TLSCHECK(gnutls_credentials_set(tls_session->session, GNUTLS_CRD_CERTIFICATE, tls_data->x509_cred)); - gnutls_certificate_server_set_request(tls_session->session, GNUTLS_CERT_REQUEST); - gnutls_dh_set_prime_bits(tls_session->session, DH_BITS); - gnutls_transport_set_ptr(tls_session->session, (gnutls_transport_ptr)web); - gnutls_transport_set_pull_function(tls_session->session, (gnutls_pull_func)tls_pull); - gnutls_transport_set_push_function(tls_session->session, (gnutls_push_func)tls_push); - gnutls_transport_set_lowat(tls_session->session, 0); - - web->input.tls_detect = True; - - return NT_STATUS_OK; - -failed: - DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret))); - web->tls_session = NULL; - talloc_free(tls_session); - return NT_STATUS_OK; -} - - -#else - -/* for systems without tls we just map the tls socket calls to the - normal socket calls */ -NTSTATUS tls_socket_recv(struct websrv_context *web, void *buf, size_t wantlen, - size_t *nread) -{ - return socket_recv(web->conn->socket, buf, wantlen, nread, 0); -} - -NTSTATUS tls_socket_send(struct websrv_context *web, const DATA_BLOB *blob, - size_t *sendlen) -{ - return socket_send(web->conn->socket, blob, sendlen, 0); -} - -NTSTATUS tls_init_connection(struct websrv_context *web) -{ - web->tls_session = NULL; - return NT_STATUS_OK; -} - -void tls_initialise(struct task_server *task) -{ - struct esp_data *edata = talloc_get_type(task->private, struct esp_data); - edata->tls_data = NULL; -} - -#endif diff --git a/source4/web_server/tlscert.c b/source4/web_server/tlscert.c deleted file mode 100644 index 22e46a726c..0000000000 --- a/source4/web_server/tlscert.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - 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)); -#ifdef GNUTLS_KP_TLS_WWW_SERVER - TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(cacrt, GNUTLS_KP_TLS_WWW_SERVER, 0)); -#endif - 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)); -#ifdef GNUTLS_KP_TLS_WWW_SERVER - TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0)); -#endif - 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 diff --git a/source4/web_server/web_server.c b/source4/web_server/web_server.c index faa30fc55f..e54c0b6e9f 100644 --- a/source4/web_server/web_server.c +++ b/source4/web_server/web_server.c @@ -26,6 +26,7 @@ #include "web_server/web_server.h" #include "lib/events/events.h" #include "system/filesys.h" +#include "lib/tls/tls.h" /* don't allow connections to hang around forever */ #define HTTP_TIMEOUT 30 @@ -68,7 +69,7 @@ static void websrv_recv(struct stream_connection *conn, uint16_t flags) DATA_BLOB b; /* not the most efficient http parser ever, but good enough for us */ - status = tls_socket_recv(web, buf, sizeof(buf), &nread); + status = tls_socket_recv(web->tls, buf, sizeof(buf), &nread); if (NT_STATUS_IS_ERR(status)) goto failed; if (!NT_STATUS_IS_OK(status)) return; @@ -128,7 +129,7 @@ static void websrv_send(struct stream_connection *conn, uint16_t flags) b.data += web->output.nsent; b.length -= web->output.nsent; - status = tls_socket_send(web, &b, &nsent); + status = tls_socket_send(web->tls, &b, &nsent); if (NT_STATUS_IS_ERR(status)) { stream_terminate_connection(web->conn, "socket_send: failed"); return; @@ -161,6 +162,8 @@ static void websrv_send(struct stream_connection *conn, uint16_t flags) if (web->output.content.length == web->output.nsent && web->output.fd == -1) { + talloc_free(web->tls); + web->tls = NULL; stream_terminate_connection(web->conn, NULL); } } @@ -171,8 +174,8 @@ static void websrv_send(struct stream_connection *conn, uint16_t flags) static void websrv_accept(struct stream_connection *conn) { struct task_server *task = talloc_get_type(conn->private, struct task_server); + struct esp_data *edata = talloc_get_type(task->private, struct esp_data); struct websrv_context *web; - NTSTATUS status; web = talloc_zero(conn, struct websrv_context); if (web == NULL) goto failed; @@ -187,8 +190,9 @@ static void websrv_accept(struct stream_connection *conn) timeval_current_ofs(HTTP_TIMEOUT, 0), websrv_timeout, web); - status = tls_init_connection(web); - if (!NT_STATUS_IS_OK(status)) goto failed; + web->tls = tls_init_server(edata->tls_params, conn->socket, + conn->event.fde, "GPHO"); + if (web->tls == NULL) goto failed; return; @@ -241,8 +245,6 @@ static void websrv_task_init(struct task_server *task) status = http_setup_esp(task); if (!NT_STATUS_IS_OK(status)) goto failed; - tls_initialise(task); - return; failed: diff --git a/source4/web_server/web_server.h b/source4/web_server/web_server.h index 53f97964f1..92bc673d75 100644 --- a/source4/web_server/web_server.h +++ b/source4/web_server/web_server.h @@ -55,7 +55,7 @@ struct websrv_context { int response_code; const char **headers; } output; - void *tls_session; + struct tls_context *tls; struct session_data *session; }; @@ -74,6 +74,6 @@ struct esp_data { int lifetime; } *sessions; struct MprVar *application_data; - void *tls_data; + struct tls_params *tls_params; }; |