| /* | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| #include <netinet/in.h> | |
| #include <arpa/inet.h> | |
| #include <openssl/ssl.h> | |
| #include <openssl/x509.h> | |
| #include <openssl/x509v3.h> | |
| #include <openssl/bio.h> | |
| #include <vector> | |
| #include <string> | |
| #include "ts_lua_util.h" | |
| #include "ts_lua_client_cert_helpers.h" | |
| enum TSLuaPPInfoKey { | |
| TS_LUA_PP_INFO_VERSION = TS_PP_INFO_VERSION, | |
| TS_LUA_PP_INFO_SRC_ADDR = TS_PP_INFO_SRC_ADDR, | |
| TS_LUA_PP_INFO_SRC_PORT = TS_PP_INFO_SRC_PORT, | |
| TS_LUA_PP_INFO_DST_ADDR = TS_PP_INFO_DST_ADDR, | |
| TS_LUA_PP_INFO_DST_PORT = TS_PP_INFO_DST_PORT, | |
| TS_LUA_PP_INFO_PROTOCOL = TS_PP_INFO_PROTOCOL, | |
| TS_LUA_PP_INFO_SOCK_TYPE = TS_PP_INFO_SOCK_TYPE | |
| }; | |
| ts_lua_var_item ts_lua_pp_info_key_vars[] = { | |
| TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_VERSION), TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_SRC_ADDR), | |
| TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_SRC_PORT), TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_DST_ADDR), | |
| TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_DST_PORT), TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_PROTOCOL), | |
| TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_SOCK_TYPE)}; | |
| static void ts_lua_inject_client_request_client_addr_api(lua_State *L); | |
| static void ts_lua_inject_client_request_server_addr_api(lua_State *L); | |
| static int ts_lua_client_request_header_get(lua_State *L); | |
| static int ts_lua_client_request_header_set(lua_State *L); | |
| static int ts_lua_client_request_header_table_get(lua_State *L); | |
| static int ts_lua_client_request_header_table_set(lua_State *L); | |
| static int ts_lua_client_request_get_headers(lua_State *L); | |
| static int ts_lua_client_request_get_header_block(lua_State *L); | |
| static int ts_lua_client_request_get_url(lua_State *L); | |
| static int ts_lua_client_request_get_pristine_url(lua_State *L); | |
| static int ts_lua_client_request_get_url_host(lua_State *L); | |
| static int ts_lua_client_request_set_url_host(lua_State *L); | |
| static int ts_lua_client_request_get_url_port(lua_State *L); | |
| static int ts_lua_client_request_set_url_port(lua_State *L); | |
| static int ts_lua_client_request_get_url_scheme(lua_State *L); | |
| static int ts_lua_client_request_set_url_scheme(lua_State *L); | |
| static int ts_lua_client_request_get_uri(lua_State *L); | |
| static int ts_lua_client_request_set_uri(lua_State *L); | |
| static int ts_lua_client_request_set_uri_args(lua_State *L); | |
| static int ts_lua_client_request_get_uri_args(lua_State *L); | |
| static int ts_lua_client_request_get_method(lua_State *L); | |
| static int ts_lua_client_request_set_method(lua_State *L); | |
| static int ts_lua_client_request_get_version(lua_State *L); | |
| static int ts_lua_client_request_set_version(lua_State *L); | |
| static int ts_lua_client_request_get_body_size(lua_State *L); | |
| static int ts_lua_client_request_get_header_size(lua_State *L); | |
| static void ts_lua_inject_client_request_socket_api(lua_State *L); | |
| static void ts_lua_inject_client_request_header_api(lua_State *L); | |
| static void ts_lua_inject_client_request_header_table_api(lua_State *L); | |
| static void ts_lua_inject_client_request_headers_api(lua_State *L); | |
| static void ts_lua_inject_client_request_url_api(lua_State *L); | |
| static void ts_lua_inject_client_request_uri_api(lua_State *L); | |
| static void ts_lua_inject_client_request_args_api(lua_State *L); | |
| static void ts_lua_inject_client_request_method_api(lua_State *L); | |
| static void ts_lua_inject_client_request_version_api(lua_State *L); | |
| static void ts_lua_inject_client_request_body_size_api(lua_State *L); | |
| static void ts_lua_inject_client_request_header_size_api(lua_State *L); | |
| static int ts_lua_client_request_client_addr_get_ip(lua_State *L); | |
| static int ts_lua_client_request_client_addr_get_port(lua_State *L); | |
| static int ts_lua_client_request_client_addr_get_addr(lua_State *L); | |
| static int ts_lua_client_request_client_addr_get_incoming_port(lua_State *L); | |
| static int ts_lua_client_request_client_addr_get_verified_addr(lua_State *L); | |
| static int ts_lua_client_request_client_addr_set_verified_addr(lua_State *L); | |
| static void ts_lua_inject_client_request_ssl_reused_api(lua_State *L); | |
| static int ts_lua_client_request_get_ssl_reused(lua_State *L); | |
| static void ts_lua_inject_client_request_ssl_cipher_api(lua_State *L); | |
| static int ts_lua_client_request_get_ssl_cipher(lua_State *L); | |
| static void ts_lua_inject_client_request_ssl_protocol_api(lua_State *L); | |
| static int ts_lua_client_request_get_ssl_protocol(lua_State *L); | |
| static void ts_lua_inject_client_request_ssl_curve_api(lua_State *L); | |
| static int ts_lua_client_request_get_ssl_curve(lua_State *L); | |
| static void ts_lua_inject_client_request_cert_api(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_pem(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_subject(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_issuer(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_serial(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_signature(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_not_before(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_not_after(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_version(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_san_dns(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_san_ip(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_san_email(lua_State *L); | |
| static int ts_lua_client_request_client_cert_get_san_uri(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_pem(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_subject(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_issuer(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_serial(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_signature(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_not_before(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_not_after(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_version(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_san_dns(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_san_ip(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_san_email(lua_State *L); | |
| static int ts_lua_client_request_server_cert_get_san_uri(lua_State *L); | |
| static void ts_lua_inject_client_request_pp_info_api(lua_State *L); | |
| static int ts_lua_client_request_get_pp_info(lua_State *L); | |
| static int ts_lua_client_request_get_pp_info_int(lua_State *L); | |
| void | |
| ts_lua_inject_client_request_api(lua_State *L) | |
| { | |
| lua_newtable(L); | |
| ts_lua_inject_client_request_socket_api(L); | |
| ts_lua_inject_client_request_header_api(L); | |
| ts_lua_inject_client_request_header_table_api(L); | |
| ts_lua_inject_client_request_headers_api(L); | |
| ts_lua_inject_client_request_url_api(L); | |
| ts_lua_inject_client_request_uri_api(L); | |
| ts_lua_inject_client_request_args_api(L); | |
| ts_lua_inject_client_request_method_api(L); | |
| ts_lua_inject_client_request_version_api(L); | |
| ts_lua_inject_client_request_body_size_api(L); | |
| ts_lua_inject_client_request_header_size_api(L); | |
| ts_lua_inject_client_request_ssl_reused_api(L); | |
| ts_lua_inject_client_request_ssl_cipher_api(L); | |
| ts_lua_inject_client_request_ssl_protocol_api(L); | |
| ts_lua_inject_client_request_ssl_curve_api(L); | |
| ts_lua_inject_client_request_cert_api(L); | |
| ts_lua_inject_client_request_pp_info_api(L); | |
| lua_setfield(L, -2, "client_request"); | |
| } | |
| static void | |
| ts_lua_inject_client_request_socket_api(lua_State *L) | |
| { | |
| ts_lua_inject_client_request_client_addr_api(L); | |
| ts_lua_inject_client_request_server_addr_api(L); | |
| } | |
| static void | |
| ts_lua_inject_client_request_client_addr_api(lua_State *L) | |
| { | |
| lua_newtable(L); | |
| lua_pushcfunction(L, ts_lua_client_request_client_addr_get_ip); | |
| lua_setfield(L, -2, "get_ip"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_addr_get_port); | |
| lua_setfield(L, -2, "get_port"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_addr_get_addr); | |
| lua_setfield(L, -2, "get_addr"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_addr_get_incoming_port); | |
| lua_setfield(L, -2, "get_incoming_port"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_addr_get_verified_addr); | |
| lua_setfield(L, -2, "get_verified_addr"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_addr_set_verified_addr); | |
| lua_setfield(L, -2, "set_verified_addr"); | |
| lua_setfield(L, -2, "client_addr"); | |
| } | |
| static void | |
| ts_lua_inject_client_request_server_addr_api(lua_State *L ATS_UNUSED) | |
| { | |
| return; | |
| } | |
| static void | |
| ts_lua_inject_client_request_header_api(lua_State *L) | |
| { | |
| lua_newtable(L); /* .header */ | |
| lua_createtable(L, 0, 2); /* metatable for .header */ | |
| lua_pushcfunction(L, ts_lua_client_request_header_get); | |
| lua_setfield(L, -2, "__index"); | |
| lua_pushcfunction(L, ts_lua_client_request_header_set); | |
| lua_setfield(L, -2, "__newindex"); | |
| lua_setmetatable(L, -2); | |
| lua_setfield(L, -2, "header"); | |
| } | |
| static int | |
| ts_lua_client_request_header_get(lua_State *L) | |
| { | |
| const char *key; | |
| const char *val; | |
| int val_len; | |
| size_t key_len; | |
| int count; | |
| TSMLoc field_loc, next_field_loc; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| /* we skip the first argument that is the table */ | |
| key = luaL_checklstring(L, 2, &key_len); | |
| if (key && key_len) { | |
| field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len); | |
| if (field_loc != TS_NULL_MLOC) { | |
| count = 0; | |
| while (field_loc != TS_NULL_MLOC) { | |
| val = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &val_len); | |
| next_field_loc = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| lua_pushlstring(L, val, val_len); | |
| count++; | |
| // multiple headers with the same name must be semantically the same as one value which is comma separated | |
| if (next_field_loc != TS_NULL_MLOC) { | |
| lua_pushlstring(L, ",", 1); | |
| count++; | |
| } | |
| TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| field_loc = next_field_loc; | |
| } | |
| lua_concat(L, count); | |
| } else { | |
| lua_pushnil(L); | |
| } | |
| } else { | |
| lua_pushnil(L); | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_header_set(lua_State *L) | |
| { | |
| const char *key; | |
| const char *val; | |
| size_t val_len; | |
| size_t key_len; | |
| int remove; | |
| int first; | |
| TSMLoc field_loc, tmp; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| remove = 0; | |
| val = nullptr; | |
| /* we skip the first argument that is the table */ | |
| key = luaL_checklstring(L, 2, &key_len); | |
| if (lua_isnil(L, 3)) { | |
| remove = 1; | |
| } else { | |
| val = luaL_checklstring(L, 3, &val_len); | |
| } | |
| field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len); | |
| if (remove) { | |
| while (field_loc != TS_NULL_MLOC) { | |
| tmp = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| TSMimeHdrFieldDestroy(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| field_loc = tmp; | |
| } | |
| } else if (field_loc != TS_NULL_MLOC) { | |
| first = 1; | |
| while (field_loc != TS_NULL_MLOC) { | |
| tmp = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| if (first) { | |
| first = 0; | |
| TSMimeHdrFieldValueStringSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, val, val_len); | |
| } else { | |
| TSMimeHdrFieldDestroy(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| } | |
| TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| field_loc = tmp; | |
| } | |
| } else if (TSMimeHdrFieldCreateNamed(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len, &field_loc) != | |
| TS_SUCCESS) { | |
| TSError("[ts_lua][%s] TSMimeHdrFieldCreateNamed error", __FUNCTION__); | |
| return 0; | |
| } else { | |
| TSMimeHdrFieldValueStringSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, val, val_len); | |
| TSMimeHdrFieldAppend(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| } | |
| if (field_loc != TS_NULL_MLOC) { | |
| TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| } | |
| return 0; | |
| } | |
| static void | |
| ts_lua_inject_client_request_header_table_api(lua_State *L) | |
| { | |
| lua_newtable(L); /* .header */ | |
| lua_createtable(L, 0, 2); /* metatable for .header */ | |
| lua_pushcfunction(L, ts_lua_client_request_header_table_get); | |
| lua_setfield(L, -2, "__index"); | |
| lua_pushcfunction(L, ts_lua_client_request_header_table_set); | |
| lua_setfield(L, -2, "__newindex"); | |
| lua_setmetatable(L, -2); | |
| lua_setfield(L, -2, "header_table"); | |
| } | |
| static int | |
| ts_lua_client_request_header_table_get(lua_State *L) | |
| { | |
| const char *key; | |
| const char *val; | |
| int val_len; | |
| size_t key_len; | |
| int count; | |
| TSMLoc field_loc, next_field_loc; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| /* we skip the first argument that is the table */ | |
| key = luaL_checklstring(L, 2, &key_len); | |
| if (key && key_len) { | |
| field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len); | |
| if (field_loc != TS_NULL_MLOC) { | |
| lua_newtable(L); | |
| count = 0; | |
| while (field_loc != TS_NULL_MLOC) { | |
| val = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &val_len); | |
| next_field_loc = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| count++; | |
| lua_pushlstring(L, val, val_len); | |
| lua_rawseti(L, -2, count); | |
| TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| field_loc = next_field_loc; | |
| } | |
| } else { | |
| lua_pushnil(L); | |
| } | |
| } else { | |
| lua_pushnil(L); | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_header_table_set(lua_State * /* L ATS_UNUSED */) | |
| { | |
| return 0; | |
| } | |
| static void | |
| ts_lua_inject_client_request_headers_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_headers); | |
| lua_setfield(L, -2, "get_headers"); | |
| lua_pushcfunction(L, ts_lua_client_request_get_header_block); | |
| lua_setfield(L, -2, "get_header_block"); | |
| } | |
| static int | |
| ts_lua_client_request_get_headers(lua_State *L) | |
| { | |
| const char *name; | |
| const char *value; | |
| int name_len; | |
| int value_len; | |
| TSMLoc field_loc; | |
| TSMLoc next_field_loc; | |
| const char *tvalue; | |
| size_t tvalue_len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| lua_newtable(L); | |
| field_loc = TSMimeHdrFieldGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, 0); | |
| while (field_loc != TS_NULL_MLOC) { | |
| name = TSMimeHdrFieldNameGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, &name_len); | |
| if (name && name_len) { | |
| // retrieve the header name from table | |
| lua_pushlstring(L, name, name_len); | |
| lua_gettable(L, -2); | |
| if (lua_isnil(L, -1)) { | |
| // if header name does not exist in the table, insert it | |
| lua_pop(L, 1); | |
| value = | |
| TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &value_len); | |
| lua_pushlstring(L, name, name_len); | |
| lua_pushlstring(L, value, value_len); | |
| lua_rawset(L, -3); | |
| } else { | |
| // if header name exists in the table, append a command and the new value to the end of the existing value | |
| tvalue = lua_tolstring(L, -1, &tvalue_len); | |
| lua_pop(L, 1); | |
| value = | |
| TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &value_len); | |
| lua_pushlstring(L, name, name_len); | |
| lua_pushlstring(L, tvalue, tvalue_len); | |
| lua_pushlstring(L, ",", 1); | |
| lua_pushlstring(L, value, value_len); | |
| lua_concat(L, 3); | |
| lua_rawset(L, -3); | |
| } | |
| } | |
| next_field_loc = TSMimeHdrFieldNext(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| field_loc = next_field_loc; | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_get_header_block(lua_State *L) | |
| { | |
| TSIOBuffer output_buffer; | |
| TSIOBufferReader reader; | |
| int total_avail; | |
| TSIOBufferBlock block; | |
| const char *block_start; | |
| int64_t block_avail; | |
| char *output_string; | |
| int64_t output_len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| output_buffer = TSIOBufferCreate(); | |
| reader = TSIOBufferReaderAlloc(output_buffer); | |
| TSMimeHdrPrint(http_ctx->client_request_hdrp, output_buffer); | |
| total_avail = TSIOBufferReaderAvail(reader); | |
| output_string = static_cast<char *>(TSmalloc(total_avail + 1)); | |
| output_len = 0; | |
| block = TSIOBufferReaderStart(reader); | |
| while (block) { | |
| block_start = TSIOBufferBlockReadStart(block, reader, &block_avail); | |
| if (block_avail == 0) { | |
| break; | |
| } | |
| memcpy(output_string + output_len, block_start, block_avail); | |
| output_len += block_avail; | |
| TSIOBufferReaderConsume(reader, block_avail); | |
| block = TSIOBufferReaderStart(reader); | |
| } | |
| output_string[output_len] = '\0'; | |
| output_len++; | |
| TSIOBufferReaderFree(reader); | |
| TSIOBufferDestroy(output_buffer); | |
| if (output_string && output_len) { | |
| lua_pushlstring(L, output_string, output_len); | |
| } else { | |
| lua_pushnil(L); | |
| } | |
| TSfree(output_string); | |
| return 1; | |
| } | |
| static void | |
| ts_lua_inject_client_request_url_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_url); | |
| lua_setfield(L, -2, "get_url"); | |
| lua_pushcfunction(L, ts_lua_client_request_get_pristine_url); | |
| lua_setfield(L, -2, "get_pristine_url"); | |
| lua_pushcfunction(L, ts_lua_client_request_get_url_host); | |
| lua_setfield(L, -2, "get_url_host"); | |
| lua_pushcfunction(L, ts_lua_client_request_set_url_host); | |
| lua_setfield(L, -2, "set_url_host"); | |
| lua_pushcfunction(L, ts_lua_client_request_get_url_port); | |
| lua_setfield(L, -2, "get_url_port"); | |
| lua_pushcfunction(L, ts_lua_client_request_set_url_port); | |
| lua_setfield(L, -2, "set_url_port"); | |
| lua_pushcfunction(L, ts_lua_client_request_get_url_scheme); | |
| lua_setfield(L, -2, "get_url_scheme"); | |
| lua_pushcfunction(L, ts_lua_client_request_set_url_scheme); | |
| lua_setfield(L, -2, "set_url_scheme"); | |
| } | |
| static void | |
| ts_lua_inject_client_request_uri_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_set_uri); | |
| lua_setfield(L, -2, "set_uri"); | |
| lua_pushcfunction(L, ts_lua_client_request_get_uri); | |
| lua_setfield(L, -2, "get_uri"); | |
| } | |
| static int | |
| ts_lua_client_request_get_url(lua_State *L) | |
| { | |
| char *url; | |
| int url_len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| url = TSHttpTxnEffectiveUrlStringGet(http_ctx->txnp, &url_len); | |
| if (url) { | |
| lua_pushlstring(L, url, url_len); | |
| TSfree(url); | |
| } else { | |
| lua_pushnil(L); | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_get_pristine_url(lua_State *L) | |
| { | |
| char *url; | |
| int url_len; | |
| TSMBuffer bufp; | |
| TSMLoc url_loc; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| if (TSHttpTxnPristineUrlGet(http_ctx->txnp, &bufp, &url_loc) != TS_SUCCESS) { | |
| return 0; | |
| } | |
| url = TSUrlStringGet(bufp, url_loc, &url_len); | |
| if (url) { | |
| lua_pushlstring(L, url, url_len); | |
| TSfree(url); | |
| } else { | |
| lua_pushnil(L); | |
| } | |
| TSHandleMLocRelease(bufp, nullptr, url_loc); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_get_url_host(lua_State *L) | |
| { | |
| const char *host; | |
| int len = 0; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| host = TSUrlHostGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &len); | |
| if (len == 0) { | |
| char const *key = "Host"; | |
| char const *l_key = "host"; | |
| int key_len = 4; | |
| TSMLoc field_loc; | |
| field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len); | |
| if (field_loc) { | |
| host = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &len); | |
| TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| } else { | |
| field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, l_key, key_len); | |
| if (field_loc) { | |
| host = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &len); | |
| TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc); | |
| } | |
| } | |
| } | |
| lua_pushlstring(L, host, len); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_set_url_host(lua_State *L) | |
| { | |
| const char *host; | |
| size_t len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| host = luaL_checklstring(L, 1, &len); | |
| TSUrlHostSet(http_ctx->client_request_bufp, http_ctx->client_request_url, host, len); | |
| return 0; | |
| } | |
| static int | |
| ts_lua_client_request_get_url_port(lua_State *L) | |
| { | |
| int port; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| port = TSUrlPortGet(http_ctx->client_request_bufp, http_ctx->client_request_url); | |
| lua_pushnumber(L, port); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_set_url_port(lua_State *L) | |
| { | |
| int port; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| // NOLINTNEXTLINE | |
| port = luaL_checkint(L, 1); | |
| TSUrlPortSet(http_ctx->client_request_bufp, http_ctx->client_request_url, port); | |
| return 0; | |
| } | |
| static int | |
| ts_lua_client_request_get_url_scheme(lua_State *L) | |
| { | |
| const char *scheme; | |
| int len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| scheme = TSUrlSchemeGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &len); | |
| lua_pushlstring(L, scheme, len); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_set_url_scheme(lua_State *L) | |
| { | |
| const char *scheme; | |
| size_t len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| scheme = luaL_checklstring(L, 1, &len); | |
| TSUrlSchemeSet(http_ctx->client_request_bufp, http_ctx->client_request_url, scheme, len); | |
| return 0; | |
| } | |
| static int | |
| ts_lua_client_request_get_uri(lua_State *L) | |
| { | |
| const char *path; | |
| int path_len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| path = TSUrlPathGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &path_len); | |
| lua_pushlstring(L, "/", 1); | |
| lua_pushlstring(L, path, path_len >= TS_LUA_MAX_URL_LENGTH - 1 ? TS_LUA_MAX_URL_LENGTH - 2 : path_len); | |
| lua_concat(L, 2); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_set_uri(lua_State *L) | |
| { | |
| const char *path; | |
| size_t path_len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| path = luaL_checklstring(L, 1, &path_len); | |
| if (*path == '/') { | |
| path++; | |
| path_len--; | |
| } | |
| TSUrlPathSet(http_ctx->client_request_bufp, http_ctx->client_request_url, path, path_len); | |
| return 0; | |
| } | |
| static void | |
| ts_lua_inject_client_request_args_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_set_uri_args); | |
| lua_setfield(L, -2, "set_uri_args"); | |
| lua_pushcfunction(L, ts_lua_client_request_get_uri_args); | |
| lua_setfield(L, -2, "get_uri_args"); | |
| } | |
| static int | |
| ts_lua_client_request_get_uri_args(lua_State *L) | |
| { | |
| const char *param; | |
| int param_len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| param = TSUrlHttpQueryGet(http_ctx->client_request_bufp, http_ctx->client_request_url, ¶m_len); | |
| if (param && param_len > 0) { | |
| lua_pushlstring(L, param, param_len); | |
| } else { | |
| lua_pushnil(L); | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_set_uri_args(lua_State *L) | |
| { | |
| const char *param; | |
| size_t param_len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| param = luaL_checklstring(L, 1, ¶m_len); | |
| TSUrlHttpQuerySet(http_ctx->client_request_bufp, http_ctx->client_request_url, param, param_len); | |
| return 0; | |
| } | |
| static int | |
| ts_lua_client_request_client_addr_get_ip(lua_State *L) | |
| { | |
| struct sockaddr const *client_ip; | |
| char cip[128] = ""; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| client_ip = TSHttpTxnClientAddrGet(http_ctx->txnp); | |
| if (client_ip == nullptr) { | |
| lua_pushnil(L); | |
| } else { | |
| if (client_ip->sa_family == AF_INET) { | |
| inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)client_ip)->sin_addr, cip, sizeof(cip)); | |
| } else if (client_ip->sa_family == AF_INET6) { | |
| inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)client_ip)->sin6_addr, cip, sizeof(cip)); | |
| } | |
| lua_pushstring(L, cip); | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_addr_get_port(lua_State *L) | |
| { | |
| struct sockaddr const *client_ip; | |
| ts_lua_http_ctx *http_ctx; | |
| int port = 0; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| client_ip = TSHttpTxnClientAddrGet(http_ctx->txnp); | |
| if (client_ip == nullptr) { | |
| lua_pushnil(L); | |
| } else { | |
| if (client_ip->sa_family == AF_INET) { | |
| port = ((struct sockaddr_in *)client_ip)->sin_port; | |
| } else if (client_ip->sa_family == AF_INET6) { | |
| port = ((struct sockaddr_in6 *)client_ip)->sin6_port; | |
| } | |
| lua_pushnumber(L, port); | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_addr_get_incoming_port(lua_State *L) | |
| { | |
| struct sockaddr const *incoming_addr; | |
| ts_lua_http_ctx *http_ctx; | |
| int port = 0; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| incoming_addr = TSHttpTxnIncomingAddrGet(http_ctx->txnp); | |
| if (incoming_addr == nullptr) { | |
| lua_pushnil(L); | |
| } else { | |
| if (incoming_addr->sa_family == AF_INET) { | |
| port = ((struct sockaddr_in *)incoming_addr)->sin_port; | |
| } else if (incoming_addr->sa_family == AF_INET6) { | |
| port = ((struct sockaddr_in6 *)incoming_addr)->sin6_port; | |
| } | |
| lua_pushnumber(L, ntohs(port)); | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_addr_get_addr(lua_State *L) | |
| { | |
| struct sockaddr const *client_ip; | |
| ts_lua_http_ctx *http_ctx; | |
| int port = 0; | |
| int family = AF_UNSPEC; | |
| char cip[128] = ""; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| client_ip = TSHttpTxnClientAddrGet(http_ctx->txnp); | |
| if (client_ip == nullptr) { | |
| lua_pushnil(L); | |
| lua_pushnil(L); | |
| lua_pushnil(L); | |
| } else { | |
| if (client_ip->sa_family == AF_INET) { | |
| port = ntohs(((struct sockaddr_in *)client_ip)->sin_port); | |
| inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)client_ip)->sin_addr, cip, sizeof(cip)); | |
| family = AF_INET; | |
| } else if (client_ip->sa_family == AF_INET6) { | |
| port = ntohs(((struct sockaddr_in6 *)client_ip)->sin6_port); | |
| inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)client_ip)->sin6_addr, cip, sizeof(cip)); | |
| family = AF_INET6; | |
| } else if (client_ip->sa_family == AF_UNIX) { | |
| family = AF_UNIX; | |
| } | |
| lua_pushstring(L, cip); | |
| lua_pushnumber(L, port); | |
| lua_pushnumber(L, family); | |
| } | |
| return 3; | |
| } | |
| static void | |
| ts_lua_inject_client_request_method_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_method); | |
| lua_setfield(L, -2, "get_method"); | |
| lua_pushcfunction(L, ts_lua_client_request_set_method); | |
| lua_setfield(L, -2, "set_method"); | |
| } | |
| static int | |
| ts_lua_client_request_get_method(lua_State *L) | |
| { | |
| const char *method; | |
| int method_len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| method = TSHttpHdrMethodGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, &method_len); | |
| if (method && method_len) { | |
| lua_pushlstring(L, method, method_len); | |
| } else { | |
| lua_pushnil(L); | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_set_method(lua_State *L) | |
| { | |
| const char *method; | |
| size_t method_len; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| method = luaL_checklstring(L, 1, &method_len); | |
| if (method) { | |
| TSHttpHdrMethodSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, method, method_len); | |
| } | |
| return 0; | |
| } | |
| static void | |
| ts_lua_inject_client_request_body_size_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_body_size); | |
| lua_setfield(L, -2, "get_body_size"); | |
| } | |
| static int | |
| ts_lua_client_request_get_body_size(lua_State *L) | |
| { | |
| int64_t body_size; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| body_size = TSHttpTxnClientReqBodyBytesGet(http_ctx->txnp); | |
| lua_pushnumber(L, body_size); | |
| return 1; | |
| } | |
| static void | |
| ts_lua_inject_client_request_version_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_version); | |
| lua_setfield(L, -2, "get_version"); | |
| lua_pushcfunction(L, ts_lua_client_request_set_version); | |
| lua_setfield(L, -2, "set_version"); | |
| } | |
| static int | |
| ts_lua_client_request_get_version(lua_State *L) | |
| { | |
| int version; | |
| char buf[32]; | |
| int n; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| version = TSHttpHdrVersionGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp); | |
| n = snprintf(buf, sizeof(buf), "%d.%d", TS_HTTP_MAJOR(version), TS_HTTP_MINOR(version)); | |
| if (n >= (int)sizeof(buf)) { | |
| lua_pushlstring(L, buf, sizeof(buf) - 1); | |
| } else if (n > 0) { | |
| lua_pushlstring(L, buf, n); | |
| } | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_set_version(lua_State *L) | |
| { | |
| const char *version; | |
| size_t len; | |
| unsigned int major, minor; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| version = luaL_checklstring(L, 1, &len); | |
| if (sscanf(version, "%2u.%2u", &major, &minor) != 2) { | |
| return luaL_error(L, "failed to set version. Format must be X.Y"); | |
| } | |
| TSHttpHdrVersionSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, TS_HTTP_VERSION(major, minor)); | |
| return 0; | |
| } | |
| static void | |
| ts_lua_inject_client_request_header_size_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_header_size); | |
| lua_setfield(L, -2, "get_header_size"); | |
| } | |
| static int | |
| ts_lua_client_request_get_header_size(lua_State *L) | |
| { | |
| int header_size; | |
| ts_lua_http_ctx *http_ctx; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| header_size = TSHttpTxnClientReqHdrBytesGet(http_ctx->txnp); | |
| lua_pushnumber(L, header_size); | |
| return 1; | |
| } | |
| static void | |
| ts_lua_inject_client_request_ssl_reused_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_ssl_reused); | |
| lua_setfield(L, -2, "get_ssl_reused"); | |
| } | |
| static int | |
| ts_lua_client_request_get_ssl_reused(lua_State *L) | |
| { | |
| int ssl_reused = 0; | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| ssl_reused = TSVConnIsSslReused(client_conn); | |
| } | |
| lua_pushnumber(L, ssl_reused); | |
| return 1; | |
| } | |
| static void | |
| ts_lua_inject_client_request_ssl_cipher_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_ssl_cipher); | |
| lua_setfield(L, -2, "get_ssl_cipher"); | |
| } | |
| static int | |
| ts_lua_client_request_get_ssl_cipher(lua_State *L) | |
| { | |
| const char *ssl_cipher = "-"; | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| ssl_cipher = TSVConnSslCipherGet(client_conn); | |
| } | |
| lua_pushstring(L, ssl_cipher); | |
| return 1; | |
| } | |
| static void | |
| ts_lua_inject_client_request_ssl_protocol_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_ssl_protocol); | |
| lua_setfield(L, -2, "get_ssl_protocol"); | |
| } | |
| static int | |
| ts_lua_client_request_get_ssl_protocol(lua_State *L) | |
| { | |
| const char *ssl_protocol = "-"; | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| ssl_protocol = TSVConnSslProtocolGet(client_conn); | |
| } | |
| lua_pushstring(L, ssl_protocol); | |
| return 1; | |
| } | |
| static void | |
| ts_lua_inject_client_request_ssl_curve_api(lua_State *L) | |
| { | |
| lua_pushcfunction(L, ts_lua_client_request_get_ssl_curve); | |
| lua_setfield(L, -2, "get_ssl_curve"); | |
| } | |
| static int | |
| ts_lua_client_request_get_ssl_curve(lua_State *L) | |
| { | |
| const char *ssl_curve = "-"; | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| ssl_curve = TSVConnSslCurveGet(client_conn); | |
| } | |
| lua_pushstring(L, ssl_curve); | |
| return 1; | |
| } | |
| // Certificate API Functions | |
| static void | |
| ts_lua_inject_client_request_cert_api(lua_State *L) | |
| { | |
| // Client certificate functions | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_pem); | |
| lua_setfield(L, -2, "client_cert_get_pem"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_subject); | |
| lua_setfield(L, -2, "client_cert_get_subject"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_issuer); | |
| lua_setfield(L, -2, "client_cert_get_issuer"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_serial); | |
| lua_setfield(L, -2, "client_cert_get_serial"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_signature); | |
| lua_setfield(L, -2, "client_cert_get_signature"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_not_before); | |
| lua_setfield(L, -2, "client_cert_get_not_before"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_not_after); | |
| lua_setfield(L, -2, "client_cert_get_not_after"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_version); | |
| lua_setfield(L, -2, "client_cert_get_version"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_san_dns); | |
| lua_setfield(L, -2, "client_cert_get_san_dns"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_san_ip); | |
| lua_setfield(L, -2, "client_cert_get_san_ip"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_san_email); | |
| lua_setfield(L, -2, "client_cert_get_san_email"); | |
| lua_pushcfunction(L, ts_lua_client_request_client_cert_get_san_uri); | |
| lua_setfield(L, -2, "client_cert_get_san_uri"); | |
| // Server certificate functions | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_pem); | |
| lua_setfield(L, -2, "server_cert_get_pem"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_subject); | |
| lua_setfield(L, -2, "server_cert_get_subject"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_issuer); | |
| lua_setfield(L, -2, "server_cert_get_issuer"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_serial); | |
| lua_setfield(L, -2, "server_cert_get_serial"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_signature); | |
| lua_setfield(L, -2, "server_cert_get_signature"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_not_before); | |
| lua_setfield(L, -2, "server_cert_get_not_before"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_not_after); | |
| lua_setfield(L, -2, "server_cert_get_not_after"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_version); | |
| lua_setfield(L, -2, "server_cert_get_version"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_san_dns); | |
| lua_setfield(L, -2, "server_cert_get_san_dns"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_san_ip); | |
| lua_setfield(L, -2, "server_cert_get_san_ip"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_san_email); | |
| lua_setfield(L, -2, "server_cert_get_san_email"); | |
| lua_pushcfunction(L, ts_lua_client_request_server_cert_get_san_uri); | |
| lua_setfield(L, -2, "server_cert_get_san_uri"); | |
| } | |
| // Client Certificate Functions | |
| static int | |
| ts_lua_client_request_client_cert_get_pem(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::string pem = get_x509_pem_string(cert); | |
| X509_free(cert); | |
| if (!pem.empty()) { | |
| lua_pushlstring(L, pem.c_str(), pem.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_subject(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::string subject = get_x509_name_string(X509_get_subject_name(cert)); | |
| X509_free(cert); | |
| if (!subject.empty()) { | |
| lua_pushlstring(L, subject.c_str(), subject.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_issuer(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::string issuer = get_x509_name_string(X509_get_issuer_name(cert)); | |
| X509_free(cert); | |
| if (!issuer.empty()) { | |
| lua_pushlstring(L, issuer.c_str(), issuer.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_serial(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::string serial = get_x509_serial_string(cert); | |
| X509_free(cert); | |
| if (!serial.empty()) { | |
| lua_pushlstring(L, serial.c_str(), serial.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_signature(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::string sig = get_x509_signature_string(cert); | |
| X509_free(cert); | |
| if (!sig.empty()) { | |
| lua_pushlstring(L, sig.c_str(), sig.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_not_before(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::string not_before = get_x509_time_string(X509_get_notBefore(cert)); | |
| X509_free(cert); | |
| if (!not_before.empty()) { | |
| lua_pushlstring(L, not_before.c_str(), not_before.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_not_after(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::string not_after = get_x509_time_string(X509_get_notAfter(cert)); | |
| X509_free(cert); | |
| if (!not_after.empty()) { | |
| lua_pushlstring(L, not_after.c_str(), not_after.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_version(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| long version = X509_get_version(cert); | |
| X509_free(cert); | |
| lua_pushinteger(L, version); | |
| return 1; | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_san_dns(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::vector<std::string> dns_names = get_x509_san_strings(cert, GEN_DNS); | |
| X509_free(cert); | |
| if (!dns_names.empty()) { | |
| lua_newtable(L); | |
| for (size_t i = 0; i < dns_names.size(); i++) { | |
| lua_pushlstring(L, dns_names[i].c_str(), dns_names[i].length()); | |
| lua_rawseti(L, -2, i + 1); | |
| } | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_san_ip(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::vector<std::string> ip_addrs = get_x509_san_strings(cert, GEN_IPADD); | |
| X509_free(cert); | |
| if (!ip_addrs.empty()) { | |
| lua_newtable(L); | |
| for (size_t i = 0; i < ip_addrs.size(); i++) { | |
| lua_pushlstring(L, ip_addrs[i].c_str(), ip_addrs[i].length()); | |
| lua_rawseti(L, -2, i + 1); | |
| } | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_san_email(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::vector<std::string> emails = get_x509_san_strings(cert, GEN_EMAIL); | |
| X509_free(cert); | |
| if (!emails.empty()) { | |
| lua_newtable(L); | |
| for (size_t i = 0; i < emails.size(); i++) { | |
| lua_pushlstring(L, emails[i].c_str(), emails[i].length()); | |
| lua_rawseti(L, -2, i + 1); | |
| } | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_cert_get_san_uri(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| #ifdef OPENSSL_IS_AT_LEAST_OPENSSL3 | |
| X509 *cert = SSL_get1_peer_certificate(ssl); | |
| #else | |
| X509 *cert = SSL_get_peer_certificate(ssl); | |
| #endif | |
| if (cert) { | |
| std::vector<std::string> uris = get_x509_san_strings(cert, GEN_URI); | |
| X509_free(cert); | |
| if (!uris.empty()) { | |
| lua_newtable(L); | |
| for (size_t i = 0; i < uris.size(); i++) { | |
| lua_pushlstring(L, uris[i].c_str(), uris[i].length()); | |
| lua_rawseti(L, -2, i + 1); | |
| } | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| // Server Certificate Functions | |
| static int | |
| ts_lua_client_request_server_cert_get_pem(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::string pem = get_x509_pem_string(cert); | |
| if (!pem.empty()) { | |
| lua_pushlstring(L, pem.c_str(), pem.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_subject(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::string subject = get_x509_name_string(X509_get_subject_name(cert)); | |
| if (!subject.empty()) { | |
| lua_pushlstring(L, subject.c_str(), subject.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_issuer(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::string issuer = get_x509_name_string(X509_get_issuer_name(cert)); | |
| if (!issuer.empty()) { | |
| lua_pushlstring(L, issuer.c_str(), issuer.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_serial(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::string serial = get_x509_serial_string(cert); | |
| if (!serial.empty()) { | |
| lua_pushlstring(L, serial.c_str(), serial.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_signature(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::string sig = get_x509_signature_string(cert); | |
| if (!sig.empty()) { | |
| lua_pushlstring(L, sig.c_str(), sig.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_not_before(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::string not_before = get_x509_time_string(X509_get_notBefore(cert)); | |
| if (!not_before.empty()) { | |
| lua_pushlstring(L, not_before.c_str(), not_before.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_not_after(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::string not_after = get_x509_time_string(X509_get_notAfter(cert)); | |
| if (!not_after.empty()) { | |
| lua_pushlstring(L, not_after.c_str(), not_after.length()); | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_version(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| long version = X509_get_version(cert); | |
| lua_pushinteger(L, version); | |
| return 1; | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_san_dns(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::vector<std::string> dns_names = get_x509_san_strings(cert, GEN_DNS); | |
| if (!dns_names.empty()) { | |
| lua_newtable(L); | |
| for (size_t i = 0; i < dns_names.size(); i++) { | |
| lua_pushlstring(L, dns_names[i].c_str(), dns_names[i].length()); | |
| lua_rawseti(L, -2, i + 1); | |
| } | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_san_ip(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::vector<std::string> ip_addrs = get_x509_san_strings(cert, GEN_IPADD); | |
| if (!ip_addrs.empty()) { | |
| lua_newtable(L); | |
| for (size_t i = 0; i < ip_addrs.size(); i++) { | |
| lua_pushlstring(L, ip_addrs[i].c_str(), ip_addrs[i].length()); | |
| lua_rawseti(L, -2, i + 1); | |
| } | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_san_email(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::vector<std::string> emails = get_x509_san_strings(cert, GEN_EMAIL); | |
| if (!emails.empty()) { | |
| lua_newtable(L); | |
| for (size_t i = 0; i < emails.size(); i++) { | |
| lua_pushlstring(L, emails[i].c_str(), emails[i].length()); | |
| lua_rawseti(L, -2, i + 1); | |
| } | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_server_cert_get_san_uri(lua_State *L) | |
| { | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnIsSsl(client_conn)) { | |
| TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn); | |
| if (ssl_conn) { | |
| SSL *ssl = reinterpret_cast<SSL *>(ssl_conn); | |
| X509 *cert = SSL_get_certificate(ssl); | |
| if (cert) { | |
| std::vector<std::string> uris = get_x509_san_strings(cert, GEN_URI); | |
| if (!uris.empty()) { | |
| lua_newtable(L); | |
| for (size_t i = 0; i < uris.size(); i++) { | |
| lua_pushlstring(L, uris[i].c_str(), uris[i].length()); | |
| lua_rawseti(L, -2, i + 1); | |
| } | |
| return 1; | |
| } | |
| } | |
| } | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static void | |
| ts_lua_inject_client_request_pp_info_api(lua_State *L) | |
| { | |
| size_t i; | |
| for (i = 0; i < sizeof(ts_lua_pp_info_key_vars) / sizeof(ts_lua_var_item); i++) { | |
| lua_pushinteger(L, ts_lua_pp_info_key_vars[i].nvar); | |
| lua_setglobal(L, ts_lua_pp_info_key_vars[i].svar); | |
| } | |
| lua_pushcfunction(L, ts_lua_client_request_get_pp_info); | |
| lua_setfield(L, -2, "get_pp_info"); | |
| lua_pushcfunction(L, ts_lua_client_request_get_pp_info_int); | |
| lua_setfield(L, -2, "get_pp_info_int"); | |
| } | |
| static int | |
| ts_lua_client_request_get_pp_info(lua_State *L) | |
| { | |
| uint16_t key; | |
| const char *value = nullptr; | |
| int length; | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| key = static_cast<uint16_t>(luaL_checkinteger(L, 1)); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnPPInfoGet(client_conn, key, &value, &length) == TS_SUCCESS) { | |
| if (key == TS_PP_INFO_SRC_ADDR || key == TS_PP_INFO_DST_ADDR) { | |
| // For addresses, convert sockaddr to string | |
| char ip_str[INET6_ADDRSTRLEN]; | |
| const sockaddr *addr = reinterpret_cast<const sockaddr *>(value); | |
| const sockaddr_in *addr_in; | |
| const sockaddr_in6 *addr_in6; | |
| if (addr->sa_family == AF_INET) { | |
| addr_in = reinterpret_cast<const sockaddr_in *>(addr); | |
| inet_ntop(AF_INET, &addr_in->sin_addr, ip_str, sizeof(ip_str)); | |
| } else if (addr->sa_family == AF_INET6) { | |
| addr_in6 = reinterpret_cast<const sockaddr_in6 *>(addr); | |
| inet_ntop(AF_INET6, &addr_in6->sin6_addr, ip_str, sizeof(ip_str)); | |
| } else { | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| lua_pushstring(L, ip_str); | |
| } else { | |
| // For other types, return as string | |
| lua_pushlstring(L, value, length); | |
| } | |
| return 1; | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_get_pp_info_int(lua_State *L) | |
| { | |
| uint16_t key; | |
| TSMgmtInt value; | |
| ts_lua_http_ctx *http_ctx; | |
| TSHttpSsn ssnp; | |
| TSVConn client_conn; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| key = static_cast<uint16_t>(luaL_checkinteger(L, 1)); | |
| ssnp = TSHttpTxnSsnGet(http_ctx->txnp); | |
| client_conn = TSHttpSsnClientVConnGet(ssnp); | |
| if (TSVConnPPInfoIntGet(client_conn, key, &value) == TS_SUCCESS) { | |
| lua_pushinteger(L, value); | |
| return 1; | |
| } | |
| lua_pushnil(L); | |
| return 1; | |
| } | |
| static int | |
| ts_lua_client_request_client_addr_get_verified_addr(lua_State *L) | |
| { | |
| struct sockaddr const *verified_addr; | |
| ts_lua_http_ctx *http_ctx; | |
| int family = AF_UNSPEC; | |
| char vip[128] = ""; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| if (TSHttpTxnVerifiedAddrGet(http_ctx->txnp, &verified_addr) == TS_SUCCESS) { | |
| if (verified_addr->sa_family == AF_INET) { | |
| inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)verified_addr)->sin_addr, vip, sizeof(vip)); | |
| family = AF_INET; | |
| lua_pushstring(L, vip); | |
| lua_pushnumber(L, family); | |
| } else if (verified_addr->sa_family == AF_INET6) { | |
| inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)verified_addr)->sin6_addr, vip, sizeof(vip)); | |
| family = AF_INET6; | |
| lua_pushstring(L, vip); | |
| lua_pushnumber(L, family); | |
| } else { | |
| lua_pushnil(L); | |
| lua_pushnil(L); | |
| } | |
| } else { | |
| lua_pushnil(L); | |
| lua_pushnil(L); | |
| } | |
| return 2; | |
| } | |
| static int | |
| ts_lua_client_request_client_addr_set_verified_addr(lua_State *L) | |
| { | |
| union { | |
| struct sockaddr_in sin4; | |
| struct sockaddr_in6 sin6; | |
| struct sockaddr sa; | |
| } addr; | |
| memset(&addr, 0, sizeof(addr)); | |
| ts_lua_http_ctx *http_ctx; | |
| int n; | |
| int family; | |
| const char *vip; | |
| size_t vip_len; | |
| GET_HTTP_CONTEXT(http_ctx, L); | |
| n = lua_gettop(L); | |
| if (n == 2) { | |
| vip = luaL_checklstring(L, 1, &vip_len); | |
| family = luaL_checknumber(L, 2); | |
| if (family == AF_INET) { | |
| addr.sin4.sin_family = AF_INET; | |
| addr.sin4.sin_port = 0; | |
| if (!inet_pton(family, vip, &addr.sin4.sin_addr)) { | |
| return luaL_error(L, "invalid ipv4 address"); | |
| } | |
| } else if (family == AF_INET6) { | |
| addr.sin6.sin6_family = AF_INET6; | |
| addr.sin6.sin6_port = 0; | |
| if (!inet_pton(family, vip, &addr.sin6.sin6_addr)) { | |
| return luaL_error(L, "invalid ipv6 address"); | |
| } | |
| } else { | |
| return luaL_error(L, "invalid address family"); | |
| } | |
| TSHttpTxnVerifiedAddrSet(http_ctx->txnp, &addr.sa); | |
| } else { | |
| return luaL_error(L, "incorrect # of arguments to ts.client_request.client_addr.set_verified_addr, receiving %d instead of 2", | |
| n); | |
| } | |
| return 0; | |
| } |