diff options
author | Andrew Bartlett <abartlet@samba.org> | 2019-05-06 13:45:37 +1200 |
---|---|---|
committer | Gary Lockyer <gary@samba.org> | 2019-05-06 05:46:11 +0000 |
commit | eb15acdd35600878aba3319e070199200d9a1357 (patch) | |
tree | 0058b9e77837a31b56b128ca8c46ad79739cdf79 /source4/lib | |
parent | e995c9c16f6a9a1d7d5dab53a75cd1ff3775aeb1 (diff) | |
download | samba-eb15acdd35600878aba3319e070199200d9a1357.tar.gz |
lib/tls: Remove unused source4/lib/tls/tls.c (tls socket wrapper)
The last caller was removed in 72c79e30f07bcc98610cca878f5de50e7db239a0
to remove the web server as all other callers use tls_tstream.
Found by callcatcher.
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
Diffstat (limited to 'source4/lib')
-rw-r--r-- | source4/lib/tls/tls.c | 609 | ||||
-rw-r--r-- | source4/lib/tls/wscript_build | 2 |
2 files changed, 0 insertions, 611 deletions
diff --git a/source4/lib/tls/tls.c b/source4/lib/tls/tls.c deleted file mode 100644 index efff0e6ba82..00000000000 --- a/source4/lib/tls/tls.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - transport layer security handling code - - Copyright (C) Andrew Tridgell 2004-2005 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Andrew Bartlett 2006 - - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "system/filesys.h" -#include "lib/events/events.h" -#include "lib/socket/socket.h" -#include "lib/tls/tls.h" -#include "param/param.h" - -#include <gnutls/gnutls.h> - -#define DH_BITS 2048 - -/* hold persistent tls data */ -struct tls_params { - gnutls_certificate_credentials_t x509_cred; - gnutls_dh_params_t dh_params; - bool tls_enabled; - const char *tls_priority; -}; - -/* hold per connection tls data */ -struct tls_context { - struct socket_context *socket; - struct tevent_fd *fde; - bool tls_enabled; - gnutls_session_t session; - bool done_handshake; - bool have_first_byte; - uint8_t first_byte; - bool tls_detect; - const char *plain_chars; - bool output_pending; - gnutls_certificate_credentials_t xcred; - bool interrupted; -}; - -bool tls_enabled(struct socket_context *sock) -{ - struct tls_context *tls; - if (!sock) { - return false; - } - if (strcmp(sock->backend_name, "tls") != 0) { - return false; - } - tls = talloc_get_type(sock->private_data, struct tls_context); - if (!tls) { - return false; - } - return tls->tls_enabled; -} - - -static const struct socket_ops tls_socket_ops; - -static NTSTATUS tls_socket_init(struct socket_context *sock) -{ - switch (sock->type) { - case SOCKET_TYPE_STREAM: - break; - default: - return NT_STATUS_INVALID_PARAMETER; - } - - sock->backend_name = "tls"; - - 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) - - -/* - callback for reading from a socket -*/ -static ssize_t tls_pull(gnutls_transport_ptr_t ptr, void *buf, size_t size) -{ - struct tls_context *tls = talloc_get_type(ptr, struct tls_context); - NTSTATUS status; - size_t nread; - - if (tls->have_first_byte) { - *(uint8_t *)buf = tls->first_byte; - tls->have_first_byte = false; - return 1; - } - - status = socket_recv(tls->socket, buf, size, &nread); - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - return 0; - } - if (NT_STATUS_IS_ERR(status)) { - TEVENT_FD_NOT_READABLE(tls->fde); - TEVENT_FD_NOT_WRITEABLE(tls->fde); - errno = EBADF; - return -1; - } - if (!NT_STATUS_IS_OK(status)) { - TEVENT_FD_READABLE(tls->fde); - errno = EAGAIN; - return -1; - } - if (tls->output_pending) { - TEVENT_FD_WRITEABLE(tls->fde); - } - if (size != nread) { - TEVENT_FD_READABLE(tls->fde); - } - return nread; -} - -/* - callback for writing to a socket -*/ -static ssize_t tls_push(gnutls_transport_ptr_t ptr, const void *buf, size_t size) -{ - struct tls_context *tls = talloc_get_type(ptr, struct tls_context); - NTSTATUS status; - size_t nwritten, total_nwritten = 0; - DATA_BLOB b; - - if (!tls->tls_enabled) { - return size; - } - - b.data = discard_const(buf); - b.length = size; - - /* Cope with socket_wrapper 1500 byte chunking for PCAP */ - do { - status = socket_send(tls->socket, &b, &nwritten); - - if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { - errno = EAGAIN; - return -1; - } - if (!NT_STATUS_IS_OK(status)) { - TEVENT_FD_WRITEABLE(tls->fde); - return -1; - } - - total_nwritten += nwritten; - - if (size == nwritten) { - break; - } - - b.data += nwritten; - b.length -= nwritten; - - TEVENT_FD_WRITEABLE(tls->fde); - } while (b.length); - - return total_nwritten; -} - -/* - destroy a tls session - */ -static int tls_destructor(struct tls_context *tls) -{ - int ret; - ret = gnutls_bye(tls->session, GNUTLS_SHUT_WR); - if (ret < 0) { - DEBUG(4,("TLS gnutls_bye failed - %s\n", gnutls_strerror(ret))); - } - return 0; -} - - -/* - possibly continue the handshake process -*/ -static NTSTATUS tls_handshake(struct tls_context *tls) -{ - int ret; - - if (tls->done_handshake) { - return NT_STATUS_OK; - } - - ret = gnutls_handshake(tls->session); - if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { - if (gnutls_record_get_direction(tls->session) == 1) { - TEVENT_FD_WRITEABLE(tls->fde); - } - 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->done_handshake = true; - return NT_STATUS_OK; -} - -/* - possibly continue an interrupted operation -*/ -static NTSTATUS tls_interrupted(struct tls_context *tls) -{ - int ret; - - if (!tls->interrupted) { - return NT_STATUS_OK; - } - if (gnutls_record_get_direction(tls->session) == 1) { - ret = gnutls_record_send(tls->session, NULL, 0); - } else { - ret = gnutls_record_recv(tls->session, NULL, 0); - } - if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { - return STATUS_MORE_ENTRIES; - } - tls->interrupted = false; - return NT_STATUS_OK; -} - -/* - see how many bytes are pending on the connection -*/ -static NTSTATUS tls_socket_pending(struct socket_context *sock, size_t *npending) -{ - struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); - if (!tls->tls_enabled || tls->tls_detect) { - return socket_pending(tls->socket, npending); - } - *npending = gnutls_record_check_pending(tls->session); - if (*npending == 0) { - NTSTATUS status = socket_pending(tls->socket, npending); - if (*npending == 0) { - /* seems to be a gnutls bug */ - (*npending) = 100; - } - return status; - } - return NT_STATUS_OK; -} - -/* - receive data either by tls or normal socket_recv -*/ -static NTSTATUS tls_socket_recv(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread) -{ - int ret; - NTSTATUS status; - struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); - - if (tls->tls_enabled && tls->tls_detect) { - status = socket_recv(tls->socket, &tls->first_byte, 1, nread); - NT_STATUS_NOT_OK_RETURN(status); - if (*nread == 0) return NT_STATUS_OK; - tls->tls_detect = false; - /* look for the first byte of a valid HTTP operation */ - if (strchr(tls->plain_chars, tls->first_byte)) { - /* not a tls link */ - tls->tls_enabled = false; - *(uint8_t *)buf = tls->first_byte; - return NT_STATUS_OK; - } - tls->have_first_byte = true; - } - - if (!tls->tls_enabled) { - return socket_recv(tls->socket, buf, wantlen, nread); - } - - status = tls_handshake(tls); - NT_STATUS_NOT_OK_RETURN(status); - - status = tls_interrupted(tls); - NT_STATUS_NOT_OK_RETURN(status); - - ret = gnutls_record_recv(tls->session, buf, wantlen); - if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { - if (gnutls_record_get_direction(tls->session) == 1) { - TEVENT_FD_WRITEABLE(tls->fde); - } - tls->interrupted = true; - return STATUS_MORE_ENTRIES; - } - if (ret < 0) { - return NT_STATUS_UNEXPECTED_NETWORK_ERROR; - } - *nread = ret; - return NT_STATUS_OK; -} - - -/* - send data either by tls or normal socket_recv -*/ -static NTSTATUS tls_socket_send(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen) -{ - NTSTATUS status; - int ret; - struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); - - if (!tls->tls_enabled) { - return socket_send(tls->socket, blob, sendlen); - } - - status = tls_handshake(tls); - NT_STATUS_NOT_OK_RETURN(status); - - status = tls_interrupted(tls); - NT_STATUS_NOT_OK_RETURN(status); - - ret = gnutls_record_send(tls->session, blob->data, blob->length); - if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { - if (gnutls_record_get_direction(tls->session) == 1) { - TEVENT_FD_WRITEABLE(tls->fde); - } - tls->interrupted = true; - return STATUS_MORE_ENTRIES; - } - if (ret < 0) { - DEBUG(0,("gnutls_record_send of %d failed - %s\n", (int)blob->length, gnutls_strerror(ret))); - return NT_STATUS_UNEXPECTED_NETWORK_ERROR; - } - *sendlen = ret; - tls->output_pending = (ret < blob->length); - return NT_STATUS_OK; -} - - -/* - initialise global tls state -*/ -struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) -{ - struct tls_params *params; - int ret; - struct stat st; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - const char *keyfile = lpcfg_tls_keyfile(tmp_ctx, lp_ctx); - const char *certfile = lpcfg_tls_certfile(tmp_ctx, lp_ctx); - const char *cafile = lpcfg_tls_cafile(tmp_ctx, lp_ctx); - const char *crlfile = lpcfg_tls_crlfile(tmp_ctx, lp_ctx); - const char *dhpfile = lpcfg_tls_dhpfile(tmp_ctx, lp_ctx); - void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *, const char *); - params = talloc(mem_ctx, struct tls_params); - if (params == NULL) { - talloc_free(tmp_ctx); - return NULL; - } - - if (!lpcfg_tls_enabled(lp_ctx) || keyfile == NULL || *keyfile == 0) { - params->tls_enabled = false; - talloc_free(tmp_ctx); - return params; - } - - params->tls_priority = lpcfg_tls_priority(lp_ctx); - - if (!file_exist(cafile)) { - char *hostname = talloc_asprintf(mem_ctx, "%s.%s", - lpcfg_netbios_name(lp_ctx), - lpcfg_dnsdomain(lp_ctx)); - if (hostname == NULL) { - ret = GNUTLS_E_MEMORY_ERROR; - goto init_failed; - } - tls_cert_generate(params, hostname, keyfile, certfile, cafile); - talloc_free(hostname); - } - - if (file_exist(keyfile) && - !file_check_permissions(keyfile, geteuid(), 0600, &st)) - { - DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n" - "owner uid %u should be %u, mode 0%o should be 0%o\n" - "This is known as CVE-2013-4476.\n" - "Removing all tls .pem files will cause an " - "auto-regeneration with the correct permissions.\n", - keyfile, - (unsigned int)st.st_uid, geteuid(), - (unsigned int)(st.st_mode & 0777), 0600)); - talloc_free(tmp_ctx); - return NULL; - } - - ret = gnutls_global_init(); - if (ret < 0) goto init_failed; - - gnutls_certificate_allocate_credentials(¶ms->x509_cred); - if (ret < 0) goto init_failed; - - if (cafile && *cafile) { - ret = gnutls_certificate_set_x509_trust_file(params->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(params->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(params->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(¶ms->dh_params); - if (ret < 0) goto init_failed; - - if (dhpfile && *dhpfile) { - gnutls_datum_t dhparms; - size_t size; - dhparms.data = (uint8_t *)file_load(dhpfile, &size, 0, 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; - - talloc_free(tmp_ctx); - return params; - -init_failed: - DEBUG(0,("GNUTLS failed to initialise - %s\n", gnutls_strerror(ret))); - params->tls_enabled = false; - talloc_free(tmp_ctx); - return params; -} - - -/* - setup for a new connection -*/ -struct socket_context *tls_init_server(struct tls_params *params, - struct socket_context *socket_ctx, - struct tevent_fd *fde, - const char *plain_chars) -{ - struct tls_context *tls; - int ret; - struct socket_context *new_sock; - NTSTATUS nt_status; - const char *error_pos; - - nt_status = socket_create_with_ops(socket_ctx, &tls_socket_ops, &new_sock, - SOCKET_TYPE_STREAM, - socket_ctx->flags | SOCKET_FLAG_ENCRYPT); - if (!NT_STATUS_IS_OK(nt_status)) { - return NULL; - } - - tls = talloc(new_sock, struct tls_context); - if (tls == NULL) { - return NULL; - } - - tls->socket = socket_ctx; - talloc_steal(tls, socket_ctx); - tls->fde = fde; - - new_sock->private_data = tls; - - if (!params->tls_enabled) { - talloc_free(new_sock); - return NULL; - } - - TLSCHECK(gnutls_init(&tls->session, GNUTLS_SERVER)); - - talloc_set_destructor(tls, tls_destructor); - - ret = gnutls_priority_set_direct(tls->session, - params->tls_priority, - &error_pos); - if (ret != GNUTLS_E_SUCCESS) { - DEBUG(0,("TLS %s - %s. Check 'tls priority' option at '%s'\n", - __location__, gnutls_strerror(ret), error_pos)); - talloc_free(new_sock); - return NULL; - } - - TLSCHECK(gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, - params->x509_cred)); - gnutls_certificate_server_set_request(tls->session, GNUTLS_CERT_REQUEST); - gnutls_dh_set_prime_bits(tls->session, DH_BITS); - gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr_t)tls); - gnutls_transport_set_pull_function(tls->session, (gnutls_pull_func)tls_pull); - gnutls_transport_set_push_function(tls->session, (gnutls_push_func)tls_push); - - tls->plain_chars = plain_chars; - if (plain_chars) { - tls->tls_detect = true; - } else { - tls->tls_detect = false; - } - - tls->output_pending = false; - tls->done_handshake = false; - tls->have_first_byte = false; - tls->tls_enabled = true; - tls->interrupted = false; - - new_sock->state = SOCKET_STATE_SERVER_CONNECTED; - - return new_sock; - -failed: - DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret))); - talloc_free(new_sock); - return NULL; -} - - -static NTSTATUS tls_socket_set_option(struct socket_context *sock, const char *option, const char *val) -{ - set_socket_options(socket_get_fd(sock), option); - return NT_STATUS_OK; -} - -static char *tls_socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); - return socket_get_peer_name(tls->socket, mem_ctx); -} - -static struct socket_address *tls_socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); - return socket_get_peer_addr(tls->socket, mem_ctx); -} - -static struct socket_address *tls_socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); - return socket_get_my_addr(tls->socket, mem_ctx); -} - -static int tls_socket_get_fd(struct socket_context *sock) -{ - struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); - return socket_get_fd(tls->socket); -} - -static const struct socket_ops tls_socket_ops = { - .name = "tls", - .fn_init = tls_socket_init, - .fn_recv = tls_socket_recv, - .fn_send = tls_socket_send, - .fn_pending = tls_socket_pending, - - .fn_set_option = tls_socket_set_option, - - .fn_get_peer_name = tls_socket_get_peer_name, - .fn_get_peer_addr = tls_socket_get_peer_addr, - .fn_get_my_addr = tls_socket_get_my_addr, - .fn_get_fd = tls_socket_get_fd -}; diff --git a/source4/lib/tls/wscript_build b/source4/lib/tls/wscript_build index 40a9520e6e1..7980a633574 100644 --- a/source4/lib/tls/wscript_build +++ b/source4/lib/tls/wscript_build @@ -2,7 +2,6 @@ bld.SAMBA_SUBSYSTEM('LIBTLS', source=''' - tls.c tlscert.c tls_tstream.c ''', @@ -10,7 +9,6 @@ bld.SAMBA_SUBSYSTEM('LIBTLS', talloc gnutls samba-hostconfig - samba_socket LIBTSOCKET tevent tevent-util |