فهرست منبع

check_http: Allow for requesting TLSv1.1/TLSv1.2

check_http's -S/--ssl option now allows for requesting the TLSv1.1 and
TLSv1.2 protocols.  Apart from that, a '+' suffix can be appended in
oder to also accept newer protocols than the specified version.

Closes #1338, and closes #1354, and closes #1359.
Holger Weiss 10 سال پیش
والد
کامیت
8e03ae7340
4فایلهای تغییر یافته به همراه95 افزوده شده و 28 حذف شده
  1. 4 0
      NEWS
  2. 17 5
      plugins/check_http.c
  3. 10 0
      plugins/netutils.h
  4. 64 23
      plugins/sslutils.c

+ 4 - 0
NEWS

@@ -9,6 +9,10 @@ This file documents the major additions and syntax changes between releases.
 	Make sure check_disk won't hang on hanging (network) file systems
 	New check_mailq -s option which tells the plugin to use sudo(8)
 	New -W/-C option for check_ldap to check number of entries (Gerhard Lausser)
+	The check_http -S/--ssl option now accepts the arguments "1.1" and "1.2"
+	  to force TLSv1.1 and TLSv1.2 connections, respectively
+	The check_http -S/--ssl option now allows for specifying the desired
+	  protocol with a "+" suffix to also accept newer versions
 
 2.1.0 30th July 2015
 	SECURITY FIXES

+ 17 - 5
plugins/check_http.c

@@ -340,9 +340,20 @@ process_arguments (int argc, char **argv)
          parameters, like -S and -C combinations */
       use_ssl = TRUE;
       if (c=='S' && optarg != NULL) {
-        ssl_version = atoi(optarg);
-        if (ssl_version < 1 || ssl_version > 3)
-            usage4 (_("Invalid option - Valid values for SSL Version are 1 (TLSv1), 2 (SSLv2) or 3 (SSLv3)"));
+        int got_plus = strchr(optarg, '+') != NULL;
+
+        if (!strncmp (optarg, "1.2", 3))
+          ssl_version = got_plus ? MP_TLSv1_2_OR_NEWER : MP_TLSv1_2;
+        else if (!strncmp (optarg, "1.1", 3))
+          ssl_version = got_plus ? MP_TLSv1_1_OR_NEWER : MP_TLSv1_1;
+        else if (optarg[0] == '1')
+          ssl_version = got_plus ? MP_TLSv1_OR_NEWER : MP_TLSv1;
+        else if (optarg[0] == '3')
+          ssl_version = got_plus ? MP_SSLv3_OR_NEWER : MP_SSLv3;
+        else if (optarg[0] == '2')
+          ssl_version = got_plus ? MP_SSLv2_OR_NEWER : MP_SSLv2;
+        else
+          usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)"));
       }
       if (specify_port == FALSE)
         server_port = HTTPS_PORT;
@@ -1632,9 +1643,10 @@ print_help (void)
   printf (UT_IPv46);
 
 #ifdef HAVE_SSL
-  printf (" %s\n", "-S, --ssl=VERSION");
+  printf (" %s\n", "-S, --ssl=VERSION[+]");
   printf ("    %s\n", _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents"));
-  printf ("    %s\n", _("auto-negotiation (1 = TLSv1, 2 = SSLv2, 3 = SSLv3)."));
+  printf ("    %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,"));
+  printf ("    %s\n", _("1.2 = TLSv1.2). With a '+' suffix, newer versions are also accepted."));
   printf (" %s\n", "--sni");
   printf ("    %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
   printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");

+ 10 - 0
plugins/netutils.h

@@ -89,6 +89,16 @@ RETSIGTYPE socket_timeout_alarm_handler (int) __attribute__((noreturn));
 
 /* SSL-Related functionality */
 #ifdef HAVE_SSL
+#  define MP_SSLv2 1
+#  define MP_SSLv3 2
+#  define MP_TLSv1 3
+#  define MP_TLSv1_1 4
+#  define MP_TLSv1_2 5
+#  define MP_SSLv2_OR_NEWER 6
+#  define MP_SSLv3_OR_NEWER 7
+#  define MP_TLSv1_OR_NEWER 8
+#  define MP_TLSv1_1_OR_NEWER 9
+#  define MP_TLSv1_2_OR_NEWER 10
 /* maybe this could be merged with the above np_net_connect, via some flags */
 int np_net_ssl_init(int sd);
 int np_net_ssl_init_with_hostname(int sd, char *host_name);

+ 64 - 23
plugins/sslutils.c

@@ -48,39 +48,80 @@ int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int versi
 }
 
 int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey) {
-	const SSL_METHOD *method = NULL;
-	long ssl_options = NULL;
+	SSL_METHOD *method = NULL;
+	long options = 0;
 
 	switch (version) {
-	case 0: /* Deafult to auto negotiation */
-		method = SSLv23_client_method();
-		ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
-		break;
-	case 1: /* TLSv1 protocol */
-		method = TLSv1_client_method();
-		ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
-		break;
-	case 2: /* SSLv2 protocol */
+	case MP_SSLv2: /* SSLv2 protocol */
 #if defined(USE_GNUTLS) || defined(OPENSSL_NO_SSL2)
-		printf(("%s\n", _("CRITICAL - SSL protocol version 2 is not supported by your SSL library.")));
-		return STATE_CRITICAL;
+		printf("%s\n", _("UNKNOWN - SSL protocol version 2 is not supported by your SSL library."));
+		return STATE_UNKNOWN;
 #else
 		method = SSLv2_client_method();
-		ssl_options = SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1;
-#endif
 		break;
-	case 3: /* SSLv3 protocol */
+#endif
+	case MP_SSLv3: /* SSLv3 protocol */
 #if defined(OPENSSL_NO_SSL3)
-		printf(("%s\n", _("CRITICAL - SSL protocol version 3 is not supported by your SSL library.")));
-		return STATE_CRITICAL;
+		printf("%s\n", _("UNKNOWN - SSL protocol version 3 is not supported by your SSL library."));
+		return STATE_UNKNOWN;
 #else
 		method = SSLv3_client_method();
 		ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_TLSv1;
 		break;
 #endif
-	default: /* Unsupported */
-		printf("%s\n", _("CRITICAL - Unsupported SSL protocol version."));
-		return STATE_CRITICAL;
+	case MP_TLSv1: /* TLSv1 protocol */
+#if defined(OPENSSL_NO_TLS1)
+		printf("%s\n", _("UNKNOWN - TLS protocol version 1 is not supported by your SSL library."));
+		return STATE_UNKNOWN;
+#else
+		method = TLSv1_client_method();
+		break;
+#endif
+	case MP_TLSv1_1: /* TLSv1.1 protocol */
+#if !defined(SSL_OP_NO_TLSv1_1)
+		printf("%s\n", _("UNKNOWN - TLS protocol version 1.1 is not supported by your SSL library."));
+		return STATE_UNKNOWN;
+#else
+		method = TLSv1_1_client_method();
+		break;
+#endif
+	case MP_TLSv1_2: /* TLSv1.2 protocol */
+#if !defined(SSL_OP_NO_TLSv1_2)
+		printf("%s\n", _("UNKNOWN - TLS protocol version 1.2 is not supported by your SSL library."));
+		return STATE_UNKNOWN;
+#else
+		method = TLSv1_2_client_method();
+		break;
+#endif
+	case MP_TLSv1_2_OR_NEWER:
+#if !defined(SSL_OP_NO_TLSv1_1)
+		printf("%s\n", _("UNKNOWN - Disabling TLSv1.1 is not supported by your SSL library."));
+		return STATE_UNKNOWN;
+#else
+		options |= SSL_OP_NO_TLSv1_1;
+#endif
+		/* FALLTHROUGH */
+	case MP_TLSv1_1_OR_NEWER:
+#if !defined(SSL_OP_NO_TLSv1)
+		printf("%s\n", _("UNKNOWN - Disabling TLSv1 is not supported by your SSL library."));
+		return STATE_UNKNOWN;
+#else
+		options |= SSL_OP_NO_TLSv1;
+#endif
+		/* FALLTHROUGH */
+	case MP_TLSv1_OR_NEWER:
+#if defined(SSL_OP_NO_SSLv3)
+		options |= SSL_OP_NO_SSLv3;
+#endif
+		/* FALLTHROUGH */
+	case MP_SSLv3_OR_NEWER:
+#if defined(SSL_OP_NO_SSLv2)
+		options |= SSL_OP_NO_SSLv2;
+#endif
+	case MP_SSLv2_OR_NEWER:
+		/* FALLTHROUGH */
+	default: /* Default to auto negotiation */
+		method = SSLv23_client_method();
 	}
 	if (!initialized) {
 		/* Initialize SSL context */
@@ -104,9 +145,9 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
 #endif
 	}
 #ifdef SSL_OP_NO_TICKET
-	ssl_options |= SSL_OP_NO_TICKET;
+	options |= SSL_OP_NO_TICKET;
 #endif
-	if (ssl_options) SSL_CTX_set_options(c, ssl_options);
+	SSL_CTX_set_options(c, options);
 	SSL_CTX_set_mode(c, SSL_MODE_AUTO_RETRY);
 	if ((s = SSL_new(c)) != NULL) {
 #ifdef SSL_set_tlsext_host_name