summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/ldap_server/ldap_server.c19
-rw-r--r--source4/ldap_server/ldap_server.h1
-rw-r--r--source4/lib/socket/socket.c6
-rw-r--r--source4/lib/socket/socket.h3
-rw-r--r--source4/lib/stream/packet.c34
-rw-r--r--source4/lib/stream/packet.h3
-rw-r--r--source4/lib/tls/tls.c219
-rw-r--r--source4/lib/tls/tls.h26
-rw-r--r--source4/libcli/ldap/ldap_bind.c2
-rw-r--r--source4/libcli/ldap/ldap_client.c39
-rw-r--r--source4/libcli/ldap/ldap_client.h1
-rw-r--r--source4/web_server/http.c6
-rw-r--r--source4/web_server/web_server.c13
-rw-r--r--source4/web_server/web_server.h1
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;
};