diff options
author | Andrew Bartlett <abartlet@samba.org> | 2006-05-02 20:15:47 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:05:32 -0500 |
commit | 742c110cd67f4995639822981e8bfcb1f652f2c4 (patch) | |
tree | cd6774c861b0a968c3d22b24b5a02a0be9c54043 /source4 | |
parent | 49994442bbb035b2c438a33f411d6b5a8b2313df (diff) | |
download | samba-742c110cd67f4995639822981e8bfcb1f652f2c4.tar.gz samba-742c110cd67f4995639822981e8bfcb1f652f2c4.tar.bz2 samba-742c110cd67f4995639822981e8bfcb1f652f2c4.zip |
r15400: Move the TLS code behind the socket interface.
This reduces caller complexity, because the TLS code is now called
just like any other socket. (A new socket context is returned by the
tls_init_server and tls_init_client routines).
When TLS is not available, the original socket is returned.
Andrew Bartlett
(This used to be commit 09b2f30dfa7a640f5187b4933204e9680be61497)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/ldap_server/ldap_server.c | 19 | ||||
-rw-r--r-- | source4/ldap_server/ldap_server.h | 1 | ||||
-rw-r--r-- | source4/lib/socket/socket.c | 6 | ||||
-rw-r--r-- | source4/lib/socket/socket.h | 3 | ||||
-rw-r--r-- | source4/lib/stream/packet.c | 34 | ||||
-rw-r--r-- | source4/lib/stream/packet.h | 3 | ||||
-rw-r--r-- | source4/lib/tls/tls.c | 219 | ||||
-rw-r--r-- | source4/lib/tls/tls.h | 26 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap_bind.c | 2 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap_client.c | 39 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap_client.h | 1 | ||||
-rw-r--r-- | source4/web_server/http.c | 6 | ||||
-rw-r--r-- | source4/web_server/web_server.c | 13 | ||||
-rw-r--r-- | source4/web_server/web_server.h | 1 |
14 files changed, 216 insertions, 157 deletions
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index ba5f415169..6f57073f18 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -46,10 +46,6 @@ static void ldapsrv_terminate_connection(struct ldapsrv_connection *conn, const char *reason) { - if (conn->tls) { - talloc_free(conn->tls); - conn->tls = NULL; - } stream_terminate_connection(conn->connection, reason); } @@ -430,13 +426,14 @@ static void ldapsrv_accept(struct stream_connection *c) port = socket_address->port; talloc_free(socket_address); - conn->tls = tls_init_server(ldapsrv_service->tls_params, c->socket, - c->event.fde, NULL, port != 389); - if (!conn->tls) { - ldapsrv_terminate_connection(conn, "ldapsrv_accept: tls_init_server() failed"); - return; + if (port == 636) { + c->socket = tls_init_server(ldapsrv_service->tls_params, c->socket, + c->event.fde, NULL); + if (!c->socket) { + ldapsrv_terminate_connection(conn, "ldapsrv_accept: tls_init_server() failed"); + return; + } } - conn->packet = packet_init(conn); if (conn->packet == NULL) { ldapsrv_terminate_connection(conn, "out of memory"); @@ -444,7 +441,7 @@ static void ldapsrv_accept(struct stream_connection *c) } packet_set_private(conn->packet, conn); - packet_set_tls(conn->packet, conn->tls); + packet_set_socket(conn->packet, c->socket); packet_set_callback(conn->packet, ldapsrv_decode); packet_set_full_request(conn->packet, ldapsrv_complete_packet); packet_set_error_handler(conn->packet, ldapsrv_error_handler); diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h index 10c93f6610..033f8ef67c 100644 --- a/source4/ldap_server/ldap_server.h +++ b/source4/ldap_server/ldap_server.h @@ -26,7 +26,6 @@ struct ldapsrv_connection { struct gensec_security *gensec; struct auth_session_info *session_info; struct ldapsrv_service *service; - struct tls_context *tls; struct cli_credentials *server_credentials; struct ldb_context *ldb; diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 4f7f4ef4b9..b7d4431c94 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -37,9 +37,9 @@ static int socket_destructor(void *ptr) return 0; } -static NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops, - struct socket_context **new_sock, - enum socket_type type, uint32_t flags) +_PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops, + struct socket_context **new_sock, + enum socket_type type, uint32_t flags) { NTSTATUS status; diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h index 04ae53e464..fefa999e08 100644 --- a/source4/lib/socket/socket.h +++ b/source4/lib/socket/socket.h @@ -117,6 +117,9 @@ struct socket_context { /* prototypes */ +NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops, + struct socket_context **new_sock, + enum socket_type type, uint32_t flags); NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_context **new_sock, uint32_t flags); NTSTATUS socket_connect(struct socket_context *sock, diff --git a/source4/lib/stream/packet.c b/source4/lib/stream/packet.c index 613400226b..1da7f5706b 100644 --- a/source4/lib/stream/packet.c +++ b/source4/lib/stream/packet.c @@ -26,7 +26,6 @@ #include "dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" -#include "lib/tls/tls.h" #include "lib/stream/packet.h" @@ -37,7 +36,6 @@ struct packet_context { DATA_BLOB partial; uint32_t num_read; uint32_t initial_read; - struct tls_context *tls; struct socket_context *sock; struct event_context *ev; size_t packet_size; @@ -126,15 +124,7 @@ _PUBLIC_ void packet_set_full_request(struct packet_context *pc, packet_full_req } /* - set a tls context to use. You must either set a tls_context or a socket_context -*/ -_PUBLIC_ void packet_set_tls(struct packet_context *pc, struct tls_context *tls) -{ - pc->tls = tls; -} - -/* - set a socket context to use. You must either set a tls_context or a socket_context + set a socket context to use. You must set a socket_context */ _PUBLIC_ void packet_set_socket(struct packet_context *pc, struct socket_context *sock) { @@ -194,7 +184,6 @@ _PUBLIC_ void packet_set_nofree(struct packet_context *pc) */ static void packet_error(struct packet_context *pc, NTSTATUS status) { - pc->tls = NULL; pc->sock = NULL; if (pc->error_handler) { pc->error_handler(pc->private, status); @@ -266,9 +255,7 @@ _PUBLIC_ void packet_recv(struct packet_context *pc) } else if (pc->initial_read != 0) { npending = pc->initial_read - pc->num_read; } else { - if (pc->tls) { - status = tls_socket_pending(pc->tls, &npending); - } else if (pc->sock) { + if (pc->sock) { status = socket_pending(pc->sock, &npending); } else { status = NT_STATUS_CONNECTION_DISCONNECTED; @@ -293,13 +280,9 @@ _PUBLIC_ void packet_recv(struct packet_context *pc) } } - if (pc->tls) { - status = tls_socket_recv(pc->tls, pc->partial.data + pc->num_read, - npending, &nread); - } else { - status = socket_recv(pc->sock, pc->partial.data + pc->num_read, - npending, &nread); - } + status = socket_recv(pc->sock, pc->partial.data + pc->num_read, + npending, &nread); + if (NT_STATUS_IS_ERR(status)) { packet_error(pc, status); return; @@ -452,11 +435,8 @@ _PUBLIC_ void packet_queue_run(struct packet_context *pc) DATA_BLOB blob = data_blob_const(el->blob.data + el->nsent, el->blob.length - el->nsent); - if (pc->tls) { - status = tls_socket_send(pc->tls, &blob, &nwritten); - } else { - status = socket_send(pc->sock, &blob, &nwritten); - } + status = socket_send(pc->sock, &blob, &nwritten); + if (NT_STATUS_IS_ERR(status)) { packet_error(pc, NT_STATUS_NET_WRITE_FAULT); return; diff --git a/source4/lib/stream/packet.h b/source4/lib/stream/packet.h index 79d4acacd0..b7ee428186 100644 --- a/source4/lib/stream/packet.h +++ b/source4/lib/stream/packet.h @@ -21,8 +21,6 @@ */ -#include "lib/tls/tls.h" - typedef NTSTATUS (*packet_full_request_fn_t)(void *private, DATA_BLOB blob, size_t *packet_size); typedef NTSTATUS (*packet_callback_fn_t)(void *private, DATA_BLOB blob); @@ -35,7 +33,6 @@ void packet_set_callback(struct packet_context *pc, packet_callback_fn_t callbac void packet_set_error_handler(struct packet_context *pc, packet_error_handler_fn_t handler); void packet_set_private(struct packet_context *pc, void *private); void packet_set_full_request(struct packet_context *pc, packet_full_request_fn_t callback); -void packet_set_tls(struct packet_context *pc, struct tls_context *tls); void packet_set_socket(struct packet_context *pc, struct socket_context *sock); void packet_set_event_context(struct packet_context *pc, struct event_context *ev); void packet_set_fde(struct packet_context *pc, struct fd_event *fde); diff --git a/source4/lib/tls/tls.c b/source4/lib/tls/tls.c index 5fd80e383a..2872669948 100644 --- a/source4/lib/tls/tls.c +++ b/source4/lib/tls/tls.c @@ -3,8 +3,10 @@ transport layer security handling code - Copyright (C) Andrew Tridgell 2005 - + 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 2 of the License, or @@ -35,23 +37,61 @@ struct tls_params { gnutls_dh_params dh_params; BOOL tls_enabled; }; +#endif /* hold per connection tls data */ struct tls_context { struct socket_context *socket; struct fd_event *fde; + BOOL tls_enabled; +#if HAVE_LIBGNUTLS gnutls_session session; BOOL done_handshake; BOOL have_first_byte; uint8_t first_byte; - BOOL tls_enabled; BOOL tls_detect; const char *plain_chars; BOOL output_pending; gnutls_certificate_credentials xcred; BOOL interrupted; +#endif }; +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; +} + + +#if HAVE_LIBGNUTLS + +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) { \ @@ -61,7 +101,6 @@ struct tls_context { } while (0) - /* callback for reading from a socket */ @@ -199,8 +238,9 @@ static NTSTATUS tls_interrupted(struct tls_context *tls) /* see how many bytes are pending on the connection */ -NTSTATUS tls_socket_pending(struct tls_context *tls, size_t *npending) +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); } @@ -219,11 +259,13 @@ NTSTATUS tls_socket_pending(struct tls_context *tls, size_t *npending) /* receive data either by tls or normal socket_recv */ -NTSTATUS tls_socket_recv(struct tls_context *tls, void *buf, size_t wantlen, - size_t *nread) +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); @@ -268,10 +310,12 @@ NTSTATUS tls_socket_recv(struct tls_context *tls, void *buf, size_t wantlen, /* send data either by tls or normal socket_recv */ -NTSTATUS tls_socket_send(struct tls_context *tls, const DATA_BLOB *blob, size_t *sendlen) +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); @@ -389,24 +433,41 @@ init_failed: /* setup for a new connection */ -struct tls_context *tls_init_server(struct tls_params *params, +struct socket_context *tls_init_server(struct tls_params *params, struct socket_context *socket, struct fd_event *fde, - const char *plain_chars, - BOOL tls_enable) + const char *plain_chars) { struct tls_context *tls; int ret; + struct socket_context *new_sock; + NTSTATUS nt_status; + + nt_status = socket_create_with_ops(socket, &tls_socket_ops, &new_sock, + SOCKET_TYPE_STREAM, 0); + if (!NT_STATUS_IS_OK(nt_status)) { + return NULL; + } - tls = talloc(socket, struct tls_context); - if (tls == NULL) return NULL; + tls = talloc(new_sock, struct tls_context); + if (tls == NULL) { + return NULL; + } tls->socket = socket; tls->fde = fde; + if (talloc_reference(tls, fde) == NULL) { + return NULL; + } + if (talloc_reference(tls, socket) == NULL) { + return NULL; + } + + new_sock->private_data = tls; - if (!params->tls_enabled || !tls_enable) { + if (!params->tls_enabled) { tls->tls_enabled = False; - return tls; + return new_sock; } TLSCHECK(gnutls_init(&tls->session, GNUTLS_SERVER)); @@ -436,38 +497,49 @@ struct tls_context *tls_init_server(struct tls_params *params, tls->tls_enabled = True; tls->interrupted = False; - return tls; + new_sock->state = SOCKET_STATE_SERVER_CONNECTED; + + return new_sock; failed: DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret))); tls->tls_enabled = False; params->tls_enabled = False; - return tls; + return new_sock; } /* setup for a new client connection */ -struct tls_context *tls_init_client(struct socket_context *socket, - struct fd_event *fde, - BOOL tls_enable) +struct socket_context *tls_init_client(struct socket_context *socket, + struct fd_event *fde) { struct tls_context *tls; - int ret=0; + int ret = 0; const int cert_type_priority[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; char *cafile; + struct socket_context *new_sock; + NTSTATUS nt_status; + + nt_status = socket_create_with_ops(socket, &tls_socket_ops, &new_sock, + SOCKET_TYPE_STREAM, 0); + if (!NT_STATUS_IS_OK(nt_status)) { + return NULL; + } - tls = talloc(socket, struct tls_context); + tls = talloc(new_sock, struct tls_context); if (tls == NULL) return NULL; tls->socket = socket; tls->fde = fde; - tls->tls_enabled = tls_enable; - - if (!tls->tls_enabled) { - return tls; + if (talloc_reference(tls, fde) == NULL) { + return NULL; + } + if (talloc_reference(tls, socket) == NULL) { + return NULL; } + new_sock->private_data = tls; cafile = private_path(tls, lp_tls_cafile()); if (!cafile || !*cafile) { @@ -498,76 +570,101 @@ struct tls_context *tls_init_client(struct socket_context *socket, tls->tls_enabled = True; tls->interrupted = False; - return tls; + new_sock->state = SOCKET_STATE_CLIENT_CONNECTED; + + return new_sock; failed: DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret))); tls->tls_enabled = False; - return tls; + return new_sock; } -BOOL tls_enabled(struct tls_context *tls) +static NTSTATUS tls_socket_set_option(struct socket_context *sock, const char *option, const char *val) { - return tls->tls_enabled; + set_socket_options(socket_get_fd(sock), option); + return NT_STATUS_OK; } -BOOL tls_support(struct tls_params *params) +static char *tls_socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - return params->tls_enabled; + struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); + return socket_get_peer_name(tls->socket, mem_ctx); } -#else - -/* for systems without tls we just map the tls socket calls to the - normal socket calls */ - -struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) +static struct socket_address *tls_socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - return talloc_new(mem_ctx); + struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); + return socket_get_peer_addr(tls->socket, mem_ctx); } -struct tls_context *tls_init_server(struct tls_params *params, - struct socket_context *sock, - struct fd_event *fde, - const char *plain_chars, - BOOL tls_enable) +static struct socket_address *tls_socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - if (tls_enable && plain_chars == NULL) return NULL; - return (struct tls_context *)sock; + struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); + return socket_get_my_addr(tls->socket, mem_ctx); } -struct tls_context *tls_init_client(struct socket_context *sock, - struct fd_event *fde, - BOOL tls_enable) +static int tls_socket_get_fd(struct socket_context *sock) { - return (struct tls_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, -NTSTATUS tls_socket_recv(struct tls_context *tls, void *buf, size_t wantlen, - size_t *nread) + .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 +}; + +BOOL tls_support(struct tls_params *params) { - return socket_recv((struct socket_context *)tls, buf, wantlen, nread); + return params->tls_enabled; } -NTSTATUS tls_socket_send(struct tls_context *tls, const DATA_BLOB *blob, size_t *sendlen) +#else + +/* for systems without tls we just map the tls socket calls to the + normal socket calls */ + +struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) { - return socket_send((struct socket_context *)tls, blob, sendlen); + return talloc_new(mem_ctx); } -BOOL tls_enabled(struct tls_context *tls) +/* + setup for a new connection +*/ +struct socket_context *tls_init_server(struct tls_params *params, + struct socket_context *socket, + struct fd_event *fde, + const char *plain_chars) { - return False; + return socket; } -BOOL tls_support(struct tls_params *params) + +/* + setup for a new client connection +*/ +struct socket_context *tls_init_client(struct socket_context *socket, + struct fd_event *fde) { - return False; + return socket; } -NTSTATUS tls_socket_pending(struct tls_context *tls, size_t *npending) +BOOL tls_support(struct tls_params *params) { - return socket_pending((struct socket_context *)tls, npending); + return False; } #endif + diff --git a/source4/lib/tls/tls.h b/source4/lib/tls/tls.h index df67bad0e4..00186408e0 100644 --- a/source4/lib/tls/tls.h +++ b/source4/lib/tls/tls.h @@ -37,31 +37,21 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx); tls and non-tls servers on the same port. If this is NULL then only tls connections will be allowed */ -struct tls_context *tls_init_server(struct tls_params *parms, +struct socket_context *tls_init_server(struct tls_params *parms, struct socket_context *sock, struct fd_event *fde, - const char *plain_chars, - BOOL tls_enable); + const char *plain_chars); /* call tls_init_client() on each new client connection */ -struct tls_context *tls_init_client(struct socket_context *sock, - struct fd_event *fde, - BOOL tls_enable); - -/* - call these to send and receive data. They behave like socket_send() and socket_recv() - */ -NTSTATUS tls_socket_recv(struct tls_context *tls, void *buf, size_t wantlen, - size_t *nread); -NTSTATUS tls_socket_send(struct tls_context *tls, const DATA_BLOB *blob, - size_t *sendlen); +struct socket_context *tls_init_client(struct socket_context *sock, + struct fd_event *fde); /* return True if a connection used tls */ -BOOL tls_enabled(struct tls_context *tls); +BOOL tls_enabled(struct socket_context *tls); /* @@ -69,10 +59,6 @@ BOOL tls_enabled(struct tls_context *tls); */ BOOL tls_support(struct tls_params *parms); - -/* - ask for the number of bytes in a pending incoming packet -*/ -NTSTATUS tls_socket_pending(struct tls_context *tls, size_t *npending); +const struct socket_ops *socket_tls_ops(enum socket_type type); #endif diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index c33d53f775..6714d68b0e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -223,7 +223,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr /* require Kerberos SIGN/SEAL only if we don't use SSL * Windows seem not to like double encryption */ - if (conn->tls == NULL || (! tls_enabled(conn->tls))) { + if (!tls_enabled(conn->sock)) { gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 27cab38916..8d815c7103 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -32,6 +32,7 @@ #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" #include "lib/stream/packet.h" +#include "lib/tls/tls.h" #include "auth/gensec/gensec.h" #include "system/time.h" @@ -85,12 +86,10 @@ static void ldap_connection_dead(struct ldap_connection *conn) if (req->async.fn) { req->async.fn(req); } - } + } - talloc_free(conn->tls); -/* talloc_free(conn->sock); this will also free event.fde */ + talloc_free(conn->sock); /* this will also free event.fde */ talloc_free(conn->packet); - conn->tls = NULL; conn->sock = NULL; conn->event.fde = NULL; conn->packet = NULL; @@ -270,7 +269,7 @@ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, struct ldap_connection); if (flags & EVENT_FD_WRITE) { packet_queue_run(conn->packet); - if (conn->tls == NULL) return; + if (!tls_enabled(conn->sock)) return; } if (flags & EVENT_FD_READ) { packet_recv(conn->packet); @@ -339,11 +338,6 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, struct composite_context *result, *ctx; struct ldap_connect_state *state; - if (conn->reconnect.url == NULL) { - conn->reconnect.url = talloc_strdup(conn, url); - if (conn->reconnect.url == NULL) goto failed; - } - result = talloc_zero(NULL, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; @@ -357,6 +351,11 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, state->conn = conn; + if (conn->reconnect.url == NULL) { + conn->reconnect.url = talloc_strdup(conn, url); + if (conn->reconnect.url == NULL) goto failed; + } + state->ctx->status = ldap_parse_basic_url(conn, url, &conn->host, &conn->port, &conn->ldaps); if (!NT_STATUS_IS_OK(state->ctx->status)) { @@ -379,6 +378,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, static void ldap_connect_recv_conn(struct composite_context *ctx) { + struct socket_context *initial_socket; struct ldap_connect_state *state = talloc_get_type(ctx->async.private_data, struct ldap_connect_state); @@ -398,21 +398,24 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) return; } - conn->tls = tls_init_client(conn->sock, conn->event.fde, conn->ldaps); - if (conn->tls == NULL) { - talloc_free(conn->sock); - return; + talloc_steal(conn, conn->sock); + initial_socket = conn->sock; + if (conn->ldaps) { + conn->sock = tls_init_client(conn->sock, conn->event.fde); + if (conn->sock == NULL) { + talloc_free(initial_socket); + return; + } } - talloc_steal(conn, conn->tls); - talloc_steal(conn->tls, conn->sock); conn->packet = packet_init(conn); if (conn->packet == NULL) { talloc_free(conn->sock); return; } + packet_set_private(conn->packet, conn); - packet_set_tls(conn->packet, conn->tls); + packet_set_socket(conn->packet, conn->sock); packet_set_callback(conn->packet, ldap_recv_handler); packet_set_full_request(conn->packet, ldap_complete_packet); packet_set_error_handler(conn->packet, ldap_error_handler); @@ -535,7 +538,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, req = talloc_zero(conn, struct ldap_request); if (req == NULL) return NULL; - if (conn->tls == NULL) { + if (conn->sock == NULL) { status = NT_STATUS_INVALID_CONNECTION; goto failed; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 7801f8b6bc..28b9f2763c 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -51,7 +51,6 @@ struct ldap_request { /* main context for a ldap client connection */ struct ldap_connection { - struct tls_context *tls; struct socket_context *sock; char *host; uint16_t port; diff --git a/source4/web_server/http.c b/source4/web_server/http.c index 93d81ef1d0..f79bedb2de 100644 --- a/source4/web_server/http.c +++ b/source4/web_server/http.c @@ -237,12 +237,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", - tls_enabled(web->tls)?"s":"", + tls_enabled(web->conn->socket)?"s":"", host, url); } else { int dirlen = p - web->input.url; url = talloc_asprintf(web, "http%s://%s%*.*s/%s", - tls_enabled(web->tls)?"s":"", + tls_enabled(web->conn->socket)?"s":"", host, dirlen, dirlen, web->input.url, url); @@ -452,7 +452,7 @@ static void http_setup_arrays(struct esp_state *esp) } SETVAR(ESP_SERVER_OBJ, "DOCUMENT_ROOT", lp_swat_directory()); - SETVAR(ESP_SERVER_OBJ, "SERVER_PROTOCOL", tls_enabled(web->tls)?"https":"http"); + SETVAR(ESP_SERVER_OBJ, "SERVER_PROTOCOL", tls_enabled(web->conn->socket)?"https":"http"); SETVAR(ESP_SERVER_OBJ, "SERVER_SOFTWARE", "SWAT"); SETVAR(ESP_SERVER_OBJ, "GATEWAY_INTERFACE", "CGI/1.1"); SETVAR(ESP_SERVER_OBJ, "TLS_SUPPORT", tls_support(edata->tls_params)?"True":"False"); diff --git a/source4/web_server/web_server.c b/source4/web_server/web_server.c index 05c315e4fa..93d59cc47a 100644 --- a/source4/web_server/web_server.c +++ b/source4/web_server/web_server.c @@ -76,7 +76,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->tls, buf, sizeof(buf), &nread); + status = socket_recv(conn->socket, buf, sizeof(buf), &nread); if (NT_STATUS_IS_ERR(status)) goto failed; if (!NT_STATUS_IS_OK(status)) return; @@ -149,7 +149,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->tls, &b, &nsent); + status = socket_send(conn->socket, &b, &nsent); if (NT_STATUS_IS_ERR(status)) { stream_terminate_connection(web->conn, "socket_send: failed"); return; @@ -183,8 +183,6 @@ 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, "websrv_send: finished sending"); } } @@ -211,9 +209,10 @@ static void websrv_accept(struct stream_connection *conn) timeval_current_ofs(HTTP_TIMEOUT, 0), websrv_timeout, web); - web->tls = tls_init_server(edata->tls_params, conn->socket, - conn->event.fde, "GPHO", True); - if (web->tls == NULL) goto failed; + /* Overwrite the socket with a (possibly) TLS socket */ + conn->socket = tls_init_server(edata->tls_params, conn->socket, + conn->event.fde, "GPHO"); + if (conn->socket == NULL) goto failed; return; diff --git a/source4/web_server/web_server.h b/source4/web_server/web_server.h index 6e266cc8bc..f64a946bee 100644 --- a/source4/web_server/web_server.h +++ b/source4/web_server/web_server.h @@ -54,7 +54,6 @@ struct websrv_context { int response_code; const char **headers; } output; - struct tls_context *tls; struct session_data *session; }; |