You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2014/01/16 00:50:03 UTC

git commit: Add a SSL certificate matching integration test

Updated Branches:
  refs/heads/master bed4b4595 -> b25bce3c6


Add a SSL certificate matching integration test

Various fixes the the tsqa harness to improve output legibility.
Crank up the configuration sync frequency so that we don't need to
wait so long for configuration changes.

Add a new integration test to ensure that SSL certificate matching
works correctly for wildcards, SNI names, IP addresses and address/port
combinations. Still missing is the default match; for that I need
a portable way to determine a local IP address.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/b25bce3c
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/b25bce3c
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/b25bce3c

Branch: refs/heads/master
Commit: b25bce3c6e304bcb3d4144f341f7056e9254d575
Parents: bed4b45
Author: James Peach <jp...@apache.org>
Authored: Tue Jan 14 10:39:55 2014 -0800
Committer: James Peach <jp...@apache.org>
Committed: Wed Jan 15 15:49:45 2014 -0800

----------------------------------------------------------------------
 ci/tsqa/functions             |  70 ++++++++++++++++---
 ci/tsqa/test-ssl-certificates | 135 +++++++++++++++++++++++++++++++++++++
 iocore/net/SSLUtils.cc        |   1 +
 3 files changed, 195 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b25bce3c/ci/tsqa/functions
----------------------------------------------------------------------
diff --git a/ci/tsqa/functions b/ci/tsqa/functions
index 8535255..cf3d9d4 100644
--- a/ci/tsqa/functions
+++ b/ci/tsqa/functions
@@ -16,10 +16,10 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-NCPU=${NCPU:-$(( $(getconf _NPROCESSORS_ONLN) * 2 ))}
-PORT=${PORT:-9090}
-VALGRIND=${VALGRIND:-N}
-TMPDIR=${TMPDIR:-/tmp}
+NCPU=${NCPU:-$(( $(getconf _NPROCESSORS_ONLN) * 2 ))} # Numer of CPUs to build with
+PORT=${PORT:-9090}                                    # Initial listen port for Traffic Server
+VALGRIND=${VALGRIND:-N}                               # Whether to run under valgrind
+TMPDIR=${TMPDIR:-/tmp}                                # Scratch directory for test instance construction
 
 TSQA_FAIL=0                                         # Test failure count
 TSQA_TESNAME=${TSQA_TESTNAME:-tsqa}                 # Name of current test
@@ -31,6 +31,14 @@ msg() {
   echo "MSG:" "$@"
 }
 
+msgwait() {
+  local secs="$1"
+  shift
+
+  echo "MSG: waiting ${secs}s" "$@"
+  sleep $secs
+}
+
 # Print a failure message and increment the failure count.
 fail() {
   TSQA_FAIL=$(($TSQA_FAIL + 1))
@@ -49,6 +57,12 @@ quiet() {
   "$@" 2>/dev/null
 }
 
+# Run a command with all output redirected to the pest log file.
+logexec() {
+  echo "$@" >> "$TSQA_ROOT/$TSQA_TESTNAME.log" 2>&1
+  "$@" >> "$TSQA_ROOT/$TSQA_TESTNAME.log" 2>&1
+}
+
 tsxs() {
   $TSQA_TSXS "$@"
 }
@@ -63,13 +77,17 @@ tsexec() {
     *) run=env ;;
   esac
 
+  # XXX enabling MallocStackLogging on all processes is annoying
+  # because it logs 3 lines to stderr every time. We generally only
+  # want leaks detection on traffic_server, so this is a bit of a
+  # waste ...
+
   # MALLOC_CHECK_=2 => enable glibc malloc checking, abort on error
   # MallocStackLogging=1 => record OS X malloc stacks for leak checking
   $run \
-  MallocStackLogging=1 \
   MALLOC_CHECK_=2 \
+  MallocErrorAbort=1 \
   TS_ROOT=$TSQA_ROOT \
-  PROXY_CONFIG_HTTP_SERVER_PORTS=$PORT \
     $(bindir)/$cmd "$@"
 }
 
@@ -161,11 +179,14 @@ shutdown() {
     return
   fi
 
-  # If we are on Darwin, we can check the traffic_server for leaks before shutting down
-  if [ -x /usr/bin/leaks ]; then
-    msg checking for leaks ...
-    /usr/bin/leaks $(pidof server)
-  fi
+# XXX If we are on Darwin, we can check the traffic_server for leaks before shutting down, but
+# we really only want to do this for traffic_server ... or we should sink the output to the test
+# log and fail on the exit status.
+
+#  if [ -x /usr/bin/leaks ]; then
+#    msg checking for leaks ...
+#    /usr/bin/leaks $(pidof server)
+#  fi
 
   msg shutting down ...
   while quiet kill -0 $pid ; do
@@ -179,6 +200,24 @@ shutdown() {
   exit $TSQA_FAIL
 }
 
+restart() {
+  local pid=$(pidof cop)
+  if [[ -z "$pid" ]] ; then
+    return
+  fi
+
+  msg shutting down ...
+  while quiet kill -0 $pid ; do
+    quiet kill -TERM $pid
+    pid=$(pidof cop)
+    if [[ -z "$pid" ]] ; then
+      return
+    fi
+  done
+
+  startup
+}
+
 # Test for Traffic Server crash logs.
 crash() {
   local outfile="$TSQA_ROOT/$(logdir)/traffic.out"
@@ -216,6 +255,8 @@ bootstrap() {
     -e/proxy.config.bin_path/d \
     -e/proxy.config.admin.user_id/d \
     -e/proxy.config.diags/d \
+    -e/proxy.config.http.server_ports/d \
+    -e/proxy.config.config_update_interval_ms/d \
     $TSQA_ROOT/$sysconfdir/records.config
 
   cat >> $TSQA_ROOT/$sysconfdir/records.config <<EOF
@@ -224,7 +265,12 @@ CONFIG proxy.config.plugin.plugin_dir STRING $(tsxs -q LIBEXECDIR)
 CONFIG proxy.config.body_factory.template_sets_dir STRING $(tsxs -q SYSCONFDIR)/body_factory
 
 CONFIG proxy.config.admin.user_id STRING $(whoami)
+CONFIG proxy.config.http.server_ports STRING $PORT
+
+# Flush config updates every 0.5s so that we don't have to sleep so long making config changes.
+CONFIG proxy.config.config_update_interval_ms INT 500
 
+# Send all diagnostics to both traffic.out and diags.log.
 CONFIG proxy.config.diags.output.diag STRING OL
 CONFIG proxy.config.diags.output.debug STRING OL
 CONFIG proxy.config.diags.output.status STRING OL
@@ -239,6 +285,8 @@ CONFIG proxy.config.diags.debug.enabled INT 1
 CONFIG proxy.config.diags.debug.tags STRING NULL
 CONFIG proxy.config.diags.show_location INT 1
 EOF
+
+  msg bootstrapped Traffic Server into $TSQA_ROOT
 }
 
 # vim: set sw=2 ts=2 et :

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b25bce3c/ci/tsqa/test-ssl-certificates
----------------------------------------------------------------------
diff --git a/ci/tsqa/test-ssl-certificates b/ci/tsqa/test-ssl-certificates
new file mode 100755
index 0000000..f45441a
--- /dev/null
+++ b/ci/tsqa/test-ssl-certificates
@@ -0,0 +1,135 @@
+#! /usr/bin/env bash
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+TSQA_TSXS=${TSQA_TSXS:-/opt/ats/bin/tsxs}
+TSQA_TESTNAME=$(basename $0)
+source $(dirname $0)/functions
+
+OPENSSL=${OPENSSL:-openssl}
+
+check_openssl_version() {
+  local vers=$($OPENSSL version)
+
+  # Apparantly OpenSSL SNI was added in 0.9.8f, but I'm too lazy to
+  # parse the version properly, so let's just say that 1.0 and greater is ok.
+  case $vers in
+  OpenSSL\ [1-9].[0-9].*) return 0;;
+  *) return 1;;
+  esac
+}
+
+make_ssl_certificate() {
+  local cn="$1"
+  local filename="$2"
+
+  msg generating SSL key and certificate for "$cn"
+
+  $OPENSSL genrsa -out ${cn}.key 2048
+  $OPENSSL req -new -key ${cn}.key -out ${cn}.csr \
+    -subj "/C=US/ST=CA/L=Norm/O=TrafficServer/OU=Test/CN=${cn}"
+  $OPENSSL x509 -req -days 1 -in ${cn}.csr -signkey ${cn}.key -out ${cn}.crt
+
+  cat ${cn}.crt ${cn}.key > ${filename}
+
+  rm -rf ${cn}.csr ${cn}.key ${cn}.crt
+}
+
+openssl_verify_certificate() {
+  local certname="$1" # Certificate CN to expect
+  local status=1  # default status is FAIL
+
+  shift
+  msg "checking for the $certname certificate ..."
+
+  # When s_client verifies the certificate, it will log a line that looks like:
+  # depth=0 C = US, ST = CA, L = Norm, O = TrafficServer, OU = Test, CN = address.tsqa.trafficserver.apache.org
+  $OPENSSL s_client "$@" < /dev/null 2>&1 | tee -a "$TSQA_ROOT/$TSQA_TESTNAME.log" | \
+    grep -q "depth=0.* CN = \Q$certname\E"
+
+  if [ "$?" != 0 ]; then
+    fail "certificate name $certname did not match"
+  fi
+}
+
+check_openssl_version || fatal OpenSSL 1.0 or later is required
+
+bootstrap
+
+# If Traffic Server is not up, bring it up ...
+alive cop || startup || fatal unable to start Traffic Server
+trap shutdown 0 EXIT
+
+for name in \
+  \*.tsqa.trafficserver.apache.org \
+  sni.tsqa.trafficserver.apache.org \
+  port.tsqa.trafficserver.apache.org \
+  address.tsqa.trafficserver.apache.org \
+  default.tsqa.trafficserver.apache.org
+do
+  logexec make_ssl_certificate $name $TSQA_ROOT/$(sysconfdir)/${name}.pem \
+    || fatal failed to generate SSL certificate for "$name"
+done
+
+cat > $TSQA_ROOT/$(sysconfdir)/ssl_multicert.config <<EOF
+ssl_cert_name=sni.tsqa.trafficserver.apache.org.pem
+ssl_cert_name=*.tsqa.trafficserver.apache.org.pem
+
+ssl_cert_name=port.tsqa.trafficserver.apache.org.pem dest_ip=127.0.0.1:10443
+ssl_cert_name=address.tsqa.trafficserver.apache.org.pem dest_ip=127.0.0.1
+ssl_cert_name=default.tsqa.trafficserver.apache.org.pem dest_ip=*
+EOF
+
+# XXX hardcoding the ports is lame ...
+PORT=9443:ssl,10443:ssl,11443:ssl
+
+# Enable SSL and bounce Traffic Server.
+tsexec traffic_line -s proxy.config.http.server_ports -v $PORT
+tsexec traffic_line -s proxy.config.diags.debug.tags -v ssl
+
+# The sleep is needed to let Traffic Server schedule the config change.
+msgwait 2 to restart with SSL ports enabled
+tsexec traffic_line -L
+
+msgwait 6 for traffic_server to restart
+alive server || startup || fatal unable to start Traffic Server
+
+# debugging ...
+# tsexec traffic_line -r proxy.config.diags.debug.tags
+# tsexec traffic_line -r proxy.config.http.server_ports
+
+# This should get *.tsqa.trafficserver.apache.org ...
+openssl_verify_certificate '*.tsqa.trafficserver.apache.org' \
+  -connect 127.0.0.1:9443 -servername wildcard.tsqa.trafficserver.apache.org
+
+# This should get sni.tsqa.trafficserver.apache.org ...
+openssl_verify_certificate 'sni.tsqa.trafficserver.apache.org' \
+  -connect 127.0.0.1:9443 -servername sni.tsqa.trafficserver.apache.org
+
+# This should get port.tsqa.trafficserver.apache.org ...
+openssl_verify_certificate 'port.tsqa.trafficserver.apache.org' \
+  -connect 127.0.0.1:10443
+
+# This should get address.tsqa.trafficserver.apache.org ...
+openssl_verify_certificate 'address.tsqa.trafficserver.apache.org' \
+  -connect 127.0.0.1:9443
+
+# XXX not sure how to get the default.tsqa.trafficserver.apache.org; need to listen on a second address for that.
+
+exit $TSQA_FAIL
+
+# vim: set sw=2 ts=2 et :

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b25bce3c/iocore/net/SSLUtils.cc
----------------------------------------------------------------------
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index 45682ef..833ac7d 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -722,6 +722,7 @@ ssl_store_ssl_context(
   // Insert additional mappings. Note that this maps multiple keys to the same value, so when
   // this code is updated to reconfigure the SSL certificates, it will need some sort of
   // refcounting or alternate way of avoiding double frees.
+  Debug("ssl", "importing SNI names from %s", (const char *)certpath);
   ssl_index_certificate(lookup, ctx, certpath);
 
   return true;