Browse Source

Merge pull request #207 from lvasiliev/fix-dos-attack

When using a non-blocking socket, nothing is to be done, but select()…
Sebastian Wolf 6 năm trước cách đây
mục cha
commit
efe56c128a
1 tập tin đã thay đổi với 42 bổ sung6 xóa
  1. 42 6
      src/nrpe.c

+ 42 - 6
src/nrpe.c

@@ -1995,13 +1995,31 @@ int handle_conn_ssl(int sock, void *ssl_ptr)
 	char      buffer[MAX_INPUT_BUFFER];
 	SSL      *ssl = (SSL*)ssl_ptr;
 	X509     *peer;
-	int       rc, x;
+	int       rc, x, sockfd, retval;
+	fd_set    rfds;
+	struct timeval timeout;
 
 	SSL_set_fd(ssl, sock);
+	sockfd = SSL_get_fd(ssl);
+
+	FD_ZERO(&rfds);
+	FD_SET(sockfd, &rfds);
+
+	timeout.tv_sec = connection_timeout;
+	timeout.tv_usec = 0;
+
 
 	/* keep attempting the request if needed */
-	while (((rc = SSL_accept(ssl)) != 1)
-			&& (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ));
+	do {
+		retval = select(sockfd + 1, &rfds, NULL, NULL, &timeout);
+
+		if (retval > 0) {
+			rc = SSL_accept(ssl);
+		} else {
+			logit(LOG_ERR, "Error: (!log_opts) Could not complete SSL handshake with %s: timeout %d seconds", remote_host, connection_timeout);
+			return ERROR;
+		}
+	} while (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ);
 
 	if (rc != 1) {
 		/* oops, got an unrecoverable error -- get out */
@@ -2148,10 +2166,28 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
 #ifdef HAVE_SSL
 	else {
 		SSL      *ssl = (SSL *) ssl_ptr;
+		int       sockfd, retval;
+		fd_set    rfds;
+		struct timeval timeout;
 
-		while (((rc = SSL_read(ssl, v2_pkt, bytes_to_recv)) <= 0)
-			   && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
-		}
+		sockfd = SSL_get_fd(ssl);
+
+		FD_ZERO(&rfds);
+		FD_SET(sockfd, &rfds);
+
+		timeout.tv_sec = connection_timeout;
+		timeout.tv_usec = 0;
+
+		do {
+			retval = select(sockfd + 1, &rfds, NULL, NULL, &timeout);
+
+			if (retval > 0) {
+				rc = SSL_read(ssl, v2_pkt, bytes_to_recv);
+			} else {
+				logit(LOG_ERR, "Error (!log_opts): Could not complete SSL_read with %s: timeout %d seconds", remote_host, connection_timeout);
+				return -1;
+			}
+		} while (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ);
 
 		if (rc <= 0 || rc != bytes_to_recv)
 			return -1;