From 903efaf3b1f090a992963480fa2924dac02f9174 Mon Sep 17 00:00:00 2001 From: Bruno Silvestre Date: Mon, 21 Apr 2014 13:20:17 -0300 Subject: [PATCH] SNI support. --- Makefile | 16 +++++------ src/Makefile | 19 +++++++------ src/ssl.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/ssl.lua | 2 +- 4 files changed, 91 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index c8aa90f..fb61cde 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,19 @@ # Inform the location to intall the modules -LUAPATH ?= /usr/share/lua/5.1 -LUACPATH ?= /usr/lib/lua/5.1 +LUAPATH ?= /usr/share/lua/5.1 +LUACPATH ?= /usr/lib/lua/5.1 # Compile with build-in LuaSocket's help files. # Comment this lines if you will link with non-internal LuaSocket's help files # and edit INCDIR and LIBDIR properly. -EXTRA = luasocket -DEFS = -DWITH_LUASOCKET +EXTRA = luasocket +DEFS = -DWITH_LUASOCKET # Edit the lines below to inform new path, if necessary. # Path below points to internal LuaSocket's help files. -INC_PATH ?= -I/usr/include -LIB_PATH ?= -L/usr/lib -INCDIR = -I. $(INC_PATH) -LIBDIR = -L./luasocket $(LIB_PATH) +INC_PATH ?= -I/usr/include +LIB_PATH ?= -L/usr/lib +INCDIR = -I. $(INC_PATH) +LIBDIR = -L./luasocket $(LIB_PATH) # For Mac OS X: set the system version MACOSX_VERSION=10.4 diff --git a/src/Makefile b/src/Makefile index 7c94870..727794b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,22 +20,21 @@ MAC_ENV=env MACOSX_DEPLOYMENT_TARGET='$(MACVER)' MAC_CFLAGS=-O2 -fno-common $(WARN) $(INCDIR) $(DEFS) MAC_LDFLAGS=-bundle -undefined dynamic_lookup $(LIBDIR) -INSTALL ?= install -CC ?= cc -LD ?= $(MYENV) cc -CFLAGS += $(MYCFLAGS) -LDFLAGS += $(MYLDFLAGS) -DESTDIR ?= / +INSTALL = install +CC = cc +LD = $(MYENV) cc +CFLAGS += $(MYCFLAGS) +LDFLAGS += $(MYLDFLAGS) .PHONY: all clean install none linux bsd macosx luasocket all: install: $(CMOD) $(LMOD) - $(INSTALL) -d $(DESTDIR)$(LUAPATH)/ssl $(DESTDIR)$(LUACPATH) - $(INSTALL) -D $(CMOD) $(DESTDIR)$(LUACPATH) - $(INSTALL) -m644 -D $(LMOD) $(DESTDIR)$(LUAPATH) - $(INSTALL) -m644 -D https.lua $(DESTDIR)$(LUAPATH)/ssl + $(INSTALL) -d $(LUAPATH)/ssl $(LUACPATH) + $(INSTALL) $(CMOD) $(LUACPATH) + $(INSTALL) -m644 $(LMOD) $(LUAPATH) + $(INSTALL) -m644 https.lua $(LUAPATH)/ssl linux: @$(MAKE) $(CMOD) MYCFLAGS="$(LNX_CFLAGS)" MYLDFLAGS="$(LNX_LDFLAGS)" EXTRA="$(EXTRA)" diff --git a/src/ssl.c b/src/ssl.c index 2fa6ede..92d0881 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -28,6 +28,7 @@ #include #include "x509.h" +#include "context.h" #include "ssl.h" /** @@ -80,11 +81,15 @@ static int meth_destroy(lua_State *L) } ssl->state = LSEC_STATE_CLOSED; if (ssl->ssl) { - /* Clear the registry */ + /* Clear the registries */ luaL_getmetatable(L, "SSL:Verify:Registry"); lua_pushlightuserdata(L, (void*)ssl->ssl); lua_pushnil(L); lua_settable(L, -3); + luaL_getmetatable(L, "SSL:SNI:Registry"); + lua_pushlightuserdata(L, (void*)ssl->ssl); + lua_pushnil(L); + lua_settable(L, -3); /* Destroy the object */ SSL_free(ssl->ssl); ssl->ssl = NULL; @@ -653,6 +658,67 @@ static int meth_info(lua_State *L) return 4; } +static int sni_cb(SSL *ssl, int *ad, void *arg) +{ + SSL_CTX *newctx = NULL; + SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); + lua_State *L = ((p_context)SSL_CTX_get_app_data(ctx))->L; + const char *name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); + /* No name, use default context */ + if (!name) + return SSL_TLSEXT_ERR_NOACK; + /* Search for the name in the map */ + luaL_getmetatable(L, "SSL:SNI:Registry"); + lua_pushlightuserdata(L, (void*)ssl); + lua_gettable(L, -2); + lua_pushstring(L, name); + lua_gettable(L, -2); + if (lua_isuserdata(L, -1)) + newctx = lsec_checkcontext(L, -1); + lua_pop(L, 3); + if (newctx) { + SSL_set_SSL_CTX(ssl, newctx); + return SSL_TLSEXT_ERR_OK; + } + return SSL_TLSEXT_ERR_ALERT_FATAL; +} + +static int meth_sni(lua_State *L) +{ + SSL_CTX *aux; + const char *name; + p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); + SSL_CTX *ctx = SSL_get_SSL_CTX(ssl->ssl); + p_context pctx = (p_context)SSL_CTX_get_app_data(ctx); + switch (pctx->mode) { + case LSEC_MODE_CLIENT: + name = luaL_checkstring(L, 2); + SSL_set_tlsext_host_name(ssl->ssl, name); + break; + case LSEC_MODE_SERVER: + luaL_checktype(L, 2, LUA_TTABLE); + /* Check if the table contains only (string -> context) */ + lua_pushnil(L); + while (lua_next(L, 2)) { + luaL_checkstring(L, 3); + aux = lsec_checkcontext(L, 4); + /* Set callback in every context */ + SSL_CTX_set_tlsext_servername_callback(aux, sni_cb); + /* leave the next key on the stack */ + lua_pop(L, 1); + } + /* Save table in the register */ + luaL_getmetatable(L, "SSL:SNI:Registry"); + lua_pushlightuserdata(L, (void*)ssl->ssl); + lua_pushvalue(L, 2); + lua_settable(L, -3); + /* Set callback in the default context */ + SSL_CTX_set_tlsext_servername_callback(ctx, sni_cb); + break; + } + return 0; +} + static int meth_copyright(lua_State *L) { lua_pushstring(L, "LuaSec 0.5 - Copyright (C) 2006-2011 Bruno Silvestre" @@ -683,6 +749,7 @@ static luaL_Reg methods[] = { {"receive", meth_receive}, {"send", meth_send}, {"settimeout", meth_settimeout}, + {"sni", meth_sni}, {"want", meth_want}, {NULL, NULL} }; @@ -727,7 +794,9 @@ LSEC_API int luaopen_ssl_core(lua_State *L) /* Initialize internal library */ socket_open(); #endif - + + luaL_newmetatable(L, "SSL:SNI:Registry"); + /* Register the functions and tables */ luaL_newmetatable(L, "SSL:Connection"); luaL_register(L, NULL, meta); @@ -758,6 +827,8 @@ LSEC_API int luaopen_ssl_core(lua_State *L) socket_open(); #endif + luaL_newmetatable(L, "SSL:SNI:Registry"); + /* Register the functions and tables */ luaL_newmetatable(L, "SSL:Connection"); luaL_setfuncs(L, meta, 0); diff --git a/src/ssl.lua b/src/ssl.lua index 0b465e2..220b8dc 100644 --- a/src/ssl.lua +++ b/src/ssl.lua @@ -10,7 +10,7 @@ local x509 = require("ssl.x509") module("ssl", package.seeall) -_VERSION = "0.5.PR" +_VERSION = "0.5" _COPYRIGHT = core.copyright() -- Export