/*---------------------------------------------------------------------*/ tree_cell * nasl_close_socket(lex_ctxt * lexic) { int soc; int type; int opt_len = sizeof(type); int e; soc = get_int_var_by_num(lexic, 0, -1); if(soc <= 4) { nasl_perror(lexic, "close(): invalid argument\n"); return NULL; } if ( fd_is_stream(soc) ) { return close_stream_connection(soc) < 0 ? NULL:FAKE_CELL; } e = getsockopt(soc, SOL_SOCKET, SO_TYPE, &type, &opt_len); if(e == 0 ) { if (type == SOCK_DGRAM) { rm_udp_data(lexic->script_infos, soc); return FAKE_CELL; } closesocket(soc); return FAKE_CELL; } else nasl_perror(lexic, "close(): invalid argument\n"); return NULL; }
/*---------------------------------------------------------------------*/ tree_cell * nasl_close_socket (lex_ctxt * lexic) { int soc; int type; unsigned int opt_len = sizeof (type); int e; soc = get_int_var_by_num (lexic, 0, -1); /* XXX: These are thoughts expressed on the openvas-devel mailing list 2008-08-06: * * nasl_close_socket seems to be the only place in nasl/nasl_socket.c where the * value of the socket filedescriptor is checked in this way. That in itself is * strange. Why only there? Also, why can't the socket fd be less than 4? I * could sort of understand 3 (0, 1, 2 are already taken by the standard * streams) but 4? Does the openvas server and/or the NASL interpreter guarantee * that at least one other file is open? * * My guess is that the check is there to prevent NASL scripts from closing file * descriptors needed by openvas/NASL which includes the ones it uses for * accessing the knowledgebase. If that's the case, then the test has too much * knowledge of the circumstances under which the NASL interpreter runs. It * should be moved to a separate function whose behavior can be influenced by * the program embedding the NASL interpreter. Other functions should probably * also check the descriptors. * * I also wonder whether the original code (disallowing any file descriptor <= 4) * actually was correct and the real defect is that open_sock_udp actually * returned 4. Under which circumstances does it actually do that? In my brief * tests with the stand-alone nasl interpreter the smallest number it returned * was 5. */ if (soc < 4) { nasl_perror (lexic, "close(): invalid argument\n"); return NULL; } if (fd_is_stream (soc)) return close_stream_connection (soc) < 0 ? NULL : FAKE_CELL; e = getsockopt (soc, SOL_SOCKET, SO_TYPE, &type, &opt_len); if (e == 0) { if (type == SOCK_DGRAM) { rm_udp_data (lexic->script_infos, soc); return FAKE_CELL; } close (soc); return FAKE_CELL; } else nasl_perror (lexic, "close(): invalid argument\n"); return NULL; }
tree_cell * nasl_end_denial(lex_ctxt * lexic) { int port = (int)arg_get_value(lexic->script_infos, "denial_port"); int soc; int to = lexic->recv_timeout; struct arglist * script_infos = lexic->script_infos; tree_cell * retc = NULL; /* * We must wait the time the DoS does its effect */ Sleep(10); if(!port) { int ping = (int)arg_get_value(script_infos, "tcp_ping_result"); if(ping) return nasl_tcp_ping(lexic); else { retc = alloc_tree_cell(0, NULL); retc->type = CONST_INT; retc->x.i_val = 1; return retc; } } else { retc = alloc_tree_cell(0, NULL); retc->type = CONST_INT; soc = open_stream_connection(script_infos, port, NESSUS_ENCAPS_IP, to); if(soc > 0) { /* Send some data */ #define BOGUS "are you dead ?" if((nsend(soc, BOGUS, sizeof(BOGUS)-1, 0))>=0) { retc->x.i_val = 1; close_stream_connection(soc); return retc; } } } retc->x.i_val = 0; return retc; }
/* * @brief Handles a client request when the scanner is still loading. * * @param[in] soc Client socket to send and receive from. */ static void loading_client_handle (int soc) { int soc2, opt = 1; if (soc <= 0) return; soc2 = ovas_scanner_context_attach (ovas_scanner_ctx, soc); if (soc2 < 0) { close (soc); return; } setsockopt (soc, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof (opt)); comm_loading (soc2); close_stream_connection (soc2); }
tree_cell * nasl_start_denial(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; int to = lexic->recv_timeout; int port = plug_get_host_open_port(script_infos); int soc; int alive = 0; tree_cell * p; if(port) { soc = open_stream_connection(script_infos, port, NESSUS_ENCAPS_IP, to); if(soc>=0) { if(arg_get_value(script_infos, "denial_port") != 0) arg_set_value(script_infos, "denial_port", sizeof(int), (void*)port); else arg_add_value(script_infos, "denial_port", ARG_INT, sizeof(int), (void*)port); close_stream_connection(soc); return FAKE_CELL; } } p = nasl_tcp_ping(lexic); if (p != NULL) alive = p->x.i_val; if(arg_get_value(script_infos, "tcp_ping_result") != 0) arg_set_value(script_infos, "tcp_ping_result", sizeof(int), (void*)alive); else arg_add_value(script_infos, "tcp_ping_result", ARG_INT, sizeof(int), (void*)alive); deref_cell(p); return FAKE_CELL; }
static void scanner_thread (struct arglist *globals) { struct arglist *prefs = arg_get_value (globals, "preferences"); char asciiaddr[INET6_ADDRSTRLEN], x509_dname[512] = { '\0' }; int opt = 1, soc2 = -1, nice_retval, family, soc; void *addr = arg_get_value (globals, "client_address"); struct sockaddr_in *saddr = NULL; struct sockaddr_in6 *s6addr = NULL; family = GPOINTER_TO_SIZE (arg_get_value (globals, "family")); soc = GPOINTER_TO_SIZE (arg_get_value (globals, "global_socket")); if (family == AF_INET) { saddr = (struct sockaddr_in *) addr; inet_ntop (AF_INET, &saddr->sin_addr, asciiaddr, sizeof(asciiaddr)); } else { s6addr = (struct sockaddr_in6 *) addr; inet_ntop (AF_INET6, &s6addr->sin6_addr, asciiaddr, sizeof (asciiaddr)); } proctitle_set ("openvassd: Serving %s", asciiaddr); /* Everyone runs with a nicelevel of 10 */ if (preferences_benice (prefs)) { errno = 0; nice_retval = nice (10); if (nice_retval == -1 && errno != 0) { log_write ("Unable to renice process: %d", errno); } } /* Close the scanner thread - it is useless for us now */ close (global_iana_socket); soc2 = ovas_scanner_context_attach (ovas_scanner_ctx, soc); if (soc2 < 0) goto shutdown_and_exit; /* FIXME: The pre-gnutls code optionally printed information about * the peer's certificate at this point. */ setsockopt (soc, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof (opt)); /* arg_set_value *replaces* an existing value, but it shouldn't fail here */ (void) arg_set_value (globals, "global_socket", -1, GSIZE_TO_POINTER (soc2)); if (comm_init (soc2) < 0) { close_stream_connection (soc); exit (0); } /* Get X.509 cert subject name */ if (get_x509_dname (soc2, x509_dname, sizeof (x509_dname)) != 0) goto shutdown_and_exit; if (!check_client (x509_dname)) { auth_printf (globals, "Bad login attempt !\n"); log_write ("bad login attempt from %s\n", asciiaddr); goto shutdown_and_exit; } handle_client (globals); shutdown_and_exit: if (soc2 >= 0) close_stream_connection (soc2); else { shutdown (soc, 2); close (soc); } /* Kill left overs */ end_daemon_mode (); exit (0); }