# HG changeset patch # User jbe # Date 1472896946 -7200 # Node ID d39f818aff02ba70791b10a4699114d38f467efb # Parent f3988723732a10c67d57379876ccc43e34439300 Fixes for TLS extension of moonbridge_io (userdata instead of lightuserdata for TLS configuration required) diff -r f3988723732a -r d39f818aff02 moonbridge_io.c --- a/moonbridge_io.c Sat Sep 03 11:41:26 2016 +0200 +++ b/moonbridge_io.c Sat Sep 03 12:02:26 2016 +0200 @@ -54,6 +54,11 @@ #ifdef MOONBR_IO_USE_TLS #define MOONBR_IO_TLSCONF_MT_REGKEY "moonbridge_io_tlsconf" + +typedef struct { + struct tls_config *config; + int server; +} moonbr_io_tlsconf_t; #endif typedef struct { @@ -1800,7 +1805,7 @@ if (valuetype != LUA_TNIL) { \ luaL_argcheck(L, valuetype == LUA_TSTRING, 1, "field \"" field "\" is not a string"); \ value = lua_tostring(L, -1); \ - if (func(tlsconf, value)) { \ + if (func(tlsconf->config, value)) { \ lua_pushnil(L); \ lua_pushfstring(L, "Could not set " name " \"%s\"", value); \ return 2; \ @@ -1815,7 +1820,7 @@ if (valuetype != LUA_TNIL) { \ luaL_argcheck(L, valuetype == LUA_TSTRING, 1, "field \"" field "\" is not a string"); \ value = lua_tolstring(L, -1, &valuelen); \ - if (func(tlsconf, (void *)value, valuelen)) { \ + if (func(tlsconf->config, (void *)value, valuelen)) { \ lua_pushnil(L); \ lua_pushliteral(L, "Could not set " name); \ return 2; \ @@ -1824,29 +1829,22 @@ lua_pop(L, 1); static int moonbr_io_tlsconf(lua_State *L) { - struct tls_config *tlsconf; + moonbr_io_tlsconf_t *tlsconf; int valuetype; const char *value; size_t valuelen; luaL_checktype(L, 1, LUA_TTABLE); - tlsconf = tls_config_new(); - if (!tlsconf) { + tlsconf = lua_newuserdata(L, sizeof(moonbr_io_tlsconf_t)); + tlsconf->config = tls_config_new(); + if (!tlsconf->config) { return luaL_error(L, "Could not allocate memory for TLS configuration"); } - lua_pushlightuserdata(L, tlsconf); luaL_setmetatable(L, MOONBR_IO_TLSCONF_MT_REGKEY); - lua_pushvalue(L, 1); - lua_setuservalue(L, -2); -#if LUA_VERSION_NUM >= 503 - if (lua_getfield(L, 1, "mode") == LUA_TSTRING) value = lua_tostring(L, -1); -#else lua_getfield(L, 1, "mode"); - if (lua_type(L, -1) == LUA_TSTRING) value = lua_tostring(L, -1); -#endif - else value = ""; - if (strcmp(value, "server") && strcmp(value, "client")) { - luaL_argcheck(L, 0, 1, "field \"mode\" must be set to \"server\" or \"client\""); - } + value = lua_tostring(L, -1); + if (value && !strcmp(value, "server")) tlsconf->server = 1; + else if (value && !strcmp(value, "client")) tlsconf->server = 0; + else luaL_argcheck(L, 0, 1, "field \"mode\" must be set to \"server\" or \"client\""); lua_pop(L, 1); moonbr_io_tlsconf_string("CA file", "ca_file", tls_config_set_ca_file); moonbr_io_tlsconf_string("CA path", "ca_path", tls_config_set_ca_path); @@ -1861,16 +1859,11 @@ lua_getfield(L, 1, "verify_client"); #endif if (lua_toboolean(L, -1)) { -#if LUA_VERSION_NUM >= 503 - if (valuetype == LUA_TSTRING) value = lua_tostring(L, -1); -#else - if (lua_type(L, -1) == LUA_TSTRING) value = lua_tostring(L, -1); -#endif - else value = ""; - if (!strcmp(value, "required")) { - tls_config_verify_client(tlsconf); - } else if (!strcmp(value, "optional")) { - tls_config_verify_client_optional(tlsconf); + value = lua_tostring(L, -1); + if (value && !strcmp(value, "required")) { + tls_config_verify_client(tlsconf->config); + } else if (value && !strcmp(value, "optional")) { + tls_config_verify_client_optional(tlsconf->config); } else { luaL_argcheck(L, 0, 1, "field \"verify_client\" must be set to \"required\", \"optional\", or be false or nil"); } @@ -1879,45 +1872,19 @@ return 1; } -static int moonbr_io_tlsconfindex(lua_State *L) { - struct tls_config *tlsconf; +static int moonbr_io_tlsconfgc(lua_State *L) { + moonbr_io_tlsconf_t *tlsconf; tlsconf = luaL_checkudata(L, 1, MOONBR_IO_TLSCONF_MT_REGKEY); - luaL_checkany(L, 2); -#if LUA_VERSION_NUM >= 503 - if (lua_getuservalue(L, 1) == LUA_TNIL) { -#else - lua_getuservalue(L, 1); - if (lua_isnil(L, -1)) { -#endif - return luaL_error(L, "Attempt to use a destroyed TLS configuration"); - } - lua_pushvalue(L, 2); - lua_gettable(L, -2); - return 1; -} - -static int moonbr_io_tlsconfgc(lua_State *L) { - struct tls_config *tlsconf; - tlsconf = luaL_checkudata(L, 1, MOONBR_IO_TLSCONF_MT_REGKEY); -#if LUA_VERSION_NUM >= 503 - if (lua_getuservalue(L, 1) == LUA_TNIL) return 0; -#else - lua_getuservalue(L, 1); - if (lua_isnil(L, -1)) return 0; -#endif - tls_config_free(tlsconf); - lua_pushnil(L); - lua_setuservalue(L, 1); + if (tlsconf->config) tls_config_free(tlsconf->config); + tlsconf->config = NULL; return 0; } static int moonbr_io_starttls(lua_State *L) { moonbr_io_handle_t *handle; - struct tls_config *tlsconf; - const char *mode; + moonbr_io_tlsconf_t *tlsconf; const char *servername; struct tls *tls, *tls2; - int is_server = 0; handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); if (lua_type(L, 2) == LUA_TTABLE) { lua_pushcfunction(L, moonbr_io_tlsconf); @@ -1936,26 +1903,16 @@ if (handle->readbufin || handle->writebufin) { return luaL_error(L, "Attempt to start TLS on an I/O handle with non-empty buffers"); } - lua_getfield(L, 2, "mode"); - mode = lua_tostring(L, -1); - if (mode && !strcmp(mode, "server")) { - lua_pop(L, 1); - tls = tls_server(); - is_server = 1; - } else if (mode && !strcmp(mode, "client")) { - lua_pop(L, 1); + if (tlsconf->server) tls = tls_server(); + else { servername = luaL_checkstring(L, 3); tls = tls_client(); - } else { - /* shouldn't happen unless table has been modified */ - lua_pop(L, 1); - return luaL_error(L, "Field \"mode\" of TLS configuration is neither set to \"server\" nor \"client\""); } if (!tls) { return luaL_error(L, "Could not allocate memory for TLS context"); } - if (tls_configure(tls, tlsconf)) goto moonbr_io_starttls_error; - if (is_server) { + if (tls_configure(tls, tlsconf->config)) goto moonbr_io_starttls_error; + if (tlsconf->server) { if (tls_accept_socket(tls, &tls2, handle->fd)) goto moonbr_io_starttls_error; handle->servertls = tls; handle->tls = tls2; @@ -2053,7 +2010,6 @@ #ifdef MOONBR_IO_USE_TLS static const struct luaL_Reg moonbr_io_tlsconf_metamethods[] = { - {"__index", moonbr_io_tlsconfindex}, {"__gc", moonbr_io_tlsconfgc}, {NULL, NULL} };