summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2011-09-07 17:28:04 +0000
committerAlan Conway <aconway@apache.org>2011-09-07 17:28:04 +0000
commit47c16ba2e19ad4bb149258312f86b4bcd7b04d24 (patch)
treebc3bbee7e5438ed2ea4a583e759801956edc1893 /cpp
parent12ff1511fa1483c7a3c683e2502e854a02144202 (diff)
downloadqpid-python-47c16ba2e19ad4bb149258312f86b4bcd7b04d24.tar.gz
Bug 730017, QPID-3475: Cluster authentication ignores cluster-* settings.
When a broker joins a cluster, it should be authenticated authenticate using the options --cluster-username, --cluster-password and --cluster-mechanism. The broker was ignoring the settings and joining the cluster even if an invalid user or password are supplied. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1166279 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/qpid/cluster/Connection.cpp4
-rw-r--r--cpp/src/qpid/cluster/SecureConnectionFactory.cpp8
-rw-r--r--cpp/src/qpid/cluster/UpdateClient.cpp1
-rwxr-xr-xcpp/src/tests/cluster_tests.py115
4 files changed, 123 insertions, 5 deletions
diff --git a/cpp/src/qpid/cluster/Connection.cpp b/cpp/src/qpid/cluster/Connection.cpp
index 0feb4c19ff..015301573e 100644
--- a/cpp/src/qpid/cluster/Connection.cpp
+++ b/cpp/src/qpid/cluster/Connection.cpp
@@ -99,7 +99,9 @@ Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out,
external,
isLink,
isCatchUp ? ++catchUpId : 0,
- isCatchUp), // isCatchUp => shadow
+ // The first catch-up connection is not considered a shadow
+ // as it needs to be authenticated.
+ isCatchUp && self.second > 1),
expectProtocolHeader(isLink),
mcastFrameHandler(cluster.getMulticast(), self),
updateIn(c.getUpdateReceiver()),
diff --git a/cpp/src/qpid/cluster/SecureConnectionFactory.cpp b/cpp/src/qpid/cluster/SecureConnectionFactory.cpp
index 6ddef66226..2672d8360c 100644
--- a/cpp/src/qpid/cluster/SecureConnectionFactory.cpp
+++ b/cpp/src/qpid/cluster/SecureConnectionFactory.cpp
@@ -7,9 +7,9 @@
* 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
@@ -48,7 +48,7 @@ SecureConnectionFactory::create(ProtocolVersion v, sys::OutputControl& out, cons
if (clusterCodec) {
SecureConnectionPtr sc(new SecureConnection());
clusterCodec->setSecureConnection(sc.get());
- sc->setCodec(codec);
+ sc->setCodec(codec);
return sc.release();
}
return 0;
@@ -63,7 +63,7 @@ SecureConnectionFactory::create(sys::OutputControl& out, const std::string& id,
if (clusterCodec) {
SecureConnectionPtr sc(new SecureConnection());
clusterCodec->setSecureConnection(sc.get());
- sc->setCodec(codec);
+ sc->setCodec(codec);
return sc.release();
}
return 0;
diff --git a/cpp/src/qpid/cluster/UpdateClient.cpp b/cpp/src/qpid/cluster/UpdateClient.cpp
index 3142b44d71..2be1bf1f77 100644
--- a/cpp/src/qpid/cluster/UpdateClient.cpp
+++ b/cpp/src/qpid/cluster/UpdateClient.cpp
@@ -151,6 +151,7 @@ void UpdateClient::run() {
try {
connection.open(updateeUrl, connectionSettings);
session = connection.newSession(UPDATE);
+ session.sync();
update();
done();
} catch (const std::exception& e) {
diff --git a/cpp/src/tests/cluster_tests.py b/cpp/src/tests/cluster_tests.py
index e4d5bdab04..4e3339650b 100755
--- a/cpp/src/tests/cluster_tests.py
+++ b/cpp/src/tests/cluster_tests.py
@@ -164,6 +164,121 @@ acl allow all all
self.fail("Expected exception")
except messaging.exceptions.NotFound: pass
+ def test_sasl_join(self):
+ """Verify SASL authentication between brokers when joining a cluster."""
+ sasl_config=os.path.join(self.rootdir, "sasl_config")
+
+ # Valid user/password, ensure queue is created.
+ c = cluster[0].connect(username="zig", password="zig")
+ c.session().sender("ziggy;{create:always}")
+ c.close()
+ c = cluster[1].connect(username="zig", password="zig")
+ c.session().receiver("ziggy;{assert:always}")
+ c.close()
+ for b in cluster: b.ready() # Make sure all brokers still running.
+
+ # Valid user, bad password
+ try:
+ cluster[0].connect(username="zig", password="foo").close()
+ self.fail("Expected exception")
+ except messaging.exceptions.ConnectionError: pass
+ for b in cluster: b.ready() # Make sure all brokers still running.
+
+ # Bad user ID
+ try:
+ cluster[0].connect(username="foo", password="bar").close()
+ self.fail("Expected exception")
+ except messaging.exceptions.ConnectionError: pass
+ for b in cluster: b.ready() # Make sure all brokers still running.
+
+ # Action disallowed by ACL
+ c = cluster[0].connect(username="zag", password="zag")
+ try:
+ s = c.session()
+ s.sender("zaggy;{create:always}")
+ s.close()
+ self.fail("Expected exception")
+ except messaging.exceptions.UnauthorizedAccess: pass
+ # make sure the queue was not created at the other node.
+ c = cluster[0].connect(username="zag", password="zag")
+ try:
+ s = c.session()
+ s.sender("zaggy;{assert:always}")
+ s.close()
+ self.fail("Expected exception")
+ except messaging.exceptions.NotFound: pass
+
+ def test_sasl_join(self):
+ """Verify SASL authentication between brokers when joining a cluster."""
+ # Valid user/password, ensure queue is created.
+ c = cluster[0].connect(username="zig", password="zig")
+ c.session().sender("ziggy;{create:always}")
+ c.close()
+ c = cluster[1].connect(username="zig", password="zig")
+ c.session().receiver("ziggy;{assert:always}")
+ c.close()
+ for b in cluster: b.ready() # Make sure all brokers still running.
+
+ # Valid user, bad password
+ try:
+ cluster[0].connect(username="zig", password="foo").close()
+ self.fail("Expected exception")
+ except messaging.exceptions.ConnectionError: pass
+ for b in cluster: b.ready() # Make sure all brokers still running.
+
+ # Bad user ID
+ try:
+ cluster[0].connect(username="foo", password="bar").close()
+ self.fail("Expected exception")
+ except messaging.exceptions.ConnectionError: pass
+ for b in cluster: b.ready() # Make sure all brokers still running.
+
+ # Action disallowed by ACL
+ c = cluster[0].connect(username="zag", password="zag")
+ try:
+ s = c.session()
+ s.sender("zaggy;{create:always}")
+ s.close()
+ self.fail("Expected exception")
+ except messaging.exceptions.UnauthorizedAccess: pass
+ # make sure the queue was not created at the other node.
+ c = cluster[0].connect(username="zag", password="zag")
+ try:
+ s = c.session()
+ s.sender("zaggy;{assert:always}")
+ s.close()
+ self.fail("Expected exception")
+ except messaging.exceptions.NotFound: pass
+
+ def test_sasl_join(self):
+ """Verify SASL authentication between brokers when joining a cluster."""
+ sasl_config=os.path.join(self.rootdir, "sasl_config")
+ # Test with a valid username/password
+ cluster = self.cluster(1, args=["--auth", "yes",
+ "--sasl-config", sasl_config,
+ "--load-module", os.getenv("ACL_LIB"),
+ "--cluster-username=zig",
+ "--cluster-password=zig",
+ "--cluster-mechanism=PLAIN"
+ ])
+ cluster.start()
+ cluster.ready()
+ c = cluster[1].connect(username="zag", password="zag")
+
+ # Test with an invalid username/password
+ cluster = self.cluster(1, args=["--auth", "yes",
+ "--sasl-config", sasl_config,
+ "--load-module", os.getenv("ACL_LIB"),
+ "--cluster-username=x",
+ "--cluster-password=y",
+ "--cluster-mechanism=PLAIN"
+ ])
+ try:
+ cluster.start(expect=EXPECT_EXIT_OK)
+ cluster[1].ready()
+ self.fail("Expected exception")
+ except: pass
+
def test_user_id_update(self):
"""Ensure that user-id of an open session is updated to new cluster members"""
sasl_config=os.path.join(self.rootdir, "sasl_config")