Skip to content

Commit

Permalink
Move KKDCP OpenSSL code to an internal plugin
Browse files Browse the repository at this point in the history
Create an internal pluggable interface "tls" with one in-tree dynamic
plugin module named "k5tls".  Move all of the OpenSSL calls to the
plugin module, and make the libkrb5 code load and invoke the plugin.
This way we do not load or initialize libssl unless an HTTP proxy is
used.

ticket: 7929
  • Loading branch information
greghudson committed Jul 19, 2014
1 parent 4abfd7b commit 472349d
Show file tree
Hide file tree
Showing 23 changed files with 899 additions and 669 deletions.
3 changes: 2 additions & 1 deletion src/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SUBDIRS=util include lib \
@ldap_plugin_dir@ \
plugins/preauth/otp \
plugins/preauth/pkinit \
plugins/tls/k5tls \
kdc kadmin slave clients appl tests \
config-files build-tools man doc @po@
WINSUBDIRS=include util lib ccapi windows clients appl
Expand Down Expand Up @@ -62,7 +63,7 @@ INSTALLMKDIRS = $(KRB5ROOT) $(KRB5MANROOT) $(KRB5OTHERMKDIRS) \
$(KRB5_LIBDIR) $(KRB5_INCDIR) \
$(KRB5_DB_MODULE_DIR) $(KRB5_PA_MODULE_DIR) \
$(KRB5_AD_MODULE_DIR) \
$(KRB5_LIBKRB5_MODULE_DIR) \
$(KRB5_LIBKRB5_MODULE_DIR) $(KRB5_TLS_MODULE_DIR) \
@localstatedir@ @localstatedir@/krb5kdc \
@runstatedir@ @runstatedir@/krb5kdc \
$(KRB5_INCSUBDIRS) $(datadir) $(EXAMPLEDIR) \
Expand Down
1 change: 1 addition & 0 deletions src/config/pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ KRB5_DB_MODULE_DIR = $(MODULE_DIR)/kdb
KRB5_PA_MODULE_DIR = $(MODULE_DIR)/preauth
KRB5_AD_MODULE_DIR = $(MODULE_DIR)/authdata
KRB5_LIBKRB5_MODULE_DIR = $(MODULE_DIR)/libkrb5
KRB5_TLS_MODULE_DIR = $(MODULE_DIR)/tls
KRB5_LOCALEDIR = @localedir@
GSS_MODULE_DIR = @libdir@/gss
KRB5_INCSUBDIRS = \
Expand Down
6 changes: 6 additions & 0 deletions src/configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,11 @@ no)
;;
esac

if test "$PROXY_TLS_IMPL" = no; then
AC_DEFINE(PROXY_TLS_IMPL_NONE,1,
[Define if no HTTP TLS implementation is selected])
fi

AC_SUBST(PROXY_TLS_IMPL)
AC_SUBST(PROXY_TLS_IMPL_CFLAGS)
AC_SUBST(PROXY_TLS_IMPL_LIBS)
Expand Down Expand Up @@ -1386,6 +1391,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test
plugins/authdata/greet
plugins/authdata/greet_client
plugins/authdata/greet_server
plugins/tls/k5tls

clients clients/klist clients/kinit clients/kvno
clients/kdestroy clients/kpasswd clients/ksu clients/kswitch
Expand Down
7 changes: 6 additions & 1 deletion src/include/k5-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,8 @@ struct plugin_interface {
#define PLUGIN_INTERFACE_LOCALAUTH 5
#define PLUGIN_INTERFACE_HOSTREALM 6
#define PLUGIN_INTERFACE_AUDIT 7
#define PLUGIN_NUM_INTERFACES 8
#define PLUGIN_INTERFACE_TLS 8
#define PLUGIN_NUM_INTERFACES 9

/* Retrieve the plugin module of type interface_id and name modname,
* storing the result into module. */
Expand Down Expand Up @@ -1126,6 +1127,7 @@ typedef struct krb5_preauth_context_st krb5_preauth_context;
struct ccselect_module_handle;
struct localauth_module_handle;
struct hostrealm_module_handle;
struct k5_tls_vtable_st;
struct _krb5_context {
krb5_magic magic;
krb5_enctype *in_tkt_etypes;
Expand Down Expand Up @@ -1169,6 +1171,9 @@ struct _krb5_context {
/* hostrealm module stuff */
struct hostrealm_module_handle **hostrealm_handles;

/* TLS module vtable (if loaded) */
struct k5_tls_vtable_st *tls;

/* error detail info */
struct errinfo err;

Expand Down
104 changes: 104 additions & 0 deletions src/include/k5-tls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* include/k5-tls.h - internal pluggable interface for TLS */
/*
* Copyright (C) 2014 by the Massachusetts Institute of Technology.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* This internal pluggable interface allows libkrb5 to load an in-tree module
* providing TLS support at runtime. It is currently tailored for the needs of
* the OpenSSL module as used for HTTP proxy support. As an internal
* interface, it can be changed to fit different implementations and consumers
* without regard for backward compatibility.
*/

#ifndef K5_TLS_H
#define K5_TLS_H

#include "k5-int.h"

/* An abstract type for localauth module data. */
typedef struct k5_tls_handle_st *k5_tls_handle;

typedef enum {
DATA_READ, DONE, WANT_READ, WANT_WRITE, ERROR_TLS
} k5_tls_status;

/*
* Create a handle for fd, where the server certificate must match servername
* and be trusted according to anchors. anchors is a null-terminated list
* using the DIR:/FILE:/ENV: syntax borrowed from PKINIT. If anchors is null,
* use the system default trust anchors.
*/
typedef krb5_error_code
(*k5_tls_setup_fn)(krb5_context context, SOCKET fd, const char *servername,
char **anchors, k5_tls_handle *handle_out);

/*
* Write len bytes of data using TLS. Return DONE if writing is complete,
* WANT_READ or WANT_WRITE if the underlying socket must be readable or
* writable to continue, and ERROR_TLS if the TLS channel or underlying socket
* experienced an error. After WANT_READ or WANT_WRITE, the operation will be
* retried with the same arguments even if some data has already been written.
* (OpenSSL makes this contract easy to fulfill. For other implementations we
* might want to change it.)
*/
typedef k5_tls_status
(*k5_tls_write_fn)(krb5_context context, k5_tls_handle handle,
const void *data, size_t len);

/*
* Read up to data_size bytes of data using TLS. Return DATA_READ and set
* *len_out if any data is read. Return DONE if there is no more data to be
* read on the connection, WANT_READ or WANT_WRITE if the underlying socket
* must be readable or writable to continue, and ERROR_TLS if the TLS channel
* or underlying socket experienced an error.
*
* After DATA_READ, there may still be pending buffered data to read. The
* caller must call this method again with additional buffer space before
* selecting for reading on the underlying socket.
*/
typedef k5_tls_status
(*k5_tls_read_fn)(krb5_context context, k5_tls_handle handle, void *data,
size_t data_size, size_t *len_out);

/* Release a handle. Do not pass a null pointer. */
typedef void
(*k5_tls_free_handle_fn)(krb5_context context, k5_tls_handle handle);

/* All functions are mandatory unless they are all null, in which case the
* caller should assume that TLS is unsupported. */
typedef struct k5_tls_vtable_st {
k5_tls_setup_fn setup;
k5_tls_write_fn write;
k5_tls_read_fn read;
k5_tls_free_handle_fn free_handle;
} *k5_tls_vtable;

#endif /* K5_TLS_H */
33 changes: 17 additions & 16 deletions src/include/k5-trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,23 +324,11 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
TRACE(c, "Resolving hostname {str}", hostname)
#define TRACE_SENDTO_KDC_RESPONSE(c, len, raddr) \
TRACE(c, "Received answer ({int} bytes) from {raddr}", len, raddr)
#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MISMATCH(c, hostname) \
TRACE(c, "HTTPS certificate name mismatch: server certificate is " \
"not for \"{str}\"", hostname)
#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MATCH(c, hostname) \
TRACE(c, "HTTPS certificate name matched \"{str}\"", hostname)
#define TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(c) \
TRACE(c, "HTTPS server certificate not received")
#define TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(c, depth, \
namelen, name, \
err, errs) \
TRACE(c, "HTTPS certificate error at {int} ({lenstr}): " \
"{int} ({str})", depth, namelen, name, err, errs)
#define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr) \
#define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr) \
TRACE(c, "HTTPS error connecting to {raddr}", raddr)
#define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr, err) \
TRACE(c, "HTTPS error receiving from {raddr}: {errno}", raddr, err)
#define TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(c, raddr) \
#define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr) \
TRACE(c, "HTTPS error receiving from {raddr}", raddr)
#define TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(c, raddr) \
TRACE(c, "HTTPS error sending to {raddr}", raddr)
#define TRACE_SENDTO_KDC_HTTPS_SEND(c, raddr) \
TRACE(c, "Sending HTTPS request to {raddr}", raddr)
Expand Down Expand Up @@ -383,6 +371,19 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
TRACE(c, "TGS reply didn't decode with subkey; trying session key " \
"({keyblock)}", keyblock)

#define TRACE_TLS_ERROR(c, errs) \
TRACE(c, "TLS error: {str}", errs)
#define TRACE_TLS_NO_REMOTE_CERTIFICATE(c) \
TRACE(c, "TLS server certificate not received")
#define TRACE_TLS_CERT_ERROR(c, depth, namelen, name, err, errs) \
TRACE(c, "TLS certificate error at {int} ({lenstr}): {int} ({str})", \
depth, namelen, name, err, errs)
#define TRACE_TLS_SERVER_NAME_MISMATCH(c, hostname) \
TRACE(c, "TLS certificate name mismatch: server certificate is " \
"not for \"{str}\"", hostname)
#define TRACE_TLS_SERVER_NAME_MATCH(c, hostname) \
TRACE(c, "TLS certificate name matched \"{str}\"", hostname)

#define TRACE_TKT_CREDS(c, creds, cache) \
TRACE(c, "Getting credentials {creds} using ccache {ccache}", \
creds, cache)
Expand Down
3 changes: 1 addition & 2 deletions src/lib/krb5/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ RELDIR=krb5
SHLIB_EXPDEPS = \
$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
$(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB)
SHLIB_EXPLIBS=-lk5crypto -lcom_err $(PROXY_TLS_IMPL_LIBS) $(SUPPORT_LIB) \
@GEN_LIB@ $(LIBS)
SHLIB_EXPLIBS=-lk5crypto -lcom_err $(SUPPORT_LIB) @GEN_LIB@ $(LIBS)

all-unix:: all-liblinks

Expand Down
1 change: 1 addition & 0 deletions src/lib/krb5/krb/copy_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ krb5_copy_context(krb5_context ctx, krb5_context *nctx_out)
nctx->ccselect_handles = NULL;
nctx->localauth_handles = NULL;
nctx->hostrealm_handles = NULL;
nctx->tls = NULL;
nctx->kdblog_context = NULL;
nctx->trace_callback = NULL;
nctx->trace_callback_data = NULL;
Expand Down
1 change: 1 addition & 0 deletions src/lib/krb5/krb/init_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ krb5_free_context(krb5_context ctx)
k5_localauth_free_context(ctx);
k5_plugin_free_context(ctx);
free(ctx->plugin_base_dir);
free(ctx->tls);

ctx->magic = 0;
free(ctx);
Expand Down
3 changes: 2 additions & 1 deletion src/lib/krb5/krb/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ const char *interface_names[] = {
"ccselect",
"localauth",
"hostrealm",
"audit"
"audit",
"tls"
};

/* Return the context's interface structure for id, or NULL if invalid. */
Expand Down
2 changes: 0 additions & 2 deletions src/lib/krb5/krb5_libinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ int krb5int_lib_init(void)
if (err)
return err;

k5_sendto_kdc_initialize();

return 0;
}

Expand Down
3 changes: 1 addition & 2 deletions src/lib/krb5/os/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mydir=lib$(S)krb5$(S)os
BUILDTOP=$(REL)..$(S)..$(S)..
DEFINES=-DLIBDIR=\"$(KRB5_LIBDIR)\" -DBINDIR=\"$(CLIENT_BINDIR)\" \
-DSBINDIR=\"$(ADMIN_BINDIR)\"
LOCALINCLUDES= $(PROXY_TLS_IMPL_CFLAGS) -I$(top_srcdir)/util/profile
LOCALINCLUDES= -I$(top_srcdir)/util/profile

##DOS##BUILDTOP = ..\..\..
##DOS##PREFIXDIR=os
Expand All @@ -13,7 +13,6 @@ STLIBOBJS= \
c_ustime.o \
ccdefname.o \
changepw.o \
checkhost.o \
dnsglue.o \
dnssrv.o \
expand_path.o \
Expand Down

0 comments on commit 472349d

Please sign in to comment.