OpenVAS Scanner 23.32.3
nasl_ssh.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Greenbone AG
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
14
15#include "nasl_ssh.h"
16
17#include "../misc/network.h" /* for openvas_get_socket_from_connection */
18#include "../misc/plugutils.h"
19#include "exec.h"
20#include "nasl_debug.h"
21#include "nasl_func.h"
22#include "nasl_global_ctxt.h"
23#include "nasl_lex_ctxt.h"
24#include "nasl_tree.h"
25#include "nasl_var.h"
26
27#include <arpa/inet.h>
28#include <ctype.h>
29#include <errno.h>
30#include <fcntl.h>
31#include <glib.h>
32#include <glib/gstdio.h>
33#include <gvm/base/logging.h>
34#include <gvm/base/networking.h>
35#include <gvm/base/prefs.h> /* for prefs_get() */
36#include <gvm/util/kb.h>
37#include <libssh/sftp.h>
38#include <netinet/in.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <sys/select.h>
43#include <sys/socket.h>
44#include <sys/time.h>
45#include <sys/types.h>
46#include <unistd.h>
47
48#ifndef DIM
49#define DIM(v) (sizeof (v) / sizeof ((v)[0]))
50#define DIMof(type, member) DIM (((type *) 0)->member)
51#endif
52
53#if SSH_OK != 0
54#error Oops, libssh ABI changed
55#endif
56
57#undef G_LOG_DOMAIN
61#define G_LOG_DOMAIN "lib nasl"
62
63/* This object is used to keep track of libssh contexts. Because they
64 are pointers they can't be mapped easily to the NASL type system.
65 We would need to define a new type featuring a callback which would
66 be called when that variable will be freed. This is not easy and
67 has several implications. A clean solution requires a decent
68 garbage collector system with an interface to flange arbitrary C
69 subsystems to it. After all we would end up with a complete VM
70 and FFI. We don't want to do that now.
71
72 Our solution is to track those contexts here and clean up any left
73 over context at the end of a script run. We could use undocumented
74 "on_exit" feature but that one is not well implemented; thus we use
75 explicit code in the interpreter for the cleanup. The scripts are
76 expected to close the sessions, but as long as they don't open too
77 many of them, the system will take care of it at script termination
78 time.
79
80 We associate each context with a session id, which is a global
81 counter of this process. The simpler version of using slot numbers
82 won't allow for better consistency checks. A session id of 0 marks
83 an unused table entry.
84
85 Note that we can't reuse a session for another connection. To use a
86 session is always an active or meanwhile broken connection to the
87 server.
88 */
90{
92 ssh_session session;
93 ssh_channel channel;
94 int sock; /* The associated socket. */
95 int authmethods; /* Bit fields with available
96 authentication methods. */
97 unsigned int authmethods_valid : 1; /* Indicating that methods is valid. */
98 unsigned int user_set : 1; /* Set if a user has been set for
99 the session. */
100 unsigned int verbose : 1; /* Verbose diagnostics. */
101};
102
103#define MAX_SSH_SESSIONS 10
105
106/* Local prototypes. */
107static int
109
110static void
111g_string_comma_str (GString *gstr, const char *str)
112{
113 if (gstr->len)
114 g_string_append (gstr, ",");
115 g_string_append (gstr, str);
116}
117
118/* Return the next session id. Note that the first session ID we will
119 hand out is an arbitrary high number, this is only to help
120 debugging. This function is also used to setup a hook to the
121 network layer. */
122static int
124{
125 static int initialized;
126 static int last = 9000;
127 unsigned int i;
128
129 if (!initialized)
130 {
132 initialized = 1;
133 }
134
135again:
136 last++;
137 /* Because we don't have an unsigned type, it is better to avoid
138 negative values. Thus if LAST turns negative we wrap around to
139 1; this also avoids the verboten zero. */
140 if (last <= 0)
141 last = 1;
142 /* Now it may happen that after wrapping there is still a session id
143 with that new value in use. We can't allow that and check for
144 it. */
145 for (i = 0; i < DIM (session_table); i++)
146 if (session_table[i].session_id == last)
147 goto again;
148
149 return last;
150}
151
152/* Return the port for an SSH connection. It first looks up the port
153 in the preferences, then falls back to the KB, and finally resorts
154 to the standard port. */
155static unsigned short
157{
158 const char *value;
159 int type = KB_TYPE_INT;
160 unsigned short port, *port_aux = NULL;
161
162 value = prefs_get ("auth_port_ssh");
163 if (value && (port = (unsigned short) strtoul (value, NULL, 10)) > 0)
164 return port;
165
166 port_aux = (unsigned short *) plug_get_key (lexic->script_infos,
167 "Services/ssh", &type, NULL, 0);
168
169 if (port_aux)
170 {
171 port = *port_aux;
172 g_free (port_aux);
173 if (type == KB_TYPE_INT && port > 0)
174 return port;
175 }
176
177 return 22;
178}
179
180extern int lowest_socket;
181
224tree_cell *
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}
447
448/* Helper function to find and validate the session id. On error 0 is
449 returned, on success the session id and in this case the slot number
450 from the table is stored at R_SLOT. */
451static int
452verify_session_id (int session_id, const char *funcname, int *r_slot,
453 lex_ctxt *lexic)
454{
455 unsigned int tbl_slot;
456 if (session_id <= 0)
457 {
458 if (funcname)
459 nasl_perror (lexic, "Invalid SSH session id %d passed to %s",
460 session_id, funcname);
461 return 0;
462 }
463 for (tbl_slot = 0; tbl_slot < DIM (session_table); tbl_slot++)
464 if (session_table[tbl_slot].session_id == session_id)
465 break;
466 if (!(tbl_slot < DIM (session_table)))
467 {
468 if (funcname)
469 nasl_perror (lexic, "Bad SSH session id %d passed to %s", session_id,
470 funcname);
471 return 0;
472 }
473
474 *r_slot = tbl_slot;
475 return session_id;
476}
477
478/* Helper for nasl_ssh_disconnect et al. */
479static void
481{
482 if (session_table[tbl_slot].channel)
483 ssh_channel_free (session_table[tbl_slot].channel);
484 ssh_disconnect (session_table[tbl_slot].session);
485 ssh_free (session_table[tbl_slot].session);
486 session_table[tbl_slot].session_id = 0;
487 session_table[tbl_slot].session = NULL;
488 session_table[tbl_slot].channel = NULL;
489 session_table[tbl_slot].sock = -1;
490}
491
512tree_cell *
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}
524
539static int
541{
542 int session_id;
543 unsigned int tbl_slot;
544
545 if (sock == -1)
546 return -1;
547
548 session_id = 0;
549 for (tbl_slot = 0; tbl_slot < DIM (session_table); tbl_slot++)
550 {
551 if (session_table[tbl_slot].sock == sock
552 && session_table[tbl_slot].session_id)
553 {
554 session_id = session_table[tbl_slot].session_id;
555 break;
556 }
557 }
558 if (!session_id || tbl_slot >= DIM (session_table))
559 return -1;
560 do_nasl_ssh_disconnect (tbl_slot);
561 return 0;
562}
563
577tree_cell *
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}
601
620tree_cell *
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}
636
637/* Get the list of supported authentication schemes. Returns 0 if no
638 authentication is required; otherwise non-zero. */
639static int
640get_authmethods (int tbl_slot)
641{
642 int rc;
643 int retc_val = -1;
644 ssh_session session;
645 int verbose;
646 int methods;
647
648 session = session_table[tbl_slot].session;
649 verbose = session_table[tbl_slot].verbose;
650
651 rc = ssh_userauth_none (session, NULL);
652 if (rc == SSH_AUTH_SUCCESS)
653 {
654 g_message ("SSH authentication succeeded using the none method - "
655 "should not happen; very old server?");
656 retc_val = 0;
657 methods = 0;
658 goto leave;
659 }
660 else if (rc == SSH_AUTH_DENIED)
661 {
662 methods = ssh_userauth_list (session, NULL);
663 }
664 else
665 {
666 if (verbose)
667 g_message ("SSH server did not return a list of authentication methods"
668 " - trying all");
669 methods = (SSH_AUTH_METHOD_NONE | SSH_AUTH_METHOD_PASSWORD
670 | SSH_AUTH_METHOD_PUBLICKEY | SSH_AUTH_METHOD_HOSTBASED
671 | SSH_AUTH_METHOD_INTERACTIVE);
672 }
673
674 if (verbose)
675 {
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);
688 }
689
690leave:
691 session_table[tbl_slot].authmethods = methods;
692 session_table[tbl_slot].authmethods_valid = 1;
693
694 return retc_val;
695}
696
727tree_cell *
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}
766
824tree_cell *
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}
989
1015tree_cell *
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}
1100
1127tree_cell *
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}
1189
1190static void
1192{
1193 (void) signal;
1194 g_message ("exec_ssh_cmd: Timeout");
1195}
1196
1212static int
1213exec_ssh_cmd (ssh_session session, char *cmd, int verbose, int compat_mode,
1214 int to_stdout, int to_stderr, GString *response,
1215 GString *compat_buf)
1216{
1217 int rc = 1;
1218 ssh_channel channel;
1219 char buffer[4096];
1220
1221 /* Work-around for LibSSH calling poll() with an infinite timeout. */
1222 signal (SIGALRM, exec_ssh_cmd_alarm);
1223 alarm (30);
1224 if ((channel = ssh_channel_new (session)) == NULL)
1225 {
1226 g_message ("Function %s (calling internal function %s) called from %s: "
1227 "ssh_channel_new failed: %s",
1229 : "script_main_function",
1230 __func__, nasl_get_plugin_filename (),
1231 ssh_get_error (session));
1232 return SSH_ERROR;
1233 }
1234
1235 if (ssh_channel_open_session (channel))
1236 {
1237 /* FIXME: Handle SSH_AGAIN. */
1238 if (verbose)
1239 g_message ("ssh_channel_open_session failed: %s",
1240 ssh_get_error (session));
1241 ssh_channel_free (channel);
1242 return SSH_ERROR;
1243 }
1244
1245 if (ssh_channel_request_pty (channel) && verbose)
1246 g_message ("ssh_channel_request_pty failed: %s", ssh_get_error (session));
1247
1248 if (ssh_channel_request_exec (channel, cmd))
1249 {
1250 /* FIXME: Handle SSH_AGAIN. */
1251 if (verbose)
1252 g_message ("ssh_channel_request_exec failed for '%s': %s", cmd,
1253 ssh_get_error (session));
1254 ssh_channel_free (channel);
1255 return SSH_ERROR;
1256 }
1257 alarm (0);
1258 signal (SIGALRM, _exit);
1259 while (rc > 0)
1260 {
1261 if ((rc = ssh_channel_read_timeout (channel, buffer, sizeof (buffer), 1,
1262 15000))
1263 > 0)
1264 {
1265 if (to_stderr)
1266 g_string_append_len (response, buffer, rc);
1267 if (compat_mode)
1268 g_string_append_len (compat_buf, buffer, rc);
1269 }
1270 if (rc == SSH_ERROR)
1271 goto exec_err;
1272 }
1273 rc = 1;
1274 while (rc > 0)
1275 {
1276 if ((rc = ssh_channel_read_timeout (channel, buffer, sizeof (buffer), 0,
1277 15000))
1278 > 0)
1279 {
1280 if (to_stdout)
1281 g_string_append_len (response, buffer, rc);
1282 }
1283 if (rc == SSH_ERROR)
1284 goto exec_err;
1285 }
1286 rc = SSH_OK;
1287
1288exec_err:
1289 ssh_channel_free (channel);
1290 return rc;
1291}
1292
1344tree_cell *
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}
1450
1470tree_cell *
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}
1500
1519tree_cell *
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}
1542
1560tree_cell *
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}
1583
1604tree_cell *
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}
1644
1645static void
1647{
1648 (void) signal;
1649 g_message ("request_ssh_shell: Timeout");
1650}
1651
1660static int
1661request_ssh_shell (ssh_channel channel, int pty)
1662{
1663 assert (channel);
1664
1665 /* Work-around for LibSSH calling poll() with an infinite timeout. */
1666 signal (SIGALRM, request_ssh_shell_alarm);
1667 alarm (30);
1668
1669 if (pty == 1)
1670 {
1671 if (ssh_channel_request_pty (channel))
1672 return -1;
1673
1674 if (ssh_channel_change_pty_size (channel, 80, 24))
1675 return -1;
1676 }
1677 if (ssh_channel_request_shell (channel))
1678 return -1;
1679
1680 alarm (0);
1681 signal (SIGALRM, _exit);
1682
1683 return 0;
1684}
1685
1704tree_cell *
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}
1752
1763static int
1764read_ssh_blocking (ssh_channel channel, GString *response, int timeout)
1765{
1766 int rc;
1767 char buffer[4096];
1768
1769 /* Read stderr */
1770 do
1771 {
1772 if ((rc = ssh_channel_read_timeout (channel, buffer, sizeof (buffer), 1,
1773 timeout))
1774 > 0)
1775 g_string_append_len (response, buffer, rc);
1776
1777 else if (rc == SSH_ERROR)
1778 goto exec_err;
1779 }
1780 while (rc > 0 || rc == SSH_AGAIN);
1781
1782 /* Read stdout */
1783 do
1784 {
1785 if ((rc = ssh_channel_read_timeout (channel, buffer, sizeof (buffer), 0,
1786 timeout))
1787 > 0)
1788 g_string_append_len (response, buffer, rc);
1789
1790 else if (rc == SSH_ERROR)
1791 goto exec_err;
1792 }
1793 while (rc > 0 || rc == SSH_AGAIN);
1794 rc = SSH_OK;
1795
1796exec_err:
1797 return rc;
1798}
1799
1808static int
1809read_ssh_nonblocking (ssh_channel channel, GString *response)
1810{
1811 int rc;
1812 char buffer[4096];
1813
1814 if (!ssh_channel_is_open (channel) || ssh_channel_is_eof (channel))
1815 return -1;
1816
1817 if ((rc = ssh_channel_read_nonblocking (channel, buffer, sizeof (buffer), 1))
1818 > 0)
1819 g_string_append_len (response, buffer, rc);
1820 if (rc == SSH_ERROR)
1821 return -1;
1822 if ((rc = ssh_channel_read_nonblocking (channel, buffer, sizeof (buffer), 0))
1823 > 0)
1824 g_string_append_len (response, buffer, rc);
1825 if (rc == SSH_ERROR)
1826 return -1;
1827 return 0;
1828}
1829
1849tree_cell *
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}
1882
1901tree_cell *
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}
1946
1957tree_cell *
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}
1973
1974/*
1975 * NASL SFTP
1976 */
1977
1992tree_cell *
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}
2044
2045/*
2046 * NASL NETCONF
2047 */
2059tree_cell *
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}
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
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition nasl_debug.c:105
#define DIM(v)
struct struct_lex_ctxt lex_ctxt
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1118
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition nasl_var.c:1094
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition nasl_var.c:1101
uint8_t len
int lowest_socket
static void g_string_comma_str(GString *gstr, const char *str)
Definition nasl_ssh.c:111
static void do_nasl_ssh_disconnect(int tbl_slot)
Definition nasl_ssh.c:480
tree_cell * nasl_ssh_shell_close(lex_ctxt *lexic)
Close an ssh shell.
Definition nasl_ssh.c:1958
#define DIM(v)
Definition nasl_ssh.c:49
tree_cell * nasl_ssh_shell_read(lex_ctxt *lexic)
Read the output of an ssh shell.
Definition nasl_ssh.c:1850
tree_cell * nasl_ssh_set_login(lex_ctxt *lexic)
Set the login name for the authentication.
Definition nasl_ssh.c:728
tree_cell * nasl_ssh_userauth(lex_ctxt *lexic)
Authenticate a user on an ssh connection.
Definition nasl_ssh.c:825
static int nasl_ssh_close_hook(int)
Hook to close a socket associated with an ssh connection.
Definition nasl_ssh.c:540
tree_cell * nasl_ssh_shell_open(lex_ctxt *lexic)
Request an ssh shell.
Definition nasl_ssh.c:1705
static int get_authmethods(int tbl_slot)
Definition nasl_ssh.c:640
tree_cell * nasl_ssh_execute_netconf_subsystem(lex_ctxt *lexic)
Excecute the NETCONF subsystem on the the ssh channel.
Definition nasl_ssh.c:2060
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
tree_cell * nasl_ssh_login_interactive(lex_ctxt *lexic)
Authenticate a user on an ssh connection.
Definition nasl_ssh.c:1016
tree_cell * nasl_ssh_get_issue_banner(lex_ctxt *lexic)
Get the issue banner.
Definition nasl_ssh.c:1471
tree_cell * nasl_ssh_request_exec(lex_ctxt *lexic)
Run a command via ssh.
Definition nasl_ssh.c:1345
tree_cell * nasl_ssh_get_host_key(lex_ctxt *lexic)
Get the host key.
Definition nasl_ssh.c:1561
static struct session_table_item_s session_table[MAX_SSH_SESSIONS]
Definition nasl_ssh.c:104
static int next_session_id(void)
Definition nasl_ssh.c:123
tree_cell * nasl_ssh_login_interactive_pass(lex_ctxt *lexic)
Authenticate a user on an ssh connection.
Definition nasl_ssh.c:1128
static unsigned short get_ssh_port(lex_ctxt *lexic)
Definition nasl_ssh.c:156
tree_cell * nasl_ssh_get_auth_methods(lex_ctxt *lexic)
Get the list of authmethods.
Definition nasl_ssh.c:1605
tree_cell * nasl_sftp_enabled_check(lex_ctxt *lexic)
Check if the SFTP subsystem is enabled on the remote SSH server.
Definition nasl_ssh.c:1993
static void exec_ssh_cmd_alarm(int signal)
Definition nasl_ssh.c:1191
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
#define MAX_SSH_SESSIONS
Definition nasl_ssh.c:103
tree_cell * nasl_ssh_disconnect(lex_ctxt *lexic)
Disconnect an ssh connection.
Definition nasl_ssh.c:513
tree_cell * nasl_ssh_connect(lex_ctxt *lexic)
Connect to the target host via TCP and setup an ssh connection.
Definition nasl_ssh.c:225
tree_cell * nasl_ssh_shell_write(lex_ctxt *lexic)
Write string to ssh shell.
Definition nasl_ssh.c:1902
static void request_ssh_shell_alarm(int signal)
Definition nasl_ssh.c:1646
tree_cell * nasl_ssh_get_server_banner(lex_ctxt *lexic)
Get the server banner.
Definition nasl_ssh.c:1520
static int request_ssh_shell(ssh_channel channel, int pty)
Open a shell on an ssh channel.
Definition nasl_ssh.c:1661
tree_cell * nasl_ssh_session_id_from_sock(lex_ctxt *lexic)
Given a socket, return the corresponding session id.
Definition nasl_ssh.c:578
static int read_ssh_nonblocking(ssh_channel channel, GString *response)
read from an ssh channel without blocking.
Definition nasl_ssh.c:1809
static int verify_session_id(int session_id, const char *funcname, int *r_slot, lex_ctxt *lexic)
Definition nasl_ssh.c:452
tree_cell * nasl_ssh_get_sock(lex_ctxt *lexic)
Given a session id, return the corresponding socket.
Definition nasl_ssh.c:621
Protos and data structures for SSH functions used by NASL scripts.
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ CONST_DATA
Definition nasl_tree.h:82
@ CONST_INT
Definition nasl_tree.h:79
struct TC tree_cell
#define FAKE_CELL
Definition nasl_tree.h:110
int openvas_get_socket_from_connection(int fd)
Definition network.c:357
void add_close_stream_connection_hook(int(*fnc)(int fd))
Register a hook function for close_stream_connection.
Definition network.c:1666
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.
Definition plugutils.c:1226
struct in6_addr * plug_get_host_ip(struct script_infos *args)
Definition plugutils.c:371
kb_t plug_get_kb(struct script_infos *args)
Definition plugutils.c:1152
Header file for module plugutils.
int size
Definition nasl_tree.h:99
long int i_val
Definition nasl_tree.h:104
union TC::@332262321161220155002104006201360276211317150140 x
char * str_val
Definition nasl_tree.h:103
ssh_channel channel
Definition nasl_ssh.c:93
unsigned int authmethods_valid
Definition nasl_ssh.c:97
ssh_session session
Definition nasl_ssh.c:92
unsigned int user_set
Definition nasl_ssh.c:98
unsigned int verbose
Definition nasl_ssh.c:100
struct script_infos * script_infos