[Openvas-commits] r3510 - in trunk/openvas-manager: . src src/tests
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Thu May 28 13:08:40 CEST 2009
Author: mattm
Date: 2009-05-28 13:08:39 +0200 (Thu, 28 May 2009)
New Revision: 3510
Added:
trunk/openvas-manager/src/tests/read_protocol_0.c
Modified:
trunk/openvas-manager/ChangeLog
trunk/openvas-manager/src/openvasmd.c
trunk/openvas-manager/src/tests/CMakeLists.txt
trunk/openvas-manager/src/tests/common.c
trunk/openvas-manager/src/tests/common.h
Log:
Timeout if reading the protocol takes too long.
* src/openvasmd.c (READ_PROTOCOL_TIMEOUT): New define.
(protocol_read_t): Add PROTOCOL_TIMEOUT.
(read_protocol): Timeout if reading takes PROTOCOL_TIMEOUT or longer.
(serve_client): Handle read_protocol timeout.
* src/tests/common.c (setup_test): New function.
* src/tests/common.h (setup_test): New header.
* src/tests/CMakeLists.txt: Add read_protocol_0.c.
* src/tests/read_protocol_0.c: New file.
Modified: trunk/openvas-manager/ChangeLog
===================================================================
--- trunk/openvas-manager/ChangeLog 2009-05-28 10:53:01 UTC (rev 3509)
+++ trunk/openvas-manager/ChangeLog 2009-05-28 11:08:39 UTC (rev 3510)
@@ -1,3 +1,19 @@
+2009-05-28 Matthew Mundell <mmundell at intevation.de>
+
+ Timeout if reading the protocol takes too long.
+
+ * src/openvasmd.c (READ_PROTOCOL_TIMEOUT): New define.
+ (protocol_read_t): Add PROTOCOL_TIMEOUT.
+ (read_protocol): Timeout if reading takes PROTOCOL_TIMEOUT or longer.
+ (serve_client): Handle read_protocol timeout.
+
+ * src/tests/common.c (setup_test): New function.
+ * src/tests/common.h (setup_test): New header.
+
+ * src/tests/CMakeLists.txt: Add read_protocol_0.c.
+
+ * src/tests/read_protocol_0.c: New file.
+
2009-05-27 Matthew Mundell <mmundell at intevation.de>
* src/omp.c (send_plugin): Correct g_convert charset names.
Modified: trunk/openvas-manager/src/openvasmd.c
===================================================================
--- trunk/openvas-manager/src/openvasmd.c 2009-05-28 10:53:01 UTC (rev 3509)
+++ trunk/openvas-manager/src/openvasmd.c 2009-05-28 11:08:39 UTC (rev 3510)
@@ -181,6 +181,13 @@
*/
#define MAX_CONNECTIONS 512
+/**
+ * @brief Maximum number of seconds spent trying to read the protocol.
+ */
+#ifndef READ_PROTOCOL_TIMEOUT
+#define READ_PROTOCOL_TIMEOUT 20
+#endif
+
#if FROM_BUFFER_SIZE > SSIZE_MAX
#error FROM_BUFFER_SIZE too big for `read'
#endif
@@ -215,7 +222,8 @@
PROTOCOL_OTP,
PROTOCOL_OMP,
PROTOCOL_CLOSE,
- PROTOCOL_FAIL
+ PROTOCOL_FAIL,
+ PROTOCOL_TIMEOUT
} protocol_read_t;
/**
@@ -266,11 +274,16 @@
* @param[in] client_session The TLS session with the client.
* @param[in] client_socket The socket connected to the client.
*
- * @return PROTOCOL_FAIL, PROTOCOL_CLOSE, PROTOCOL_OTP or PROTOCOL_OMP.
+ * @return PROTOCOL_FAIL, PROTOCOL_CLOSE, PROTOCOL_OTP, PROTOCOL_OMP or
+ * PROTOCOL_TIMEOUT.
*/
protocol_read_t
read_protocol (gnutls_session_t* client_session, int client_socket)
{
+ protocol_read_t ret;
+ char* from_client_current;
+ time_t start_time;
+
/* Turn on blocking. */
// FIX get flags first
if (fcntl (client_socket, F_SETFL, 0L) == -1)
@@ -280,76 +293,125 @@
}
/* Read from the client, checking the protocol when a newline or return
- * is read. */
- protocol_read_t ret = PROTOCOL_FAIL;
- char* from_client_current = from_client + from_client_end;
+ * is read. Fail if reading the protocol takes too long. */
+ if (time (&start_time) == -1)
+ {
+ perror ("Failed to get current time");
+ return PROTOCOL_FAIL;
+ }
+ ret = PROTOCOL_FAIL;
+ from_client_current = from_client + from_client_end;
while (from_client_end < FROM_BUFFER_SIZE)
{
- ssize_t count;
+ int select_ret;
+ int nfds;
+ fd_set readfds, exceptfds;
+ struct timeval timeout;
- while (1)
+ FD_ZERO (&readfds);
+ FD_SET (manager_socket, &readfds);
+ FD_ZERO (&exceptfds);
+ FD_SET (manager_socket, &exceptfds);
+ nfds = manager_socket + 1;
+
+ timeout.tv_usec = 0;
+ timeout.tv_sec = READ_PROTOCOL_TIMEOUT - (time (NULL) - start_time);
+ if (timeout.tv_sec <= 0)
{
- count = gnutls_record_recv (*client_session,
- from_client + from_client_end,
- FROM_BUFFER_SIZE
- - from_client_end);
- if (count == GNUTLS_E_INTERRUPTED)
- /* Interrupted, try read again. */
- continue;
- if (count == GNUTLS_E_REHANDSHAKE)
- /* Try again. TODO Rehandshake. */
- continue;
+ ret = PROTOCOL_TIMEOUT;
break;
}
- if (count < 0)
+ select_ret = select (nfds, &readfds, NULL, &exceptfds, &timeout);
+
+ if (select_ret == -1)
{
- if (gnutls_error_is_fatal (count) == 0
- && (count == GNUTLS_E_WARNING_ALERT_RECEIVED
- || count == GNUTLS_E_FATAL_ALERT_RECEIVED))
- {
- int alert = gnutls_alert_get (*client_session);
- fprintf (stderr, "TLS Alert %d: %s.\n",
- alert,
- gnutls_alert_get_name (alert));
- }
- fprintf (stderr, "Failed to read from client (read_protocol).\n");
- gnutls_perror (count);
+ perror ("Select (read_protocol) failed");
break;
}
- if (count == 0)
+ if (select_ret > 0)
{
- /* End of file. */
- ret = PROTOCOL_CLOSE;
- break;
- }
- from_client_end += count;
+ if (FD_ISSET (manager_socket, &exceptfds))
+ {
+ fprintf (stderr, "Exception in select.\n");
+ break;
+ }
+ if (FD_ISSET (manager_socket, &readfds))
+ {
+ ssize_t count;
+ while (1)
+ {
+
+ count = gnutls_record_recv (*client_session,
+ from_client + from_client_end,
+ FROM_BUFFER_SIZE
+ - from_client_end);
+ if (count == GNUTLS_E_INTERRUPTED)
+ /* Interrupted, try read again. */
+ continue;
+ if (count == GNUTLS_E_REHANDSHAKE)
+ /* Try again. TODO Rehandshake. */
+ continue;
+ break;
+ }
+
+ if (count < 0)
+ {
+ if (gnutls_error_is_fatal (count) == 0
+ && (count == GNUTLS_E_WARNING_ALERT_RECEIVED
+ || count == GNUTLS_E_FATAL_ALERT_RECEIVED))
+ {
+ int alert = gnutls_alert_get (*client_session);
+ fprintf (stderr, "TLS Alert %d: %s.\n",
+ alert,
+ gnutls_alert_get_name (alert));
+ }
+ fprintf (stderr, "Failed to read from client (read_protocol).\n");
+ gnutls_perror (count);
+ break;
+ }
+ if (count == 0)
+ {
+ /* End of file. */
+ ret = PROTOCOL_CLOSE;
+ break;
+ }
+ from_client_end += count;
+
#if 0
- /* Check for newline or return. */
- from_client[from_client_end] = '\0';
- if (strchr (from_client_current, 10) || strchr (from_client_current, 13))
- {
- if (strstr (from_client, "< OTP/1.0 >"))
- ret = PROTOCOL_OTP;
- else
- ret = PROTOCOL_OMP;
- break;
+ /* Check for newline or return. */
+ from_client[from_client_end] = '\0';
+ if (strchr (from_client_current, 10) || strchr (from_client_current, 13))
+ {
+ if (strstr (from_client, "< OTP/1.0 >"))
+ ret = PROTOCOL_OTP;
+ else
+ ret = PROTOCOL_OMP;
+ break;
+ }
+#else
+ /* Check for ">". FIX need a better check */
+ from_client[from_client_end] = '\0';
+ if (strchr (from_client_current, '>'))
+ {
+ if (strstr (from_client, "< OTP/1.0 >"))
+ ret = PROTOCOL_OTP;
+ else
+ ret = PROTOCOL_OMP;
+ break;
+ }
+#endif
+
+ from_client_current += count;
+ }
}
-#else
- /* Check for ">". FIX need a better check */
- from_client[from_client_end] = '\0';
- if (strchr (from_client_current, '>'))
+
+ if ((time (NULL) - start_time) >= READ_PROTOCOL_TIMEOUT)
{
- if (strstr (from_client, "< OTP/1.0 >"))
- ret = PROTOCOL_OTP;
- else
- ret = PROTOCOL_OMP;
+ ret = PROTOCOL_TIMEOUT;
break;
}
-#endif
-
- from_client_current += count;
}
// FIX use orig value
@@ -439,6 +501,8 @@
case PROTOCOL_CLOSE:
fprintf (stderr, "EOF while trying to read protocol.\n");
goto fail;
+ case PROTOCOL_TIMEOUT:
+ break;
default:
fprintf (stderr, "Failed to determine protocol.\n");
}
Modified: trunk/openvas-manager/src/tests/CMakeLists.txt
===================================================================
--- trunk/openvas-manager/src/tests/CMakeLists.txt 2009-05-28 10:53:01 UTC (rev 3509)
+++ trunk/openvas-manager/src/tests/CMakeLists.txt 2009-05-28 11:08:39 UTC (rev 3510)
@@ -114,6 +114,15 @@
set_target_properties (strip_space_3 PROPERTIES LINK_FLAGS "${GLIB_LDFLAGS}")
ADD_TEST (strip_space_3 strip_space_3)
+## Tests of the manager
+
+add_executable (read_protocol_0 read_protocol_0.c)
+target_link_libraries (read_protocol_0 string)
+set_target_properties (read_protocol_0 PROPERTIES COMPILE_FLAGS "-I .. ${GLIB_CFLAGS}")
+set_target_properties (read_protocol_0 PROPERTIES LINK_FLAGS "${OVAS_LDFLAG} ${GLIB_LDFLAGS}")
+target_link_libraries (read_protocol_0 common)
+ADD_TEST (read_protocol_0 read_protocol_0)
+
## Tests of OMP
add_executable (omp_abort_task_0 omp_abort_task_0.c)
Modified: trunk/openvas-manager/src/tests/common.c
===================================================================
--- trunk/openvas-manager/src/tests/common.c 2009-05-28 10:53:01 UTC (rev 3509)
+++ trunk/openvas-manager/src/tests/common.c 2009-05-28 11:08:39 UTC (rev 3510)
@@ -87,6 +87,7 @@
#include <glib.h> /* For XML parsing. */
#include <netdb.h>
#include <netinet/in.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -283,7 +284,7 @@
* @param[in] session Pointer to GNUTLS session.
* @param[in] string String to send.
*
- * @return 0 on success, -1 on error.
+ * @return 0 on success, 1 if manager closed connection, -1 on error.
*/
int
send_to_manager (gnutls_session_t* session, const char* string)
@@ -294,6 +295,7 @@
ssize_t count;
tracef ("send %i from %.*s[...]\n", left, left < 30 ? left : 30, string);
count = gnutls_record_send (*session, string, left);
+ tracef (" count: %i\n", count);
if (count < 0)
{
if (count == GNUTLS_E_INTERRUPTED)
@@ -309,6 +311,12 @@
gnutls_perror (count);
return -1;
}
+ if (count == 0)
+ {
+ /* Manager closed connection. */
+ tracef ("= manager closed\n");
+ return 1;
+ }
tracef ("=> %.*s\n", count, string);
string += count;
left -= count;
@@ -324,7 +332,7 @@
* @param[in] session Pointer to GNUTLS session.
* @param[in] format printf-style format string for message.
*
- * @return 0 on success, -1 on error.
+ * @return 0 on success, 1 if manager closed connection, -1 on error.
*/
int
sendf_to_manager (gnutls_session_t* session, const char* format, ...)
@@ -857,7 +865,7 @@
* @param[in] username Username.
* @param[in] password Password.
*
- * @return 0 on success, -1 on error.
+ * @return 0 on success, 1 if manager closed connection, -1 on error.
*/
int
authenticate (gnutls_session_t* session,
@@ -872,7 +880,7 @@
password);
int ret = send_to_manager (session, msg);
g_free (msg);
- if (ret) return -1;
+ if (ret) return ret;
#if 1
return 0;
@@ -902,7 +910,7 @@
*
* @param[in] session Pointer to GNUTLS session.
*
- * @return 0 on success, -1 on error.
+ * @return 0 on success, 1 if manager closed connection, -1 on error.
*/
int
env_authenticate (gnutls_session_t* session)
@@ -1312,3 +1320,14 @@
if (first == '2') return 0;
return -1;
}
+
+
+/* Setup. */
+
+void
+setup_test ()
+{
+ char* env_verbose = getenv ("OPENVAS_TEST_VERBOSE");
+ if (env_verbose) verbose = strcmp (env_verbose, "0");
+ signal (SIGPIPE, SIG_IGN);
+}
Modified: trunk/openvas-manager/src/tests/common.h
===================================================================
--- trunk/openvas-manager/src/tests/common.h 2009-05-28 10:53:01 UTC (rev 3509)
+++ trunk/openvas-manager/src/tests/common.h 2009-05-28 11:08:39 UTC (rev 3510)
@@ -119,3 +119,8 @@
int
wait_for_task_start (gnutls_session_t*, char*);
+
+/* Setup. */
+
+void
+setup_test ();
Added: trunk/openvas-manager/src/tests/read_protocol_0.c
===================================================================
--- trunk/openvas-manager/src/tests/read_protocol_0.c 2009-05-28 10:53:01 UTC (rev 3509)
+++ trunk/openvas-manager/src/tests/read_protocol_0.c 2009-05-28 11:08:39 UTC (rev 3510)
@@ -0,0 +1,80 @@
+/* Test 0 of read_protocol.
+ * $Id$
+ * Description: Test read_protcol timing out.
+ *
+ * Authors:
+ * Matthew Mundell <matt at mundell.ukfsn.org>
+ *
+ * Copyright:
+ * Copyright (C) 2009 Greenbone Networks GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or, at your option, any later version as published by the Free
+ * Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define TRACE 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "../tracef.h"
+
+int
+main ()
+{
+ int socket;
+ gnutls_session_t session;
+ char* id;
+
+ setup_test ();
+
+ socket = connect_to_manager (&session);
+ if (socket == -1) return EXIT_FAILURE;
+
+ /* FIX This must be more than the timeout, which is currently 20. */
+ sleep (25);
+
+ switch (env_authenticate (&session))
+ {
+ case 1:
+ /* Manager closed connection. */
+ close_manager_connection (socket, session);
+ return EXIT_SUCCESS;
+ default:
+ /* Authentication failed. */
+ break;
+ }
+
+ if (create_task_from_rc_file (&session,
+ "new_task_small_rc",
+ "Test for omp_delete_task_0",
+ "Simple test scan.",
+ &id))
+ {
+ close_manager_connection (socket, session);
+ return EXIT_SUCCESS;
+ }
+ entity_t entity = NULL;
+ if (read_entity (&session, &entity))
+ {
+ close_manager_connection (socket, session);
+ return EXIT_SUCCESS;
+ }
+
+ close_manager_connection (socket, session);
+ return EXIT_FAILURE;
+}
More information about the Openvas-commits
mailing list