r15400: Move the TLS code behind the socket interface.
authorAndrew Bartlett <abartlet@samba.org>
Tue, 2 May 2006 20:15:47 +0000 (20:15 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:05:32 +0000 (14:05 -0500)
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)

14 files changed:
source4/ldap_server/ldap_server.c
source4/ldap_server/ldap_server.h
source4/lib/socket/socket.c
source4/lib/socket/socket.h
source4/lib/stream/packet.c
source4/lib/stream/packet.h
source4/lib/tls/tls.c
source4/lib/tls/tls.h
source4/libcli/ldap/ldap_bind.c
source4/libcli/ldap/ldap_client.c
source4/libcli/ldap/ldap_client.h
source4/web_server/http.c
source4/web_server/web_server.c
source4/web_server/web_server.h

index ba5f41516964bd9dd78cadbf6c2eedaa5e9b11a2..6f57073f185c55794ccb18df0f7168fd605075df 100644 (file)
 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);
index 10c93f661043898704c0c5729026304adbbb5734..033f8ef67cfd0ba724355c110892839964c0c46f 100644 (file)
@@ -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;
 
index 4f7f4ef4b91e367a43fe17cf76ebf562ef256aa2..b7d4431c945de96aa285fc729cca7d64c81a212b 100644 (file)
@@ -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;
 
index 04ae53e464530e481438fd914665f777c923d758..fefa999e08195a0d9e6678db089724cde8ec8248 100644 (file)
@@ -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,
index 613400226bec5e23e8dab87fcdffee9a7a1b8e40..1da7f5706b9706e1a0f205041b6bedb2c64b9bf8 100644 (file)
@@ -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;
index 79d4acacd01f136fe62e41f1f403b3aa00ac2ce4..b7ee428186b8ef2e0ec9dcd6f35b0305fd498f94 100644 (file)
@@ -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);
index 5fd80e383ad914007fdbd4ed03763b9eeb90b7a9..2872669948e7208bb5801f085e96896c7648ece7 100644 (file)
@@ -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
+
index df67bad0e41b646471233c2d132fe5283d4d3cff..00186408e0ffef103c7044e98e423c5aeb67fd32 100644 (file)
@@ -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
index c33d53f775751c2396cb52cf62d523ddd6f2b05e..6714d68b0ed2b3a20249231ab8c6f2c50742b3ea 100644 (file)
@@ -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);
        }
 
index 27cab3891619d45c49a23a179eb6e798fa48443b..8d815c71039f21be8d738c6ea32ae295df959ff6 100644 (file)
@@ -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;
        }
index 7801f8b6bc5ea17eb835e430055a458c60f9bbe5..28b9f2763cf7ad78ffaf422a821a930afd8d6bc3 100644 (file)
@@ -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;
index 93d81ef1d0bc9fa41239573e3dfc1344c9ca29a1..f79bedb2de493a3e5e918ce4d131ccb16598abca 100644 (file)
@@ -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");
index 05c315e4fa3c270b398c2ed02f9da0586be7d079..93d59cc47a19dff9de830fd427f1d1e1fa51c699 100644 (file)
@@ -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;
 
index 6e266cc8bc3183b8018c86d2729dcc28d71329cc..f64a946bee22f9e87946bda6bd43582fe437f2a6 100644 (file)
@@ -54,7 +54,6 @@ struct websrv_context {
                int response_code;
                const char **headers;
        } output;
-       struct tls_context *tls;
        struct session_data *session;
 };