diff --git a/proxy.h b/proxy.h index 53a833b1d..a32885968 100644 --- a/proxy.h +++ b/proxy.h @@ -789,6 +789,7 @@ int mcplib_rcontext_res_any(lua_State *L); int mcplib_rcontext_res_ok(lua_State *L); int mcplib_rcontext_result(lua_State *L); int mcplib_rcontext_cfd(lua_State *L); +int mcplib_rcontext_tls_peer_cn(lua_State *L); int mcplib_rcontext_sleep(lua_State *L); int mcplib_funcgenbare_new(lua_State *L); int mcplib_funcgen_new(lua_State *L); diff --git a/proxy_lua.c b/proxy_lua.c index f13957a77..61f1bec58 100644 --- a/proxy_lua.c +++ b/proxy_lua.c @@ -1673,6 +1673,7 @@ int proxy_register_libs(void *ctx, LIBEVENT_THREAD *t, void *state) { {"res_any", mcplib_rcontext_res_any}, {"result", mcplib_rcontext_result}, {"cfd", mcplib_rcontext_cfd}, + {"tls_peer_cn", mcplib_rcontext_tls_peer_cn}, //{"sleep", mcplib_rcontext_sleep}, see comments on function {NULL, NULL} }; diff --git a/proxy_luafgen.c b/proxy_luafgen.c index eae45eeac..9d68b0122 100644 --- a/proxy_luafgen.c +++ b/proxy_luafgen.c @@ -1,6 +1,9 @@ /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "proxy.h" +#ifdef TLS +#include "tls.h" +#endif static mcp_funcgen_t *mcp_funcgen_route(lua_State *L, mcp_funcgen_t *fgen, mcp_parser_t *pr); static int mcp_funcgen_router_cleanup(lua_State *L, mcp_funcgen_t *fgen); @@ -1405,6 +1408,29 @@ int mcplib_rcontext_cfd(lua_State *L) { return 1; } +// Must not call this if rctx has returned result to client already. +int mcplib_rcontext_tls_peer_cn(lua_State *L) { + mcp_rcontext_t *rctx = lua_touserdata(L, 1); + if (!rctx->c) { + lua_pushnil(L); + return 1; + } + +#ifdef TLS + int len = 0; + const unsigned char *cn = ssl_get_peer_cn(rctx->c, &len); + if (cn) { + lua_pushlstring(L, (const char *)cn, len); + } else { + lua_pushnil(L); + } +#else + lua_pushnil(L); +#endif + + return 1; +} + // the supplied handle must be valid. void mcp_rcontext_push_rqu_res(lua_State *L, mcp_rcontext_t *rctx, int handle) { struct mcp_rqueue_s *rqu = &rctx->qslots[handle]; diff --git a/tls.c b/tls.c index caf2f97a7..71a29f863 100644 --- a/tls.c +++ b/tls.c @@ -119,6 +119,41 @@ void *ssl_accept(conn *c, int sfd, bool *fail) { * that for a future refactor. */ +// TODO: add int offset, and find the nth NID here. +// or different function that accepts a string, then does etc? +// Caller _must immediately_ use the string and not store the pointer. +const unsigned char *ssl_get_peer_cn(conn *c, int *len) { + if (!c->ssl) { + return NULL; + } + + // can't use get0 to avoid getting a reference since that requires 3.0.0+ + X509 *cert = SSL_get_peer_certificate(c->ssl); + if (cert == NULL) { + return NULL; + } + X509_NAME *name = X509_get_subject_name(cert); + if (name == NULL) { + X509_free(cert); + return NULL; + } + + int r = X509_NAME_get_index_by_NID(name, NID_commonName, -1); + if (r == -1) { + X509_free(cert); + return NULL; + } + ASN1_STRING *asn1 = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, r)); + + if (asn1 == NULL) { + X509_free(cert); + return NULL; + } + *len = ASN1_STRING_length(asn1); + X509_free(cert); + return ASN1_STRING_get0_data(asn1); +} + /* * Reads decrypted data from the underlying BIO read buffers, * which reads from the socket. diff --git a/tls.h b/tls.h index b183e478a..acbb3a536 100644 --- a/tls.h +++ b/tls.h @@ -8,6 +8,7 @@ #ifdef TLS void *ssl_accept(conn *c, int sfd, bool *fail); +const unsigned char *ssl_get_peer_cn(conn *c, int *len); int ssl_init(void); void ssl_init_settings(void); void ssl_init_conn(conn *c, void *ssl);