OpenVAS Scanner  21.4.1
Data Structures | Macros | Functions | Variables
nasl_ssh.c File Reference

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

#include "nasl_ssh.h"
#include "../misc/network.h"
#include "../misc/plugutils.h"
#include "exec.h"
#include "nasl_debug.h"
#include "nasl_func.h"
#include "nasl_global_ctxt.h"
#include "nasl_lex_ctxt.h"
#include "nasl_tree.h"
#include "nasl_var.h"
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <gvm/base/logging.h>
#include <gvm/base/networking.h>
#include <gvm/base/prefs.h>
#include <gvm/util/kb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

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 G_LOG_DOMAIN   "lib nasl"
 GLib logging domain. More...
 
#define MAX_SSH_SESSIONS   10
 

Functions

static int nasl_ssh_close_hook (int sock)
 Hook to close a socket associated with an ssh connection. More...
 
static void g_string_comma_str (GString *gstr, const char *str)
 
static int next_session_id (void)
 
static unsigned short get_ssh_port (lex_ctxt *lexic)
 
tree_cellnasl_ssh_connect (lex_ctxt *lexic)
 Connect to the target host via TCP and setup an ssh connection. More...
 
static int verify_session_id (int session_id, const char *funcname, int *r_slot, lex_ctxt *lexic)
 
static void do_nasl_ssh_disconnect (int tbl_slot)
 
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...
 
static int get_authmethods (int tbl_slot)
 
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...
 
static void exec_ssh_cmd_alarm (int signal)
 
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. 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...
 
static void request_ssh_shell_alarm (int signal)
 
static int request_ssh_shell (ssh_channel channel, int pty)
 Open a shell on an ssh channel. More...
 
tree_cellnasl_ssh_shell_open (lex_ctxt *lexic)
 Request an ssh shell. More...
 
static int read_ssh_nonblocking (ssh_channel channel, GString *response)
 read from an ssh channel without blocking. 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

static struct session_table_item_s session_table [MAX_SSH_SESSIONS]
 
int lowest_socket
 

Detailed Description

Implementation of an API for SSH functions.

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

Macro Definition Documentation

◆ DIM

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

◆ DIMof

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

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "lib nasl"

GLib logging domain.

◆ MAX_SSH_SESSIONS

#define MAX_SSH_SESSIONS   10

Function Documentation

◆ do_nasl_ssh_disconnect()

static void do_nasl_ssh_disconnect ( int  tbl_slot)
static

◆ exec_ssh_cmd()

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 
)
static

Execute an ssh command.

Parameters
[in]sessionSSH session.
[in]cmdCommand to execute.
[in]verbose1 for verbose mode, 0 otherwise.
[in]compat_mode1 for compatibility mode, 0 otherwise.
[in]to_stdout1 to return command output to stdout.
[in]to_stderr1 to return command output to stderr.
[out]responseResponse buffer.
[out]compat_bufCompatibility buffer.
Returns
SSH_OK if success, SSH_ERROR otherwise.

◆ exec_ssh_cmd_alarm()

static void exec_ssh_cmd_alarm ( int  signal)
static

◆ g_string_comma_str()

static void g_string_comma_str ( GString *  gstr,
const char *  str 
)
static

◆ get_authmethods()

static int get_authmethods ( int  tbl_slot)
static

◆ get_ssh_port()

static unsigned short get_ssh_port ( lex_ctxt lexic)
static

◆ nasl_ssh_close_hook()

static int nasl_ssh_close_hook ( int  sock)
static

Hook to close a socket associated with an ssh connection.

NASL code may be using "ssh_connect" passing an open socket and later closing this socket using "close" instead of calling "ssh_disconnect". Thus the close code needs to check whether the socket refers to an ssh connection and call ssh_disconnect then (libssh takes ownership of the socket if set via SSH_OPTIONS_FD). This function implements the hook for checking and closing.

Parameters
[in]sockA socket
Returns
Zero if the socket was closed (disconnected).

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ next_session_id()

static int next_session_id ( void  )
static

◆ read_ssh_nonblocking()

static int read_ssh_nonblocking ( ssh_channel  channel,
GString *  response 
)
static

read from an ssh channel without blocking.

Parameters
[in]channelSSH Channel.
[out]responseBuffer to store response in.
Returns
0 if success, -1 if error.

◆ request_ssh_shell()

static int request_ssh_shell ( ssh_channel  channel,
int  pty 
)
static

Open a shell on an ssh channel.

Parameters
[in]channelSSH Channel.
[in]pty1 interactive shell, 0 non-intercative shell
Returns
0 if success, -1 if error.

◆ request_ssh_shell_alarm()

static void request_ssh_shell_alarm ( int  signal)
static

◆ verify_session_id()

static int verify_session_id ( int  session_id,
const char *  funcname,
int *  r_slot,
lex_ctxt lexic 
)
static

Variable Documentation

◆ lowest_socket

int lowest_socket
extern

◆ session_table

struct session_table_item_s session_table[MAX_SSH_SESSIONS]
static