From 79b35dcb04b049a027315c4b3e4b2e7d66eeb33c Mon Sep 17 00:00:00 2001 From: dmiller Date: Thu, 3 Oct 2024 19:18:13 +0000 Subject: [PATCH] Add binding for libssh2_userauth_publickey_frommemory --- nse_libssh2.cc | 82 ++++++++++++++++++++++++++------------ nselib/libssh2-utility.lua | 23 ++++++++++- 2 files changed, 78 insertions(+), 27 deletions(-) diff --git a/nse_libssh2.cc b/nse_libssh2.cc index ee146edd2..e95ef1d90 100644 --- a/nse_libssh2.cc +++ b/nse_libssh2.cc @@ -506,45 +506,76 @@ static int l_userauth_banner (lua_State *L) { return userauth_banner(L, 0, 0); } +struct publickey_ctx { + struct ssh_userdata *state; + const char *username; + size_t username_len; + const char *privkey; + size_t privkey_len; + const char *pubkey; + size_t pubkey_len; + const char *passphrase; +}; + +static void validate_publickey_params(lua_State *L, struct publickey_ctx *ctx) { + memset(ctx, 0, sizeof(struct publickey_ctx)); + ctx->state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + ctx->username = luaL_checklstring(L, 2, &ctx->username_len); + ctx->privkey = luaL_checklstring(L, 3, &ctx->privkey_len); + + ctx->passphrase = lua_isstring(L, 4) ? lua_tostring(L, 4) : NULL; + ctx->pubkey = lua_isstring(L, 4) ? lua_tolstring(L, 4, &ctx->pubkey_len) : NULL; +} + static int userauth_publickey (lua_State *L, int status, lua_KContext ctx) { + struct publickey_ctx *context = (struct publickey_ctx *)ctx; int rc; - const char *username, *private_key_file, *passphrase, *public_key_file; - struct ssh_userdata *state = NULL; - state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); - - username = luaL_checkstring(L, 2); - private_key_file = luaL_checkstring(L, 3); - - if (lua_isstring(L, 4)) - passphrase = lua_tostring(L, 4); - else - passphrase = NULL; - - if (lua_isstring(L, 5)) - public_key_file = lua_tostring(L, 5); - else - public_key_file = NULL; - - while ((rc = libssh2_userauth_publickey_fromfile( - state->session, username, public_key_file, private_key_file, passphrase + while ((rc = libssh2_userauth_publickey_fromfile_ex( + context->state->session, context->username, context->username_len, + context->pubkey, context->privkey, context->passphrase )) == LIBSSH2_ERROR_EAGAIN) { luaL_getmetafield(L, 1, "filter"); lua_pushvalue(L, 1); assert(lua_status(L) == LUA_OK); - lua_callk(L, 1, 0, 0, userauth_publickey); + lua_callk(L, 1, 0, ctx, userauth_publickey); } - if (rc == 0) - lua_pushboolean(L, 1); - else - lua_pushboolean(L, 0); + lua_pushboolean(L, (rc == 0)); return 1; } static int l_userauth_publickey (lua_State *L) { - return userauth_publickey(L, 0, 0); + struct publickey_ctx params; + validate_publickey_params(L, ¶ms); + return userauth_publickey(L, 0, (lua_KContext) ¶ms); +} + +static int userauth_publickey_frommemory (lua_State *L, int status, lua_KContext ctx) { + struct publickey_ctx *context = (struct publickey_ctx *)ctx; + int rc; + while ((rc = libssh2_userauth_publickey_frommemory( + context->state->session, context->username, context->username_len, + context->pubkey, context->pubkey_len, context->privkey, + context->privkey_len, context->passphrase + )) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + + assert(lua_status(L) == LUA_OK); + lua_callk(L, 1, 0, ctx, userauth_publickey_frommemory); + } + + lua_pushboolean(L, (rc == 0)); + + return 1; +} + +static int l_userauth_publickey_frommemory (lua_State *L) { + struct publickey_ctx params; + validate_publickey_params(L, ¶ms); + return userauth_publickey_frommemory(L, 0, (lua_KContext) ¶ms); } static int l_read_publickey (lua_State *L) { @@ -891,6 +922,7 @@ static const struct luaL_Reg libssh2[] = { { "userauth_banner", l_userauth_banner }, { "userauth_list", l_userauth_list }, { "userauth_publickey", l_userauth_publickey }, + { "userauth_publickey_frommemory", l_userauth_publickey_frommemory }, { "read_publickey", l_read_publickey }, { "publickey_canauth", l_publickey_canauth }, { "userauth_password", l_userauth_password }, diff --git a/nselib/libssh2-utility.lua b/nselib/libssh2-utility.lua index 73626e443..5795de140 100644 --- a/nselib/libssh2-utility.lua +++ b/nselib/libssh2-utility.lua @@ -95,10 +95,10 @@ function SSHConnection:password_auth (username, password) end --- --- Attempts to authenticate using provided private key. +-- Attempts to authenticate using provided private key file. -- -- @param username A username to authenticate as. --- @param privatekey_file A path to a privatekey. +-- @param privatekey_file A path to a privatekey file. -- @param passphrase A passphrase for the privatekey. -- @return true on success or false on failure. function SSHConnection:publickey_auth (username, privatekey_file, passphrase) @@ -113,6 +113,25 @@ function SSHConnection:publickey_auth (username, privatekey_file, passphrase) end end +--- +-- Attempts to authenticate using provided private key. +-- +-- @param username A username to authenticate as. +-- @param privatekey The privatekey as a string. +-- @param passphrase A passphrase for the privatekey. +-- @return true on success or false on failure. +function SSHConnection:publickey_auth_frommemory (username, privatekey, passphrase) + if not self.session then + return false + end + if libssh2.userauth_publickey_frommemory(self.session, username, privatekey, passphrase or "") then + self.authenticated = true + return true + else + return false + end +end + --- -- Closes connection. function SSHConnection:disconnect ()