OpenVAS Libraries  9.0.3
nasl_ssh.c File Reference

Implementation of an API for SSH functions. More...

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gstdio.h>
#include "nasl_tree.h"
#include "nasl_global_ctxt.h"
#include "nasl_func.h"
#include "nasl_var.h"
#include "nasl_lex_ctxt.h"
#include "exec.h"
#include "../misc/plugutils.h"
#include "../base/kb.h"
#include "nasl_debug.h"
#include "../misc/network.h"
#include "../misc/openvas_logging.h"
#include "../misc/prefs.h"
#include "../misc/openvas_ssh.h"
#include "nasl_ssh.h"
Include dependency graph for nasl_ssh.c:

Go to the source code of this file.

Data Structures

struct  session_table_item_s
 

Macros

#define DIM(v)   (sizeof(v)/sizeof((v)[0]))
 
#define DIMof(type, member)   DIM(((type *)0)->member)
 
#define MAX_SSH_SESSIONS   10
 

Functions

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

Variables

int lowest_socket
 

Detailed Description

Implementation of an API for SSH functions.

This file contains the implementaion of the Secure Shell related NASL builtin functions. They are only available if build with libssh support.

Definition in file nasl_ssh.c.

Macro Definition Documentation

◆ DIM

#define DIM (   v)    (sizeof(v)/sizeof((v)[0]))

Definition at line 71 of file nasl_ssh.c.

◆ DIMof

#define DIMof (   type,
  member 
)    DIM(((type *)0)->member)

Definition at line 72 of file nasl_ssh.c.

◆ MAX_SSH_SESSIONS

#define MAX_SSH_SESSIONS   10

Definition at line 122 of file nasl_ssh.c.

Function Documentation

◆ 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 overriden 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.
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 486 of file nasl_ssh.c.

487 {
488  ssh_session session;
489  tree_cell *retc;
490  const char *hostname, *key_type, *csciphers, *scciphers;
491  int port, sock;
492  int tbl_slot;
493  const char *s;
494  int verbose = 0;
495  int forced_sock = -1;
496 
497  sock = get_int_local_var_by_name (lexic, "socket", 0);
498  if (sock)
499  port = 0; /* The port is ignored if "socket" is given. */
500  else
501  {
502  port = get_int_local_var_by_name (lexic, "port", 0);
503  if (port <= 0)
504  port = get_ssh_port (lexic);
505  }
506 
507  hostname = plug_get_hostname (lexic->script_infos);
508  if (!hostname)
509  {
510  /* Note: We want the hostname even if we are working on an open
511  socket. libssh may use it for example to maintain its
512  known_hosts file. */
513  log_legacy_write ("No hostname available to ssh_connect\n");
514  return NULL;
515  }
516 
517  session = ssh_new ();
518  if (!session)
519  {
520  log_legacy_write ("Failed to allocate a new SSH session\n");
521  return NULL;
522  }
523 
524  if ((s = getenv ("OPENVAS_LIBSSH_DEBUG")))
525  {
526  verbose = 1;
527  if (*s)
528  {
529  int intval = atoi (s);
530 
531  ssh_options_set (session, SSH_OPTIONS_LOG_VERBOSITY, &intval);
532  }
533  }
534 
535  if (ssh_options_set (session, SSH_OPTIONS_HOST, hostname))
536  {
537  log_legacy_write ("Failed to set SSH hostname '%s': %s\n",
538  hostname, ssh_get_error (session));
539  ssh_free (session);
540  return NULL;
541  }
542 
543  key_type = get_str_local_var_by_name (lexic, "keytype");
544 #if LIBSSH_VERSION_INT >= SSH_VERSION_INT (0, 6, 0)
545  if (key_type && ssh_options_set (session, SSH_OPTIONS_HOSTKEYS, key_type))
546  {
547  log_legacy_write ("Failed to set SSH key type '%s': %s",
548  key_type, ssh_get_error (session));
549  ssh_free (session);
550  return NULL;
551  }
552 #else
553  if (key_type)
554  {
555  log_legacy_write ("SSH_OPTIONS_HOSTKEYS not supported");
556  ssh_free (session);
557  return NULL;
558  }
559 #endif
560 
561  csciphers = get_str_local_var_by_name (lexic, "csciphers");
562  if (csciphers && ssh_options_set (session, SSH_OPTIONS_CIPHERS_C_S, csciphers))
563  {
564  log_legacy_write ("Failed to set SSH client to server ciphers '%s': %s",
565  csciphers, ssh_get_error (session));
566  ssh_free (session);
567  return NULL;
568  }
569  scciphers = get_str_local_var_by_name (lexic, "scciphers");
570  if (scciphers && ssh_options_set (session, SSH_OPTIONS_CIPHERS_S_C, scciphers))
571  {
572  log_legacy_write ("Failed to set SSH server to client ciphers '%s': %s",
573  scciphers, ssh_get_error (session));
574  ssh_free (session);
575  return NULL;
576  }
577 
578  if (port)
579  {
580  unsigned int my_port = port;
581 
582  if (ssh_options_set (session, SSH_OPTIONS_PORT, &my_port))
583  {
584  log_legacy_write ("Failed to set SSH port for '%s' to %d: %s\n",
585  hostname, port, ssh_get_error (session));
586  ssh_free (session);
587  return NULL;
588  }
589  }
590  if (sock)
591  {
592  socket_t my_fd = openvas_get_socket_from_connection (sock);
593 
594  if (verbose)
595  log_legacy_write ("Setting SSH fd for '%s' to %d (NASL sock=%d)\n",
596  hostname, my_fd, sock);
597  if (ssh_options_set (session, SSH_OPTIONS_FD, &my_fd))
598  {
600  ("Failed to set SSH fd for '%s' to %d (NASL sock=%d): %s\n",
601  hostname, my_fd, sock, ssh_get_error (session));
602  ssh_free (session);
603  return NULL;
604  }
605  /* Remember the NASL socket. */
606  forced_sock = sock;
607  }
608 
609  /* Find a place in the table to save the session. */
610  for (tbl_slot=0; tbl_slot < DIM (session_table); tbl_slot++)
611  if (!session_table[tbl_slot].session_id)
612  break;
613  if (!(tbl_slot < DIM (session_table)))
614  {
615  if (verbose)
616  log_legacy_write ("No space left in SSH session table\n");
617  ssh_free (session);
618  return NULL;
619  }
620 
621  /* Prepare the session table entry. */
622  session_table[tbl_slot].session = session;
623  session_table[tbl_slot].authmethods_valid = 0;
624  session_table[tbl_slot].user_set = 0;
625  session_table[tbl_slot].verbose = verbose;
626 
627  /* Connect to the host. */
628  if (verbose)
629  log_legacy_write ("Connecting to SSH server '%s' (port %d, sock %d)\n",
630  hostname, port, sock);
631  if (ssh_connect (session))
632  {
633  if (verbose)
634  log_legacy_write ("Failed to connect to SSH server '%s'"
635  " (port %d, sock %d, f=%d): %s\n", hostname, port,
636  sock, forced_sock, ssh_get_error (session));
637  if (forced_sock != -1)
638  {
639  /* If the caller passed us a socket we can't call ssh_free
640  on it because we expect the caller to close that socket
641  himself. Instead we need to setup a table entry so that
642  it will then be close it via nasl_ssh_internal_close. */
643  session_table[tbl_slot].session_id = next_session_id ();
644  session_table[tbl_slot].sock = forced_sock;
645  }
646  else
647  ssh_free (session);
648 
649  /* return 0 to indicate the error. */
650  /* FIXME: Set the last error string. */
651  retc = alloc_typed_cell (CONST_INT);
652  retc->x.i_val = 0;
653  return retc;
654  }
655 
656  /* How that we are connected, save the session. */
657  session_table[tbl_slot].session_id = next_session_id ();
658  session_table[tbl_slot].sock =
659  forced_sock != -1? forced_sock : ssh_get_fd (session);
660  if (lowest_socket == 0 && session_table[tbl_slot].sock > 0)
661  lowest_socket = session_table[tbl_slot].sock;
662 
663  /* Return the session id. */
664  retc = alloc_typed_cell (CONST_INT);
665  retc->x.i_val = session_table[tbl_slot].session_id;
666  return retc;
667 }
int openvas_get_socket_from_connection(int fd)
Definition: network.c:395
ssh_session session
Definition: nasl_ssh.c:110
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
long int get_int_local_var_by_name(lex_ctxt *, const char *, int)
Definition: nasl_var.c:1240
unsigned int user_set
Definition: nasl_ssh.c:116
char * get_str_local_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1262
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
unsigned int authmethods_valid
Definition: nasl_ssh.c:115
unsigned int verbose
Definition: nasl_ssh.c:118
#define DIM(v)
Definition: nasl_ssh.c:71
long int i_val
Definition: nasl_tree.h:114
int lowest_socket
Definition: nasl_socket.c:223
struct arglist * script_infos
Definition: nasl_lex_ctxt.h:39
const char * plug_get_hostname(struct arglist *desc)
Definition: plugutils.c:190

References get_int_local_var_by_name().

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 737 of file nasl_ssh.c.

738 {
739  int tbl_slot;
740  int session_id;
741 
742  session_id = get_int_var_by_num (lexic, 0, -1);
743  if (!verify_session_id (session_id, NULL, &tbl_slot, lexic))
744  return FAKE_CELL;
745  do_nasl_ssh_disconnect (tbl_slot);
746  return FAKE_CELL;
747 }
#define FAKE_CELL
Definition: nasl_tree.h:120
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226

References get_int_var_by_num().

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 1863 of file nasl_ssh.c.

1864 {
1865  int tbl_slot, methods, session_id;
1866  GString *buffer;
1867  char *p;
1868  tree_cell *retc;
1869 
1870  session_id = get_int_var_by_num (lexic, 0, -1);
1871  if (!verify_session_id (session_id, "ssh_get_auth_methods", &tbl_slot, lexic))
1872  return NULL;
1873 
1874  if (!session_table[tbl_slot].user_set && !nasl_ssh_set_login (lexic))
1875  return NULL;
1876  if (!session_table[tbl_slot].authmethods_valid)
1877  get_authmethods (tbl_slot);
1878 
1879  methods = session_table[tbl_slot].authmethods;
1880 
1881  buffer = g_string_sized_new (128);
1882  if ((methods & SSH_AUTH_METHOD_NONE))
1883  g_string_comma_str (buffer, "none");
1884  if ((methods & SSH_AUTH_METHOD_PASSWORD))
1885  g_string_comma_str (buffer, "password");
1886  if ((methods & SSH_AUTH_METHOD_PUBLICKEY))
1887  g_string_comma_str (buffer, "publickey");
1888  if ((methods & SSH_AUTH_METHOD_HOSTBASED))
1889  g_string_comma_str (buffer, "hostbased");
1890  if ((methods & SSH_AUTH_METHOD_INTERACTIVE))
1891  g_string_comma_str (buffer, "keyboard-interactive");
1892  g_string_append_c (buffer, 0x00);
1893  p = g_string_free (buffer, FALSE);
1894  if (!p)
1895  return NULL;
1896 
1897  retc = alloc_typed_cell (CONST_DATA);
1898  retc->x.str_val = p;
1899  retc->size = strlen (p);
1900  return retc;
1901 }
char * str_val
Definition: nasl_tree.h:113
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
tree_cell * nasl_ssh_set_login(lex_ctxt *lexic)
Set the login name for the authentication.
Definition: nasl_ssh.c:956
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
int size
Definition: nasl_tree.h:110

References get_int_var_by_num().

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 1819 of file nasl_ssh.c.

1820 {
1821  int tbl_slot, session_id;
1822  ssh_session session;
1823  ssh_string sstring;
1824  tree_cell *retc;
1825 
1826  session_id = get_int_var_by_num (lexic, 0, -1);
1827  if (!verify_session_id (session_id, "ssh_get_host_key", &tbl_slot, lexic))
1828  return NULL;
1829  session = session_table[tbl_slot].session;
1830 
1831  sstring = ssh_get_pubkey (session);
1832  if (!sstring)
1833  return NULL;
1834 
1835  retc = alloc_typed_cell (CONST_DATA);
1836  retc->x.str_val = ssh_string_to_char (sstring);
1837  retc->size = ssh_string_len (sstring);
1838  ssh_string_free (sstring);
1839  return retc;
1840 }
char * str_val
Definition: nasl_tree.h:113
ssh_session session
Definition: nasl_ssh.c:110
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
int size
Definition: nasl_tree.h:110

References get_int_var_by_num().

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 1723 of file nasl_ssh.c.

1724 {
1725  int tbl_slot, session_id;
1726  ssh_session session;
1727  char *banner;
1728  tree_cell *retc;
1729 
1730  session_id = get_int_var_by_num (lexic, 0, -1);
1731  if (!verify_session_id (session_id, "ssh_get_issue_banner", &tbl_slot, lexic))
1732  return NULL;
1733  session = session_table[tbl_slot].session;
1734 
1735  /* We need to make sure that we got the auth methods so that libssh
1736  has the banner. */
1737  if (!session_table[tbl_slot].user_set && !nasl_ssh_set_login (lexic))
1738  return NULL;
1739  if (!session_table[tbl_slot].authmethods_valid)
1740  get_authmethods (tbl_slot);
1741 
1742  banner = ssh_get_issue_banner (session);
1743  if (!banner)
1744  return NULL;
1745 
1746  retc = alloc_typed_cell (CONST_DATA);
1747  retc->x.str_val = g_strdup (banner);
1748  retc->size = strlen (banner);
1749  ssh_string_free_char (banner);
1750  return retc;
1751 }
char * str_val
Definition: nasl_tree.h:113
ssh_session session
Definition: nasl_ssh.c:110
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
tree_cell * nasl_ssh_set_login(lex_ctxt *lexic)
Set the login name for the authentication.
Definition: nasl_ssh.c:956
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
int size
Definition: nasl_tree.h:110

References get_int_var_by_num().

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 1774 of file nasl_ssh.c.

1775 {
1776  int tbl_slot, session_id;
1777  ssh_session session;
1778  const char *banner;
1779  tree_cell *retc;
1780 
1781  session_id = get_int_var_by_num (lexic, 0, -1);
1782  if (!verify_session_id (session_id, "ssh_get_server_banner",
1783  &tbl_slot, lexic))
1784  return NULL;
1785  session = session_table[tbl_slot].session;
1786 
1787  //banner = ssh_get_serverbanner (session);
1788  banner = (char*) ssh_get_serverbanner (session);
1789  if (!banner)
1790  return NULL;
1791 
1792  retc = alloc_typed_cell (CONST_DATA);
1793  retc->x.str_val = g_strdup (banner);
1794  retc->size = strlen (banner);
1795  return retc;
1796  (void)lexic;
1797  return NULL;
1798 }
char * str_val
Definition: nasl_tree.h:113
ssh_session session
Definition: nasl_ssh.c:110
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
int size
Definition: nasl_tree.h:110

References get_int_var_by_num().

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 844 of file nasl_ssh.c.

845 {
846  int tbl_slot, sock, session_id;
847  tree_cell *retc;
848 
849  session_id = get_int_var_by_num (lexic, 0, -1);
850  if (!verify_session_id (session_id, "ssh_get_sock", &tbl_slot, lexic))
851  sock = -1;
852  else
853  sock = session_table[tbl_slot].sock;
854 
855  retc = alloc_typed_cell (CONST_INT);
856  retc->x.i_val = sock;
857  return retc;
858 }
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
long int i_val
Definition: nasl_tree.h:114

References get_int_var_by_num().

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 1275 of file nasl_ssh.c.

1276 {
1277  int tbl_slot;
1278  int session_id;
1279  ssh_session session;
1280  int rc;
1281  const char *s = NULL;
1282  int methods;
1283  int verbose;
1284 
1285  session_id = get_int_var_by_num (lexic, 0, -1);
1286  if (!verify_session_id (session_id, "ssh_login_interactive",
1287  &tbl_slot, lexic))
1288  return NULL; /* Ooops. */
1289  session = session_table[tbl_slot].session;
1290  verbose = session_table[tbl_slot].verbose;
1291 
1292  /* Check if we need to set the user. This is done only once per
1293  session. */
1294  if (!session_table[tbl_slot].user_set && !nasl_ssh_set_login (lexic))
1295  return NULL;
1296 
1297  /* Get the authentication methods onlye once per session. */
1298  if (!session_table[tbl_slot].authmethods_valid)
1299  {
1300  if (!get_authmethods (tbl_slot))
1301  {
1302  s = g_strdup ("");
1303  goto leave;
1304  }
1305  }
1306  methods = session_table[tbl_slot].authmethods;
1307 
1308  if (methods & SSH_AUTH_METHOD_INTERACTIVE)
1309  {
1310  /* Our strategy for kbint is to send the password to the first
1311  prompt marked as non-echo. */
1312  while ((rc = ssh_userauth_kbdint (session, NULL, NULL)) == SSH_AUTH_INFO)
1313  {
1314  int n, nprompt;
1315  char echoflag;
1316  int found_prompt = 0;
1317 
1318  if (verbose)
1319  {
1320  s = ssh_userauth_kbdint_getname (session);
1321  if (s && *s)
1322  g_message ("SSH kbdint name='%s'", s);
1323  s = ssh_userauth_kbdint_getinstruction (session);
1324  if (s && *s)
1325  g_message ("SSH kbdint instruction='%s'", s);
1326  }
1327 
1328  nprompt = ssh_userauth_kbdint_getnprompts (session);
1329  for (n=0; n < nprompt; n++)
1330  {
1331  s = ssh_userauth_kbdint_getprompt (session, n, &echoflag);
1332  if (s && *s && verbose)
1333  g_message ("SSH kbdint prompt='%s'%s",
1334  s, echoflag ? "" : " [hide input]");
1335  if (s && *s && !echoflag && !found_prompt)
1336  goto leave;
1337  }
1338  }
1339  if (verbose)
1340  g_message
1341  ("SSH keyboard-interactive authentication failed for session %d"
1342  ": %s", session_id, ssh_get_error (session));
1343  }
1344 
1345  if (!s)
1346  return NULL;
1347 
1348  leave:
1349  {
1350  tree_cell *retc;
1351 
1352  retc = alloc_typed_cell (CONST_DATA);
1353  retc->x.str_val = g_strdup (s);
1354  retc->size = strlen (s);
1355  return retc;
1356  }
1357 }
char * str_val
Definition: nasl_tree.h:113
ssh_session session
Definition: nasl_ssh.c:110
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
unsigned int verbose
Definition: nasl_ssh.c:118
tree_cell * nasl_ssh_set_login(lex_ctxt *lexic)
Set the login name for the authentication.
Definition: nasl_ssh.c:956
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
int size
Definition: nasl_tree.h:110

References get_int_var_by_num().

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 1387 of file nasl_ssh.c.

1388 {
1389  int tbl_slot;
1390  int session_id;
1391  ssh_session session;
1392  const char *password = NULL;
1393  int rc;
1394  int retc_val = -1;
1395  int verbose;
1396 
1397  session_id = get_int_var_by_num (lexic, 0, -1);
1398  if (!verify_session_id (session_id, "ssh_login_interactive_pass",
1399  &tbl_slot, lexic))
1400  return NULL; /* Ooops. */
1401  session = session_table[tbl_slot].session;
1402  verbose = session_table[tbl_slot].verbose;
1403 
1404  /* A prompt is waiting for the password. */
1405  if ((password = get_str_local_var_by_name (lexic, "password")) == NULL)
1406  return NULL;
1407 
1408  rc = ssh_userauth_kbdint_setanswer (session, 0, password);
1409 
1410  if (rc < 0)
1411  {
1412  if (verbose)
1413  g_message ("SSH keyboard-interactive authentication "
1414  "failed at prompt %d for session %d: %s",
1415  0, session_id, ssh_get_error (session));
1416  retc_val = -1;
1417  goto leave;
1418  }
1419 
1420  if (rc == 0)
1421  {
1422  /* I need to do that to finish the auth process. */
1423  while ((rc = ssh_userauth_kbdint (session, NULL, NULL)) == SSH_AUTH_INFO)
1424  {
1425  ssh_userauth_kbdint_getnprompts (session);
1426  }
1427  if (rc == SSH_AUTH_SUCCESS)
1428  {
1429  retc_val = 0;
1430  goto leave;
1431  }
1432  if (rc != SSH_AUTH_SUCCESS)
1433  {
1434  retc_val = -1;
1435  goto leave;
1436  }
1437  }
1438 
1439  leave:
1440  {
1441  tree_cell *retc;
1442 
1443  retc = alloc_typed_cell (CONST_INT);
1444  retc->x.i_val = retc_val;
1445  return retc;
1446  }
1447 }
ssh_session session
Definition: nasl_ssh.c:110
char * get_str_local_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1262
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
unsigned int verbose
Definition: nasl_ssh.c:118
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
long int i_val
Definition: nasl_tree.h:114

References get_int_var_by_num().

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 1603 of file nasl_ssh.c.

1604 {
1605  int tbl_slot;
1606  int session_id;
1607  ssh_session session;
1608  int verbose;
1609  char *cmd;
1610  int rc;
1611  GString *response, *compat_buf;
1612  size_t len = 0;
1613  tree_cell *retc;
1614  char *p;
1615  int to_stdout, to_stderr, compat_mode, compat_buf_inuse;
1616 
1617  session_id = get_int_var_by_num (lexic, 0, -1);
1618  if (!verify_session_id (session_id, "ssh_request_exec", &tbl_slot, lexic))
1619  return NULL;
1620  session = session_table[tbl_slot].session;
1621 
1622  verbose = session_table[tbl_slot].verbose;
1623 
1624  cmd = get_str_local_var_by_name (lexic, "cmd");
1625  if (!cmd || !*cmd)
1626  {
1627  log_legacy_write ("No command passed to ssh_request_exec\n");
1628  return NULL;
1629  }
1630 
1631  to_stdout = get_int_local_var_by_name (lexic, "stdout", -1);
1632  to_stderr = get_int_local_var_by_name (lexic, "stderr", -1);
1633  compat_mode = 0;
1634  if (to_stdout == -1 && to_stderr == -1)
1635  {
1636  /* None of the two named args are given. */
1637  to_stdout = 1;
1638  }
1639  else if (to_stdout == 0 && to_stderr == 0)
1640  {
1641  /* Compatibility mode. */
1642  to_stdout = 1;
1643  compat_mode = 1;
1644  }
1645 
1646  if (to_stdout < 0)
1647  to_stdout = 0;
1648  if (to_stderr < 0)
1649  to_stderr = 0;
1650 
1651 
1652  memset (&compat_buf, '\0', sizeof (compat_buf));
1653  /* Allocate some space in advance. Most commands won't output too
1654  much and thus 512 bytes (6 standard terminal lines) should often
1655  be sufficient. */
1656  response = g_string_sized_new (512);
1657  if (compat_mode)
1658  {
1659  compat_buf = g_string_sized_new (512);
1660  compat_buf_inuse = 1;
1661  }
1662  else
1663  compat_buf_inuse = 0;
1664 
1665  rc = exec_ssh_cmd (session, cmd, verbose, compat_mode, to_stdout, to_stderr,
1666  response, compat_buf);
1667  if (rc == SSH_ERROR)
1668  {
1669  if (compat_buf_inuse)
1670  g_string_free (compat_buf, TRUE);
1671  g_string_free (response, TRUE);
1672  return NULL;
1673  }
1674 
1675  /* Append the compatibility buffer to the output. */
1676  if (compat_buf_inuse)
1677  {
1678  len = compat_buf->len;
1679  p = g_string_free (compat_buf, FALSE);
1680  if (p)
1681  {
1682  g_string_append_len (response, p, len);
1683  g_free (p);
1684  }
1685  }
1686 
1687  /* Return the the output. */
1688  len = response->len;
1689  p = g_string_free (response, FALSE);
1690  if (!p)
1691  {
1692  log_legacy_write ("ssh_request_exec memory problem: %s\n", strerror (-1));
1693  return NULL;
1694  }
1695 
1696  retc = alloc_typed_cell (CONST_DATA);
1697  retc->size = len;
1698  retc->x.str_val = p;
1699  return retc;
1700 }
char * str_val
Definition: nasl_tree.h:113
ssh_session session
Definition: nasl_ssh.c:110
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
long int get_int_local_var_by_name(lex_ctxt *, const char *, int)
Definition: nasl_var.c:1240
char * get_str_local_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1262
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
unsigned int verbose
Definition: nasl_ssh.c:118
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
int size
Definition: nasl_tree.h:110

References get_int_var_by_num().

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 802 of file nasl_ssh.c.

803 {
804  int tbl_slot, sock, session_id;
805  tree_cell *retc;
806 
807  session_id = 0;
808  sock = get_int_var_by_num (lexic, 0, -1);
809  if (sock != -1)
810  {
811  for (tbl_slot=0; tbl_slot < DIM (session_table); tbl_slot++)
812  if (session_table[tbl_slot].sock == sock
813  && session_table[tbl_slot].session_id) {
814  session_id = session_table[tbl_slot].session_id;
815  break;
816  }
817  }
818 
819  retc = alloc_typed_cell (CONST_INT);
820  retc->x.i_val = session_id;
821  return retc;
822 }
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
#define DIM(v)
Definition: nasl_ssh.c:71
long int i_val
Definition: nasl_tree.h:114

References DIM, and get_int_var_by_num().

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 chnage the user after the first call to an authentication methods - getting the banner usees an authntication 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 956 of file nasl_ssh.c.

957 {
958  int tbl_slot, session_id;
959 
960  session_id = get_int_var_by_num (lexic, 0, -1);
961  if (!verify_session_id (session_id, "ssh_set_login", &tbl_slot, lexic))
962  return NULL; /* Ooops. */
963  if (!session_table[tbl_slot].user_set)
964  {
965  ssh_session session = session_table[tbl_slot].session;
966  kb_t kb;
967  char *username;
968 
969  username = get_str_local_var_by_name (lexic, "login");
970  if (!username)
971  {
972  kb = plug_get_kb (lexic->script_infos);
973  username = kb_item_get_str (kb, "Secret/SSH/login");
974  }
975  if (username && *username &&
976  ssh_options_set (session, SSH_OPTIONS_USER, username))
977  {
978  log_legacy_write ("Failed to set SSH username '%s': %s\n",
979  username, ssh_get_error (session));
980  return NULL; /* Ooops. */
981  }
982  /* In any case mark the user has set. */
983  session_table[tbl_slot].user_set = 1;
984  }
985  return FAKE_CELL;
986 }
#define FAKE_CELL
Definition: nasl_tree.h:120
ssh_session session
Definition: nasl_ssh.c:110
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
unsigned int user_set
Definition: nasl_ssh.c:116
char * get_str_local_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1262
kb_t plug_get_kb(struct arglist *args)
Definition: plugutils.c:710
Top-level KB. This is to be inherited by KB implementations.
Definition: kb.h:102
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
struct arglist * script_infos
Definition: nasl_lex_ctxt.h:39

References get_int_var_by_num().

Here is the call 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 2118 of file nasl_ssh.c.

2119 {
2120  int tbl_slot, session_id;
2121 
2122  session_id = get_int_var_by_num (lexic, 0, -1);
2123  if (!verify_session_id (session_id, "ssh_shell_close", &tbl_slot, lexic))
2124  return NULL;
2125  if (session_table[tbl_slot].channel)
2126  {
2127  ssh_channel_free (session_table[tbl_slot].channel);
2128  session_table[tbl_slot].channel = NULL;
2129  }
2130 
2131  return NULL;
2132 }
ssh_channel channel
Definition: nasl_ssh.c:111
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226

References get_int_var_by_num().

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 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 1951 of file nasl_ssh.c.

1952 {
1953  int tbl_slot, session_id;
1954  ssh_channel channel;
1955  ssh_session session;
1956  tree_cell *retc;
1957 
1958  session_id = get_int_var_by_num (lexic, 0, -1);
1959  if (!verify_session_id (session_id, "ssh_shell_open", &tbl_slot, lexic))
1960  return NULL;
1961  session = session_table[tbl_slot].session;
1962  channel = ssh_channel_new (session);
1963  if (!channel)
1964  return NULL;
1965  if (ssh_channel_open_session (channel))
1966  {
1967  log_legacy_write ("ssh_channel_open_session: %s",
1968  ssh_get_error (session));
1969  ssh_channel_free (channel);
1970  return NULL;
1971  }
1972 
1973  if (request_ssh_shell (channel))
1974  {
1975  log_legacy_write ("request_ssh_shell: %s", ssh_get_error (session));
1976  ssh_channel_free (channel);
1977  return NULL;
1978  }
1979  if (session_table[tbl_slot].channel)
1980  ssh_channel_free (session_table[tbl_slot].channel);
1981  session_table[tbl_slot].channel = channel;
1982 
1983  retc = alloc_typed_cell (CONST_INT);
1984  retc->x.i_val = session_table[tbl_slot].session_id;
1985  return retc;
1986 }
ssh_channel channel
Definition: nasl_ssh.c:111
ssh_session session
Definition: nasl_ssh.c:110
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
long int i_val
Definition: nasl_tree.h:114

References get_int_var_by_num().

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.
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 2033 of file nasl_ssh.c.

2034 {
2035  int tbl_slot, session_id;
2036  ssh_channel channel;
2037  tree_cell *retc;
2038  GString *response;
2039 
2040  session_id = get_int_var_by_num (lexic, 0, -1);
2041  if (!verify_session_id (session_id, "ssh_shell_read", &tbl_slot, lexic))
2042  return NULL;
2043  channel = session_table[tbl_slot].channel;
2044 
2045  response = g_string_new (NULL);
2046  if (read_ssh_nonblocking (channel, response))
2047  return NULL;
2048  retc = alloc_typed_cell (CONST_DATA);
2049  retc->size = response->len;
2050  retc->x.str_val = g_string_free (response, FALSE);
2051  return retc;
2052 }
char * str_val
Definition: nasl_tree.h:113
ssh_channel channel
Definition: nasl_ssh.c:111
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
int size
Definition: nasl_tree.h:110

References get_int_var_by_num().

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.
  • 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 2070 of file nasl_ssh.c.

2071 {
2072  int tbl_slot, rc = -1, len, session_id;
2073  ssh_channel channel;
2074  tree_cell *retc;
2075  char *cmd;
2076 
2077  session_id = get_int_var_by_num (lexic, 0, -1);
2078  if (!verify_session_id (session_id, "ssh_shell_write", &tbl_slot, lexic))
2079  goto write_ret;
2080  if (!(channel = session_table[tbl_slot].channel))
2081  {
2082  log_legacy_write ("ssh_shell_write: No shell channel found");
2083  goto write_ret;
2084  }
2085 
2086  cmd = get_str_local_var_by_name (lexic, "cmd");
2087  if (!cmd || !*cmd)
2088  {
2089  log_legacy_write ("ssh_shell_write: No command passed");
2090  goto write_ret;
2091  }
2092  len = strlen (cmd);
2093  if (ssh_channel_write (channel, cmd, len) != len)
2094  {
2095  log_legacy_write ("ssh_shell_write: %s",
2096  ssh_get_error (session_table[tbl_slot].session));
2097  goto write_ret;
2098  }
2099  rc = 0;
2100 
2101 write_ret:
2102  retc = alloc_typed_cell (CONST_INT);
2103  retc->x.i_val = rc;
2104  return retc;
2105 }
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
char * get_str_local_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1262
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
Definition: nasl_tree.h:105
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
long int i_val
Definition: nasl_tree.h:114

References get_int_var_by_num().

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 1047 of file nasl_ssh.c.

1048 {
1049  int tbl_slot;
1050  int session_id;
1051  ssh_session session;
1052  const char *password = NULL;
1053  const char *privkeystr = NULL;
1054  const char *privkeypass = NULL;
1055  int rc;
1056  kb_t kb;
1057  int retc_val = -1;
1058  int methods;
1059  int verbose;
1060 
1061  session_id = get_int_var_by_num (lexic, 0, -1);
1062  if (!verify_session_id (session_id, "ssh_userauth", &tbl_slot, lexic))
1063  return NULL; /* Ooops. */
1064  session = session_table[tbl_slot].session;
1065  verbose = session_table[tbl_slot].verbose;
1066 
1067  /* Check if we need to set the user. This is done only once per
1068  session. */
1069  if (!session_table[tbl_slot].user_set && !nasl_ssh_set_login (lexic))
1070  return NULL;
1071 
1072  kb = plug_get_kb (lexic->script_infos);
1073  password = get_str_local_var_by_name (lexic, "password");
1074  privkeystr = get_str_local_var_by_name (lexic, "privatekey");
1075  privkeypass = get_str_local_var_by_name (lexic, "passphrase");
1076  if (!password && !privkeystr && !privkeypass)
1077  {
1078  password = kb_item_get_str (kb, "Secret/SSH/password");
1079  privkeystr = kb_item_get_str (kb, "Secret/SSH/privatekey");
1080  privkeypass = kb_item_get_str (kb, "Secret/SSH/passphrase");
1081  }
1082 
1083  /* Get the authentication methods onlye once per session. */
1084  if (!session_table[tbl_slot].authmethods_valid)
1085  {
1086  if (!get_authmethods (tbl_slot))
1087  {
1088  retc_val = 0;
1089  goto leave;
1090  }
1091  }
1092  methods = session_table[tbl_slot].authmethods;
1093 
1094  /* Check whether a password has been given. If so, try to
1095  authenticate using that password. Note that the OpenSSH client
1096  uses a different order it first tries the public key and then the
1097  password. However, the old NASL SSH protocol implementation tries
1098  the password before the public key authentication. Because we
1099  want to be compatible, we do it in that order. */
1100  if (password && (methods & SSH_AUTH_METHOD_PASSWORD))
1101  {
1102  rc = ssh_userauth_password (session, NULL, password);
1103  if (rc == SSH_AUTH_SUCCESS)
1104  {
1105  retc_val = 0;
1106  goto leave;
1107  }
1108 
1109  if (verbose)
1110  log_legacy_write ("SSH password authentication failed for session"
1111  " %d: %s\n", session_id, ssh_get_error (session));
1112  /* Keep on trying. */
1113  }
1114 
1115  if (password && (methods & SSH_AUTH_METHOD_INTERACTIVE))
1116  {
1117  /* Our strategy for kbint is to send the password to the first
1118  prompt marked as non-echo. */
1119  while ((rc = ssh_userauth_kbdint (session, NULL, NULL)) == SSH_AUTH_INFO)
1120  {
1121  const char *s;
1122  int n, nprompt;
1123  char echoflag;
1124  int found_prompt = 0;
1125 
1126  if (verbose)
1127  {
1128  s = ssh_userauth_kbdint_getname (session);
1129  if (s && *s)
1130  log_legacy_write ("SSH kbdint name='%s'\n", s);
1131  s = ssh_userauth_kbdint_getinstruction (session);
1132  if (s && *s)
1133  log_legacy_write ("SSH kbdint instruction='%s'\n", s);
1134  }
1135  nprompt = ssh_userauth_kbdint_getnprompts (session);
1136  for (n=0; n < nprompt; n++)
1137  {
1138  s = ssh_userauth_kbdint_getprompt (session, n, &echoflag);
1139  if (s && *s && verbose)
1140  log_legacy_write ("SSH kbdint prompt='%s'%s\n",
1141  s, echoflag ? "" : " [hide input]");
1142  if (s && *s && !echoflag && !found_prompt)
1143  {
1144  found_prompt = 1;
1145  rc = ssh_userauth_kbdint_setanswer (session, n, password);
1146  if (rc != SSH_AUTH_SUCCESS)
1147  {
1148  if (verbose)
1150  ("SSH keyboard-interactive authentication "
1151  "failed at prompt %d for session %d: %s\n",
1152  n, session_id, ssh_get_error (session));
1153  }
1154  }
1155  }
1156  }
1157 
1158  if (rc == SSH_AUTH_SUCCESS)
1159  {
1160  retc_val = 0;
1161  goto leave;
1162  }
1163 
1164  if (verbose)
1166  ("SSH keyboard-interactive authentication failed for session %d"
1167  ": %s\n", session_id, ssh_get_error (session));
1168  /* Keep on trying. */
1169  }
1170 
1171  /* If we have a private key, try public key authentication. */
1172  if (privkeystr && *privkeystr && (methods & SSH_AUTH_METHOD_PUBLICKEY))
1173  {
1174 #if LIBSSH_VERSION_INT >= SSH_VERSION_INT (0, 6, 0)
1175  ssh_key key = NULL;
1176 
1177  if (ssh_pki_import_privkey_base64 (privkeystr, privkeypass, NULL, NULL,
1178  &key))
1179  {
1180  if (verbose)
1182  ("SSH public key authentication failed for "
1183  "session %d: %s\n", session_id, "Error converting provided key");
1184  }
1185  else if (ssh_userauth_try_publickey (session, NULL, key)
1186  != SSH_AUTH_SUCCESS)
1187  {
1188  if (verbose)
1190  ("SSH public key authentication failed for "
1191  "session %d: %s\n", session_id, "Server does not want our key");
1192  }
1193  else if (ssh_userauth_publickey (session, NULL, key) == SSH_AUTH_SUCCESS)
1194  {
1195  retc_val = 0;
1196  ssh_key_free (key);
1197  goto leave;
1198  }
1199  ssh_key_free (key);
1200 
1201 #else
1202 
1203  my_ssh_key key = NULL;
1204 
1205  /* SESSION is only used by our emulation - FIXME: remove it for 0.6. */
1206  if (my_ssh_pki_import_privkey_base64 (session, verbose,
1207  privkeystr, privkeypass,
1208  NULL, NULL, &key))
1209  {
1210  if (verbose)
1212  ("SSH public key authentication failed for "
1213  "session %d: %s\n", session_id, "Error converting provided key");
1214  }
1215  else if (my_ssh_userauth_try_publickey (session, NULL, key)
1216  != SSH_AUTH_SUCCESS)
1217  {
1218  if (verbose)
1220  ("SSH public key authentication failed for "
1221  "session %d: %s\n", session_id, "Server does not want our key");
1222  }
1223  else if (my_ssh_userauth_publickey (session, NULL, key)
1224  == SSH_AUTH_SUCCESS)
1225  {
1226  retc_val = 0;
1227  my_ssh_key_free (key);
1228  goto leave;
1229  }
1230  my_ssh_key_free (key);
1231 #endif
1232  /* Keep on trying. */
1233  }
1234 
1235  if (verbose)
1236  log_legacy_write ("SSH authentication failed for session %d: %s\n",
1237  session_id, "No more authentication methods to try");
1238  leave:
1239  {
1240  tree_cell *retc;
1241 
1242  retc = alloc_typed_cell (CONST_INT);
1243  retc->x.i_val = retc_val;
1244  return retc;
1245  }
1246 }
ssh_session session
Definition: nasl_ssh.c:110
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
char * get_str_local_var_by_name(lex_ctxt *, const char *)
Definition: nasl_var.c:1262
union TC::@7 x
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
kb_t plug_get_kb(struct arglist *args)
Definition: plugutils.c:710
Top-level KB. This is to be inherited by KB implementations.
Definition: kb.h:102
Definition: nasl_tree.h:105
unsigned int verbose
Definition: nasl_ssh.c:118
tree_cell * nasl_ssh_set_login(lex_ctxt *lexic)
Set the login name for the authentication.
Definition: nasl_ssh.c:956
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
long int i_val
Definition: nasl_tree.h:114
struct arglist * script_infos
Definition: nasl_lex_ctxt.h:39

References get_int_var_by_num().

Here is the call graph for this function:

Variable Documentation

◆ lowest_socket

int lowest_socket

Definition at line 223 of file nasl_socket.c.

Referenced by nasl_open_sock_udp().