@@ -32,6 +32,7 @@ static int ngx_stream_lua_socket_tcp_bind(lua_State *L);
3232static int ngx_stream_lua_socket_tcp_connect (lua_State * L );
3333#if (NGX_STREAM_SSL )
3434static int ngx_stream_lua_socket_tcp_sslhandshake (lua_State * L );
35+ static int ngx_stream_lua_socket_tcp_serversslhandshake (lua_State * L );
3536#endif
3637static int ngx_stream_lua_socket_tcp_receive (lua_State * L );
3738static int ngx_stream_lua_socket_tcp_receiveany (lua_State * L );
@@ -181,6 +182,12 @@ static int ngx_stream_lua_ssl_handshake_retval_handler(
181182 ngx_stream_lua_request_t * r , ngx_stream_lua_socket_tcp_upstream_t * u ,
182183 lua_State * L );
183184static void ngx_stream_lua_ssl_handshake_handler (ngx_connection_t * c );
185+ static int ngx_stream_lua_server_ssl_handshake_retval_handler (
186+ ngx_stream_lua_request_t * r , ngx_stream_lua_socket_tcp_upstream_t * u ,
187+ lua_State * L );
188+ static void ngx_stream_lua_ssl_handshake_session_info (ngx_connection_t * c ,
189+ lua_State * L );
190+ static void ngx_stream_lua_server_ssl_handshake_handler (ngx_connection_t * c );
184191static int ngx_stream_lua_ssl_free_session (lua_State * L );
185192#endif
186193static void ngx_stream_lua_socket_tcp_close_connection (ngx_connection_t * c );
@@ -327,6 +334,13 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
327334 lua_pushcfunction (L , ngx_stream_lua_socket_tcp_shutdown );
328335 lua_setfield (L , -2 , "shutdown" );
329336
337+ #if (NGX_STREAM_SSL )
338+
339+ lua_pushcfunction (L , ngx_stream_lua_socket_tcp_serversslhandshake );
340+ lua_setfield (L , -2 , "serversslhandshake" );
341+
342+ #endif
343+
330344 lua_pushvalue (L , -1 );
331345 lua_setfield (L , -2 , "__index" );
332346
@@ -2036,6 +2050,260 @@ ngx_stream_lua_ssl_handshake_retval_handler(ngx_stream_lua_request_t *r,
20362050 return 1 ;
20372051}
20382052
2053+
2054+ static int
2055+ ngx_stream_lua_socket_tcp_serversslhandshake (lua_State * L )
2056+ {
2057+ int n , top ;
2058+ ngx_int_t rc ;
2059+ ngx_connection_t * c ;
2060+
2061+ ngx_stream_lua_request_t * r ;
2062+ ngx_stream_lua_ctx_t * ctx ;
2063+ ngx_stream_lua_co_ctx_t * coctx ;
2064+ ngx_stream_lua_socket_tcp_upstream_t * u ;
2065+ ngx_stream_ssl_srv_conf_t * sscf ;
2066+
2067+ /* Lua function arguments: self */
2068+
2069+ n = lua_gettop (L );
2070+ if (n != 1 ) {
2071+ return luaL_error (L , "ngx.socket serversslhandshake: expecting 1 "
2072+ "argument (the object), but seen %d" , n );
2073+ }
2074+
2075+ r = ngx_stream_lua_get_req (L );
2076+ if (r == NULL ) {
2077+ return luaL_error (L , "no request found" );
2078+ }
2079+
2080+ ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , r -> connection -> log , 0 ,
2081+ "stream lua tcp socket server ssl handshake" );
2082+
2083+ luaL_checktype (L , 1 , LUA_TTABLE );
2084+
2085+ lua_rawgeti (L , 1 , SOCKET_CTX_INDEX );
2086+ u = lua_touserdata (L , -1 );
2087+
2088+ if (u == NULL
2089+ || u -> peer .connection == NULL
2090+ || u -> read_closed
2091+ || u -> write_closed )
2092+ {
2093+ lua_pushnil (L );
2094+ lua_pushliteral (L , "closed" );
2095+ return 2 ;
2096+ }
2097+
2098+ if (u -> request != r ) {
2099+ return luaL_error (L , "bad request" );
2100+ }
2101+
2102+ ngx_stream_lua_socket_check_busy_connecting (r , u , L );
2103+ ngx_stream_lua_socket_check_busy_reading (r , u , L );
2104+ ngx_stream_lua_socket_check_busy_writing (r , u , L );
2105+
2106+ if (!u -> raw_downstream && !u -> body_downstream ) {
2107+ lua_pushnil (L );
2108+ lua_pushliteral (L , "only supported for downstream socket" );
2109+ return 2 ;
2110+ }
2111+
2112+ /* For downstream sockets, the connection is r->connection */
2113+ c = r -> connection ;
2114+
2115+ if (c -> ssl && c -> ssl -> handshaked ) {
2116+ /* SSL handshake already completed, return session info */
2117+ ngx_stream_lua_ssl_handshake_session_info (c , L );
2118+ return 1 ;
2119+ }
2120+
2121+ sscf = ngx_stream_get_module_srv_conf (r -> session , ngx_stream_ssl_module );
2122+
2123+ if (sscf == NULL || sscf -> ssl .ctx == NULL ) {
2124+ lua_pushnil (L );
2125+ lua_pushliteral (L , "ssl not configured for this server" );
2126+ return 2 ;
2127+ }
2128+
2129+ if (ngx_ssl_create_connection (& sscf -> ssl , c , NGX_SSL_BUFFER ) != NGX_OK ) {
2130+ lua_pushnil (L );
2131+ lua_pushliteral (L , "failed to create ssl connection" );
2132+ return 2 ;
2133+ }
2134+
2135+ ctx = ngx_stream_lua_get_module_ctx (r , ngx_stream_lua_module );
2136+ if (ctx == NULL ) {
2137+ return luaL_error (L , "no ctx found" );
2138+ }
2139+
2140+ coctx = ctx -> cur_co_ctx ;
2141+
2142+ c -> sendfile = 0 ;
2143+
2144+ u -> write_co_ctx = coctx ;
2145+
2146+ rc = ngx_ssl_handshake (c );
2147+
2148+ dd ("ngx_ssl_handshake returned %d" , (int ) rc );
2149+
2150+ if (rc == NGX_AGAIN ) {
2151+ if (c -> write -> timer_set ) {
2152+ ngx_del_timer (c -> write );
2153+ }
2154+
2155+ ngx_add_timer (c -> read , u -> read_timeout );
2156+
2157+ u -> conn_waiting = 1 ;
2158+ u -> write_prepare_retvals = ngx_stream_lua_server_ssl_handshake_retval_handler ;
2159+
2160+ ngx_stream_lua_cleanup_pending_operation (coctx );
2161+ coctx -> cleanup = ngx_stream_lua_coctx_cleanup ;
2162+ coctx -> data = u ;
2163+
2164+ c -> ssl -> handler = ngx_stream_lua_server_ssl_handshake_handler ;
2165+
2166+ if (ctx -> entered_content_phase ) {
2167+ r -> write_event_handler = ngx_stream_lua_content_wev_handler ;
2168+
2169+ } else {
2170+ r -> write_event_handler = ngx_stream_lua_core_run_phases ;
2171+ }
2172+
2173+ return lua_yield (L , 0 );
2174+ }
2175+
2176+ top = lua_gettop (L );
2177+ ngx_stream_lua_server_ssl_handshake_handler (c );
2178+ return lua_gettop (L ) - top ;
2179+ }
2180+
2181+
2182+ static void
2183+ ngx_stream_lua_server_ssl_handshake_handler (ngx_connection_t * c )
2184+ {
2185+ int waiting ;
2186+ lua_State * L ;
2187+ ngx_int_t rc ;
2188+ ngx_stream_lua_request_t * r ;
2189+ ngx_stream_session_t * s ;
2190+
2191+ ngx_stream_lua_ctx_t * ctx ;
2192+ ngx_stream_lua_socket_tcp_upstream_t * u ;
2193+
2194+ /* For downstream sockets, c->data points to the session. */
2195+ s = c -> data ;
2196+
2197+ /* Get the context from the session */
2198+ ctx = ngx_stream_get_module_ctx (s , ngx_stream_lua_module );
2199+ if (ctx == NULL ) {
2200+ return ;
2201+ }
2202+
2203+ r = ctx -> request ;
2204+ /* For downstream sockets, u is stored in ctx->downstream */
2205+ u = ctx -> downstream ;
2206+
2207+ c -> read -> handler = ngx_stream_lua_request_handler ;
2208+ c -> write -> handler = ngx_stream_lua_request_handler ;
2209+
2210+ waiting = u -> conn_waiting ;
2211+
2212+ L = u -> write_co_ctx -> co ;
2213+
2214+ if (c -> read -> timedout ) {
2215+ lua_pushnil (L );
2216+ lua_pushliteral (L , "timeout" );
2217+ goto failed ;
2218+ }
2219+
2220+ if (c -> read -> timer_set ) {
2221+ ngx_del_timer (c -> read );
2222+ }
2223+
2224+ r = u -> request ;
2225+ if (r == NULL ) {
2226+ return ;
2227+ }
2228+
2229+ if (c -> ssl -> handshaked ) {
2230+ if (waiting ) {
2231+ ngx_stream_lua_socket_handle_conn_success (r , u );
2232+
2233+ } else {
2234+ (void ) ngx_stream_lua_server_ssl_handshake_retval_handler (r , u , L );
2235+ }
2236+
2237+ return ;
2238+ }
2239+
2240+ lua_pushnil (L );
2241+ lua_pushliteral (L , "handshake failed" );
2242+
2243+ failed :
2244+
2245+ if (waiting ) {
2246+ ngx_stream_lua_socket_handle_conn_error (r , u ,
2247+ NGX_STREAM_LUA_SOCKET_FT_SSL );
2248+
2249+ } else {
2250+ (void ) ngx_stream_lua_socket_write_error_retval_handler (r , u , L );
2251+ }
2252+ }
2253+
2254+
2255+ static void
2256+ ngx_stream_lua_ssl_handshake_session_info (ngx_connection_t * c , lua_State * L )
2257+ {
2258+ const char * protocol ;
2259+ SSL_CIPHER * cipher ;
2260+ const char * cipher_name ;
2261+
2262+ /* Create a table with SSL session information */
2263+ lua_createtable (L , 0 , 3 );
2264+
2265+ /* Add protocol version */
2266+ protocol = SSL_get_version (c -> ssl -> connection );
2267+ if (protocol ) {
2268+ lua_pushstring (L , protocol );
2269+ lua_setfield (L , -2 , "protocol" );
2270+ }
2271+
2272+ /* Add cipher name */
2273+ cipher = (SSL_CIPHER * ) SSL_get_current_cipher (c -> ssl -> connection );
2274+ if (cipher ) {
2275+ cipher_name = SSL_CIPHER_get_name (cipher );
2276+ if (cipher_name ) {
2277+ lua_pushstring (L , cipher_name );
2278+ lua_setfield (L , -2 , "cipher" );
2279+ }
2280+ }
2281+
2282+ /* Add session reused flag */
2283+ lua_pushboolean (L , SSL_session_reused (c -> ssl -> connection ));
2284+ lua_setfield (L , -2 , "session_reused" );
2285+ }
2286+
2287+
2288+ static int
2289+ ngx_stream_lua_server_ssl_handshake_retval_handler (ngx_stream_lua_request_t * r ,
2290+ ngx_stream_lua_socket_tcp_upstream_t * u , lua_State * L )
2291+ {
2292+ ngx_connection_t * c ;
2293+
2294+ /* Check if an error occurred during the handshake */
2295+ if (u -> ft_type ) {
2296+ return ngx_stream_lua_socket_conn_error_retval_handler (r , u , L );
2297+ }
2298+
2299+ /* For downstream sockets, the connection is r->connection */
2300+ c = r -> connection ;
2301+
2302+ ngx_stream_lua_ssl_handshake_session_info (c , L );
2303+
2304+ return 1 ;
2305+ }
2306+
20392307#endif /* NGX_STREAM_SSL */
20402308
20412309
0 commit comments