12c593315Sopenharmony_ci/* 22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library 32c593315Sopenharmony_ci * 42c593315Sopenharmony_ci * Copyright (c) 2015 Tatsuhiro Tsujikawa 52c593315Sopenharmony_ci * 62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the 82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 122c593315Sopenharmony_ci * the following conditions: 132c593315Sopenharmony_ci * 142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be 152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software. 162c593315Sopenharmony_ci * 172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 242c593315Sopenharmony_ci */ 252c593315Sopenharmony_ci#include "shrpx_mruby_module_env.h" 262c593315Sopenharmony_ci 272c593315Sopenharmony_ci#include <mruby/variable.h> 282c593315Sopenharmony_ci#include <mruby/string.h> 292c593315Sopenharmony_ci#include <mruby/hash.h> 302c593315Sopenharmony_ci 312c593315Sopenharmony_ci#include "shrpx_downstream.h" 322c593315Sopenharmony_ci#include "shrpx_upstream.h" 332c593315Sopenharmony_ci#include "shrpx_client_handler.h" 342c593315Sopenharmony_ci#include "shrpx_mruby.h" 352c593315Sopenharmony_ci#include "shrpx_mruby_module.h" 362c593315Sopenharmony_ci#include "shrpx_log.h" 372c593315Sopenharmony_ci#include "shrpx_tls.h" 382c593315Sopenharmony_ci 392c593315Sopenharmony_cinamespace shrpx { 402c593315Sopenharmony_ci 412c593315Sopenharmony_cinamespace mruby { 422c593315Sopenharmony_ci 432c593315Sopenharmony_cinamespace { 442c593315Sopenharmony_cimrb_value env_init(mrb_state *mrb, mrb_value self) { return self; } 452c593315Sopenharmony_ci} // namespace 462c593315Sopenharmony_ci 472c593315Sopenharmony_cinamespace { 482c593315Sopenharmony_cimrb_value env_get_req(mrb_state *mrb, mrb_value self) { 492c593315Sopenharmony_ci return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "req")); 502c593315Sopenharmony_ci} 512c593315Sopenharmony_ci} // namespace 522c593315Sopenharmony_ci 532c593315Sopenharmony_cinamespace { 542c593315Sopenharmony_cimrb_value env_get_resp(mrb_state *mrb, mrb_value self) { 552c593315Sopenharmony_ci return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "resp")); 562c593315Sopenharmony_ci} 572c593315Sopenharmony_ci} // namespace 582c593315Sopenharmony_ci 592c593315Sopenharmony_cinamespace { 602c593315Sopenharmony_cimrb_value env_get_ctx(mrb_state *mrb, mrb_value self) { 612c593315Sopenharmony_ci auto data = reinterpret_cast<MRubyAssocData *>(mrb->ud); 622c593315Sopenharmony_ci auto downstream = data->downstream; 632c593315Sopenharmony_ci 642c593315Sopenharmony_ci auto dsym = intern_ptr(mrb, downstream); 652c593315Sopenharmony_ci 662c593315Sopenharmony_ci auto ctx = mrb_iv_get(mrb, self, dsym); 672c593315Sopenharmony_ci if (mrb_nil_p(ctx)) { 682c593315Sopenharmony_ci ctx = mrb_hash_new(mrb); 692c593315Sopenharmony_ci mrb_iv_set(mrb, self, dsym, ctx); 702c593315Sopenharmony_ci } 712c593315Sopenharmony_ci 722c593315Sopenharmony_ci return ctx; 732c593315Sopenharmony_ci} 742c593315Sopenharmony_ci} // namespace 752c593315Sopenharmony_ci 762c593315Sopenharmony_cinamespace { 772c593315Sopenharmony_cimrb_value env_get_phase(mrb_state *mrb, mrb_value self) { 782c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 792c593315Sopenharmony_ci 802c593315Sopenharmony_ci return mrb_fixnum_value(data->phase); 812c593315Sopenharmony_ci} 822c593315Sopenharmony_ci} // namespace 832c593315Sopenharmony_ci 842c593315Sopenharmony_cinamespace { 852c593315Sopenharmony_cimrb_value env_get_remote_addr(mrb_state *mrb, mrb_value self) { 862c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 872c593315Sopenharmony_ci auto downstream = data->downstream; 882c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 892c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 902c593315Sopenharmony_ci 912c593315Sopenharmony_ci auto &ipaddr = handler->get_ipaddr(); 922c593315Sopenharmony_ci 932c593315Sopenharmony_ci return mrb_str_new(mrb, ipaddr.c_str(), ipaddr.size()); 942c593315Sopenharmony_ci} 952c593315Sopenharmony_ci} // namespace 962c593315Sopenharmony_ci 972c593315Sopenharmony_cinamespace { 982c593315Sopenharmony_cimrb_value env_get_server_port(mrb_state *mrb, mrb_value self) { 992c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 1002c593315Sopenharmony_ci auto downstream = data->downstream; 1012c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 1022c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 1032c593315Sopenharmony_ci auto faddr = handler->get_upstream_addr(); 1042c593315Sopenharmony_ci 1052c593315Sopenharmony_ci return mrb_fixnum_value(faddr->port); 1062c593315Sopenharmony_ci} 1072c593315Sopenharmony_ci} // namespace 1082c593315Sopenharmony_ci 1092c593315Sopenharmony_cinamespace { 1102c593315Sopenharmony_cimrb_value env_get_server_addr(mrb_state *mrb, mrb_value self) { 1112c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 1122c593315Sopenharmony_ci auto downstream = data->downstream; 1132c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 1142c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 1152c593315Sopenharmony_ci auto faddr = handler->get_upstream_addr(); 1162c593315Sopenharmony_ci 1172c593315Sopenharmony_ci return mrb_str_new(mrb, faddr->host.c_str(), faddr->host.size()); 1182c593315Sopenharmony_ci} 1192c593315Sopenharmony_ci} // namespace 1202c593315Sopenharmony_ci 1212c593315Sopenharmony_cinamespace { 1222c593315Sopenharmony_cimrb_value env_get_tls_used(mrb_state *mrb, mrb_value self) { 1232c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 1242c593315Sopenharmony_ci auto downstream = data->downstream; 1252c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 1262c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 1272c593315Sopenharmony_ci 1282c593315Sopenharmony_ci return handler->get_ssl() ? mrb_true_value() : mrb_false_value(); 1292c593315Sopenharmony_ci} 1302c593315Sopenharmony_ci} // namespace 1312c593315Sopenharmony_ci 1322c593315Sopenharmony_cinamespace { 1332c593315Sopenharmony_cimrb_value env_get_tls_sni(mrb_state *mrb, mrb_value self) { 1342c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 1352c593315Sopenharmony_ci auto downstream = data->downstream; 1362c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 1372c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 1382c593315Sopenharmony_ci auto sni = handler->get_tls_sni(); 1392c593315Sopenharmony_ci 1402c593315Sopenharmony_ci return mrb_str_new(mrb, sni.c_str(), sni.size()); 1412c593315Sopenharmony_ci} 1422c593315Sopenharmony_ci} // namespace 1432c593315Sopenharmony_ci 1442c593315Sopenharmony_cinamespace { 1452c593315Sopenharmony_cimrb_value env_get_tls_client_fingerprint_md(mrb_state *mrb, const EVP_MD *md) { 1462c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 1472c593315Sopenharmony_ci auto downstream = data->downstream; 1482c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 1492c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 1502c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 1512c593315Sopenharmony_ci 1522c593315Sopenharmony_ci if (!ssl) { 1532c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 1542c593315Sopenharmony_ci } 1552c593315Sopenharmony_ci 1562c593315Sopenharmony_ci#if OPENSSL_3_0_0_API 1572c593315Sopenharmony_ci auto x = SSL_get0_peer_certificate(ssl); 1582c593315Sopenharmony_ci#else // !OPENSSL_3_0_0_API 1592c593315Sopenharmony_ci auto x = SSL_get_peer_certificate(ssl); 1602c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 1612c593315Sopenharmony_ci if (!x) { 1622c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 1632c593315Sopenharmony_ci } 1642c593315Sopenharmony_ci 1652c593315Sopenharmony_ci // Currently the largest hash value is SHA-256, which is 32 bytes. 1662c593315Sopenharmony_ci std::array<uint8_t, 32> buf; 1672c593315Sopenharmony_ci auto slen = tls::get_x509_fingerprint(buf.data(), buf.size(), x, md); 1682c593315Sopenharmony_ci#if !OPENSSL_3_0_0_API 1692c593315Sopenharmony_ci X509_free(x); 1702c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 1712c593315Sopenharmony_ci if (slen == -1) { 1722c593315Sopenharmony_ci mrb_raise(mrb, E_RUNTIME_ERROR, "could not compute client fingerprint"); 1732c593315Sopenharmony_ci } 1742c593315Sopenharmony_ci 1752c593315Sopenharmony_ci // TODO Use template version of format_hex 1762c593315Sopenharmony_ci auto &balloc = downstream->get_block_allocator(); 1772c593315Sopenharmony_ci auto f = util::format_hex(balloc, 1782c593315Sopenharmony_ci StringRef{std::begin(buf), std::begin(buf) + slen}); 1792c593315Sopenharmony_ci return mrb_str_new(mrb, f.c_str(), f.size()); 1802c593315Sopenharmony_ci} 1812c593315Sopenharmony_ci} // namespace 1822c593315Sopenharmony_ci 1832c593315Sopenharmony_cinamespace { 1842c593315Sopenharmony_cimrb_value env_get_tls_client_fingerprint_sha256(mrb_state *mrb, 1852c593315Sopenharmony_ci mrb_value self) { 1862c593315Sopenharmony_ci return env_get_tls_client_fingerprint_md(mrb, EVP_sha256()); 1872c593315Sopenharmony_ci} 1882c593315Sopenharmony_ci} // namespace 1892c593315Sopenharmony_ci 1902c593315Sopenharmony_cinamespace { 1912c593315Sopenharmony_cimrb_value env_get_tls_client_fingerprint_sha1(mrb_state *mrb, mrb_value self) { 1922c593315Sopenharmony_ci return env_get_tls_client_fingerprint_md(mrb, EVP_sha1()); 1932c593315Sopenharmony_ci} 1942c593315Sopenharmony_ci} // namespace 1952c593315Sopenharmony_ci 1962c593315Sopenharmony_cinamespace { 1972c593315Sopenharmony_cimrb_value env_get_tls_client_subject_name(mrb_state *mrb, mrb_value self) { 1982c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 1992c593315Sopenharmony_ci auto downstream = data->downstream; 2002c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 2012c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 2022c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 2032c593315Sopenharmony_ci 2042c593315Sopenharmony_ci if (!ssl) { 2052c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 2062c593315Sopenharmony_ci } 2072c593315Sopenharmony_ci 2082c593315Sopenharmony_ci#if OPENSSL_3_0_0_API 2092c593315Sopenharmony_ci auto x = SSL_get0_peer_certificate(ssl); 2102c593315Sopenharmony_ci#else // !OPENSSL_3_0_0_API 2112c593315Sopenharmony_ci auto x = SSL_get_peer_certificate(ssl); 2122c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 2132c593315Sopenharmony_ci if (!x) { 2142c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 2152c593315Sopenharmony_ci } 2162c593315Sopenharmony_ci 2172c593315Sopenharmony_ci auto &balloc = downstream->get_block_allocator(); 2182c593315Sopenharmony_ci auto name = tls::get_x509_subject_name(balloc, x); 2192c593315Sopenharmony_ci#if !OPENSSL_3_0_0_API 2202c593315Sopenharmony_ci X509_free(x); 2212c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 2222c593315Sopenharmony_ci return mrb_str_new(mrb, name.c_str(), name.size()); 2232c593315Sopenharmony_ci} 2242c593315Sopenharmony_ci} // namespace 2252c593315Sopenharmony_ci 2262c593315Sopenharmony_cinamespace { 2272c593315Sopenharmony_cimrb_value env_get_tls_client_issuer_name(mrb_state *mrb, mrb_value self) { 2282c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 2292c593315Sopenharmony_ci auto downstream = data->downstream; 2302c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 2312c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 2322c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 2332c593315Sopenharmony_ci 2342c593315Sopenharmony_ci if (!ssl) { 2352c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 2362c593315Sopenharmony_ci } 2372c593315Sopenharmony_ci 2382c593315Sopenharmony_ci#if OPENSSL_3_0_0_API 2392c593315Sopenharmony_ci auto x = SSL_get0_peer_certificate(ssl); 2402c593315Sopenharmony_ci#else // !OPENSSL_3_0_0_API 2412c593315Sopenharmony_ci auto x = SSL_get_peer_certificate(ssl); 2422c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 2432c593315Sopenharmony_ci if (!x) { 2442c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 2452c593315Sopenharmony_ci } 2462c593315Sopenharmony_ci 2472c593315Sopenharmony_ci auto &balloc = downstream->get_block_allocator(); 2482c593315Sopenharmony_ci auto name = tls::get_x509_issuer_name(balloc, x); 2492c593315Sopenharmony_ci#if !OPENSSL_3_0_0_API 2502c593315Sopenharmony_ci X509_free(x); 2512c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 2522c593315Sopenharmony_ci return mrb_str_new(mrb, name.c_str(), name.size()); 2532c593315Sopenharmony_ci} 2542c593315Sopenharmony_ci} // namespace 2552c593315Sopenharmony_ci 2562c593315Sopenharmony_cinamespace { 2572c593315Sopenharmony_cimrb_value env_get_tls_client_serial(mrb_state *mrb, mrb_value self) { 2582c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 2592c593315Sopenharmony_ci auto downstream = data->downstream; 2602c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 2612c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 2622c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 2632c593315Sopenharmony_ci 2642c593315Sopenharmony_ci if (!ssl) { 2652c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 2662c593315Sopenharmony_ci } 2672c593315Sopenharmony_ci 2682c593315Sopenharmony_ci#if OPENSSL_3_0_0_API 2692c593315Sopenharmony_ci auto x = SSL_get0_peer_certificate(ssl); 2702c593315Sopenharmony_ci#else // !OPENSSL_3_0_0_API 2712c593315Sopenharmony_ci auto x = SSL_get_peer_certificate(ssl); 2722c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 2732c593315Sopenharmony_ci if (!x) { 2742c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 2752c593315Sopenharmony_ci } 2762c593315Sopenharmony_ci 2772c593315Sopenharmony_ci auto &balloc = downstream->get_block_allocator(); 2782c593315Sopenharmony_ci auto sn = tls::get_x509_serial(balloc, x); 2792c593315Sopenharmony_ci#if !OPENSSL_3_0_0_API 2802c593315Sopenharmony_ci X509_free(x); 2812c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 2822c593315Sopenharmony_ci return mrb_str_new(mrb, sn.c_str(), sn.size()); 2832c593315Sopenharmony_ci} 2842c593315Sopenharmony_ci} // namespace 2852c593315Sopenharmony_ci 2862c593315Sopenharmony_cinamespace { 2872c593315Sopenharmony_cimrb_value env_get_tls_client_not_before(mrb_state *mrb, mrb_value self) { 2882c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 2892c593315Sopenharmony_ci auto downstream = data->downstream; 2902c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 2912c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 2922c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 2932c593315Sopenharmony_ci 2942c593315Sopenharmony_ci if (!ssl) { 2952c593315Sopenharmony_ci return mrb_fixnum_value(0); 2962c593315Sopenharmony_ci } 2972c593315Sopenharmony_ci 2982c593315Sopenharmony_ci#if OPENSSL_3_0_0_API 2992c593315Sopenharmony_ci auto x = SSL_get0_peer_certificate(ssl); 3002c593315Sopenharmony_ci#else // !OPENSSL_3_0_0_API 3012c593315Sopenharmony_ci auto x = SSL_get_peer_certificate(ssl); 3022c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 3032c593315Sopenharmony_ci if (!x) { 3042c593315Sopenharmony_ci return mrb_fixnum_value(0); 3052c593315Sopenharmony_ci } 3062c593315Sopenharmony_ci 3072c593315Sopenharmony_ci time_t t; 3082c593315Sopenharmony_ci if (tls::get_x509_not_before(t, x) != 0) { 3092c593315Sopenharmony_ci t = 0; 3102c593315Sopenharmony_ci } 3112c593315Sopenharmony_ci 3122c593315Sopenharmony_ci#if !OPENSSL_3_0_0_API 3132c593315Sopenharmony_ci X509_free(x); 3142c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 3152c593315Sopenharmony_ci 3162c593315Sopenharmony_ci return mrb_fixnum_value(t); 3172c593315Sopenharmony_ci} 3182c593315Sopenharmony_ci} // namespace 3192c593315Sopenharmony_ci 3202c593315Sopenharmony_cinamespace { 3212c593315Sopenharmony_cimrb_value env_get_tls_client_not_after(mrb_state *mrb, mrb_value self) { 3222c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 3232c593315Sopenharmony_ci auto downstream = data->downstream; 3242c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 3252c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 3262c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 3272c593315Sopenharmony_ci 3282c593315Sopenharmony_ci if (!ssl) { 3292c593315Sopenharmony_ci return mrb_fixnum_value(0); 3302c593315Sopenharmony_ci } 3312c593315Sopenharmony_ci 3322c593315Sopenharmony_ci#if OPENSSL_3_0_0_API 3332c593315Sopenharmony_ci auto x = SSL_get0_peer_certificate(ssl); 3342c593315Sopenharmony_ci#else // !OPENSSL_3_0_0_API 3352c593315Sopenharmony_ci auto x = SSL_get_peer_certificate(ssl); 3362c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 3372c593315Sopenharmony_ci if (!x) { 3382c593315Sopenharmony_ci return mrb_fixnum_value(0); 3392c593315Sopenharmony_ci } 3402c593315Sopenharmony_ci 3412c593315Sopenharmony_ci time_t t; 3422c593315Sopenharmony_ci if (tls::get_x509_not_after(t, x) != 0) { 3432c593315Sopenharmony_ci t = 0; 3442c593315Sopenharmony_ci } 3452c593315Sopenharmony_ci 3462c593315Sopenharmony_ci#if !OPENSSL_3_0_0_API 3472c593315Sopenharmony_ci X509_free(x); 3482c593315Sopenharmony_ci#endif // !OPENSSL_3_0_0_API 3492c593315Sopenharmony_ci 3502c593315Sopenharmony_ci return mrb_fixnum_value(t); 3512c593315Sopenharmony_ci} 3522c593315Sopenharmony_ci} // namespace 3532c593315Sopenharmony_ci 3542c593315Sopenharmony_cinamespace { 3552c593315Sopenharmony_cimrb_value env_get_tls_cipher(mrb_state *mrb, mrb_value self) { 3562c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 3572c593315Sopenharmony_ci auto downstream = data->downstream; 3582c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 3592c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 3602c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 3612c593315Sopenharmony_ci 3622c593315Sopenharmony_ci if (!ssl) { 3632c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 3642c593315Sopenharmony_ci } 3652c593315Sopenharmony_ci 3662c593315Sopenharmony_ci return mrb_str_new_cstr(mrb, SSL_get_cipher_name(ssl)); 3672c593315Sopenharmony_ci} 3682c593315Sopenharmony_ci} // namespace 3692c593315Sopenharmony_ci 3702c593315Sopenharmony_cinamespace { 3712c593315Sopenharmony_cimrb_value env_get_tls_protocol(mrb_state *mrb, mrb_value self) { 3722c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 3732c593315Sopenharmony_ci auto downstream = data->downstream; 3742c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 3752c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 3762c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 3772c593315Sopenharmony_ci 3782c593315Sopenharmony_ci if (!ssl) { 3792c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 3802c593315Sopenharmony_ci } 3812c593315Sopenharmony_ci 3822c593315Sopenharmony_ci return mrb_str_new_cstr(mrb, nghttp2::tls::get_tls_protocol(ssl)); 3832c593315Sopenharmony_ci} 3842c593315Sopenharmony_ci} // namespace 3852c593315Sopenharmony_ci 3862c593315Sopenharmony_cinamespace { 3872c593315Sopenharmony_cimrb_value env_get_tls_session_id(mrb_state *mrb, mrb_value self) { 3882c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 3892c593315Sopenharmony_ci auto downstream = data->downstream; 3902c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 3912c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 3922c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 3932c593315Sopenharmony_ci 3942c593315Sopenharmony_ci if (!ssl) { 3952c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 3962c593315Sopenharmony_ci } 3972c593315Sopenharmony_ci 3982c593315Sopenharmony_ci auto session = SSL_get_session(ssl); 3992c593315Sopenharmony_ci if (!session) { 4002c593315Sopenharmony_ci return mrb_str_new_static(mrb, "", 0); 4012c593315Sopenharmony_ci } 4022c593315Sopenharmony_ci 4032c593315Sopenharmony_ci unsigned int session_id_length = 0; 4042c593315Sopenharmony_ci auto session_id = SSL_SESSION_get_id(session, &session_id_length); 4052c593315Sopenharmony_ci 4062c593315Sopenharmony_ci // TODO Use template version of util::format_hex. 4072c593315Sopenharmony_ci auto &balloc = downstream->get_block_allocator(); 4082c593315Sopenharmony_ci auto id = util::format_hex(balloc, StringRef{session_id, session_id_length}); 4092c593315Sopenharmony_ci return mrb_str_new(mrb, id.c_str(), id.size()); 4102c593315Sopenharmony_ci} 4112c593315Sopenharmony_ci} // namespace 4122c593315Sopenharmony_ci 4132c593315Sopenharmony_cinamespace { 4142c593315Sopenharmony_cimrb_value env_get_tls_session_reused(mrb_state *mrb, mrb_value self) { 4152c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 4162c593315Sopenharmony_ci auto downstream = data->downstream; 4172c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 4182c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 4192c593315Sopenharmony_ci auto ssl = handler->get_ssl(); 4202c593315Sopenharmony_ci 4212c593315Sopenharmony_ci if (!ssl) { 4222c593315Sopenharmony_ci return mrb_false_value(); 4232c593315Sopenharmony_ci } 4242c593315Sopenharmony_ci 4252c593315Sopenharmony_ci return SSL_session_reused(ssl) ? mrb_true_value() : mrb_false_value(); 4262c593315Sopenharmony_ci} 4272c593315Sopenharmony_ci} // namespace 4282c593315Sopenharmony_ci 4292c593315Sopenharmony_cinamespace { 4302c593315Sopenharmony_cimrb_value env_get_alpn(mrb_state *mrb, mrb_value self) { 4312c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 4322c593315Sopenharmony_ci auto downstream = data->downstream; 4332c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 4342c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 4352c593315Sopenharmony_ci auto alpn = handler->get_alpn(); 4362c593315Sopenharmony_ci return mrb_str_new(mrb, alpn.c_str(), alpn.size()); 4372c593315Sopenharmony_ci} 4382c593315Sopenharmony_ci} // namespace 4392c593315Sopenharmony_ci 4402c593315Sopenharmony_cinamespace { 4412c593315Sopenharmony_cimrb_value env_get_tls_handshake_finished(mrb_state *mrb, mrb_value self) { 4422c593315Sopenharmony_ci auto data = static_cast<MRubyAssocData *>(mrb->ud); 4432c593315Sopenharmony_ci auto downstream = data->downstream; 4442c593315Sopenharmony_ci auto upstream = downstream->get_upstream(); 4452c593315Sopenharmony_ci auto handler = upstream->get_client_handler(); 4462c593315Sopenharmony_ci auto conn = handler->get_connection(); 4472c593315Sopenharmony_ci return SSL_is_init_finished(conn->tls.ssl) ? mrb_true_value() 4482c593315Sopenharmony_ci : mrb_false_value(); 4492c593315Sopenharmony_ci} 4502c593315Sopenharmony_ci} // namespace 4512c593315Sopenharmony_ci 4522c593315Sopenharmony_civoid init_env_class(mrb_state *mrb, RClass *module) { 4532c593315Sopenharmony_ci auto env_class = 4542c593315Sopenharmony_ci mrb_define_class_under(mrb, module, "Env", mrb->object_class); 4552c593315Sopenharmony_ci 4562c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "initialize", env_init, MRB_ARGS_NONE()); 4572c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "req", env_get_req, MRB_ARGS_NONE()); 4582c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "resp", env_get_resp, MRB_ARGS_NONE()); 4592c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "ctx", env_get_ctx, MRB_ARGS_NONE()); 4602c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "phase", env_get_phase, MRB_ARGS_NONE()); 4612c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "remote_addr", env_get_remote_addr, 4622c593315Sopenharmony_ci MRB_ARGS_NONE()); 4632c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "server_addr", env_get_server_addr, 4642c593315Sopenharmony_ci MRB_ARGS_NONE()); 4652c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "server_port", env_get_server_port, 4662c593315Sopenharmony_ci MRB_ARGS_NONE()); 4672c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_used", env_get_tls_used, 4682c593315Sopenharmony_ci MRB_ARGS_NONE()); 4692c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_sni", env_get_tls_sni, 4702c593315Sopenharmony_ci MRB_ARGS_NONE()); 4712c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_client_fingerprint_sha256", 4722c593315Sopenharmony_ci env_get_tls_client_fingerprint_sha256, MRB_ARGS_NONE()); 4732c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_client_fingerprint_sha1", 4742c593315Sopenharmony_ci env_get_tls_client_fingerprint_sha1, MRB_ARGS_NONE()); 4752c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_client_issuer_name", 4762c593315Sopenharmony_ci env_get_tls_client_issuer_name, MRB_ARGS_NONE()); 4772c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_client_subject_name", 4782c593315Sopenharmony_ci env_get_tls_client_subject_name, MRB_ARGS_NONE()); 4792c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_client_serial", 4802c593315Sopenharmony_ci env_get_tls_client_serial, MRB_ARGS_NONE()); 4812c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_client_not_before", 4822c593315Sopenharmony_ci env_get_tls_client_not_before, MRB_ARGS_NONE()); 4832c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_client_not_after", 4842c593315Sopenharmony_ci env_get_tls_client_not_after, MRB_ARGS_NONE()); 4852c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_cipher", env_get_tls_cipher, 4862c593315Sopenharmony_ci MRB_ARGS_NONE()); 4872c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_protocol", env_get_tls_protocol, 4882c593315Sopenharmony_ci MRB_ARGS_NONE()); 4892c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_session_id", env_get_tls_session_id, 4902c593315Sopenharmony_ci MRB_ARGS_NONE()); 4912c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_session_reused", 4922c593315Sopenharmony_ci env_get_tls_session_reused, MRB_ARGS_NONE()); 4932c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "alpn", env_get_alpn, MRB_ARGS_NONE()); 4942c593315Sopenharmony_ci mrb_define_method(mrb, env_class, "tls_handshake_finished", 4952c593315Sopenharmony_ci env_get_tls_handshake_finished, MRB_ARGS_NONE()); 4962c593315Sopenharmony_ci} 4972c593315Sopenharmony_ci 4982c593315Sopenharmony_ci} // namespace mruby 4992c593315Sopenharmony_ci 5002c593315Sopenharmony_ci} // namespace shrpx 501