| #!/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. |
| # |
| |
| #=============================================================================== |
| # These tests create federated links between two brokers using SASL security. |
| # The SASL mechanism used is EXTERNAL, which is satisfied by SSL |
| # transport-layer security. |
| #=============================================================================== |
| |
| set -eu |
| |
| if (( $# != 1 )); then |
| # These are the four different ways of creating links ( or routes+links ) |
| # that the qpid-route command provides. |
| echo "Usage: $(basename $0) dynamic|link|queue|route" |
| exit 1 |
| fi |
| |
| qpid_route_method=$1 |
| |
| WORK_DIR="${WORK_DIR}/sasl_fed_ex_${qpid_route_method}" |
| mkdir $WORK_DIR |
| |
| CERT_DIR=$WORK_DIR/test_cert_db |
| CERT_PW_FILE=$WORK_DIR/cert.password |
| TEST_HOSTNAME=127.0.0.1 |
| |
| create_certs() { |
| # Create certificate and key databases with single, simple, |
| # self-signed certificate in it |
| mkdir ${CERT_DIR} |
| certutil -N -d ${CERT_DIR} -f ${CERT_PW_FILE} |
| certutil -S -d ${CERT_DIR} -n ${TEST_HOSTNAME} -s "CN=${TEST_HOSTNAME}" -t "CT,," -x -f ${CERT_PW_FILE} -z /bin/sh 2> /dev/null |
| } |
| |
| CERTUTIL=$(type -p certutil) || : |
| |
| if [[ ! -x $CERTUTIL ]]; then |
| echo "No certutil, skipping ssl test" |
| exit 0 |
| fi |
| |
| create_certs 2> /dev/null |
| |
| if (( $? != 0 )); then |
| echo "Could not create test certificate" |
| exit 1 |
| fi |
| |
| sasl_config_dir=$BUILD_DIR/src/tests/sasl_config |
| |
| SRC_SSL_PORT=6667 |
| DST_SSL_PORT=6666 |
| |
| SRC_SSL_PORT_2=6668 |
| DST_SSL_PORT_2=6669 |
| |
| SRC_TCP_PORT=5801 |
| DST_TCP_PORT=5807 |
| |
| SRC_TCP_PORT_2=5802 |
| DST_TCP_PORT_2=5803 |
| |
| export QPID_SSL_CERT_NAME=${TEST_HOSTNAME} |
| |
| export QPID_NO_MODULE_DIR=1 |
| export QPID_SSL_CERT_DB=${CERT_DIR} |
| export QPID_SSL_CERT_PASSWORD_FILE=${CERT_PW_FILE} |
| export QPID_SSL_CERT_NAME=${TEST_HOSTNAME} |
| |
| ####################################### |
| # Understanding this Plumbing |
| ####################################### |
| # 1. when you establish the route with qpid-route, |
| # here is the best termiology to use: |
| # |
| # qpid-route route add DST SRC |
| # |
| # 2. DST will connect to SRC through the ssl port of SRC. |
| # |
| # 3. sender client connects to the tcp port of SRC. |
| # |
| # 4. sender specifies mechanism ANONYMOUS. |
| # |
| # 5. DST pulls messages off the temp queue on SRC to itself. |
| # |
| |
| COMMON_BROKER_OPTIONS=" \ |
| --ssl-sasl-no-dict \ |
| --sasl-config $sasl_config_dir \ |
| --ssl-require-client-authentication \ |
| --auth yes \ |
| --ssl-cert-db $CERT_DIR \ |
| --ssl-cert-password-file $CERT_PW_FILE \ |
| --ssl-cert-name $TEST_HOSTNAME \ |
| --no-data-dir \ |
| --no-module-dir \ |
| --mgmt-enable yes \ |
| --log-enable info+ \ |
| --log-source yes \ |
| --daemon" |
| |
| function start_brokers { |
| # vanilla brokers -------------------------------- |
| echo "Starting SRC broker" |
| qpidd \ |
| --port=${SRC_TCP_PORT} \ |
| --ssl-port ${SRC_SSL_PORT} \ |
| ${COMMON_BROKER_OPTIONS} \ |
| --log-to-file $WORK_DIR/qpidd_src.log 2> /dev/null |
| |
| broker_ports[0]=${SRC_TCP_PORT} |
| |
| echo "Starting DST broker" |
| qpidd \ |
| --port=${DST_TCP_PORT} \ |
| --ssl-port ${DST_SSL_PORT} \ |
| ${COMMON_BROKER_OPTIONS} \ |
| --log-to-file $WORK_DIR/qpidd_dst.log 2> /dev/null |
| |
| broker_ports[1]=${DST_TCP_PORT} |
| } |
| |
| function halt_brokers { |
| n_brokers=${#broker_ports[@]} |
| echo "Halting ${n_brokers} brokers" |
| for i in $(seq 0 $((${n_brokers} - 1))); do |
| halt_port=${broker_ports[$i]} |
| echo "Halting broker $i on port ${halt_port}" |
| qpidd --port ${halt_port} --quit |
| done |
| } |
| |
| start_brokers |
| trap halt_brokers EXIT |
| |
| # I am not randomizing these names, because this test creates its own brokers. |
| QUEUE_NAME=sasl_fed_queue |
| ROUTING_KEY=sasl_fed_queue |
| EXCHANGE_NAME=sasl_fedex |
| |
| echo "Add exchanges" |
| qpid-config -b localhost:${SRC_TCP_PORT} add exchange direct $EXCHANGE_NAME |
| qpid-config -b localhost:${DST_TCP_PORT} add exchange direct $EXCHANGE_NAME |
| |
| echo "Add queues" |
| qpid-config -b localhost:${SRC_TCP_PORT} add queue $QUEUE_NAME |
| qpid-config -b localhost:${DST_TCP_PORT} add queue $QUEUE_NAME |
| |
| echo "Create bindings" |
| qpid-config -b localhost:${SRC_TCP_PORT} bind $EXCHANGE_NAME $QUEUE_NAME $ROUTING_KEY |
| qpid-config -b localhost:${DST_TCP_PORT} bind $EXCHANGE_NAME $QUEUE_NAME $ROUTING_KEY |
| |
| # |
| # NOTE: The SRC broker *must* be referred to as $TEST_HOSTNAME, and not as "localhost". |
| # It must be referred to by the exact string given as the Common Name (CN) in the cert, |
| # which was created in the function create_certs, above. |
| |
| #---------------------------------------------------------------- |
| # Use qpid-route to create the link, or the link+route, depending |
| # on which of its several methods was requested. |
| #---------------------------------------------------------------- |
| if [[ $qpid_route_method == "dynamic" ]]; then |
| echo "Dynamic add" |
| qpid-route -t ssl dynamic add localhost:${DST_TCP_PORT} $TEST_HOSTNAME:${SRC_SSL_PORT} $EXCHANGE_NAME "" "" EXTERNAL || : |
| elif [[ $qpid_route_method == "link" ]]; then |
| echo "Link add" |
| qpid-route -t ssl link add localhost:${DST_TCP_PORT} $TEST_HOSTNAME:${SRC_SSL_PORT} EXTERNAL || : |
| elif [[ $qpid_route_method == "queue" ]]; then |
| echo "Queue add" |
| qpid-route -t ssl queue add localhost:${DST_TCP_PORT} $TEST_HOSTNAME:${SRC_SSL_PORT} $EXCHANGE_NAME $ROUTING_KEY EXTERNAL || : |
| elif [[ $qpid_route_method == "route" ]]; then |
| echo "Route add" |
| qpid-route -t ssl route add localhost:${DST_TCP_PORT} $TEST_HOSTNAME:${SRC_SSL_PORT} $EXCHANGE_NAME $ROUTING_KEY "" "" EXTERNAL || : |
| else |
| echo "Unknown method: |${qpid_route_method}|" |
| echo "Choices are: dynamic|link|queue|route " |
| halt_brokers |
| exit 1 |
| fi |
| |
| # I don't know how to avoid this sleep yet. It has to come after route-creation |
| # to avoid false negatives. |
| sleep 5 |
| |
| # Look only at the transport field, which should be "ssl". |
| echo "Check the link" |
| link_status=$(qpid-route link list localhost:${DST_TCP_PORT} | tail -1 | awk '{print $3}') |
| |
| sleep 1 |
| |
| if [[ ! $link_status ]]; then |
| echo "Link status is empty" |
| echo "Result: fail" |
| exit 2 |
| fi |
| |
| if [[ $link_status == "ssl" ]]; then |
| echo "Result: good" |
| exit 0 |
| fi |
| |
| echo "Link status has a bad value: ${link_status}" |
| echo "Result: fail" |
| exit 3 |