mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
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 commit is contained in:
parent
74bd8170fc
commit
09b2f30dfa
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
if (!params->tls_enabled || !tls_enable) {
|
||||
new_sock->private_data = tls;
|
||||
|
||||
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,19 +570,61 @@ 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;
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
BOOL tls_support(struct tls_params *params)
|
||||
{
|
||||
return params->tls_enabled;
|
||||
@ -526,38 +640,25 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx)
|
||||
return talloc_new(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)
|
||||
/*
|
||||
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)
|
||||
{
|
||||
if (tls_enable && plain_chars == NULL) return NULL;
|
||||
return (struct tls_context *)sock;
|
||||
}
|
||||
|
||||
struct tls_context *tls_init_client(struct socket_context *sock,
|
||||
struct fd_event *fde,
|
||||
BOOL tls_enable)
|
||||
{
|
||||
return (struct tls_context *)sock;
|
||||
return socket;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS tls_socket_recv(struct tls_context *tls, void *buf, size_t wantlen,
|
||||
size_t *nread)
|
||||
/*
|
||||
setup for a new client connection
|
||||
*/
|
||||
struct socket_context *tls_init_client(struct socket_context *socket,
|
||||
struct fd_event *fde)
|
||||
{
|
||||
return socket_recv((struct socket_context *)tls, buf, wantlen, nread);
|
||||
}
|
||||
|
||||
NTSTATUS tls_socket_send(struct tls_context *tls, const DATA_BLOB *blob, size_t *sendlen)
|
||||
{
|
||||
return socket_send((struct socket_context *)tls, blob, sendlen);
|
||||
}
|
||||
|
||||
BOOL tls_enabled(struct tls_context *tls)
|
||||
{
|
||||
return False;
|
||||
return socket;
|
||||
}
|
||||
|
||||
BOOL tls_support(struct tls_params *params)
|
||||
@ -565,9 +666,5 @@ BOOL tls_support(struct tls_params *params)
|
||||
return False;
|
||||
}
|
||||
|
||||
NTSTATUS tls_socket_pending(struct tls_context *tls, size_t *npending)
|
||||
{
|
||||
return socket_pending((struct socket_context *)tls, npending);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
||||
|
@ -54,7 +54,6 @@ struct websrv_context {
|
||||
int response_code;
|
||||
const char **headers;
|
||||
} output;
|
||||
struct tls_context *tls;
|
||||
struct session_data *session;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user