[mod_openssl] new module (preliminary layout)
parent
cb7ed13621
commit
cb9ebe9fa6
|
@ -229,7 +229,7 @@ if 1:
|
|||
autoconf.env.Append( LIBSQLITE3 = '', LIBXML2 = '', LIBMYSQL = '', LIBZ = '',
|
||||
LIBBZ2 = '', LIBCRYPT = '', LIBMEMCACHED = '', LIBFCGI = '', LIBPCRE = '',
|
||||
LIBLDAP = '', LIBLBER = '', LIBLUA = '', LIBDL = '', LIBUUID = '',
|
||||
LIBKRB5 = '', LIBGSSAPI_KRB5 = '', LIBGDBM = '')
|
||||
LIBKRB5 = '', LIBGSSAPI_KRB5 = '', LIBGDBM = '', LIBSSL = '', LIBCRYPTO = '')
|
||||
|
||||
if env['with_fam']:
|
||||
if autoconf.CheckLibWithHeader('fam', 'fam.h', 'C'):
|
||||
|
@ -253,7 +253,7 @@ if 1:
|
|||
|
||||
if env['with_openssl']:
|
||||
if autoconf.CheckLibWithHeader('ssl', 'openssl/ssl.h', 'C'):
|
||||
autoconf.env.Append(CPPFLAGS = [ '-DHAVE_OPENSSL_SSL_H', '-DHAVE_LIBSSL'] , LIBS = [ 'ssl', 'crypto' ])
|
||||
autoconf.env.Append(CPPFLAGS = [ '-DHAVE_OPENSSL_SSL_H', '-DHAVE_LIBSSL'] , LIBSSL = 'ssl', LIBCRYPTO = 'crypto', LIBS = [ 'ssl', 'crypto' ])
|
||||
|
||||
if env['with_gzip']:
|
||||
if autoconf.CheckLibWithHeader('z', 'zlib.h', 'C'):
|
||||
|
|
|
@ -383,6 +383,7 @@ else
|
|||
use_openssl=no
|
||||
fi
|
||||
AC_MSG_RESULT([$use_openssl])
|
||||
AM_CONDITIONAL(BUILD_WITH_OPENSSL, test ! $WITH_OPENSSL = no)
|
||||
|
||||
AC_ARG_WITH(openssl-includes,
|
||||
AC_HELP_STRING([--with-openssl-includes=DIR],[OpenSSL includes]),
|
||||
|
@ -403,10 +404,12 @@ if test "x$use_openssl" = "xyes"; then
|
|||
OLDLIBS="$LIBS"
|
||||
AC_CHECK_LIB(crypto, BIO_f_base64, [
|
||||
AC_CHECK_LIB(ssl, SSL_new, [ SSL_LIB="-lssl -lcrypto"
|
||||
CRYPTO_LIB="-lcrypto"
|
||||
AC_DEFINE(HAVE_LIBSSL, [], [Have libssl]) ], [], [ -lcrypto "$DL_LIB" ])
|
||||
], [], [])
|
||||
LIBS="$OLDLIBS"
|
||||
AC_SUBST(SSL_LIB)
|
||||
AC_SUBST(CRYPTO_LIB)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for perl regular expressions support)
|
||||
|
|
|
@ -774,6 +774,9 @@ endif()
|
|||
if(HAVE_LIBSSL AND HAVE_LIBCRYPTO)
|
||||
target_link_libraries(lighttpd ssl)
|
||||
target_link_libraries(lighttpd crypto)
|
||||
add_and_install_library(mod_openssl "mod_openssl.c")
|
||||
set(L_MOD_OPENSSL ${L_MOD_OPENSSL} ssl crypto)
|
||||
target_link_libraries(mod_openssl ${L_MOD_OPENSSL})
|
||||
endif()
|
||||
|
||||
if(WITH_LIBEV)
|
||||
|
|
|
@ -300,6 +300,13 @@ mod_authn_mysql_la_LIBADD = $(CRYPT_LIB) $(MYSQL_LIBS) $(common_libadd)
|
|||
mod_authn_mysql_la_CPPFLAGS = $(MYSQL_INCLUDE)
|
||||
endif
|
||||
|
||||
if BUILD_WITH_OPENSSL
|
||||
lib_LTLIBRARIES += mod_openssl.la
|
||||
mod_openssl_la_SOURCES = mod_openssl.c
|
||||
mod_openssl_la_LDFLAGS = $(common_module_ldflags)
|
||||
mod_openssl_la_LIBADD = $(SSL_LIB) $(common_libadd)
|
||||
endif
|
||||
|
||||
lib_LTLIBRARIES += mod_rewrite.la
|
||||
mod_rewrite_la_SOURCES = mod_rewrite.c
|
||||
mod_rewrite_la_LDFLAGS = $(common_module_ldflags)
|
||||
|
@ -416,6 +423,10 @@ lighttpd_SOURCES += mod_authn_mysql.c mod_mysql_vhost.c
|
|||
lighttpd_CPPFLAGS += $(MYSQL_INCLUDE)
|
||||
lighttpd_LDADD += $(MYSQL_LIBS)
|
||||
endif
|
||||
if BUILD_WITH_OPENSSL
|
||||
lighttpd_SOURCES += mod_openssl.c
|
||||
lighttpd_LDADD += $(SSL_LIB)
|
||||
endif
|
||||
if BUILD_WITH_MEMCACHED
|
||||
lighttpd_CPPFLAGS += $(MEMCACHED_CFLAGS)
|
||||
lighttpd_LDADD += $(MEMCACHED_LIB)
|
||||
|
|
|
@ -147,6 +147,9 @@ if env['with_mysql']:
|
|||
modules['mod_authn_mysql'] = { 'src' : [ 'mod_authn_mysql.c' ], 'lib' : [ env['LIBCRYPT'], env['LIBMYSQL'] ] }
|
||||
modules['mod_mysql_vhost'] = { 'src' : [ 'mod_mysql_vhost.c' ], 'lib' : [ env['LIBMYSQL'] ] }
|
||||
|
||||
if env['with_openssl']:
|
||||
modules['mod_openssl'] = { 'src' : [ 'mod_openssl.c' ], 'lib' : [ env['LIBSSL'], env['LIBCRYPTO'] ] }
|
||||
|
||||
staticenv = env.Clone(CPPFLAGS=[ env['CPPFLAGS'], '-DLIGHTTPD_STATIC' ])
|
||||
|
||||
## all the core-sources + the modules
|
||||
|
|
|
@ -46,6 +46,25 @@ static void config_warn_authn_module (server *srv, const char *module) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
|
||||
static void config_warn_openssl_module (server *srv) {
|
||||
for (size_t i = 0; i < srv->config_context->used; ++i) {
|
||||
const data_config *config = (data_config const*)srv->config_context->data[i];
|
||||
for (size_t j = 0; j < config->value->used; ++j) {
|
||||
data_unset *du = config->value->data[j];
|
||||
if (0 == strncmp(du->key->ptr, "ssl.", sizeof("ssl.")-1)) {
|
||||
/* mod_openssl should be loaded after mod_extforward */
|
||||
data_string *ds = data_string_init();
|
||||
buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_openssl"));
|
||||
array_insert_unique(srv->srvconf.modules, (data_unset *)ds);
|
||||
log_error_write(srv, __FILE__, __LINE__, "S", "Warning: please add \"mod_openssl\" to server.modules list in lighttpd.conf. A future release of lighttpd 1.4.x *will not* automatically load mod_openssl and lighttpd *will not* use SSL/TLS where your lighttpd.conf contains ssl.* directives");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int config_insert(server *srv) {
|
||||
size_t i;
|
||||
int ret = 0;
|
||||
|
@ -372,6 +391,7 @@ static int config_insert(server *srv) {
|
|||
int append_mod_authn_file = 1;
|
||||
int append_mod_authn_ldap = 1;
|
||||
int append_mod_authn_mysql = 1;
|
||||
int append_mod_openssl = 1;
|
||||
int contains_mod_auth = 0;
|
||||
|
||||
/* prepend default modules */
|
||||
|
@ -390,6 +410,10 @@ static int config_insert(server *srv) {
|
|||
append_mod_dirlisting = 0;
|
||||
}
|
||||
|
||||
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_openssl"))) {
|
||||
append_mod_openssl = 0;
|
||||
}
|
||||
|
||||
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_authn_file"))) {
|
||||
append_mod_authn_file = 0;
|
||||
}
|
||||
|
@ -409,6 +433,7 @@ static int config_insert(server *srv) {
|
|||
if (0 == prepend_mod_indexfile &&
|
||||
0 == append_mod_dirlisting &&
|
||||
0 == append_mod_staticfile &&
|
||||
0 == append_mod_openssl &&
|
||||
0 == append_mod_authn_file &&
|
||||
0 == append_mod_authn_ldap &&
|
||||
0 == append_mod_authn_mysql &&
|
||||
|
@ -447,6 +472,12 @@ static int config_insert(server *srv) {
|
|||
array_insert_unique(srv->srvconf.modules, (data_unset *)ds);
|
||||
}
|
||||
|
||||
if (append_mod_openssl) {
|
||||
#if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
|
||||
config_warn_openssl_module(srv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* mod_auth.c,http_auth.c auth backends were split into separate modules
|
||||
* Automatically load auth backend modules for compatibility with
|
||||
* existing lighttpd 1.4.x configs */
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
#include "first.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef USE_OPENSSL_KERBEROS
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
#define OPENSSL_NO_KRB5
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "base.h"
|
||||
#include "log.h"
|
||||
#include "plugin.h"
|
||||
|
||||
typedef struct {
|
||||
int dummy;
|
||||
} plugin_config;
|
||||
|
||||
typedef struct {
|
||||
PLUGIN_DATA;
|
||||
plugin_config **config_storage;
|
||||
plugin_config conf;
|
||||
} plugin_data;
|
||||
|
||||
typedef struct {
|
||||
SSL *ssl;
|
||||
buffer *tlsext_server_name;
|
||||
unsigned int renegotiations; /* count of SSL_CB_HANDSHAKE_START */
|
||||
int request_env_patched;
|
||||
plugin_config conf;
|
||||
} handler_ctx;
|
||||
|
||||
|
||||
static handler_ctx *
|
||||
handler_ctx_init (void)
|
||||
{
|
||||
handler_ctx *hctx = calloc(1, sizeof(*hctx));
|
||||
force_assert(hctx);
|
||||
return hctx;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
handler_ctx_free (handler_ctx *hctx)
|
||||
{
|
||||
buffer_free(hctx->tlsext_server_name);
|
||||
free(hctx);
|
||||
}
|
||||
|
||||
|
||||
INIT_FUNC(mod_openssl_init)
|
||||
{
|
||||
return calloc(1, sizeof(plugin_data));
|
||||
}
|
||||
|
||||
|
||||
FREE_FUNC(mod_openssl_free)
|
||||
{
|
||||
plugin_data *p = p_d;
|
||||
if (!p) return HANDLER_GO_ON;
|
||||
|
||||
if (p->config_storage) {
|
||||
for (size_t i = 0; i < srv->config_context->used; ++i) {
|
||||
plugin_config *s = p->config_storage[i];
|
||||
if (NULL == s) continue;
|
||||
|
||||
free(s);
|
||||
}
|
||||
free(p->config_storage);
|
||||
}
|
||||
|
||||
free(p);
|
||||
|
||||
UNUSED(srv);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
SETDEFAULTS_FUNC(mod_openssl_set_defaults)
|
||||
{
|
||||
UNUSED(srv);
|
||||
UNUSED(p_d);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
#define PATCH(x) \
|
||||
p->conf.x = s->x;
|
||||
static int
|
||||
mod_openssl_patch_connection (server *srv, connection *con, handler_ctx *p)
|
||||
{
|
||||
UNUSED(srv);
|
||||
UNUSED(con);
|
||||
UNUSED(p);
|
||||
return 0;
|
||||
}
|
||||
#undef PATCH
|
||||
|
||||
|
||||
CONNECTION_FUNC(mod_openssl_handle_con_accept)
|
||||
{
|
||||
server_socket *srv_sock = con->srv_socket;
|
||||
if (!srv_sock->is_ssl) return HANDLER_GO_ON;
|
||||
|
||||
{
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = handler_ctx_init();
|
||||
con->plugin_ctx[p->id] = hctx;
|
||||
mod_openssl_patch_connection(srv, con, hctx);
|
||||
}
|
||||
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
CONNECTION_FUNC(mod_openssl_handle_con_shut_wr)
|
||||
{
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = con->plugin_ctx[p->id];
|
||||
if (NULL == hctx) return HANDLER_GO_ON;
|
||||
|
||||
UNUSED(srv);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
CONNECTION_FUNC(mod_openssl_handle_con_close)
|
||||
{
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = con->plugin_ctx[p->id];
|
||||
if (NULL == hctx) return HANDLER_GO_ON;
|
||||
|
||||
handler_ctx_free(hctx);
|
||||
|
||||
UNUSED(srv);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
CONNECTION_FUNC(mod_openssl_handle_request_env)
|
||||
{
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = con->plugin_ctx[p->id];
|
||||
if (NULL == hctx) return HANDLER_GO_ON;
|
||||
if (hctx->request_env_patched) return HANDLER_GO_ON;
|
||||
hctx->request_env_patched = 1;
|
||||
|
||||
UNUSED(srv);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
CONNECTION_FUNC(mod_openssl_handle_uri_raw)
|
||||
{
|
||||
/* mod_openssl must be loaded prior to mod_auth
|
||||
* if mod_openssl is configured to set REMOTE_USER based on client cert */
|
||||
/* mod_openssl must be loaded after mod_extforward
|
||||
* if mod_openssl config is based on lighttpd.conf remote IP conditional
|
||||
* using remote IP address set by mod_extforward */
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = con->plugin_ctx[p->id];
|
||||
if (NULL == hctx) return HANDLER_GO_ON;
|
||||
|
||||
if (con->conf.ssl_verifyclient) {
|
||||
mod_openssl_handle_request_env(srv, con, p);
|
||||
}
|
||||
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
CONNECTION_FUNC(mod_openssl_handle_request_reset)
|
||||
{
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = con->plugin_ctx[p->id];
|
||||
if (NULL == hctx) return HANDLER_GO_ON;
|
||||
|
||||
/*
|
||||
* XXX: preserve (for now) lighttpd historical behavior which resets
|
||||
* tlsext_server_name after each request, meaning SNI is valid only for
|
||||
* initial request, prior to reading request headers. Probably should
|
||||
* instead validate that Host header (or authority in request line)
|
||||
* matches SNI server name for all requests on the connection on which
|
||||
* SNI extension has been provided.
|
||||
*/
|
||||
buffer_reset(hctx->tlsext_server_name);
|
||||
hctx->request_env_patched = 0;
|
||||
|
||||
UNUSED(srv);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
int mod_openssl_plugin_init (plugin *p);
|
||||
int mod_openssl_plugin_init (plugin *p)
|
||||
{
|
||||
p->version = LIGHTTPD_VERSION_ID;
|
||||
p->name = buffer_init_string("openssl");
|
||||
p->init = mod_openssl_init;
|
||||
p->cleanup = mod_openssl_free;
|
||||
p->set_defaults = mod_openssl_set_defaults;
|
||||
|
||||
p->handle_connection_accept = mod_openssl_handle_con_accept;
|
||||
p->handle_connection_shut_wr = mod_openssl_handle_con_shut_wr;
|
||||
p->handle_connection_close = mod_openssl_handle_con_close;
|
||||
p->handle_uri_raw = mod_openssl_handle_uri_raw;
|
||||
p->handle_request_env = mod_openssl_handle_request_env;
|
||||
p->connection_reset = mod_openssl_handle_request_reset;
|
||||
|
||||
p->data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue