32#include <glib/gstdio.h>
33#include <gvm/base/logging.h>
34#include <gvm/base/networking.h>
35#include <gvm/base/prefs.h>
36#include <gvm/util/kb.h>
37#include <libssh/sftp.h>
38#include <netinet/in.h>
42#include <sys/select.h>
43#include <sys/socket.h>
49#define DIM(v) (sizeof (v) / sizeof ((v)[0]))
50#define DIMof(type, member) DIM (((type *) 0)->member)
54#error Oops, libssh ABI changed
61#define G_LOG_DOMAIN "lib nasl"
103#define MAX_SSH_SESSIONS 10
114 g_string_append (gstr,
",");
115 g_string_append (gstr, str);
125 static int initialized;
126 static int last = 9000;
159 int type = KB_TYPE_INT;
160 unsigned short port, *port_aux = NULL;
162 value = prefs_get (
"auth_port_ssh");
163 if (value && (port = (
unsigned short) strtoul (value, NULL, 10)) > 0)
167 "Services/ssh", &type, NULL, 0);
173 if (type == KB_TYPE_INT && port > 0)
229 const char *key_type, *csciphers, *scciphers, *s;
230 char ip_str[INET6_ADDRSTRLEN];
232 unsigned int tbl_slot;
234 int forced_sock = -1;
251 g_message (
"Function %s (calling internal function %s) called from %s: "
252 "Failed to allocate a new SSH session",
254 :
"script_main_function",
261 if (ssh_options_set (
session, SSH_OPTIONS_TIMEOUT, &timeout))
264 "Function %s called from %s: "
265 "Failed to set the SSH connection timeout to %ld seconds: %s",
272 if ((s = getenv (
"OPENVAS_LIBSSH_DEBUG")))
277 int intval = atoi (s);
279 ssh_options_set (
session, SSH_OPTIONS_LOG_VERBOSITY, &intval);
283 if (ssh_options_set (
session, SSH_OPTIONS_HOST, ip_str))
285 g_message (
"Function %s (calling internal function %s) called from %s: "
286 "Failed to set SSH hostname '%s': %s",
288 :
"script_main_function",
295 if (ssh_options_set (
session, SSH_OPTIONS_KNOWNHOSTS,
"/dev/null"))
297 g_message (
"Function %s (calling internal function %s) called from %s: "
298 "Failed to disable SSH known_hosts: %s",
300 :
"script_main_function",
309 if (key_type && ssh_options_set (
session, SSH_OPTIONS_HOSTKEYS, key_type))
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",
323 && ssh_options_set (
session, SSH_OPTIONS_CIPHERS_C_S, csciphers))
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",
336 && ssh_options_set (
session, SSH_OPTIONS_CIPHERS_S_C, scciphers))
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",
350 unsigned int my_port = port;
352 if (ssh_options_set (
session, SSH_OPTIONS_PORT, &my_port))
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",
370 g_message (
"Setting SSH fd for '%s' to %d (NASL sock=%d)", ip_str,
372 if (ssh_options_set (
session, SSH_OPTIONS_FD, &my_fd))
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",
395 g_message (
"No space left in SSH session table");
408 g_message (
"Connecting to SSH server '%s' (port %d, sock %d)", ip_str, port,
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)
438 forced_sock != -1 ? forced_sock : ssh_get_fd (
session);
455 unsigned int tbl_slot;
459 nasl_perror (lexic,
"Invalid SSH session id %d passed to %s",
543 unsigned int tbl_slot;
581 unsigned int tbl_slot;
651 rc = ssh_userauth_none (
session, NULL);
652 if (rc == SSH_AUTH_SUCCESS)
654 g_message (
"SSH authentication succeeded using the none method - "
655 "should not happen; very old server?");
660 else if (rc == SSH_AUTH_DENIED)
662 methods = ssh_userauth_list (
session, NULL);
667 g_message (
"SSH server did not return a list of authentication methods"
669 methods = (SSH_AUTH_METHOD_NONE | SSH_AUTH_METHOD_PASSWORD
670 | SSH_AUTH_METHOD_PUBLICKEY | SSH_AUTH_METHOD_HOSTBASED
671 | SSH_AUTH_METHOD_INTERACTIVE);
676 fputs (
"SSH available authentication methods:", stderr);
677 if ((methods & SSH_AUTH_METHOD_NONE))
678 fputs (
" none", stderr);
679 if ((methods & SSH_AUTH_METHOD_PASSWORD))
680 fputs (
" password", stderr);
681 if ((methods & SSH_AUTH_METHOD_PUBLICKEY))
682 fputs (
" publickey", stderr);
683 if ((methods & SSH_AUTH_METHOD_HOSTBASED))
684 fputs (
" hostbased", stderr);
685 if ((methods & SSH_AUTH_METHOD_INTERACTIVE))
686 fputs (
" keyboard-interactive", stderr);
687 fputs (
"\n", stderr);
745 username = kb_item_get_str (kb,
"Secret/SSH/login");
747 if (username && *username
748 && ssh_options_set (
session, SSH_OPTIONS_USER, username))
751 "Function %s (calling internal function %s) called from %s: "
752 "Failed to set SSH username '%s': %s",
754 :
"script_main_function",
829 char *password = NULL;
830 char *privkeystr = NULL;
831 char *privkeypass = NULL;
850 if (!password && !privkeystr && !privkeypass)
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");
874 if (password && (methods & SSH_AUTH_METHOD_PASSWORD))
876 rc = ssh_userauth_password (
session, NULL, password);
877 if (rc == SSH_AUTH_SUCCESS)
884 g_message (
"SSH password authentication failed for session"
890 if (password && (methods & SSH_AUTH_METHOD_INTERACTIVE))
894 while ((rc = ssh_userauth_kbdint (
session, NULL, NULL)) == SSH_AUTH_INFO)
899 int found_prompt = 0;
903 s = ssh_userauth_kbdint_getname (
session);
905 g_message (
"SSH kbdint name='%s'", s);
906 s = ssh_userauth_kbdint_getinstruction (
session);
908 g_message (
"SSH kbdint instruction='%s'", s);
910 nprompt = ssh_userauth_kbdint_getnprompts (
session);
911 for (n = 0; n < nprompt; n++)
913 s = ssh_userauth_kbdint_getprompt (
session, n, &echoflag);
915 g_message (
"SSH kbdint prompt='%s'%s", s,
916 echoflag ?
"" :
" [hide input]");
917 if (s && *s && !echoflag && !found_prompt)
920 rc = ssh_userauth_kbdint_setanswer (
session, n, password);
921 if (rc != SSH_AUTH_SUCCESS)
924 g_message (
"SSH keyboard-interactive authentication "
925 "failed at prompt %d for session %d: %s",
932 if (rc == SSH_AUTH_SUCCESS)
940 "SSH keyboard-interactive authentication failed for session %d"
947 if (privkeystr && *privkeystr && (methods & SSH_AUTH_METHOD_PUBLICKEY))
951 if (ssh_pki_import_privkey_base64 (privkeystr, privkeypass, NULL, NULL,
955 g_message (
"SSH public key authentication failed for "
959 else if (ssh_userauth_try_publickey (
session, NULL, key)
963 g_message (
"SSH public key authentication failed for "
967 else if (ssh_userauth_publickey (
session, NULL, key) == SSH_AUTH_SUCCESS)
978 g_message (
"SSH authentication failed for session %d: %s",
session_id,
979 "No more authentication methods to try");
984 g_free (privkeypass);
1021 const char *s = NULL;
1048 if (methods & SSH_AUTH_METHOD_INTERACTIVE)
1053 while (ssh_userauth_kbdint (
session, NULL, NULL) == SSH_AUTH_INFO)
1057 int found_prompt = 0;
1061 s = ssh_userauth_kbdint_getname (
session);
1063 g_message (
"SSH kbdint name='%s'", s);
1064 s = ssh_userauth_kbdint_getinstruction (
session);
1066 g_message (
"SSH kbdint instruction='%s'", s);
1069 nprompt = ssh_userauth_kbdint_getnprompts (
session);
1070 for (n = 0; n < nprompt; n++)
1072 s = ssh_userauth_kbdint_getprompt (
session, n, &echoflag);
1074 g_message (
"SSH kbdint prompt='%s'%s", s,
1075 echoflag ?
"" :
" [hide input]");
1076 if (s && *s && !echoflag && !found_prompt)
1082 "SSH keyboard-interactive authentication failed for session %d"
1096 retc->
size = strlen (s);
1133 const char *password = NULL;
1149 rc = ssh_userauth_kbdint_setanswer (
session, 0, password);
1154 g_message (
"SSH keyboard-interactive authentication "
1155 "failed at prompt %d for session %d: %s",
1164 while ((rc = ssh_userauth_kbdint (
session, NULL, NULL)) == SSH_AUTH_INFO)
1166 ssh_userauth_kbdint_getnprompts (
session);
1168 if (rc == SSH_AUTH_SUCCESS)
1173 if (rc != SSH_AUTH_SUCCESS)
1185 retc->
x.
i_val = retc_val;
1194 g_message (
"exec_ssh_cmd: Timeout");
1214 int to_stdout,
int to_stderr, GString *response,
1215 GString *compat_buf)
1226 g_message (
"Function %s (calling internal function %s) called from %s: "
1227 "ssh_channel_new failed: %s",
1229 :
"script_main_function",
1235 if (ssh_channel_open_session (
channel))
1239 g_message (
"ssh_channel_open_session failed: %s",
1246 g_message (
"ssh_channel_request_pty failed: %s", ssh_get_error (
session));
1248 if (ssh_channel_request_exec (
channel, cmd))
1252 g_message (
"ssh_channel_request_exec failed for '%s': %s", cmd,
1258 signal (SIGALRM, _exit);
1261 if ((rc = ssh_channel_read_timeout (
channel, buffer,
sizeof (buffer), 1,
1266 g_string_append_len (response, buffer, rc);
1268 g_string_append_len (compat_buf, buffer, rc);
1270 if (rc == SSH_ERROR)
1276 if ((rc = ssh_channel_read_timeout (
channel, buffer,
sizeof (buffer), 0,
1281 g_string_append_len (response, buffer, rc);
1283 if (rc == SSH_ERROR)
1354 GString *compat_buf = NULL;
1358 int to_stdout, to_stderr, compat_mode, compat_buf_inuse;
1370 g_message (
"Function %s (calling internal function %s) called from %s: "
1371 "No command passed",
1373 :
"script_main_function",
1381 if (to_stdout == -1 && to_stderr == -1)
1386 else if (to_stdout == 0 && to_stderr == 0)
1401 response = g_string_sized_new (512);
1404 compat_buf = g_string_sized_new (512);
1405 compat_buf_inuse = 1;
1408 compat_buf_inuse = 0;
1411 response, compat_buf);
1412 if (rc == SSH_ERROR)
1414 if (compat_buf_inuse)
1415 g_string_free (compat_buf, TRUE);
1416 g_string_free (response, TRUE);
1421 if (compat_buf_inuse)
1423 len = compat_buf->len;
1424 p = g_string_free (compat_buf, FALSE);
1427 g_string_append_len (response, p,
len);
1433 len = response->len;
1434 p = g_string_free (response, FALSE);
1437 g_message (
"Function %s (calling internal function %s) called from %s: "
1438 "memory problem: %s",
1440 :
"script_main_function",
1490 banner = ssh_get_issue_banner (
session);
1495 retc->
x.
str_val = g_strdup (banner);
1496 retc->
size = strlen (banner);
1497 ssh_string_free_char (banner);
1533 banner = ssh_get_serverbanner (
session);
1538 retc->
x.
str_val = g_strdup (banner);
1539 retc->
size = strlen (banner);
1573 sstring = ssh_get_pubkey (
session);
1578 retc->
x.
str_val = ssh_string_to_char (sstring);
1579 retc->
size = ssh_string_len (sstring);
1580 ssh_string_free (sstring);
1623 buffer = g_string_sized_new (128);
1624 if ((methods & SSH_AUTH_METHOD_NONE))
1626 if ((methods & SSH_AUTH_METHOD_PASSWORD))
1628 if ((methods & SSH_AUTH_METHOD_PUBLICKEY))
1630 if ((methods & SSH_AUTH_METHOD_HOSTBASED))
1632 if ((methods & SSH_AUTH_METHOD_INTERACTIVE))
1634 g_string_append_c (buffer, 0x00);
1635 p = g_string_free (buffer, FALSE);
1641 retc->
size = strlen (p);
1649 g_message (
"request_ssh_shell: Timeout");
1671 if (ssh_channel_request_pty (
channel))
1674 if (ssh_channel_change_pty_size (
channel, 80, 24))
1677 if (ssh_channel_request_shell (
channel))
1681 signal (SIGALRM, _exit);
1721 if (ssh_channel_open_session (
channel))
1723 g_message (
"Function %s (calling internal function %s) called from %s: "
1724 "ssh_channel_open_session: %s",
1726 :
"script_main_function",
1735 g_message (
"Function %s (calling internal function %s) called from %s: "
1736 "request_ssh_shell: %s",
1738 :
"script_main_function",
1772 if ((rc = ssh_channel_read_timeout (
channel, buffer,
sizeof (buffer), 1,
1775 g_string_append_len (response, buffer, rc);
1777 else if (rc == SSH_ERROR)
1780 while (rc > 0 || rc == SSH_AGAIN);
1785 if ((rc = ssh_channel_read_timeout (
channel, buffer,
sizeof (buffer), 0,
1788 g_string_append_len (response, buffer, rc);
1790 else if (rc == SSH_ERROR)
1793 while (rc > 0 || rc == SSH_AGAIN);
1814 if (!ssh_channel_is_open (
channel) || ssh_channel_is_eof (
channel))
1817 if ((rc = ssh_channel_read_nonblocking (
channel, buffer,
sizeof (buffer), 1))
1819 g_string_append_len (response, buffer, rc);
1820 if (rc == SSH_ERROR)
1822 if ((rc = ssh_channel_read_nonblocking (
channel, buffer,
sizeof (buffer), 0))
1824 g_string_append_len (response, buffer, rc);
1825 if (rc == SSH_ERROR)
1863 response = g_string_new (NULL);
1878 retc->
size = response->len;
1879 retc->
x.
str_val = g_string_free (response, FALSE);
1914 g_message (
"ssh_shell_write: No shell channel found");
1921 g_message (
"Function %s (calling internal function %s) called from %s: "
1922 "No command passed",
1924 :
"script_main_function",
1932 "Function %s (calling internal function %s) called from %s: %s",
1934 :
"script_main_function",
2013 "Function %s (calling internal function %s) called from %s: %s",
2015 :
"script_main_function",
2022 rc = sftp_init (sftp);
2027 g_message (
"Function %s (calling internal function %s) called from "
2030 :
"script_main_function",
2033 sftp_get_error (sftp));
2077 if (ssh_channel_open_session (
channel))
2080 g_message (
"ssh_channel_open_session failed: %s",
2084 retc->
x.
i_val = SSH_ERROR;
2089 if ((err = ssh_channel_request_subsystem (
channel,
"netconf")) < 0)
2091 g_message (
"%s Could not execute netconf subsystem", __func__);
const char * nasl_get_plugin_filename()
Get the current launched plugin filename.
const char * nasl_get_function_name()
void nasl_perror(lex_ctxt *lexic, char *msg,...)
struct struct_lex_ctxt lex_ctxt
char * get_str_var_by_name(lex_ctxt *, const char *)
long int get_int_var_by_num(lex_ctxt *, int, int)
long int get_int_var_by_name(lex_ctxt *, const char *, int)
static void g_string_comma_str(GString *gstr, const char *str)
static void do_nasl_ssh_disconnect(int tbl_slot)
tree_cell * nasl_ssh_shell_close(lex_ctxt *lexic)
Close an ssh shell.
tree_cell * nasl_ssh_shell_read(lex_ctxt *lexic)
Read the output of an ssh shell.
tree_cell * nasl_ssh_set_login(lex_ctxt *lexic)
Set the login name for the authentication.
tree_cell * nasl_ssh_userauth(lex_ctxt *lexic)
Authenticate a user on an ssh connection.
static int nasl_ssh_close_hook(int)
Hook to close a socket associated with an ssh connection.
tree_cell * nasl_ssh_shell_open(lex_ctxt *lexic)
Request an ssh shell.
static int get_authmethods(int tbl_slot)
tree_cell * nasl_ssh_execute_netconf_subsystem(lex_ctxt *lexic)
Excecute the NETCONF subsystem on the the ssh channel.
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.
tree_cell * nasl_ssh_login_interactive(lex_ctxt *lexic)
Authenticate a user on an ssh connection.
tree_cell * nasl_ssh_get_issue_banner(lex_ctxt *lexic)
Get the issue banner.
tree_cell * nasl_ssh_request_exec(lex_ctxt *lexic)
Run a command via ssh.
tree_cell * nasl_ssh_get_host_key(lex_ctxt *lexic)
Get the host key.
static struct session_table_item_s session_table[MAX_SSH_SESSIONS]
static int next_session_id(void)
tree_cell * nasl_ssh_login_interactive_pass(lex_ctxt *lexic)
Authenticate a user on an ssh connection.
static unsigned short get_ssh_port(lex_ctxt *lexic)
tree_cell * nasl_ssh_get_auth_methods(lex_ctxt *lexic)
Get the list of authmethods.
tree_cell * nasl_sftp_enabled_check(lex_ctxt *lexic)
Check if the SFTP subsystem is enabled on the remote SSH server.
static void exec_ssh_cmd_alarm(int signal)
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.
tree_cell * nasl_ssh_disconnect(lex_ctxt *lexic)
Disconnect an ssh connection.
tree_cell * nasl_ssh_connect(lex_ctxt *lexic)
Connect to the target host via TCP and setup an ssh connection.
tree_cell * nasl_ssh_shell_write(lex_ctxt *lexic)
Write string to ssh shell.
static void request_ssh_shell_alarm(int signal)
tree_cell * nasl_ssh_get_server_banner(lex_ctxt *lexic)
Get the server banner.
static int request_ssh_shell(ssh_channel channel, int pty)
Open a shell on an ssh channel.
tree_cell * nasl_ssh_session_id_from_sock(lex_ctxt *lexic)
Given a socket, return the corresponding session id.
static int read_ssh_nonblocking(ssh_channel channel, GString *response)
read from an ssh channel without blocking.
static int verify_session_id(int session_id, const char *funcname, int *r_slot, lex_ctxt *lexic)
tree_cell * nasl_ssh_get_sock(lex_ctxt *lexic)
Given a session id, return the corresponding socket.
Protos and data structures for SSH functions used by NASL scripts.
tree_cell * alloc_typed_cell(int typ)
int openvas_get_socket_from_connection(int fd)
void add_close_stream_connection_hook(int(*fnc)(int fd))
Register a hook function for close_stream_connection.
Header file for module network.
void * plug_get_key(struct script_infos *args, char *name, int *type, size_t *len, int single)
Get values from a kb under the given key name.
struct in6_addr * plug_get_host_ip(struct script_infos *args)
kb_t plug_get_kb(struct script_infos *args)
Header file for module plugutils.
union TC::@332262321161220155002104006201360276211317150140 x
unsigned int authmethods_valid
struct script_infos * script_infos