THRIFT-4084: Add a SSL/TLS negotiation check to crossfeature to verify SSLv3 is not active and that at least one of TLSv1.0 through 1.2 are accepted.
Client: csharp, d, go, nodejs, perl

This closes #1197
diff --git a/test/features/Makefile.am b/test/features/Makefile.am
index f8d6538..337d789 100644
--- a/test/features/Makefile.am
+++ b/test/features/Makefile.am
@@ -21,8 +21,10 @@
 	index.html \
 	known_failures_Linux.json \
 	Makefile.am \
+        nosslv3.sh \
 	string_limit.py \
 	tests.json \
 	theader_binary.py \
 	setup.cfg \
+        tls.sh \
 	util.py
diff --git a/test/features/nosslv3.sh b/test/features/nosslv3.sh
new file mode 100755
index 0000000..e550d51
--- /dev/null
+++ b/test/features/nosslv3.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+#
+# Checks to make sure SSLv3 is not allowed by a server.
+#
+
+THRIFTHOST=localhost
+THRIFTPORT=9090
+
+while [[ $# -ge 1 ]]; do
+  arg="$1"
+  argIN=(${arg//=/ })
+
+  case ${argIN[0]} in
+    -h|--host)
+    THRIFTHOST=${argIN[1]}
+    shift # past argument
+    ;;
+    -p|--port)
+    THRIFTPORT=${argIN[1]}
+    shift # past argument
+    ;;
+    *)
+          # unknown option ignored
+    ;;
+  esac
+
+  shift   # past argument or value
+done
+
+function nosslv3
+{
+  local nego
+  local negodenied
+
+  # echo "openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -ssl3 2>&1 < /dev/null"
+  nego=$(openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -ssl3 2>&1 < /dev/null)
+  negodenied=$?
+
+  if [[ $negodenied -ne 0 ]]; then
+    echo "[pass] SSLv3 negotiation disabled"
+    echo $nego
+    return 0
+  fi
+
+  echo "[fail] SSLv3 negotiation enabled!  stdout:"
+  echo $nego
+  return 1
+}
+
+nosslv3
+exit $?
diff --git a/test/features/tests.json b/test/features/tests.json
index cfcb4b6..3ab3b68 100644
--- a/test/features/tests.json
+++ b/test/features/tests.json
@@ -90,5 +90,27 @@
     "transports": ["buffered"],
     "sockets": ["ip"],
     "workdir": "features"
+  },
+  {
+    "name": "nosslv3",
+    "comment": "check to make sure SSLv3 is not supported",
+    "command": [
+      "nosslv3.sh"
+    ],
+    "protocols": ["binary"],
+    "transports": ["buffered"],
+    "sockets": ["ip-ssl"],
+    "workdir": "features"
+  },
+  {
+    "name": "tls",
+    "comment": "check to make sure TLSv1.0 or later is supported",
+    "command": [
+      "tls.sh"
+    ],
+    "protocols": ["binary"],
+    "transports": ["buffered"],
+    "sockets": ["ip-ssl"],
+    "workdir": "features"
   }
 ]
diff --git a/test/features/tls.sh b/test/features/tls.sh
new file mode 100755
index 0000000..dada6ab
--- /dev/null
+++ b/test/features/tls.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+
+#
+# Checks to make sure TLSv1.0 or later is allowed by a server.
+#
+
+THRIFTHOST=localhost
+THRIFTPORT=9090
+
+while [[ $# -ge 1 ]]; do
+  arg="$1"
+  argIN=(${arg//=/ })
+
+  case ${argIN[0]} in
+    -h|--host)
+    THRIFTHOST=${argIN[1]}
+    shift # past argument
+    ;;
+    -p|--port)
+    THRIFTPORT=${argIN[1]}
+    shift # past argument
+    ;;
+    *)
+          # unknown option ignored
+    ;;
+  esac
+
+  shift   # past argument or value
+done
+
+declare -A EXPECT_NEGOTIATE
+EXPECT_NEGOTIATE[tls1]=1
+EXPECT_NEGOTIATE[tls1_1]=1
+EXPECT_NEGOTIATE[tls1_2]=1
+
+failures=0
+
+function tls
+{
+  for PROTO in "${!EXPECT_NEGOTIATE[@]}"; do
+
+    local nego
+    local negodenied
+    local res
+
+    echo "openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -$PROTO 2>&1 < /dev/null"
+    nego=$(openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -$PROTO 2>&1 < /dev/null)
+    negodenied=$?
+    echo "result of command: $negodenied"
+
+    res="enabled"; if [[ ${EXPECT_NEGOTIATE[$PROTO]} -eq 0 ]]; then res="disabled"; fi
+
+    if [[ $negodenied -ne ${EXPECT_NEGOTIATE[$PROTO]} ]]; then
+      echo "$PROTO negotiation allowed"
+    else
+      echo "[warn] $PROTO negotiation did not work"
+      echo $nego
+      ((failures++))
+    fi
+  done
+}
+
+tls
+
+if [[ $failures -eq 3 ]]; then
+  echo "[fail] At least one of TLSv1.0, TLSv1.1, or TLSv1.2 needs to work, but does not"
+  exit $failures
+fi
+
+echo "[pass] At least one of TLSv1.0, TLSv1.1, or TLSv1.2 worked"
+exit 0