You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2015/10/22 21:34:21 UTC
qpid-dispatch git commit: DISPATCH-163 - Added username and password
for authentication of connectors. Added system test to verify SASL PLAIN
authentication
Repository: qpid-dispatch
Updated Branches:
refs/heads/master 8353ac674 -> 2991015c7
DISPATCH-163 - Added username and password for authentication of connectors. Added system test to verify SASL PLAIN authentication
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/2991015c
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/2991015c
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/2991015c
Branch: refs/heads/master
Commit: 2991015c7f2426814e7a1687997ebda4847ba6e5
Parents: 8353ac6
Author: ganeshmurthy <gm...@redhat.com>
Authored: Fri Oct 16 14:18:45 2015 -0400
Committer: ganeshmurthy <gm...@redhat.com>
Committed: Wed Oct 21 10:19:03 2015 -0400
----------------------------------------------------------------------
python/qpid_dispatch/management/qdrouter.json | 14 ++-
src/connection_manager.c | 2 +
src/server.c | 10 +-
tests/CMakeLists.txt | 62 ++++++++----
tests/sasl_configs/qdrouterd.sasldb | Bin 0 -> 12288 bytes
tests/sasl_configs/tests-mech-PLAIN.conf.in | 79 +++++++++++++++
tests/system_tests_sasl_plain.py.in | 106 +++++++++++++++++++++
7 files changed, 253 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/2991015c/python/qpid_dispatch/management/qdrouter.json
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch/management/qdrouter.json b/python/qpid_dispatch/management/qdrouter.json
index 6c8dae8..ca6685e 100644
--- a/python/qpid_dispatch/management/qdrouter.json
+++ b/python/qpid_dispatch/management/qdrouter.json
@@ -678,7 +678,19 @@
"default": "both",
"description": "['in', 'out', 'both', 'no'] in: Strip the dispatch router specific annotations only on ingress; out: Strip the dispatch router specific annotations only on egress; both: Strip the dispatch router specific annotations on both ingress and egress; no - do not strip dispatch router specific annotations",
"create": true
- }
+ },
+ "saslUsername": {
+ "type": "string",
+ "required": false,
+ "description": "The user name that the connector is using to connect to a peer.",
+ "create": true
+ },
+ "saslPassword": {
+ "type": "string",
+ "required": false,
+ "description": "The password that the connector is using to connect to a peer.",
+ "create": true
+ }
}
},
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/2991015c/src/connection_manager.c
----------------------------------------------------------------------
diff --git a/src/connection_manager.c b/src/connection_manager.c
index c9dc81c..c90db75 100644
--- a/src/connection_manager.c
+++ b/src/connection_manager.c
@@ -144,6 +144,8 @@ static qd_error_t load_server_config(qd_dispatch_t *qd, qd_server_config_t *conf
config->role = qd_entity_get_string(entity, "role"); CHECK();
config->max_frame_size = qd_entity_get_long(entity, "maxFrameSize"); CHECK();
config->idle_timeout_seconds = qd_entity_get_long(entity, "idleTimeoutSeconds"); CHECK();
+ config->sasl_username = qd_entity_opt_string(entity, "saslUsername", 0); CHECK();
+ config->sasl_password = qd_entity_opt_string(entity, "saslPassword", 0); CHECK();
config->sasl_mechanisms = qd_entity_opt_string(entity, "saslMechanisms", 0); CHECK();
config->ssl_enabled = has_attrs(entity, ssl_attributes, ssl_attributes_count);
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/2991015c/src/server.c
----------------------------------------------------------------------
diff --git a/src/server.c b/src/server.c
index 623a587..d53b64e 100644
--- a/src/server.c
+++ b/src/server.c
@@ -830,6 +830,8 @@ static void cxtr_try_open(void *context)
}
sys_mutex_unlock(ct->server->lock);
+ const qd_server_config_t *config = ct->config;
+
if (ctx->pn_cxtr == 0) {
sys_mutex_free(ctx->deferred_call_lock);
free_qd_connection_t(ctx);
@@ -838,6 +840,13 @@ static void cxtr_try_open(void *context)
return;
}
+ // Set the sasl user name and password on the proton connection object. This has to be done before the call to qdpn_connector_transport() which
+ // binds the transport to the connection
+ if(config->sasl_username)
+ pn_connection_set_user(ctx->pn_conn, config->sasl_username);
+ if (config->sasl_password)
+ pn_connection_set_password(ctx->pn_conn, config->sasl_password);
+
qdpn_connector_set_connection(ctx->pn_cxtr, ctx->pn_conn);
pn_connection_set_context(ctx->pn_conn, ctx);
@@ -850,7 +859,6 @@ static void cxtr_try_open(void *context)
// Set up the transport, SASL, and SSL for the connection.
//
pn_transport_t *tport = qdpn_connector_transport(ctx->pn_cxtr);
- const qd_server_config_t *config = ct->config;
//
// Configure the transport
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/2991015c/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e2b79e3..b31f642 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -50,6 +50,21 @@ set(unit_test_size_SOURCES
add_executable(unit_tests_size ${unit_test_size_SOURCES})
target_link_libraries(unit_tests_size qpid-dispatch)
+# Move all the python system tests from the src/tests dir to the build/tests dir and execute the tests from there.
+# While moving the files make sure that configure_file() is called on any .py.in files resulting in .py file
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/system_tests_sasl_plain.py.in ${CMAKE_CURRENT_BINARY_DIR}/system_tests_sasl_plain.py)
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/router_engine_test.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/system_tests_broker.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/system_tests_management.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/system_tests_one_router.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/system_tests_qdmanage.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/system_tests_qdstat.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/system_tests_two_routers.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/system_tests_link_routes.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/run_system_tests.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/system_test.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
+
set(TEST_WRAP ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/run.py)
add_test(unit_tests_size_10000 ${TEST_WRAP} --vg unit_tests_size 10000)
@@ -61,34 +76,45 @@ add_test(unit_tests_size_3 ${TEST_WRAP} --vg unit_tests_size 3)
add_test(unit_tests_size_2 ${TEST_WRAP} --vg unit_tests_size 2)
add_test(unit_tests_size_1 ${TEST_WRAP} --vg unit_tests_size 1)
add_test(unit_tests ${TEST_WRAP} --vg unit_tests ${CMAKE_CURRENT_SOURCE_DIR}/threads4.conf)
-add_test(router_tests ${TEST_WRAP} -s ${CMAKE_CURRENT_SOURCE_DIR}/router_engine_test.py -v)
-add_test(management_tests ${TEST_WRAP} -m unittest -v management)
-
-macro(add_system_test test)
- add_test(${test} ${TEST_WRAP} -m ${test} -v)
-endmacro(add_system_test)
-add_system_test(system_tests_broker)
-add_system_test(system_tests_management)
-add_system_test(system_tests_one_router)
-add_system_test(system_tests_qdmanage)
-add_system_test(system_tests_qdstat)
-add_system_test(system_tests_two_routers)
-add_system_test(system_tests_link_routes)
+# Add all sytem_tests* using add_test
+add_test(router_tests ${TEST_WRAP} -s ${CMAKE_CURRENT_BINARY_DIR}/router_engine_test.py -v)
+add_test(system_tests_broker ${TEST_WRAP} -s ${CMAKE_CURRENT_BINARY_DIR}/system_tests_broker.py -v)
+add_test(system_tests_management ${TEST_WRAP} -s ${CMAKE_CURRENT_BINARY_DIR}/system_tests_management.py -v)
+add_test(system_tests_one_router ${TEST_WRAP} -s ${CMAKE_CURRENT_BINARY_DIR}/system_tests_one_router.py -v)
+add_test(system_tests_qdmanage ${TEST_WRAP} -s ${CMAKE_CURRENT_BINARY_DIR}/system_tests_qdmanage.py -v)
+add_test(system_tests_qdstat ${TEST_WRAP} -s ${CMAKE_CURRENT_BINARY_DIR}/system_tests_qdstat.py -v)
+add_test(system_tests_two_routers ${TEST_WRAP} -s ${CMAKE_CURRENT_BINARY_DIR}/system_tests_two_routers.py -v)
+add_test(system_tests_link_routes ${TEST_WRAP} -s ${CMAKE_CURRENT_BINARY_DIR}/system_tests_link_routes.py -v)
+add_test(system_tests_sasl_plain ${TEST_WRAP} -s ${CMAKE_CURRENT_BINARY_DIR}/system_tests_sasl_plain.py -v)
+add_test(management_tests ${TEST_WRAP} -m unittest -v management)
+
+#macro(add_system_test test)
+# add_test(${test} ${TEST_WRAP} -m ${test} -v)
+#endmacro(add_system_test)
# NOTE: Don't install run.py. A system test of a dispatch installation should pick everything
# up from standard install locations.
#
set(SYSTEM_TEST_FILES
- run_system_tests.py system_test.py
- system_tests_one_router.py system_tests_two_routers.py
- system_tests_broker.py system_tests_management.py
- system_tests_qdstat.py system_tests_qdmanage.py
- system_tests_link_routes.py)
+ ${CMAKE_CURRENT_BINARY_DIR}/router_engine_test.py
+ ${CMAKE_CURRENT_BINARY_DIR}/run_system_tests.py
+ ${CMAKE_CURRENT_BINARY_DIR}/system_test.py
+ ${CMAKE_CURRENT_BINARY_DIR}/system_tests_one_router.py
+ ${CMAKE_CURRENT_BINARY_DIR}/system_tests_two_routers.py
+ ${CMAKE_CURRENT_BINARY_DIR}/system_tests_broker.py
+ ${CMAKE_CURRENT_BINARY_DIR}/system_tests_management.py
+ ${CMAKE_CURRENT_BINARY_DIR}/system_tests_qdstat.py
+ ${CMAKE_CURRENT_BINARY_DIR}/system_tests_qdmanage.py
+ ${CMAKE_CURRENT_BINARY_DIR}/system_tests_link_routes.py
+ ${CMAKE_CURRENT_BINARY_DIR}/system_tests_sasl_plain.py)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-2/A-ssl.conf.in ${CMAKE_CURRENT_BINARY_DIR}/config-2/A-ssl.conf)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-2/B-ssl.conf.in ${CMAKE_CURRENT_BINARY_DIR}/config-2/B-ssl.conf)
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/sasl_configs/qdrouterd.sasldb DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/sasl_configs)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/sasl_configs/tests-mech-PLAIN.conf.in ${CMAKE_CURRENT_BINARY_DIR}/sasl_configs/tests-mech-PLAIN.conf)
+# following install() functions will be called only if you do a make "install"
install(FILES ${SYSTEM_TEST_FILES}
DESTINATION ${QPID_DISPATCH_HOME_INSTALLED}/tests
)
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/2991015c/tests/sasl_configs/qdrouterd.sasldb
----------------------------------------------------------------------
diff --git a/tests/sasl_configs/qdrouterd.sasldb b/tests/sasl_configs/qdrouterd.sasldb
new file mode 100644
index 0000000..d73e603
Binary files /dev/null and b/tests/sasl_configs/qdrouterd.sasldb differ
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/2991015c/tests/sasl_configs/tests-mech-PLAIN.conf.in
----------------------------------------------------------------------
diff --git a/tests/sasl_configs/tests-mech-PLAIN.conf.in b/tests/sasl_configs/tests-mech-PLAIN.conf.in
new file mode 100644
index 0000000..4e04097
--- /dev/null
+++ b/tests/sasl_configs/tests-mech-PLAIN.conf.in
@@ -0,0 +1,79 @@
+#
+# 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.
+#
+#
+#---------------------------------
+# SASL Mechanisms and Users
+#---------------------------------
+#
+# This default mech list allows for PLAIN, but that
+# mechanism sends credentials in the clear, and is normally
+# only used along with SSL transport-layer security.
+#
+# This default also permits DIGEST-MD5, but you must have
+# a user and password defined in your sasldb file to use
+# this mechanism. ( See notes below. )
+#
+# PLEASE NOTE
+# For production messaging systems, a high-security mechanism such as
+# DIGEST-MD5 or PLAIN+SSL should be used.
+#
+#
+
+pwcheck_method: auxprop
+auxprop_plugin: sasldb
+sasldb_path: ${CMAKE_CURRENT_BINARY_DIR}/sasl_configs/qdrouterd.sasldb
+mech_list: ANONYMOUS DIGEST-MD5 EXTERNAL PLAIN
+
+#---------------------------------
+# Please Note
+#---------------------------------
+#
+# 1. If you use a nonstandard location for your sasl_config directory,
+# you can point qdrouterd to it by using the container->saslConfigPath
+# configuration attribute.
+#
+# If your nonstandard sasl directory is $MY_SASL_DIR, put a copy
+# of this file at $MY_SASL_DIR/qdrouterd.conf, alter the mech list as
+# appropriate for your installation, and then use the saslpasswd2
+# command to add new user+passwd pairs:
+# echo $PASSWD | saslpasswd2 -c -p -f $MY_SASL_DIR/qdrouterd.sasldb -u qdrouterd $USERNAME
+#
+#
+# 2. The standard location for the qdrouterd sasldb file is
+# /var/lib/qdrouterd/qdrouterd.sasldb
+#
+# 3. You can see what usernames have been stored in the sasldb, with the
+# command "sasldblistusers2 -f /var/lib/qdrouterd/qdrouterd.sasldb"
+#
+# 4. The sasldb file must be readable by the user running the qdrouterd
+# daemon, ( the user name is qdrouterd ) and should be readable only
+# by that user.
+#
+# 5. The EXTERNAL mechanism allows you to use SSL transport layer
+# security. In that case, you can also set the broker option
+# --ssl-require-client-authentication .
+
+
+
+# The following line stops spurious 'sql_select option missing' errors when
+# cyrus-sql-sasl plugin is installed
+sql_select: dummy select
+
+
+
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/2991015c/tests/system_tests_sasl_plain.py.in
----------------------------------------------------------------------
diff --git a/tests/system_tests_sasl_plain.py.in b/tests/system_tests_sasl_plain.py.in
new file mode 100644
index 0000000..5e03efd
--- /dev/null
+++ b/tests/system_tests_sasl_plain.py.in
@@ -0,0 +1,106 @@
+#
+# 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.
+#
+
+import unittest, os
+from subprocess import PIPE
+import system_test
+from system_test import TestCase, Qdrouterd, main_module
+
+class RouterTestPlainSasl(TestCase):
+
+ @classmethod
+ def createSasldb(cls):
+ pass
+
+
+ @classmethod
+ def setUpClass(cls):
+ """
+ Tests the sasl_username, sasl_password property of the dispatch router.
+
+ Creates two routers (QDR.X and QDR.Y) and sets up PLAIN authentication on QDR.X.
+ QDR.Y connects to QDR.X by providing a sasl_username and a sasl_password.
+
+ """
+ super(RouterTestPlainSasl, cls).setUpClass()
+
+ def router(name, connection):
+
+ config = [
+ ('router', {'mode': 'interior', 'routerId': 'QDR.%s'%name}),
+ ('fixedAddress', {'prefix': '/closest/', 'fanout': 'single', 'bias': 'closest'}),
+ ('fixedAddress', {'prefix': '/spread/', 'fanout': 'single', 'bias': 'spread'}),
+ ('fixedAddress', {'prefix': '/multicast/', 'fanout': 'multiple'}),
+ ('fixedAddress', {'prefix': '/', 'fanout': 'multiple'}),
+
+ ] + connection
+
+ config = Qdrouterd.Config(config)
+ cls.routers.append(cls.tester.qdrouterd(name, config, wait=False))
+
+ cls.routers = []
+
+ x_listener_port = cls.tester.get_port()
+ y_listener_port = cls.tester.get_port()
+
+ # Look at the tests/CMakeLists.txt to find out how CMAKE replaces ${CMAKE_CURRENT_BINARY_DIR} with the correct path
+ # CMAKE also renames this file to system_tests_sasl_plain.py and copies it to the build/tests folder before executing it.
+ sasl_config_path = '${CMAKE_CURRENT_BINARY_DIR}' + '/sasl_configs'
+
+ router('X', [
+ ('listener', {'addr': '0.0.0.0', 'role': 'inter-router', 'port': x_listener_port,
+ 'saslMechanisms':'PLAIN DIGEST-MD5', 'authenticatePeer': 'yes'}),
+ # This unauthenticated listener is for qdstat to connect to it.
+ ('listener', {'addr': '0.0.0.0', 'role': 'normal', 'port': cls.tester.get_port(),
+ 'authenticatePeer': 'no'}),
+ ('container', {'workerThreads': 4, 'containerName': 'Qpid.Dispatch.Router.X',
+ 'saslConfigName': 'tests-mech-PLAIN',
+ 'saslConfigPath': sasl_config_path}),
+ ])
+
+ router('Y', [
+ ('connector', {'addr': '0.0.0.0', 'role': 'inter-router', 'port': x_listener_port,
+ # Provide a sasl user name and password to connect to QDR.X
+ 'saslMechanisms': 'PLAIN DIGEST-MD5', 'saslUsername': 'test@domain.com', 'saslPassword': 'password'}),
+ ('container', {'workerThreads': 4, 'containerName': 'Qpid.Dispatch.Router.Y'}),
+ ('listener', {'addr': '0.0.0.0', 'role': 'normal', 'port': y_listener_port}),
+ ])
+
+ cls.routers[1].wait_router_connected('QDR.X')
+
+ def test_inter_router_plain_exists(self):
+ """
+ The setUpClass sets up two routers with SASL PLAIN enabled.
+ This test makes executes a qdstat -c via an unauthenticated listener to QDR.X and makes sure that the output
+ has an "inter-router" connection to QDR.Y whose authentication is PLAIN. This ensures that QDR.Y did not
+ somehow use SASL ANONYMOUS to connect to QDR.X
+ """
+ p = self.popen(
+ ['qdstat', '-b', str(self.routers[0].addresses[1]), '-c'],
+ name='qdstat-'+self.id(), stdout=PIPE, expect=None)
+ out = p.communicate()[0]
+ assert p.returncode == 0, \
+ "qdstat exit status %s, output:\n%s" % (p.returncode, out)
+
+ assert "inter-router" in out
+ assert "test@domain.com(PLAIN)" in out
+
+if __name__ == '__main__':
+ unittest.main(main_module())
+
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org