summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-06-19 04:21:45 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:18:30 -0500
commit822498b7f536e4c4e552c524b14d6cb691ec5b62 (patch)
tree35b8a7423c7e2454e744e9283d9fa3cbccac6706
parente485e80b512f17aba0b6b1dd5acc3f738f4189c1 (diff)
downloadsamba-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)
-rw-r--r--source4/config.list1
-rw-r--r--source4/param/loadparm.c38
-rw-r--r--source4/web_server/config.mk6
-rw-r--r--source4/web_server/http.c12
-rw-r--r--source4/web_server/tls.c376
-rw-r--r--source4/web_server/tlscert.c153
-rw-r--r--source4/web_server/web_server.c16
-rw-r--r--source4/web_server/web_server.h4
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;
};