Fix ssltest logic when some protocols are compiled out.

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Geoff Thorpe <geoff@openssl.org>
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index 9b4a320..1f6d3f3 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -799,7 +799,9 @@
 	               "                 Use \"openssl ecparam -list_curves\" for all names\n"  \
 	               "                 (default is sect163r2).\n");
 #endif
-	fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
+	fprintf(stderr," -test_cipherlist - Verifies the order of the ssl cipher lists.\n"
+		       "                    When this option is requested, the cipherlist\n"
+		       "                    tests are run instead of handshake tests.\n");
 #ifndef OPENSSL_NO_NEXTPROTONEG
 	fprintf(stderr," -npn_client - have client side offer NPN\n");
 	fprintf(stderr," -npn_server - have server side offer NPN\n");
@@ -992,6 +994,7 @@
 #ifdef OPENSSL_FIPS
 	int fips_mode=0;
 #endif
+        int no_protocol = 0;
 
 	verbose = 0;
 	debug = 0;
@@ -1101,11 +1104,26 @@
 			}
 #endif
 		else if	(strcmp(*argv,"-ssl2") == 0)
-			ssl2=1;
+			{
+#ifdef OPENSSL_NO_SSL2
+			no_protocol = 1;
+#endif
+			ssl2 = 1;
+			}
 		else if	(strcmp(*argv,"-tls1") == 0)
-			tls1=1;
+			{
+#ifdef OPENSSL_NO_TLS1
+			no_protocol = 1;
+#endif
+			tls1 = 1;
+			}
 		else if	(strcmp(*argv,"-ssl3") == 0)
-			ssl3=1;
+			{
+#ifdef OPENSSL_NO_SSL3
+			no_protocol = 1;
+#endif
+			ssl3 = 1;
+			}
 		else if	(strncmp(*argv,"-num",4) == 0)
 			{
 			if (--argc < 1) goto bad;
@@ -1272,15 +1290,41 @@
 		goto end;
 		}
 
+	/*
+	 * test_cipherlist prevails over protocol switch: we test the cipherlist
+	 * for all enabled protocols.
+	 */
 	if (test_cipherlist == 1)
 		{
 		/* ensure that the cipher list are correctly sorted and exit */
+		fprintf(stdout, "Testing cipherlist order only. Ignoring all "
+			"other options.\n");
 		if (do_test_cipherlist() == 0)
 			EXIT(1);
 		ret = 0;
 		goto end;
 		}
 
+	if (ssl2 + ssl3 + tls1 > 1)
+		{
+		fprintf(stderr, "At most one of -ssl2, -ssl3, or -tls1 should "
+			"be requested.\n");
+		EXIT(1);
+		}
+
+	/*
+	 * Testing was requested for a compiled-out protocol (e.g. SSLv2).
+         * Ideally, we would error out, but the generic test wrapper can't know
+	 * when to expect failure. So we do nothing and return success.
+	 */
+	if (no_protocol)
+		{
+		fprintf(stderr, "Testing was requested for a disabled protocol. "
+			"Skipping tests.\n");
+		ret = 0;
+		goto end;
+		}
+
 	if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
 		{
 		fprintf(stderr, "This case cannot work.  Use -f to perform "
@@ -1359,30 +1403,25 @@
 	}
 #endif
 
-#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
+/* At this point, ssl2/ssl3/tls1 is only set if the protocol is available.
+ * (Otherwise we exit early.)
+ * However the compiler doesn't know this, so we ifdef. */
+#ifndef OPENSSL_NO_SSL2
 	if (ssl2)
 		meth=SSLv2_method();
-	else 
-	if (tls1)
-		meth=TLSv1_method();
 	else
+#endif
+#ifndef OPENSSL_NO_SSL3
 	if (ssl3)
 		meth=SSLv3_method();
 	else
-		meth=SSLv23_method();
-#else
-#ifdef OPENSSL_NO_SSL2
+#endif
+#ifndef OPENSSL_NO_TLS1
 	if (tls1)
 		meth=TLSv1_method();
 	else
-	if (ssl3)
-		meth=SSLv3_method();
-	else
-		meth=SSLv23_method();
-#else
-	meth=SSLv2_method();
 #endif
-#endif
+	meth=SSLv23_method();
 
 	c_ctx=SSL_CTX_new(meth);
 	s_ctx=SSL_CTX_new(meth);