OpenVAS Scanner 23.32.3
nasl_ssh.h File Reference

Protos and data structures for SSH functions used by NASL scripts. More...

#include "nasl_lex_ctxt.h"
#include <libssh/libssh.h>
Include dependency graph for nasl_ssh.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

tree_cellnasl_ssh_connect (lex_ctxt *lexic)
 Connect to the target host via TCP and setup an ssh connection.
tree_cellnasl_ssh_disconnect (lex_ctxt *lexic)
 Disconnect an ssh connection.
tree_cellnasl_ssh_session_id_from_sock (lex_ctxt *lexic)
 Given a socket, return the corresponding session id.
tree_cellnasl_ssh_get_sock (lex_ctxt *lexic)
 Given a session id, return the corresponding socket.
tree_cellnasl_ssh_set_login (lex_ctxt *lexic)
 Set the login name for the authentication.
tree_cellnasl_ssh_userauth (lex_ctxt *lexic)
 Authenticate a user on an ssh connection.
tree_cellnasl_ssh_request_exec (lex_ctxt *lexic)
 Run a command via ssh.
tree_cellnasl_ssh_shell_open (lex_ctxt *lexic)
 Request an ssh shell.
tree_cellnasl_ssh_shell_read (lex_ctxt *lexic)
 Read the output of an ssh shell.
tree_cellnasl_ssh_shell_write (lex_ctxt *lexic)
 Write string to ssh shell.
tree_cellnasl_ssh_shell_close (lex_ctxt *lexic)
 Close an ssh shell.
tree_cellnasl_ssh_login_interactive (lex_ctxt *lexic)
 Authenticate a user on an ssh connection.
tree_cellnasl_ssh_login_interactive_pass (lex_ctxt *lexic)
 Authenticate a user on an ssh connection.
tree_cellnasl_ssh_exec (lex_ctxt *)
tree_cellnasl_ssh_get_issue_banner (lex_ctxt *lexic)
 Get the issue banner.
tree_cellnasl_ssh_get_server_banner (lex_ctxt *lexic)
 Get the server banner.
tree_cellnasl_ssh_get_auth_methods (lex_ctxt *lexic)
 Get the list of authmethods.
tree_cellnasl_ssh_get_host_key (lex_ctxt *lexic)
 Get the host key.
tree_cellnasl_sftp_enabled_check (lex_ctxt *)
 Check if the SFTP subsystem is enabled on the remote SSH server.
tree_cellnasl_ssh_execute_netconf_subsystem (lex_ctxt *)
 Excecute the NETCONF subsystem on the the ssh channel.

Detailed Description

Protos and data structures for SSH functions used by NASL scripts.

This file contains the protos for nasl_ssh.c

Definition in file nasl_ssh.h.

Function Documentation

◆ nasl_sftp_enabled_check()

tree_cell * nasl_sftp_enabled_check ( lex_ctxt * lexic)

Check if the SFTP subsystem is enabled on the remote SSH server.

NASL Function: sftp_enabled_check\n
NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Returns:\n An integer: 0 on success, -1 (SSH_ERROR) on Channel request
subsystem failure. Greater than 0 means an error during SFTP init. NULL indicates a failure during session id verification.
Parameters
[in]lexicLexical context of NASL interpreter.

Definition at line 1993 of file nasl_ssh.c.

1994{
1995 int tbl_slot, session_id;
1996 tree_cell *retc;
1997 sftp_session sftp;
1998 ssh_session session;
1999 int rc, verbose = 0;
2000
2001 session_id = get_int_var_by_num (lexic, 0, -1);
2002 if (!verify_session_id (session_id, "sftp_enabled_check", &tbl_slot, lexic))
2003 return NULL;
2004
2005 session = session_table[tbl_slot].session;
2006 verbose = session_table[tbl_slot].verbose;
2007
2008 sftp = sftp_new (session);
2009 if (sftp == NULL)
2010 {
2011 if (verbose)
2012 g_message (
2013 "Function %s (calling internal function %s) called from %s: %s",
2015 : "script_main_function",
2016 __func__, nasl_get_plugin_filename (),
2017 ssh_get_error (session_table[tbl_slot].session));
2018 rc = SSH_ERROR;
2019 goto write_ret;
2020 }
2021
2022 rc = sftp_init (sftp);
2023 if (rc != SSH_OK)
2024 {
2025 if (verbose)
2026 {
2027 g_message ("Function %s (calling internal function %s) called from "
2028 "%s: %s. Code %d",
2030 : "script_main_function",
2031 __func__, nasl_get_plugin_filename (),
2032 ssh_get_error (session_table[tbl_slot].session),
2033 sftp_get_error (sftp));
2034 }
2035 }
2036 sftp_free (sftp);
2037
2038write_ret:
2039
2040 retc = alloc_typed_cell (CONST_INT);
2041 retc->x.i_val = rc;
2042 return retc;
2043}
const char * nasl_get_plugin_filename()
Get the current launched plugin filename.
Definition nasl_debug.c:36
const char * nasl_get_function_name()
Definition nasl_debug.c:76
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition nasl_var.c:1094
static struct session_table_item_s session_table[MAX_SSH_SESSIONS]
Definition nasl_ssh.c:104
static int verify_session_id(int session_id, const char *funcname, int *r_slot, lex_ctxt *lexic)
Definition nasl_ssh.c:452
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ CONST_INT
Definition nasl_tree.h:79
struct TC tree_cell
long int i_val
Definition nasl_tree.h:104
union TC::@332262321161220155002104006201360276211317150140 x

References alloc_typed_cell(), CONST_INT, get_int_var_by_num(), TC::i_val, nasl_get_function_name(), nasl_get_plugin_filename(), session_table_item_s::session, session_table_item_s::session_id, session_table, session_table_item_s::verbose, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_connect()

tree_cell * nasl_ssh_connect ( lex_ctxt * lexic)

Connect to the target host via TCP and setup an ssh connection.

NASL Function: ssh_connect\n

If the named argument "socket" is given, that socket will be used instead of a creating a new TCP connection. If socket is not given or 0, the port is looked up in the preferences and the KB unless overridden by the named parameter "port".

On success an ssh session to the host has been established; the caller may then run an authentication function. If the connection is no longer needed, ssh_disconnect may be used to disconnect and close the socket.

NASL Named Parameters:\n
  • socket If given, this socket will be used instead of creating a new connection.
  • port A non-standard port to connect to. This is only used if socket is not given or 0.
  • keytype List of the preferred server host key types. Example: "ssh-rsa,ssh-dss"
  • csciphers SSH client-to-server ciphers.
  • scciphers SSH server-to-client ciphers.
  • timeout Set a timeout for the connection in seconds. Defaults to 10 seconds (defined by libssh internally) if not given.
NASL Returns:\n An integer to identify the ssh session. Zero on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
On success the function returns a tree-cell with a non-zero integer identifying that ssh session; zero is returned on a connection error. In case of an internal error NULL is returned.

Definition at line 225 of file nasl_ssh.c.

226{
227 ssh_session session;
228 tree_cell *retc;
229 const char *key_type, *csciphers, *scciphers, *s;
230 char ip_str[INET6_ADDRSTRLEN];
231 int port, sock;
232 unsigned int tbl_slot;
233 int verbose = 0;
234 int forced_sock = -1;
235 long timeout; // in seconds
236
237 sock = get_int_var_by_name (lexic, "socket", 0);
238 if (sock)
239 port = 0; /* The port is ignored if "socket" is given. */
240 else
241 {
242 port = get_int_var_by_name (lexic, "port", 0);
243 if (port <= 0)
244 port = get_ssh_port (lexic);
245 }
246
247 addr6_to_str (plug_get_host_ip (lexic->script_infos), ip_str);
248 session = ssh_new ();
249 if (!session)
250 {
251 g_message ("Function %s (calling internal function %s) called from %s: "
252 "Failed to allocate a new SSH session",
254 : "script_main_function",
255 __func__, nasl_get_plugin_filename ());
256 return NULL;
257 }
258
259 timeout = get_int_var_by_name (lexic, "timeout", 0);
260 if (timeout > 0)
261 if (ssh_options_set (session, SSH_OPTIONS_TIMEOUT, &timeout))
262 {
263 g_message (
264 "Function %s called from %s: "
265 "Failed to set the SSH connection timeout to %ld seconds: %s",
267 ssh_get_error (session));
268 ssh_free (session);
269 return NULL;
270 }
271
272 if ((s = getenv ("OPENVAS_LIBSSH_DEBUG")))
273 {
274 verbose = 1;
275 if (*s)
276 {
277 int intval = atoi (s);
278
279 ssh_options_set (session, SSH_OPTIONS_LOG_VERBOSITY, &intval);
280 }
281 }
282
283 if (ssh_options_set (session, SSH_OPTIONS_HOST, ip_str))
284 {
285 g_message ("Function %s (calling internal function %s) called from %s: "
286 "Failed to set SSH hostname '%s': %s",
288 : "script_main_function",
289 __func__, nasl_get_plugin_filename (), ip_str,
290 ssh_get_error (session));
291 ssh_free (session);
292 return NULL;
293 }
294
295 if (ssh_options_set (session, SSH_OPTIONS_KNOWNHOSTS, "/dev/null"))
296 {
297 g_message ("Function %s (calling internal function %s) called from %s: "
298 "Failed to disable SSH known_hosts: %s",
300 : "script_main_function",
301 __func__, nasl_get_plugin_filename (),
302 ssh_get_error (session));
303 ssh_free (session);
304 return NULL;
305 }
306
307 key_type = get_str_var_by_name (lexic, "keytype");
308
309 if (key_type && ssh_options_set (session, SSH_OPTIONS_HOSTKEYS, key_type))
310 {
311 g_message ("Function %s (calling internal function %s) called from %s: "
312 "Failed to set SSH key type '%s': %s",
314 : "script_main_function",
315 __func__, nasl_get_plugin_filename (), key_type,
316 ssh_get_error (session));
317 ssh_free (session);
318 return NULL;
319 }
320
321 csciphers = get_str_var_by_name (lexic, "csciphers");
322 if (csciphers
323 && ssh_options_set (session, SSH_OPTIONS_CIPHERS_C_S, csciphers))
324 {
325 g_message ("Function %s (calling internal function %s) called from %s: "
326 "Failed to set SSH client to server ciphers '%s': %s",
328 : "script_main_function",
329 __func__, nasl_get_plugin_filename (), csciphers,
330 ssh_get_error (session));
331 ssh_free (session);
332 return NULL;
333 }
334 scciphers = get_str_var_by_name (lexic, "scciphers");
335 if (scciphers
336 && ssh_options_set (session, SSH_OPTIONS_CIPHERS_S_C, scciphers))
337 {
338 g_message ("Function %s (calling internal function %s) called from %s: "
339 "Failed to set SSH server to client ciphers '%s': %s",
341 : "script_main_function",
342 __func__, nasl_get_plugin_filename (), scciphers,
343 ssh_get_error (session));
344 ssh_free (session);
345 return NULL;
346 }
347
348 if (port)
349 {
350 unsigned int my_port = port;
351
352 if (ssh_options_set (session, SSH_OPTIONS_PORT, &my_port))
353 {
354 g_message (
355 "Function %s (calling internal function %s) called from %s: "
356 "Failed to set SSH port for '%s' to %d: %s",
358 : "script_main_function",
359 __func__, nasl_get_plugin_filename (), ip_str, port,
360 ssh_get_error (session));
361 ssh_free (session);
362 return NULL;
363 }
364 }
365 if (sock)
366 {
367 socket_t my_fd = openvas_get_socket_from_connection (sock);
368
369 if (verbose)
370 g_message ("Setting SSH fd for '%s' to %d (NASL sock=%d)", ip_str,
371 my_fd, sock);
372 if (ssh_options_set (session, SSH_OPTIONS_FD, &my_fd))
373 {
374 g_message (
375 "Function %s (calling internal function %s) called from %s: "
376 "Failed to set SSH fd for '%s' to %d (NASL sock=%d): %s",
378 : "script_main_function",
379 __func__, nasl_get_plugin_filename (), ip_str, my_fd, sock,
380 ssh_get_error (session));
381 ssh_free (session);
382 return NULL;
383 }
384 /* Remember the NASL socket. */
385 forced_sock = sock;
386 }
387
388 /* Find a place in the table to save the session. */
389 for (tbl_slot = 0; tbl_slot < DIM (session_table); tbl_slot++)
390 if (!session_table[tbl_slot].session_id)
391 break;
392 if (!(tbl_slot < DIM (session_table)))
393 {
394 if (verbose)
395 g_message ("No space left in SSH session table");
396 ssh_free (session);
397 return NULL;
398 }
399
400 /* Prepare the session table entry. */
401 session_table[tbl_slot].session = session;
402 session_table[tbl_slot].authmethods_valid = 0;
403 session_table[tbl_slot].user_set = 0;
404 session_table[tbl_slot].verbose = verbose;
405
406 /* Connect to the host. */
407 if (verbose)
408 g_message ("Connecting to SSH server '%s' (port %d, sock %d)", ip_str, port,
409 sock);
410 if (ssh_connect (session))
411 {
412 if (verbose)
413 g_message ("Failed to connect to SSH server '%s'"
414 " (port %d, sock %d, f=%d): %s",
415 ip_str, port, sock, forced_sock, ssh_get_error (session));
416 if (forced_sock != -1)
417 {
418 /* If the caller passed us a socket we can't call ssh_free
419 on it because we expect the caller to close that socket
420 himself. Instead we need to setup a table entry so that
421 it will then be close it via nasl_ssh_internal_close. */
422 session_table[tbl_slot].session_id = next_session_id ();
423 session_table[tbl_slot].sock = forced_sock;
424 }
425 else
426 ssh_free (session);
427
428 /* return 0 to indicate the error. */
429 /* FIXME: Set the last error string. */
431 retc->x.i_val = 0;
432 return retc;
433 }
434
435 /* How that we are connected, save the session. */
436 session_table[tbl_slot].session_id = next_session_id ();
437 session_table[tbl_slot].sock =
438 forced_sock != -1 ? forced_sock : ssh_get_fd (session);
439 if (lowest_socket == 0 && session_table[tbl_slot].sock > 0)
440 lowest_socket = session_table[tbl_slot].sock;
441
442 /* Return the session id. */
444 retc->x.i_val = session_table[tbl_slot].session_id;
445 return retc;
446}
#define DIM(v)
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1118
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition nasl_var.c:1101
int lowest_socket
#define DIM(v)
Definition nasl_ssh.c:49
static int next_session_id(void)
Definition nasl_ssh.c:123
static unsigned short get_ssh_port(lex_ctxt *lexic)
Definition nasl_ssh.c:156
int openvas_get_socket_from_connection(int fd)
Definition network.c:357
struct in6_addr * plug_get_host_ip(struct script_infos *args)
Definition plugutils.c:371
struct script_infos * script_infos

References alloc_typed_cell(), CONST_INT, DIM, get_int_var_by_name(), get_ssh_port(), get_str_var_by_name(), TC::i_val, lowest_socket, nasl_get_function_name(), nasl_get_plugin_filename(), next_session_id(), openvas_get_socket_from_connection(), plug_get_host_ip(), struct_lex_ctxt::script_infos, session_table_item_s::session, session_table_item_s::session_id, session_table, session_table_item_s::sock, session_table_item_s::verbose, and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_disconnect()

tree_cell * nasl_ssh_disconnect ( lex_ctxt * lexic)

Disconnect an ssh connection.

NASL Function: ssh_disconnect\n

This function takes the ssh session id (as returned by ssh_connect) as its only unnamed argument. Passing 0 as session id is explicitly allowed and does nothing. If there are any open channels they are closed as well and their ids will be marked as invalid.

NASL Unnamed Parameters:\n
  • An SSH session id. A value of 0 is allowed and acts as a NOP.
NASL Returns:\n Nothing
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
Nothing.

Definition at line 513 of file nasl_ssh.c.

514{
515 int tbl_slot;
516 int session_id;
517
518 session_id = get_int_var_by_num (lexic, 0, -1);
519 if (!verify_session_id (session_id, NULL, &tbl_slot, lexic))
520 return FAKE_CELL;
521 do_nasl_ssh_disconnect (tbl_slot);
522 return FAKE_CELL;
523}
static void do_nasl_ssh_disconnect(int tbl_slot)
Definition nasl_ssh.c:480
#define FAKE_CELL
Definition nasl_tree.h:110

References do_nasl_ssh_disconnect(), FAKE_CELL, get_int_var_by_num(), session_table_item_s::session_id, and verify_session_id().

Here is the call graph for this function:

◆ nasl_ssh_exec()

tree_cell * nasl_ssh_exec ( lex_ctxt * )

◆ nasl_ssh_execute_netconf_subsystem()

tree_cell * nasl_ssh_execute_netconf_subsystem ( lex_ctxt * lexic)

Excecute the NETCONF subsystem on the the ssh channel.

NASL Function: ssh_execute_netconf_subsystem\n
NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Returns:\n An int on success or NULL on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
Session ID on success, NULL on failure.

Definition at line 2060 of file nasl_ssh.c.

2061{
2062 int tbl_slot, session_id;
2063 ssh_channel channel;
2064 ssh_session session;
2065 tree_cell *retc;
2066
2067 session_id = get_int_var_by_num (lexic, 0, -1);
2068
2069 if (!verify_session_id (session_id, "ssh_execute_netconf_subsystem",
2070 &tbl_slot, lexic))
2071 return NULL;
2072 session = session_table[tbl_slot].session;
2073 channel = ssh_channel_new (session);
2074 if (!channel)
2075 return NULL;
2076
2077 if (ssh_channel_open_session (channel))
2078 {
2079 /* FIXME: Handle SSH_AGAIN. */
2080 g_message ("ssh_channel_open_session failed: %s",
2081 ssh_get_error (session));
2082 ssh_channel_free (channel);
2083 retc = alloc_typed_cell (CONST_INT);
2084 retc->x.i_val = SSH_ERROR;
2085 return retc;
2086 }
2087
2088 int err;
2089 if ((err = ssh_channel_request_subsystem (channel, "netconf")) < 0)
2090 {
2091 g_message ("%s Could not execute netconf subsystem", __func__);
2092 retc = alloc_typed_cell (CONST_INT);
2093 retc->x.i_val = err;
2094 return retc;
2095 }
2096
2097 if (session_table[tbl_slot].channel)
2098 ssh_channel_free (session_table[tbl_slot].channel);
2099 session_table[tbl_slot].channel = channel;
2100
2101 retc = alloc_typed_cell (CONST_INT);
2102 retc->x.i_val = session_table[tbl_slot].session_id;
2103 return retc;
2104}

References alloc_typed_cell(), session_table_item_s::channel, CONST_INT, get_int_var_by_num(), TC::i_val, session_table_item_s::session, session_table_item_s::session_id, session_table, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_get_auth_methods()

tree_cell * nasl_ssh_get_auth_methods ( lex_ctxt * lexic)

Get the list of authmethods.

NASL Function: ssh_get_auth_methods\n

The function returns a string with comma separated authentication methods. This is basically the same as returned by SSH_MSG_USERAUTH_FAILURE protocol element; however, it has been screened and put into a definitive order.

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Returns:\n A string on success or NULL on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
A string is returned on success. NULL indicates that the connection has not yet been established.

Definition at line 1605 of file nasl_ssh.c.

1606{
1607 int tbl_slot, methods, session_id;
1608 GString *buffer;
1609 char *p;
1610 tree_cell *retc;
1611
1612 session_id = get_int_var_by_num (lexic, 0, -1);
1613 if (!verify_session_id (session_id, "ssh_get_auth_methods", &tbl_slot, lexic))
1614 return NULL;
1615
1616 if (!session_table[tbl_slot].user_set && !nasl_ssh_set_login (lexic))
1617 return NULL;
1618 if (!session_table[tbl_slot].authmethods_valid)
1619 get_authmethods (tbl_slot);
1620
1621 methods = session_table[tbl_slot].authmethods;
1622
1623 buffer = g_string_sized_new (128);
1624 if ((methods & SSH_AUTH_METHOD_NONE))
1625 g_string_comma_str (buffer, "none");
1626 if ((methods & SSH_AUTH_METHOD_PASSWORD))
1627 g_string_comma_str (buffer, "password");
1628 if ((methods & SSH_AUTH_METHOD_PUBLICKEY))
1629 g_string_comma_str (buffer, "publickey");
1630 if ((methods & SSH_AUTH_METHOD_HOSTBASED))
1631 g_string_comma_str (buffer, "hostbased");
1632 if ((methods & SSH_AUTH_METHOD_INTERACTIVE))
1633 g_string_comma_str (buffer, "keyboard-interactive");
1634 g_string_append_c (buffer, 0x00);
1635 p = g_string_free (buffer, FALSE);
1636 if (!p)
1637 return NULL;
1638
1640 retc->x.str_val = p;
1641 retc->size = strlen (p);
1642 return retc;
1643}
static void g_string_comma_str(GString *gstr, const char *str)
Definition nasl_ssh.c:111
tree_cell * nasl_ssh_set_login(lex_ctxt *lexic)
Set the login name for the authentication.
Definition nasl_ssh.c:728
static int get_authmethods(int tbl_slot)
Definition nasl_ssh.c:640
@ CONST_DATA
Definition nasl_tree.h:82
int size
Definition nasl_tree.h:99
char * str_val
Definition nasl_tree.h:103

References alloc_typed_cell(), session_table_item_s::authmethods_valid, CONST_DATA, g_string_comma_str(), get_authmethods(), get_int_var_by_num(), nasl_ssh_set_login(), session_table_item_s::session_id, session_table, TC::size, TC::str_val, session_table_item_s::user_set, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_get_host_key()

tree_cell * nasl_ssh_get_host_key ( lex_ctxt * lexic)

Get the host key.

NASL Function: ssh_get_host_key\n

The function returns a string with the MD5 host key. *

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Returns:\n A data block on success or NULL on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
A string is returned on success. NULL indicates that the connection has not yet been established.

Definition at line 1561 of file nasl_ssh.c.

1562{
1563 int tbl_slot, session_id;
1564 ssh_session session;
1565 ssh_string sstring;
1566 tree_cell *retc;
1567
1568 session_id = get_int_var_by_num (lexic, 0, -1);
1569 if (!verify_session_id (session_id, "ssh_get_host_key", &tbl_slot, lexic))
1570 return NULL;
1571 session = session_table[tbl_slot].session;
1572
1573 sstring = ssh_get_pubkey (session);
1574 if (!sstring)
1575 return NULL;
1576
1578 retc->x.str_val = ssh_string_to_char (sstring);
1579 retc->size = ssh_string_len (sstring);
1580 ssh_string_free (sstring);
1581 return retc;
1582}

References alloc_typed_cell(), CONST_DATA, get_int_var_by_num(), session_table_item_s::session, session_table_item_s::session_id, session_table, TC::size, TC::str_val, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_get_issue_banner()

tree_cell * nasl_ssh_get_issue_banner ( lex_ctxt * lexic)

Get the issue banner.

NASL Function: ssh_get_issue_banner\n

The function returns a string with the issue banner. This is usually displayed before authentication.

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Returns:\n A data block on success or NULL on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
A string is returned on success. NULL indicates that the server did not send a banner or that the connection has not yet been established.

Definition at line 1471 of file nasl_ssh.c.

1472{
1473 int tbl_slot, session_id;
1474 ssh_session session;
1475 char *banner;
1476 tree_cell *retc;
1477
1478 session_id = get_int_var_by_num (lexic, 0, -1);
1479 if (!verify_session_id (session_id, "ssh_get_issue_banner", &tbl_slot, lexic))
1480 return NULL;
1481 session = session_table[tbl_slot].session;
1482
1483 /* We need to make sure that we got the auth methods so that libssh
1484 has the banner. */
1485 if (!session_table[tbl_slot].user_set && !nasl_ssh_set_login (lexic))
1486 return NULL;
1487 if (!session_table[tbl_slot].authmethods_valid)
1488 get_authmethods (tbl_slot);
1489
1490 banner = ssh_get_issue_banner (session);
1491 if (!banner)
1492 return NULL;
1493
1495 retc->x.str_val = g_strdup (banner);
1496 retc->size = strlen (banner);
1497 ssh_string_free_char (banner);
1498 return retc;
1499}

References alloc_typed_cell(), session_table_item_s::authmethods_valid, CONST_DATA, get_authmethods(), get_int_var_by_num(), nasl_ssh_set_login(), session_table_item_s::session, session_table_item_s::session_id, session_table, TC::size, TC::str_val, session_table_item_s::user_set, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_get_server_banner()

tree_cell * nasl_ssh_get_server_banner ( lex_ctxt * lexic)

Get the server banner.

NASL Function: ssh_get_server_banner\n

The function returns a string with the server banner. This is usually the first data sent by the server.

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Returns:\n A data block on success or NULL on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
A string is returned on success. NULL indicates that the connection has not yet been established.

Definition at line 1520 of file nasl_ssh.c.

1521{
1522 int tbl_slot, session_id;
1523 ssh_session session;
1524 const char *banner;
1525 tree_cell *retc;
1526
1527 session_id = get_int_var_by_num (lexic, 0, -1);
1528 if (!verify_session_id (session_id, "ssh_get_server_banner", &tbl_slot,
1529 lexic))
1530 return NULL;
1531 session = session_table[tbl_slot].session;
1532
1533 banner = ssh_get_serverbanner (session);
1534 if (!banner)
1535 return NULL;
1536
1538 retc->x.str_val = g_strdup (banner);
1539 retc->size = strlen (banner);
1540 return retc;
1541}

References alloc_typed_cell(), CONST_DATA, get_int_var_by_num(), session_table_item_s::session, session_table_item_s::session_id, session_table, TC::size, TC::str_val, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_get_sock()

tree_cell * nasl_ssh_get_sock ( lex_ctxt * lexic)

Given a session id, return the corresponding socket.

NASL Function: ssh_get_sock\n

The socket is either a native file descriptor or a NASL connection socket (if a open socket was passed to ssh_connect). The NASL network code handles both of them.

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Returns:\n An integer representing the socket or -1 on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
The socket or -1 on error.

Definition at line 621 of file nasl_ssh.c.

622{
623 int tbl_slot, sock, session_id;
624 tree_cell *retc;
625
626 session_id = get_int_var_by_num (lexic, 0, -1);
627 if (!verify_session_id (session_id, "ssh_get_sock", &tbl_slot, lexic))
628 sock = -1;
629 else
630 sock = session_table[tbl_slot].sock;
631
633 retc->x.i_val = sock;
634 return retc;
635}

References alloc_typed_cell(), CONST_INT, get_int_var_by_num(), TC::i_val, session_table_item_s::session_id, session_table, session_table_item_s::sock, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_login_interactive()

tree_cell * nasl_ssh_login_interactive ( lex_ctxt * lexic)

Authenticate a user on an ssh connection.

NASL Function: ssh_login_intenteractive\n

The function starts the authentication process and pauses it when it finds the first non-echo prompt. The function expects the session id as its first unnamed argument. The first time this function is called for a session id, the named argument "login" is also expected.

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Named Parameters:\n
  • login A string with the login name.
NASL Returns:\n A data block on success or NULL on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
A string containing the prompt is returned on success. NULL indicates that the error.

Definition at line 1016 of file nasl_ssh.c.

1017{
1018 int tbl_slot;
1019 int session_id;
1020 ssh_session session;
1021 const char *s = NULL;
1022 int methods;
1023 int verbose;
1024
1025 session_id = get_int_var_by_num (lexic, 0, -1);
1026 if (!verify_session_id (session_id, "ssh_login_interactive", &tbl_slot,
1027 lexic))
1028 return NULL; /* Ooops. */
1029 session = session_table[tbl_slot].session;
1030 verbose = session_table[tbl_slot].verbose;
1031
1032 /* Check if we need to set the user. This is done only once per
1033 session. */
1034 if (!session_table[tbl_slot].user_set && !nasl_ssh_set_login (lexic))
1035 return NULL;
1036
1037 /* Get the authentication methods only once per session. */
1038 if (!session_table[tbl_slot].authmethods_valid)
1039 {
1040 if (!get_authmethods (tbl_slot))
1041 {
1042 s = g_strdup ("");
1043 goto leave;
1044 }
1045 }
1046 methods = session_table[tbl_slot].authmethods;
1047
1048 if (methods & SSH_AUTH_METHOD_INTERACTIVE)
1049 {
1050 /* Our strategy for kbint is to send the password to the first
1051 prompt marked as non-echo. */
1052
1053 while (ssh_userauth_kbdint (session, NULL, NULL) == SSH_AUTH_INFO)
1054 {
1055 int n, nprompt;
1056 char echoflag;
1057 int found_prompt = 0;
1058
1059 if (verbose)
1060 {
1061 s = ssh_userauth_kbdint_getname (session);
1062 if (s && *s)
1063 g_message ("SSH kbdint name='%s'", s);
1064 s = ssh_userauth_kbdint_getinstruction (session);
1065 if (s && *s)
1066 g_message ("SSH kbdint instruction='%s'", s);
1067 }
1068
1069 nprompt = ssh_userauth_kbdint_getnprompts (session);
1070 for (n = 0; n < nprompt; n++)
1071 {
1072 s = ssh_userauth_kbdint_getprompt (session, n, &echoflag);
1073 if (s && *s && verbose)
1074 g_message ("SSH kbdint prompt='%s'%s", s,
1075 echoflag ? "" : " [hide input]");
1076 if (s && *s && !echoflag && !found_prompt)
1077 goto leave;
1078 }
1079 }
1080 if (verbose)
1081 g_message (
1082 "SSH keyboard-interactive authentication failed for session %d"
1083 ": %s",
1084 session_id, ssh_get_error (session));
1085 }
1086
1087 if (!s)
1088 return NULL;
1089
1090leave:
1091 {
1092 tree_cell *retc;
1093
1095 retc->x.str_val = g_strdup (s);
1096 retc->size = strlen (s);
1097 return retc;
1098 }
1099}

References alloc_typed_cell(), session_table_item_s::authmethods_valid, CONST_DATA, get_authmethods(), get_int_var_by_num(), nasl_ssh_set_login(), session_table_item_s::session, session_table_item_s::session_id, session_table, TC::size, TC::str_val, session_table_item_s::user_set, session_table_item_s::verbose, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_login_interactive_pass()

tree_cell * nasl_ssh_login_interactive_pass ( lex_ctxt * lexic)

Authenticate a user on an ssh connection.

NASL Function: ssh_login_intenteractive_pass\n

The function finishes the authentication process started by ssh_login_interactive. The function expects the session id as its first unnamed argument.

To finish the password, the named argument "password" must contain a password.

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Named Parameters:\n
  • password A string with the password.
NASL Returns:\n An integer as status value; 0 indicates success.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
An integer is returned on success. -1 indicates an error.

Definition at line 1128 of file nasl_ssh.c.

1129{
1130 int tbl_slot;
1131 int session_id;
1132 ssh_session session;
1133 const char *password = NULL;
1134 int rc;
1135 int retc_val = -1;
1136 int verbose;
1137
1138 session_id = get_int_var_by_num (lexic, 0, -1);
1139 if (!verify_session_id (session_id, "ssh_login_interactive_pass", &tbl_slot,
1140 lexic))
1141 return NULL; /* Ooops. */
1142 session = session_table[tbl_slot].session;
1143 verbose = session_table[tbl_slot].verbose;
1144
1145 /* A prompt is waiting for the password. */
1146 if ((password = get_str_var_by_name (lexic, "password")) == NULL)
1147 return NULL;
1148
1149 rc = ssh_userauth_kbdint_setanswer (session, 0, password);
1150
1151 if (rc < 0)
1152 {
1153 if (verbose)
1154 g_message ("SSH keyboard-interactive authentication "
1155 "failed at prompt %d for session %d: %s",
1156 0, session_id, ssh_get_error (session));
1157 retc_val = -1;
1158 goto leave;
1159 }
1160
1161 if (rc == 0)
1162 {
1163 /* I need to do that to finish the auth process. */
1164 while ((rc = ssh_userauth_kbdint (session, NULL, NULL)) == SSH_AUTH_INFO)
1165 {
1166 ssh_userauth_kbdint_getnprompts (session);
1167 }
1168 if (rc == SSH_AUTH_SUCCESS)
1169 {
1170 retc_val = 0;
1171 goto leave;
1172 }
1173 if (rc != SSH_AUTH_SUCCESS)
1174 {
1175 retc_val = -1;
1176 goto leave;
1177 }
1178 }
1179
1180leave:
1181 {
1182 tree_cell *retc;
1183
1184 retc = alloc_typed_cell (CONST_INT);
1185 retc->x.i_val = retc_val;
1186 return retc;
1187 }
1188}

References alloc_typed_cell(), CONST_INT, get_int_var_by_num(), get_str_var_by_name(), TC::i_val, session_table_item_s::session, session_table_item_s::session_id, session_table, session_table_item_s::verbose, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_request_exec()

tree_cell * nasl_ssh_request_exec ( lex_ctxt * lexic)

Run a command via ssh.

NASL Function: ssh_request_exec\n

The function opens a channel to the remote end and ask it to execute a command. The output of the command is then returned as a data block. The first unnamed argument is the session id. The command itself is expected as string in the named argument "cmd".

Regarding the handling of the stderr and stdout stream, this function may be used in different modes.

If either the named arguments stdout or stderr are given and that one is set to 1, only the output of the specified stream is returned.

If stdout and stderr are both given and set to 1, the output of both is returned interleaved. NOTE: The following feature has not yet been implemented: The output is guaranteed not to switch between stderr and stdout within a line.

If stdout and stderr are both given but set to 0, a special backward compatibility mode is used: First all output to stderr is collected up until any output to stdout is received. Then all output to stdout is returned while ignoring all further stderr output; at EOF the initial collected data from stderr is returned.

If the named parameters stdout and stderr are not given, the function acts exactly as if only stdout has been set to 1.

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Named Parameters:\n
  • cmd A string with the command to execute.
  • stdout An integer with value 0 or 1; see above for a full description.
  • stderr An integer with value 0 or 1; see above for a full description.
NASL Returns:\n A data block on success or NULL on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
A data/string is returned on success. NULL indicates an error.

Definition at line 1345 of file nasl_ssh.c.

1346{
1347 int tbl_slot;
1348 int session_id;
1349 ssh_session session;
1350 int verbose;
1351 char *cmd;
1352 int rc;
1353 GString *response;
1354 GString *compat_buf = NULL;
1355 size_t len = 0;
1356 tree_cell *retc;
1357 char *p;
1358 int to_stdout, to_stderr, compat_mode, compat_buf_inuse;
1359
1360 session_id = get_int_var_by_num (lexic, 0, -1);
1361 if (!verify_session_id (session_id, "ssh_request_exec", &tbl_slot, lexic))
1362 return NULL;
1363 session = session_table[tbl_slot].session;
1364
1365 verbose = session_table[tbl_slot].verbose;
1366
1367 cmd = get_str_var_by_name (lexic, "cmd");
1368 if (!cmd || !*cmd)
1369 {
1370 g_message ("Function %s (calling internal function %s) called from %s: "
1371 "No command passed",
1373 : "script_main_function",
1374 __func__, nasl_get_plugin_filename ());
1375 return NULL;
1376 }
1377
1378 to_stdout = get_int_var_by_name (lexic, "stdout", -1);
1379 to_stderr = get_int_var_by_name (lexic, "stderr", -1);
1380 compat_mode = 0;
1381 if (to_stdout == -1 && to_stderr == -1)
1382 {
1383 /* None of the two named args are given. */
1384 to_stdout = 1;
1385 }
1386 else if (to_stdout == 0 && to_stderr == 0)
1387 {
1388 /* Compatibility mode. */
1389 to_stdout = 1;
1390 compat_mode = 1;
1391 }
1392
1393 if (to_stdout < 0)
1394 to_stdout = 0;
1395 if (to_stderr < 0)
1396 to_stderr = 0;
1397
1398 /* Allocate some space in advance. Most commands won't output too
1399 much and thus 512 bytes (6 standard terminal lines) should often
1400 be sufficient. */
1401 response = g_string_sized_new (512);
1402 if (compat_mode)
1403 {
1404 compat_buf = g_string_sized_new (512);
1405 compat_buf_inuse = 1;
1406 }
1407 else
1408 compat_buf_inuse = 0;
1409
1410 rc = exec_ssh_cmd (session, cmd, verbose, compat_mode, to_stdout, to_stderr,
1411 response, compat_buf);
1412 if (rc == SSH_ERROR)
1413 {
1414 if (compat_buf_inuse)
1415 g_string_free (compat_buf, TRUE);
1416 g_string_free (response, TRUE);
1417 return NULL;
1418 }
1419
1420 /* Append the compatibility buffer to the output. */
1421 if (compat_buf_inuse)
1422 {
1423 len = compat_buf->len;
1424 p = g_string_free (compat_buf, FALSE);
1425 if (p)
1426 {
1427 g_string_append_len (response, p, len);
1428 g_free (p);
1429 }
1430 }
1431
1432 /* Return the the output. */
1433 len = response->len;
1434 p = g_string_free (response, FALSE);
1435 if (!p)
1436 {
1437 g_message ("Function %s (calling internal function %s) called from %s: "
1438 "memory problem: %s",
1440 : "script_main_function",
1441 __func__, nasl_get_plugin_filename (), strerror (-1));
1442 return NULL;
1443 }
1444
1446 retc->size = len;
1447 retc->x.str_val = p;
1448 return retc;
1449}
uint8_t len
static int exec_ssh_cmd(ssh_session session, char *cmd, int verbose, int compat_mode, int to_stdout, int to_stderr, GString *response, GString *compat_buf)
Execute an ssh command.
Definition nasl_ssh.c:1213

References alloc_typed_cell(), CONST_DATA, exec_ssh_cmd(), get_int_var_by_name(), get_int_var_by_num(), get_str_var_by_name(), len, nasl_get_function_name(), nasl_get_plugin_filename(), session_table_item_s::session, session_table_item_s::session_id, session_table, TC::size, TC::str_val, session_table_item_s::verbose, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_session_id_from_sock()

tree_cell * nasl_ssh_session_id_from_sock ( lex_ctxt * lexic)

Given a socket, return the corresponding session id.

NASL Function: ssh_session_id_from_sock\n
NASL Unnamed Parameters:\n
  • A NASL socket value
NASL Returns:\n An integer with the corresponding ssh session id or 0 if
no session id is known for the given socket.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
The session id on success or 0 if not found.

Definition at line 578 of file nasl_ssh.c.

579{
580 int sock, session_id;
581 unsigned int tbl_slot;
582 tree_cell *retc;
583
584 session_id = 0;
585 sock = get_int_var_by_num (lexic, 0, -1);
586 if (sock != -1)
587 {
588 for (tbl_slot = 0; tbl_slot < DIM (session_table); tbl_slot++)
589 if (session_table[tbl_slot].sock == sock
590 && session_table[tbl_slot].session_id)
591 {
592 session_id = session_table[tbl_slot].session_id;
593 break;
594 }
595 }
596
598 retc->x.i_val = session_id;
599 return retc;
600}

References alloc_typed_cell(), CONST_INT, DIM, get_int_var_by_num(), TC::i_val, session_table_item_s::session_id, session_table, session_table_item_s::sock, and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_set_login()

tree_cell * nasl_ssh_set_login ( lex_ctxt * lexic)

Set the login name for the authentication.

NASL Function: ssh_set_login\n

This is an optional function and usuallay not required. However, if you want to get the banner before starting the authentication, you need to tell libssh the user because it is often not possible to change the user after the first call to an authentication methods - getting the banner uses an authentication function.

The named argument "login" is used for the login name; it defaults the KB entry "Secret/SSH/login". It should contain the user name to login. Given that many servers don't allow changing the login for an established connection, the "login" parameter is silently ignored on all further calls.

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Named Parameters:\n
  • login A string with the login name (optional).
NASL Returns:\n None
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
none.

Definition at line 728 of file nasl_ssh.c.

729{
730 int tbl_slot, session_id;
731
732 session_id = get_int_var_by_num (lexic, 0, -1);
733 if (!verify_session_id (session_id, "ssh_set_login", &tbl_slot, lexic))
734 return NULL; /* Ooops. */
735 if (!session_table[tbl_slot].user_set)
736 {
737 ssh_session session = session_table[tbl_slot].session;
738 kb_t kb;
739 char *username;
740
741 username = g_strdup (get_str_var_by_name (lexic, "login"));
742 if (!username)
743 {
744 kb = plug_get_kb (lexic->script_infos);
745 username = kb_item_get_str (kb, "Secret/SSH/login");
746 }
747 if (username && *username
748 && ssh_options_set (session, SSH_OPTIONS_USER, username))
749 {
750 g_message (
751 "Function %s (calling internal function %s) called from %s: "
752 "Failed to set SSH username '%s': %s",
754 : "script_main_function",
755 __func__, nasl_get_plugin_filename (), username,
756 ssh_get_error (session));
757 g_free (username);
758 return NULL; /* Ooops. */
759 }
760 /* In any case mark the user has set. */
761 session_table[tbl_slot].user_set = 1;
762 g_free (username);
763 }
764 return FAKE_CELL;
765}
kb_t plug_get_kb(struct script_infos *args)
Definition plugutils.c:1152

References FAKE_CELL, get_int_var_by_num(), get_str_var_by_name(), nasl_get_function_name(), nasl_get_plugin_filename(), plug_get_kb(), struct_lex_ctxt::script_infos, session_table_item_s::session, session_table_item_s::session_id, session_table, session_table_item_s::user_set, and verify_session_id().

Referenced by nasl_ssh_get_auth_methods(), nasl_ssh_get_issue_banner(), nasl_ssh_login_interactive(), and nasl_ssh_userauth().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nasl_ssh_shell_close()

tree_cell * nasl_ssh_shell_close ( lex_ctxt * lexic)

Close an ssh shell.

NASL Function: ssh_shell_close\n
NASL Unnamed Parameters:\n
  • An SSH session id.
Parameters
[in]lexicLexical context of NASL interpreter.

Definition at line 1958 of file nasl_ssh.c.

1959{
1960 int tbl_slot, session_id;
1961
1962 session_id = get_int_var_by_num (lexic, 0, -1);
1963 if (!verify_session_id (session_id, "ssh_shell_close", &tbl_slot, lexic))
1964 return NULL;
1965 if (session_table[tbl_slot].channel)
1966 {
1967 ssh_channel_free (session_table[tbl_slot].channel);
1968 session_table[tbl_slot].channel = NULL;
1969 }
1970
1971 return NULL;
1972}

References session_table_item_s::channel, get_int_var_by_num(), session_table_item_s::session_id, session_table, and verify_session_id().

Here is the call graph for this function:

◆ nasl_ssh_shell_open()

tree_cell * nasl_ssh_shell_open ( lex_ctxt * lexic)

Request an ssh shell.

NASL Function: ssh_shell_open\n
NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Named Parameters:\n
  • pty To enable/disable the interactive shell. Default is 1 (interactive).
NASL Returns:\n An int on success or NULL on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
Session ID on success, NULL on failure.

Definition at line 1705 of file nasl_ssh.c.

1706{
1707 int tbl_slot, session_id, pty;
1708 ssh_channel channel;
1709 ssh_session session;
1710 tree_cell *retc;
1711
1712 session_id = get_int_var_by_num (lexic, 0, -1);
1713 pty = get_int_var_by_name (lexic, "pty", 1);
1714
1715 if (!verify_session_id (session_id, "ssh_shell_open", &tbl_slot, lexic))
1716 return NULL;
1717 session = session_table[tbl_slot].session;
1718 channel = ssh_channel_new (session);
1719 if (!channel)
1720 return NULL;
1721 if (ssh_channel_open_session (channel))
1722 {
1723 g_message ("Function %s (calling internal function %s) called from %s: "
1724 "ssh_channel_open_session: %s",
1726 : "script_main_function",
1727 __func__, nasl_get_plugin_filename (),
1728 ssh_get_error (session));
1729 ssh_channel_free (channel);
1730 return NULL;
1731 }
1732
1733 if (request_ssh_shell (channel, pty))
1734 {
1735 g_message ("Function %s (calling internal function %s) called from %s: "
1736 "request_ssh_shell: %s",
1738 : "script_main_function",
1739 __func__, nasl_get_plugin_filename (),
1740 ssh_get_error (session));
1741 ssh_channel_free (channel);
1742 return NULL;
1743 }
1744 if (session_table[tbl_slot].channel)
1745 ssh_channel_free (session_table[tbl_slot].channel);
1746 session_table[tbl_slot].channel = channel;
1747
1748 retc = alloc_typed_cell (CONST_INT);
1749 retc->x.i_val = session_table[tbl_slot].session_id;
1750 return retc;
1751}
static int request_ssh_shell(ssh_channel channel, int pty)
Open a shell on an ssh channel.
Definition nasl_ssh.c:1661

References alloc_typed_cell(), session_table_item_s::channel, CONST_INT, get_int_var_by_name(), get_int_var_by_num(), TC::i_val, nasl_get_function_name(), nasl_get_plugin_filename(), request_ssh_shell(), session_table_item_s::session, session_table_item_s::session_id, session_table, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_shell_read()

tree_cell * nasl_ssh_shell_read ( lex_ctxt * lexic)

Read the output of an ssh shell.

NASL Function: ssh_shell_read\n
NASL Unnamed Parameters:\n
  • An SSH session id.

@naslparam timeout

  • Enable the blocking ssh read until it gives the timeout or there is no bytes left to read.
NASL Returns:\n A string on success or NULL on error.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
Data read from shell on success, NULL on failure.

Definition at line 1850 of file nasl_ssh.c.

1851{
1852 int tbl_slot, session_id;
1853 ssh_channel channel;
1854 tree_cell *retc;
1855 GString *response;
1856 int timeout;
1857
1858 session_id = get_int_var_by_num (lexic, 0, -1);
1859 if (!verify_session_id (session_id, "ssh_shell_read", &tbl_slot, lexic))
1860 return NULL;
1861 channel = session_table[tbl_slot].channel;
1862
1863 response = g_string_new (NULL);
1864
1865 timeout = get_int_var_by_name (lexic, "timeout", 0);
1866
1867 if (timeout > 0)
1868 {
1869 if (read_ssh_blocking (channel, response, timeout))
1870 return NULL;
1871 }
1872 else
1873 {
1874 if (read_ssh_nonblocking (channel, response))
1875 return NULL;
1876 }
1878 retc->size = response->len;
1879 retc->x.str_val = g_string_free (response, FALSE);
1880 return retc;
1881}
static int read_ssh_blocking(ssh_channel channel, GString *response, int timeout)
read from an ssh channel until timeouts or there is no bytes left to read.
Definition nasl_ssh.c:1764
static int read_ssh_nonblocking(ssh_channel channel, GString *response)
read from an ssh channel without blocking.
Definition nasl_ssh.c:1809

References alloc_typed_cell(), session_table_item_s::channel, CONST_DATA, get_int_var_by_name(), get_int_var_by_num(), read_ssh_blocking(), read_ssh_nonblocking(), session_table_item_s::session_id, session_table, TC::size, TC::str_val, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_shell_write()

tree_cell * nasl_ssh_shell_write ( lex_ctxt * lexic)

Write string to ssh shell.

NASL Function: ssh_shell_write\n
NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Named Parameters:\n
  • cmd A string to write to shell.
NASL Returns:\n An integer: 0 on success, -1 on failure.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
0 on success, -1 on failure.

Definition at line 1902 of file nasl_ssh.c.

1903{
1904 int tbl_slot, rc = -1, len, session_id;
1905 ssh_channel channel;
1906 tree_cell *retc;
1907 char *cmd;
1908
1909 session_id = get_int_var_by_num (lexic, 0, -1);
1910 if (!verify_session_id (session_id, "ssh_shell_write", &tbl_slot, lexic))
1911 goto write_ret;
1912 if (!(channel = session_table[tbl_slot].channel))
1913 {
1914 g_message ("ssh_shell_write: No shell channel found");
1915 goto write_ret;
1916 }
1917
1918 cmd = get_str_var_by_name (lexic, "cmd");
1919 if (!cmd || !*cmd)
1920 {
1921 g_message ("Function %s (calling internal function %s) called from %s: "
1922 "No command passed",
1924 : "script_main_function",
1925 __func__, nasl_get_plugin_filename ());
1926 goto write_ret;
1927 }
1928 len = strlen (cmd);
1929 if (ssh_channel_write (channel, cmd, len) != len)
1930 {
1931 g_message (
1932 "Function %s (calling internal function %s) called from %s: %s",
1934 : "script_main_function",
1935 __func__, nasl_get_plugin_filename (),
1936 ssh_get_error (session_table[tbl_slot].session));
1937 goto write_ret;
1938 }
1939 rc = 0;
1940
1941write_ret:
1942 retc = alloc_typed_cell (CONST_INT);
1943 retc->x.i_val = rc;
1944 return retc;
1945}

References alloc_typed_cell(), session_table_item_s::channel, CONST_INT, get_int_var_by_num(), get_str_var_by_name(), TC::i_val, len, nasl_get_function_name(), nasl_get_plugin_filename(), session_table_item_s::session, session_table_item_s::session_id, session_table, verify_session_id(), and TC::x.

Here is the call graph for this function:

◆ nasl_ssh_userauth()

tree_cell * nasl_ssh_userauth ( lex_ctxt * lexic)

Authenticate a user on an ssh connection.

NASL Function: ssh_userauth\n

The function expects the session id as its first unnamed argument. The first time this function is called for a session id, the named argument "login" is also expected; it defaults the KB entry "Secret/SSH/login". It should contain the user name to login. Given that many servers don't allow changing the login for an established connection, the "login" parameter is silently ignored on all further calls.

To perform a password based authentication, the named argument "password" must contain a password.

To perform a public key based authentication, the named argument "privatekey" must contain a base64 encoded private key in ssh native or in PKCS#8 format.

If both, "password" and "privatekey" are given as named arguments only "password" is used. If neither are given the values are taken from the KB ("Secret/SSH/password" and "Secret/SSH/privatekey") and tried in the order {password, privatekey}. Note well, that if one of the named arguments are given, only those are used and the KB is not consulted.

If the private key is protected, its passphrase is taken from the named argument "passphrase" or, if not given, taken from the KB ("Secret/SSH/passphrase").

Note that the named argument "publickey" and the KB item ("Secret/SSH/publickey") are ignored - they are not longer required because they can be derived from the private key.

NASL Unnamed Parameters:\n
  • An SSH session id.
NASL Named Parameters:\n
  • login A string with the login name.
  • password A string with the password.
  • privatekey A base64 encoded private key in ssh native or in pkcs#8 format. This parameter is ignored if password is given.
  • passphrase A string with the passphrase used to unprotect privatekey.
NASL Returns:\n An integer as status value; 0 indicates success.
Parameters
[in]lexicLexical context of NASL interpreter.
Returns
0 is returned on success. Any other value indicates an error.

Definition at line 825 of file nasl_ssh.c.

826{
827 int rc, retc_val = -1, methods, verbose, tbl_slot, session_id;
828 ssh_session session;
829 char *password = NULL;
830 char *privkeystr = NULL;
831 char *privkeypass = NULL;
832 kb_t kb;
833 tree_cell *retc;
834
835 session_id = get_int_var_by_num (lexic, 0, -1);
836 if (!verify_session_id (session_id, "ssh_userauth", &tbl_slot, lexic))
837 return NULL; /* Ooops. */
838 session = session_table[tbl_slot].session;
839 verbose = session_table[tbl_slot].verbose;
840
841 /* Check if we need to set the user. This is done only once per
842 session. */
843 if (!session_table[tbl_slot].user_set && !nasl_ssh_set_login (lexic))
844 return NULL;
845
846 kb = plug_get_kb (lexic->script_infos);
847 password = g_strdup (get_str_var_by_name (lexic, "password"));
848 privkeystr = g_strdup (get_str_var_by_name (lexic, "privatekey"));
849 privkeypass = g_strdup (get_str_var_by_name (lexic, "passphrase"));
850 if (!password && !privkeystr && !privkeypass)
851 {
852 password = kb_item_get_str (kb, "Secret/SSH/password");
853 privkeystr = kb_item_get_str (kb, "Secret/SSH/privatekey");
854 privkeypass = kb_item_get_str (kb, "Secret/SSH/passphrase");
855 }
856
857 /* Get the authentication methods only once per session. */
858 if (!session_table[tbl_slot].authmethods_valid)
859 {
860 if (!get_authmethods (tbl_slot))
861 {
862 retc_val = 0;
863 goto leave;
864 }
865 }
866 methods = session_table[tbl_slot].authmethods;
867
868 /* Check whether a password has been given. If so, try to
869 authenticate using that password. Note that the OpenSSH client
870 uses a different order it first tries the public key and then the
871 password. However, the old NASL SSH protocol implementation tries
872 the password before the public key authentication. Because we
873 want to be compatible, we do it in that order. */
874 if (password && (methods & SSH_AUTH_METHOD_PASSWORD))
875 {
876 rc = ssh_userauth_password (session, NULL, password);
877 if (rc == SSH_AUTH_SUCCESS)
878 {
879 retc_val = 0;
880 goto leave;
881 }
882
883 if (verbose)
884 g_message ("SSH password authentication failed for session"
885 " %d: %s",
886 session_id, ssh_get_error (session));
887 /* Keep on trying. */
888 }
889
890 if (password && (methods & SSH_AUTH_METHOD_INTERACTIVE))
891 {
892 /* Our strategy for kbint is to send the password to the first
893 prompt marked as non-echo. */
894 while ((rc = ssh_userauth_kbdint (session, NULL, NULL)) == SSH_AUTH_INFO)
895 {
896 const char *s;
897 int n, nprompt;
898 char echoflag;
899 int found_prompt = 0;
900
901 if (verbose)
902 {
903 s = ssh_userauth_kbdint_getname (session);
904 if (s && *s)
905 g_message ("SSH kbdint name='%s'", s);
906 s = ssh_userauth_kbdint_getinstruction (session);
907 if (s && *s)
908 g_message ("SSH kbdint instruction='%s'", s);
909 }
910 nprompt = ssh_userauth_kbdint_getnprompts (session);
911 for (n = 0; n < nprompt; n++)
912 {
913 s = ssh_userauth_kbdint_getprompt (session, n, &echoflag);
914 if (s && *s && verbose)
915 g_message ("SSH kbdint prompt='%s'%s", s,
916 echoflag ? "" : " [hide input]");
917 if (s && *s && !echoflag && !found_prompt)
918 {
919 found_prompt = 1;
920 rc = ssh_userauth_kbdint_setanswer (session, n, password);
921 if (rc != SSH_AUTH_SUCCESS)
922 {
923 if (verbose)
924 g_message ("SSH keyboard-interactive authentication "
925 "failed at prompt %d for session %d: %s",
926 n, session_id, ssh_get_error (session));
927 }
928 }
929 }
930 }
931
932 if (rc == SSH_AUTH_SUCCESS)
933 {
934 retc_val = 0;
935 goto leave;
936 }
937
938 if (verbose)
939 g_message (
940 "SSH keyboard-interactive authentication failed for session %d"
941 ": %s",
942 session_id, ssh_get_error (session));
943 /* Keep on trying. */
944 }
945
946 /* If we have a private key, try public key authentication. */
947 if (privkeystr && *privkeystr && (methods & SSH_AUTH_METHOD_PUBLICKEY))
948 {
949 ssh_key key = NULL;
950
951 if (ssh_pki_import_privkey_base64 (privkeystr, privkeypass, NULL, NULL,
952 &key))
953 {
954 if (verbose)
955 g_message ("SSH public key authentication failed for "
956 "session %d: %s",
957 session_id, "Error converting provided key");
958 }
959 else if (ssh_userauth_try_publickey (session, NULL, key)
960 != SSH_AUTH_SUCCESS)
961 {
962 if (verbose)
963 g_message ("SSH public key authentication failed for "
964 "session %d: %s",
965 session_id, "Server does not want our key");
966 }
967 else if (ssh_userauth_publickey (session, NULL, key) == SSH_AUTH_SUCCESS)
968 {
969 retc_val = 0;
970 ssh_key_free (key);
971 goto leave;
972 }
973 ssh_key_free (key);
974 /* Keep on trying. */
975 }
976
977 if (verbose)
978 g_message ("SSH authentication failed for session %d: %s", session_id,
979 "No more authentication methods to try");
980
981leave:
982 g_free (password);
983 g_free (privkeystr);
984 g_free (privkeypass);
986 retc->x.i_val = retc_val;
987 return retc;
988}

References alloc_typed_cell(), session_table_item_s::authmethods_valid, CONST_INT, get_authmethods(), get_int_var_by_num(), get_str_var_by_name(), TC::i_val, nasl_ssh_set_login(), plug_get_kb(), struct_lex_ctxt::script_infos, session_table_item_s::session, session_table_item_s::session_id, session_table, session_table_item_s::user_set, session_table_item_s::verbose, verify_session_id(), and TC::x.

Here is the call graph for this function: