mirror of
https://github.com/brunoos/luasec.git
synced 2024-12-28 05:18:21 +01:00
- Add a parameter to server:sni(), so that we can accept an unknown name, using the initial context.
- Add the method :getsniname() to retrieve the SNI hostname used.
This commit is contained in:
parent
903efaf3b1
commit
84cb83b92f
@ -19,7 +19,8 @@ conn = ssl.wrap(conn, params)
|
|||||||
|
|
||||||
-- Comment the lines to not send a name
|
-- Comment the lines to not send a name
|
||||||
--conn:sni("servera.br")
|
--conn:sni("servera.br")
|
||||||
conn:sni("serveraa.br")
|
--conn:sni("serveraa.br")
|
||||||
|
conn:sni("serverb.br")
|
||||||
|
|
||||||
assert(conn:dohandshake())
|
assert(conn:dohandshake())
|
||||||
--
|
--
|
||||||
|
@ -39,10 +39,12 @@ local conn = server:accept()
|
|||||||
conn = ssl.wrap(conn, ctx01)
|
conn = ssl.wrap(conn, ctx01)
|
||||||
|
|
||||||
-- Configure the name map
|
-- Configure the name map
|
||||||
conn:sni({
|
local sni_map = {
|
||||||
["servera.br"] = ctx01,
|
["servera.br"] = ctx01,
|
||||||
["serveraa.br"] = ctx02,
|
["serveraa.br"] = ctx02,
|
||||||
})
|
}
|
||||||
|
|
||||||
|
conn:sni(sni_map, true)
|
||||||
|
|
||||||
assert(conn:dohandshake())
|
assert(conn:dohandshake())
|
||||||
--
|
--
|
||||||
|
49
src/ssl.c
49
src/ssl.c
@ -660,6 +660,7 @@ static int meth_info(lua_State *L)
|
|||||||
|
|
||||||
static int sni_cb(SSL *ssl, int *ad, void *arg)
|
static int sni_cb(SSL *ssl, int *ad, void *arg)
|
||||||
{
|
{
|
||||||
|
int strict;
|
||||||
SSL_CTX *newctx = NULL;
|
SSL_CTX *newctx = NULL;
|
||||||
SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
|
SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
|
||||||
lua_State *L = ((p_context)SSL_CTX_get_app_data(ctx))->L;
|
lua_State *L = ((p_context)SSL_CTX_get_app_data(ctx))->L;
|
||||||
@ -667,41 +668,54 @@ static int sni_cb(SSL *ssl, int *ad, void *arg)
|
|||||||
/* No name, use default context */
|
/* No name, use default context */
|
||||||
if (!name)
|
if (!name)
|
||||||
return SSL_TLSEXT_ERR_NOACK;
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
/* Search for the name in the map */
|
/* Retrieve struct from registry */
|
||||||
luaL_getmetatable(L, "SSL:SNI:Registry");
|
luaL_getmetatable(L, "SSL:SNI:Registry");
|
||||||
lua_pushlightuserdata(L, (void*)ssl);
|
lua_pushlightuserdata(L, (void*)ssl);
|
||||||
lua_gettable(L, -2);
|
lua_gettable(L, -2);
|
||||||
|
/* Strict search? */
|
||||||
|
lua_pushstring(L, "strict");
|
||||||
|
lua_gettable(L, -2);
|
||||||
|
strict = lua_toboolean(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
/* Search for the name in the map */
|
||||||
|
lua_pushstring(L, "map");
|
||||||
|
lua_gettable(L, -2);
|
||||||
lua_pushstring(L, name);
|
lua_pushstring(L, name);
|
||||||
lua_gettable(L, -2);
|
lua_gettable(L, -2);
|
||||||
if (lua_isuserdata(L, -1))
|
if (lua_isuserdata(L, -1))
|
||||||
newctx = lsec_checkcontext(L, -1);
|
newctx = lsec_checkcontext(L, -1);
|
||||||
lua_pop(L, 3);
|
lua_pop(L, 4);
|
||||||
|
/* Found, use this context */
|
||||||
if (newctx) {
|
if (newctx) {
|
||||||
SSL_set_SSL_CTX(ssl, newctx);
|
SSL_set_SSL_CTX(ssl, newctx);
|
||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
}
|
}
|
||||||
|
/* Not found, but use initial context */
|
||||||
|
if (!strict)
|
||||||
|
return SSL_TLSEXT_ERR_OK;
|
||||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int meth_sni(lua_State *L)
|
static int meth_sni(lua_State *L)
|
||||||
{
|
{
|
||||||
|
int strict;
|
||||||
SSL_CTX *aux;
|
SSL_CTX *aux;
|
||||||
const char *name;
|
const char *name;
|
||||||
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
|
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
|
||||||
SSL_CTX *ctx = SSL_get_SSL_CTX(ssl->ssl);
|
SSL_CTX *ctx = SSL_get_SSL_CTX(ssl->ssl);
|
||||||
p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
|
p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
|
||||||
switch (pctx->mode) {
|
if (pctx->mode == LSEC_MODE_CLIENT) {
|
||||||
case LSEC_MODE_CLIENT:
|
|
||||||
name = luaL_checkstring(L, 2);
|
name = luaL_checkstring(L, 2);
|
||||||
SSL_set_tlsext_host_name(ssl->ssl, name);
|
SSL_set_tlsext_host_name(ssl->ssl, name);
|
||||||
break;
|
return 0;
|
||||||
case LSEC_MODE_SERVER:
|
} else if (pctx->mode == LSEC_MODE_SERVER) {
|
||||||
luaL_checktype(L, 2, LUA_TTABLE);
|
luaL_checktype(L, 2, LUA_TTABLE);
|
||||||
|
strict = lua_toboolean(L, 3);
|
||||||
/* Check if the table contains only (string -> context) */
|
/* Check if the table contains only (string -> context) */
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, 2)) {
|
while (lua_next(L, 2)) {
|
||||||
luaL_checkstring(L, 3);
|
luaL_checkstring(L, -2);
|
||||||
aux = lsec_checkcontext(L, 4);
|
aux = lsec_checkcontext(L, -1);
|
||||||
/* Set callback in every context */
|
/* Set callback in every context */
|
||||||
SSL_CTX_set_tlsext_servername_callback(aux, sni_cb);
|
SSL_CTX_set_tlsext_servername_callback(aux, sni_cb);
|
||||||
/* leave the next key on the stack */
|
/* leave the next key on the stack */
|
||||||
@ -710,15 +724,31 @@ static int meth_sni(lua_State *L)
|
|||||||
/* Save table in the register */
|
/* Save table in the register */
|
||||||
luaL_getmetatable(L, "SSL:SNI:Registry");
|
luaL_getmetatable(L, "SSL:SNI:Registry");
|
||||||
lua_pushlightuserdata(L, (void*)ssl->ssl);
|
lua_pushlightuserdata(L, (void*)ssl->ssl);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushstring(L, "map");
|
||||||
lua_pushvalue(L, 2);
|
lua_pushvalue(L, 2);
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
|
lua_pushstring(L, "strict");
|
||||||
|
lua_pushboolean(L, strict);
|
||||||
|
lua_settable(L, -3);
|
||||||
|
lua_settable(L, -3);
|
||||||
/* Set callback in the default context */
|
/* Set callback in the default context */
|
||||||
SSL_CTX_set_tlsext_servername_callback(ctx, sni_cb);
|
SSL_CTX_set_tlsext_servername_callback(ctx, sni_cb);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int meth_getsniname(lua_State *L)
|
||||||
|
{
|
||||||
|
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
|
||||||
|
const char *name = SSL_get_servername(ssl->ssl, TLSEXT_NAMETYPE_host_name);
|
||||||
|
if (name)
|
||||||
|
lua_pushstring(L, name);
|
||||||
|
else
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int meth_copyright(lua_State *L)
|
static int meth_copyright(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_pushstring(L, "LuaSec 0.5 - Copyright (C) 2006-2011 Bruno Silvestre"
|
lua_pushstring(L, "LuaSec 0.5 - Copyright (C) 2006-2011 Bruno Silvestre"
|
||||||
@ -742,6 +772,7 @@ static luaL_Reg methods[] = {
|
|||||||
{"getpeerchain", meth_getpeerchain},
|
{"getpeerchain", meth_getpeerchain},
|
||||||
{"getpeerverification", meth_getpeerverification},
|
{"getpeerverification", meth_getpeerverification},
|
||||||
{"getpeerfinished", meth_getpeerfinished},
|
{"getpeerfinished", meth_getpeerfinished},
|
||||||
|
{"getsniname", meth_getsniname},
|
||||||
{"getstats", meth_getstats},
|
{"getstats", meth_getstats},
|
||||||
{"setstats", meth_setstats},
|
{"setstats", meth_setstats},
|
||||||
{"dirty", meth_dirty},
|
{"dirty", meth_dirty},
|
||||||
|
Loading…
Reference in New Issue
Block a user