local ssh = require("suricata.ssh")
+If you want to use hassh, you can either set suricata.yaml option
+``app-layer.protocols.ssh.hassh`` to true,
+or specify it in the ``init`` function of your lua script
+by calling ``ssh.enable_hassh()``::
+
+ function init (args)
+ ssh.enable_hassh()
+ return {}
+ end
+
For use in rule matching, the rule must **hook** into a SSH
transaction state. Available states are listed in :ref:`ssh-hooks`.
For example:
local tx = ssh.get_tx()
local software = tx:client_software();
print (software)
+
+``client_hassh()``
+^^^^^^^^^^^^^^^^^^
+
+Should be used with ``ssh.enable_hassh()``.
+
+Get MD5 of hassh algorithms used by the client through client_hassh.
+
+Example::
+
+ local tx = ssh.get_tx()
+ local h = tx:client_hassh();
+ print (h)
+
+
+``client_hassh_string()``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Should be used with ``ssh.enable_hassh()``.
+
+Get hassh algorithms used by the client through client_hassh_string.
+
+Example::
+
+ local tx = ssh.get_tx()
+ local h = tx:client_hassh_string();
+ print (h)
+
+``server_hassh()``
+^^^^^^^^^^^^^^^^^^
+
+Should be used with ``ssh.enable_hassh()``.
+
+Get MD5 of hassh algorithms used by the server through server_hassh.
+
+Example::
+
+ local tx = ssh.get_tx()
+ local h = tx:server_hassh();
+ print (h)
+
+``server_hassh_string()``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Should be used with ``ssh.enable_hassh()``.
+
+Get hassh algorithms used by the server through server_hassh_string.
+
+Example::
+
+ local tx = ssh.get_tx()
+ local h = tx:server_hassh_string();
+ print (h)
+++ /dev/null
-/* Copyright (C) 2020 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-
-/**
- * \file
- *
- * \author Vadym Malakhatko <v.malakhatko@sirinsoftware.com>
- *
- */
-
-#include "suricata-common.h"
-#include "detect.h"
-#include "pkt-var.h"
-#include "conf.h"
-
-#include "threads.h"
-#include "threadvars.h"
-#include "tm-threads.h"
-
-#include "util-print.h"
-#include "util-unittest.h"
-
-#include "util-debug.h"
-
-#include "output.h"
-#include "app-layer.h"
-#include "app-layer-parser.h"
-#include "app-layer-ssl.h"
-#include "util-privs.h"
-#include "util-buffer.h"
-#include "util-proto-name.h"
-#include "util-logopenfile.h"
-#include "util-time.h"
-
-#include "lua.h"
-#include "lualib.h"
-#include "lauxlib.h"
-
-#include "util-lua.h"
-#include "util-lua-common.h"
-#include "util-lua-hassh.h"
-
-static int GetHasshServerString(lua_State *luastate, const Flow *f)
-{
- void *state = FlowGetAppState(f);
- if (state == NULL)
- return LuaCallbackError(luastate, "error: no app layer state");
-
- const uint8_t *hassh_server_string = NULL;
- uint32_t b_len = 0;
-
- void *tx = SCSshStateGetTx(state, 0);
- if (SCSshTxGetHasshString(tx, &hassh_server_string, &b_len, STREAM_TOCLIENT) != 1)
- return LuaCallbackError(luastate, "error: no server hassh string");
- if (hassh_server_string == NULL || b_len == 0) {
- return LuaCallbackError(luastate, "error: no server hassh string");
- }
-
- return LuaPushStringBuffer(luastate, hassh_server_string, b_len);
-}
-
-static int HasshServerGetString(lua_State *luastate)
-{
- int r;
-
- if (!(LuaStateNeedProto(luastate, ALPROTO_SSH)))
- return LuaCallbackError(luastate, "error: protocol is not ssh");
-
- Flow *f = LuaStateGetFlow(luastate);
- if (f == NULL)
- return LuaCallbackError(luastate, "internal error: no ssh flow");
-
- r = GetHasshServerString(luastate, f);
-
- return r;
-}
-
-static int GetHasshServer(lua_State *luastate, const Flow *f)
-{
- void *state = FlowGetAppState(f);
- if (state == NULL)
- return LuaCallbackError(luastate, "error: no ssh app layer state");
-
- const uint8_t *hassh_server = NULL;
- uint32_t b_len = 0;
-
- void *tx = SCSshStateGetTx(state, 0);
- if (SCSshTxGetHassh(tx, &hassh_server, &b_len, STREAM_TOCLIENT) != 1)
- return LuaCallbackError(luastate, "error: no server hassh");
- if (hassh_server == NULL || b_len == 0) {
- return LuaCallbackError(luastate, "error: no server hassh");
- }
-
- return LuaPushStringBuffer(luastate, hassh_server, b_len);
-}
-
-static int HasshServerGet(lua_State *luastate)
-{
- int r;
-
- if (!(LuaStateNeedProto(luastate, ALPROTO_SSH)))
- return LuaCallbackError(luastate, "error: protocol is not ssh");
-
- Flow *f = LuaStateGetFlow(luastate);
- if (f == NULL)
- return LuaCallbackError(luastate, "internal error: no ssh flow");
-
- r = GetHasshServer(luastate, f);
-
- return r;
-}
-
-static int GetHasshString(lua_State *luastate, const Flow *f)
-{
- void *state = FlowGetAppState(f);
- if (state == NULL)
- return LuaCallbackError(luastate, "error: no app layer state");
-
- const uint8_t *hassh_string = NULL;
- uint32_t b_len = 0;
-
- void *tx = SCSshStateGetTx(state, 0);
- if (SCSshTxGetHasshString(tx, &hassh_string, &b_len, STREAM_TOSERVER) != 1)
- return LuaCallbackError(luastate, "error: no client hassh_string");
- if (hassh_string == NULL || b_len == 0) {
- return LuaCallbackError(luastate, "error: no client hassh_string");
- }
-
- return LuaPushStringBuffer(luastate, hassh_string, b_len);
-}
-
-static int HasshGetString(lua_State *luastate)
-{
- int r;
-
- if (!(LuaStateNeedProto(luastate, ALPROTO_SSH)))
- return LuaCallbackError(luastate, "error: protocol is not ssh");
-
- Flow *f = LuaStateGetFlow(luastate);
- if (f == NULL)
- return LuaCallbackError(luastate, "internal error: no ssh flow");
-
- r = GetHasshString(luastate, f);
-
- return r;
-}
-
-static int GetHassh(lua_State *luastate, const Flow *f)
-{
- void *state = FlowGetAppState(f);
- if (state == NULL)
- return LuaCallbackError(luastate, "error: no app layer state");
-
- const uint8_t *hassh = NULL;
- uint32_t b_len = 0;
-
- void *tx = SCSshStateGetTx(state, 0);
- if (SCSshTxGetHassh(tx, &hassh, &b_len, STREAM_TOSERVER) != 1)
- return LuaCallbackError(luastate, "error: no client hassh");
- if (hassh == NULL || b_len == 0) {
- return LuaCallbackError(luastate, "error: no client hassh");
- }
-
- return LuaPushStringBuffer(luastate, hassh, b_len);
-}
-
-static int HasshGet(lua_State *luastate)
-{
- int r;
-
- if (!(LuaStateNeedProto(luastate, ALPROTO_SSH)))
- return LuaCallbackError(luastate, "error: protocol is not ssh");
-
- Flow *f = LuaStateGetFlow(luastate);
- if (f == NULL)
- return LuaCallbackError(luastate, "internal error: no sshflow");
-
- r = GetHassh(luastate, f);
-
- return r;
-}
-
-/** *\brief Register Hassh Lua extensions */
-int LuaRegisterHasshFunctions(lua_State *luastate)
-{
-
- lua_pushcfunction(luastate, HasshGet);
- lua_setglobal(luastate, "HasshGet");
-
- lua_pushcfunction(luastate, HasshGetString);
- lua_setglobal(luastate, "HasshGetString");
-
- lua_pushcfunction(luastate, HasshServerGet);
- lua_setglobal(luastate, "HasshServerGet");
-
- lua_pushcfunction(luastate, HasshServerGetString);
- lua_setglobal(luastate, "HasshServerGetString");
-
- return 0;
-}
return LuaSshTxGetSoftware(L, STREAM_TOSERVER);
}
+static int LuaSshTxGetHassh(lua_State *L, uint8_t flags)
+{
+ const uint8_t *buf = NULL;
+ uint32_t b_len = 0;
+ struct LuaTx *ltx = luaL_testudata(L, 1, ssh_tx);
+ if (ltx == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+ if (SCSshTxGetHassh(ltx->tx, &buf, &b_len, flags) != 1) {
+ lua_pushnil(L);
+ return 1;
+ }
+ return LuaPushStringBuffer(L, buf, b_len);
+}
+
+static int LuaSshTxGetClientHassh(lua_State *L)
+{
+ return LuaSshTxGetHassh(L, STREAM_TOSERVER);
+}
+
+static int LuaSshTxGetServerHassh(lua_State *L)
+{
+ return LuaSshTxGetHassh(L, STREAM_TOCLIENT);
+}
+
+static int LuaSshTxGetHasshString(lua_State *L, uint8_t flags)
+{
+ const uint8_t *buf = NULL;
+ uint32_t b_len = 0;
+ struct LuaTx *ltx = luaL_testudata(L, 1, ssh_tx);
+ if (ltx == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+ if (SCSshTxGetHasshString(ltx->tx, &buf, &b_len, flags) != 1) {
+ lua_pushnil(L);
+ return 1;
+ }
+ return LuaPushStringBuffer(L, buf, b_len);
+}
+
+static int LuaSshTxGetClientHasshString(lua_State *L)
+{
+ return LuaSshTxGetHasshString(L, STREAM_TOSERVER);
+}
+
+static int LuaSshTxGetServerHasshString(lua_State *L)
+{
+ return LuaSshTxGetHasshString(L, STREAM_TOCLIENT);
+}
+
static const struct luaL_Reg txlib[] = {
// clang-format off
{ "server_proto", LuaSshTxGetServerProto },
{ "server_software", LuaSshTxGetServerSoftware },
{ "client_proto", LuaSshTxGetClientProto },
{ "client_software", LuaSshTxGetClientSoftware },
+ { "client_hassh", LuaSshTxGetClientHassh },
+ { "server_hassh", LuaSshTxGetServerHassh },
+ { "client_hassh_string", LuaSshTxGetClientHasshString },
+ { "server_hassh_string", LuaSshTxGetServerHasshString },
{ NULL, NULL, }
// clang-format on
};
+static int LuaSshEnableHassh(lua_State *L)
+{
+ SCSshEnableHassh();
+ return 1;
+}
+
static const struct luaL_Reg sshlib[] = {
// clang-format off
{ "get_tx", LuaSshGetTx },
+ { "enable_hassh", LuaSshEnableHassh },
{ NULL, NULL,},
// clang-format on
};