@@ -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,259 @@ 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_stream_lua_request_t * r ;
2188+ ngx_stream_session_t * s ;
2189+
2190+ ngx_stream_lua_ctx_t * ctx ;
2191+ ngx_stream_lua_socket_tcp_upstream_t * u ;
2192+
2193+ /* For downstream sockets, c->data points to the session. */
2194+ s = c -> data ;
2195+
2196+ /* Get the context from the session */
2197+ ctx = ngx_stream_get_module_ctx (s , ngx_stream_lua_module );
2198+ if (ctx == NULL ) {
2199+ return ;
2200+ }
2201+
2202+ r = ctx -> request ;
2203+ /* For downstream sockets, u is stored in ctx->downstream */
2204+ u = ctx -> downstream ;
2205+
2206+ c -> read -> handler = ngx_stream_lua_request_handler ;
2207+ c -> write -> handler = ngx_stream_lua_request_handler ;
2208+
2209+ waiting = u -> conn_waiting ;
2210+
2211+ L = u -> write_co_ctx -> co ;
2212+
2213+ if (c -> read -> timedout ) {
2214+ lua_pushnil (L );
2215+ lua_pushliteral (L , "timeout" );
2216+ goto failed ;
2217+ }
2218+
2219+ if (c -> read -> timer_set ) {
2220+ ngx_del_timer (c -> read );
2221+ }
2222+
2223+ r = u -> request ;
2224+ if (r == NULL ) {
2225+ return ;
2226+ }
2227+
2228+ if (c -> ssl -> handshaked ) {
2229+ if (waiting ) {
2230+ ngx_stream_lua_socket_handle_conn_success (r , u );
2231+
2232+ } else {
2233+ (void ) ngx_stream_lua_server_ssl_handshake_retval_handler (r , u , L );
2234+ }
2235+
2236+ return ;
2237+ }
2238+
2239+ lua_pushnil (L );
2240+ lua_pushliteral (L , "handshake failed" );
2241+
2242+ failed :
2243+
2244+ if (waiting ) {
2245+ ngx_stream_lua_socket_handle_conn_error (r , u ,
2246+ NGX_STREAM_LUA_SOCKET_FT_SSL );
2247+
2248+ } else {
2249+ (void ) ngx_stream_lua_socket_write_error_retval_handler (r , u , L );
2250+ }
2251+ }
2252+
2253+
2254+ static void
2255+ ngx_stream_lua_ssl_handshake_session_info (ngx_connection_t * c , lua_State * L )
2256+ {
2257+ const char * protocol ;
2258+ SSL_CIPHER * cipher ;
2259+ const char * cipher_name ;
2260+
2261+ /* Create a table with SSL session information */
2262+ lua_createtable (L , 0 , 3 );
2263+
2264+ /* Add protocol version */
2265+ protocol = SSL_get_version (c -> ssl -> connection );
2266+ if (protocol ) {
2267+ lua_pushstring (L , protocol );
2268+ lua_setfield (L , -2 , "protocol" );
2269+ }
2270+
2271+ /* Add cipher name */
2272+ cipher = (SSL_CIPHER * ) SSL_get_current_cipher (c -> ssl -> connection );
2273+ if (cipher ) {
2274+ cipher_name = SSL_CIPHER_get_name (cipher );
2275+ if (cipher_name ) {
2276+ lua_pushstring (L , cipher_name );
2277+ lua_setfield (L , -2 , "cipher" );
2278+ }
2279+ }
2280+
2281+ /* Add session reused flag */
2282+ lua_pushboolean (L , SSL_session_reused (c -> ssl -> connection ));
2283+ lua_setfield (L , -2 , "session_reused" );
2284+ }
2285+
2286+
2287+ static int
2288+ ngx_stream_lua_server_ssl_handshake_retval_handler (ngx_stream_lua_request_t * r ,
2289+ ngx_stream_lua_socket_tcp_upstream_t * u , lua_State * L )
2290+ {
2291+ ngx_connection_t * c ;
2292+
2293+ /* Check if an error occurred during the handshake */
2294+ if (u -> ft_type ) {
2295+ return ngx_stream_lua_socket_conn_error_retval_handler (r , u , L );
2296+ }
2297+
2298+ /* For downstream sockets, the connection is r->connection */
2299+ c = r -> connection ;
2300+
2301+ ngx_stream_lua_ssl_handshake_session_info (c , L );
2302+
2303+ return 1 ;
2304+ }
2305+
20392306#endif /* NGX_STREAM_SSL */
20402307
20412308
0 commit comments