summaryrefslogtreecommitdiff
path: root/M4-RCs/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'M4-RCs/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp')
-rw-r--r--M4-RCs/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp337
1 files changed, 0 insertions, 337 deletions
diff --git a/M4-RCs/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp b/M4-RCs/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
deleted file mode 100644
index 370de8a1d1..0000000000
--- a/M4-RCs/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "Connection.h"
-#include "qpid/log/Statement.h"
-#include "qpid/framing/reply_exceptions.h"
-#include <boost/format.hpp>
-
-#if HAVE_SASL
-#include <sasl/sasl.h>
-#endif
-
-using namespace qpid::framing;
-using boost::format;
-using boost::str;
-
-namespace qpid {
-namespace broker {
-
-
-class NullAuthenticator : public SaslAuthenticator
-{
- Connection& connection;
- framing::AMQP_ClientProxy::Connection client;
- std::string realm;
-public:
- NullAuthenticator(Connection& connection);
- ~NullAuthenticator();
- void getMechanisms(framing::Array& mechanisms);
- void start(const std::string& mechanism, const std::string& response);
- void step(const std::string&) {}
-};
-
-#if HAVE_SASL
-
-class CyrusAuthenticator : public SaslAuthenticator
-{
- sasl_conn_t *sasl_conn;
- Connection& connection;
- framing::AMQP_ClientProxy::Connection client;
-
- void processAuthenticationStep(int code, const char *challenge, unsigned int challenge_len);
-
-public:
- CyrusAuthenticator(Connection& connection);
- ~CyrusAuthenticator();
- void init();
- void getMechanisms(framing::Array& mechanisms);
- void start(const std::string& mechanism, const std::string& response);
- void step(const std::string& response);
- void getUid(std::string& uid);
- void getError(std::string& error);
-};
-
-bool SaslAuthenticator::available(void)
-{
- return true;
-}
-
-// Initialize the SASL mechanism; throw if it fails.
-void SaslAuthenticator::init(const std::string& saslName)
-{
- int code = sasl_server_init(NULL, saslName.c_str());
- if (code != SASL_OK) {
- // TODO: Figure out who owns the char* returned by
- // sasl_errstring, though it probably does not matter much
- throw Exception(sasl_errstring(code, NULL, NULL));
- }
-}
-
-void SaslAuthenticator::fini(void)
-{
- sasl_done();
-}
-
-#else
-
-typedef NullAuthenticator CyrusAuthenticator;
-
-bool SaslAuthenticator::available(void)
-{
- return false;
-}
-
-void SaslAuthenticator::init(const std::string& /*saslName*/)
-{
- throw Exception("Requested authentication but SASL unavailable");
-}
-
-void SaslAuthenticator::fini(void)
-{
- return;
-}
-
-#endif
-
-std::auto_ptr<SaslAuthenticator> SaslAuthenticator::createAuthenticator(Connection& c)
-{
- static bool needWarning = true;
- if (c.getBroker().getOptions().auth) {
- return std::auto_ptr<SaslAuthenticator>(new CyrusAuthenticator(c));
- } else {
- QPID_LOG(warning, "SASL: No Authentication Performed");
- needWarning = false;
- return std::auto_ptr<SaslAuthenticator>(new NullAuthenticator(c));
- }
-}
-
-NullAuthenticator::NullAuthenticator(Connection& c) : connection(c), client(c.getOutput()),
- realm(c.getBroker().getOptions().realm) {}
-NullAuthenticator::~NullAuthenticator() {}
-
-void NullAuthenticator::getMechanisms(Array& mechanisms)
-{
- mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("ANONYMOUS")));
-}
-
-void NullAuthenticator::start(const string& mechanism, const string& response)
-{
- if (mechanism == "PLAIN") { // Old behavior
- if (response.size() > 0 && response[0] == (char) 0) {
- string temp = response.substr(1);
- string::size_type i = temp.find((char)0);
- string uid = temp.substr(0, i);
- string pwd = temp.substr(i + 1);
- i = uid.find_last_of(realm);
- if (i == string::npos || i != (uid.size() - 1)) {
- uid = str(format("%1%@%2%") % uid % realm);
- }
- connection.setUserId(uid);
- }
- } else {
- connection.setUserId("anonymous");
- }
- client.tune(framing::CHANNEL_MAX, connection.getFrameMax(), 0, 0);
-}
-
-
-#if HAVE_SASL
-
-CyrusAuthenticator::CyrusAuthenticator(Connection& c) : sasl_conn(0), connection(c), client(c.getOutput())
-{
- init();
-}
-
-void CyrusAuthenticator::init()
-{
- /* Next to the service name, which specifies the
- * /etc/sasl2/<service name>.conf file to read, the realm is
- * currently the most important argument below. When
- * performing authentication the user that is authenticating
- * will be looked up in a specific realm. If none is given
- * then the realm defaults to the hostname, which can cause
- * confusion when the daemon is run on different hosts that
- * may be logically sharing a realm (aka a user domain). This
- * is especially important for SASL PLAIN authentication,
- * which cannot specify a realm for the user that is
- * authenticating.
- */
- const char *realm = connection.getBroker().getOptions().realm.c_str();
- int code = sasl_server_new(BROKER_SASL_NAME, /* Service name */
- NULL, /* Server FQDN, gethostname() */
- realm, /* Authentication realm */
- NULL, /* Local IP, needed for some mechanism */
- NULL, /* Remote IP, needed for some mechanism */
- NULL, /* Callbacks */
- 0, /* Connection flags */
- &sasl_conn);
-
- if (SASL_OK != code) {
- QPID_LOG(info, "SASL: Connection creation failed: [" << code << "] " << sasl_errdetail(sasl_conn));
-
- // TODO: Change this to an exception signaling
- // server error, when one is available
- throw ConnectionForcedException("Unable to perform authentication");
- }
-}
-
-CyrusAuthenticator::~CyrusAuthenticator()
-{
- if (sasl_conn) {
- sasl_dispose(&sasl_conn);
- sasl_conn = 0;
- }
-}
-
-void CyrusAuthenticator::getError(string& error)
-{
- error = string(sasl_errdetail(sasl_conn));
-}
-
-void CyrusAuthenticator::getUid(string& uid)
-{
- int code;
- const void* ptr;
-
- code = sasl_getprop(sasl_conn, SASL_USERNAME, &ptr);
- if (SASL_OK != code)
- return;
-
- uid = string(const_cast<char*>(static_cast<const char*>(ptr)));
-}
-
-void CyrusAuthenticator::getMechanisms(Array& mechanisms)
-{
- const char *separator = " ";
- const char *list;
- unsigned int list_len;
- int count;
-
- int code = sasl_listmech(sasl_conn, NULL,
- "", separator, "",
- &list, &list_len,
- &count);
-
- if (SASL_OK != code) {
- QPID_LOG(info, "SASL: Mechanism listing failed: " << sasl_errdetail(sasl_conn));
-
- // TODO: Change this to an exception signaling
- // server error, when one is available
- throw ConnectionForcedException("Mechanism listing failed");
- } else {
- string mechanism;
- unsigned int start;
- unsigned int end;
-
- QPID_LOG(info, "SASL: Mechanism list: " << list);
-
- end = 0;
- do {
- start = end;
-
- // Seek to end of next mechanism
- while (end < list_len && separator[0] != list[end])
- end++;
-
- // Record the mechanism
- mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value(string(list, start, end - start))));
- end++;
- } while (end < list_len);
- }
-}
-
-void CyrusAuthenticator::start(const string& mechanism, const string& response)
-{
- const char *challenge;
- unsigned int challenge_len;
-
- QPID_LOG(info, "SASL: Starting authentication with mechanism: " << mechanism);
- int code = sasl_server_start(sasl_conn,
- mechanism.c_str(),
- response.c_str(), response.length(),
- &challenge, &challenge_len);
-
- processAuthenticationStep(code, challenge, challenge_len);
-}
-
-void CyrusAuthenticator::step(const string& response)
-{
- const char *challenge;
- unsigned int challenge_len;
-
- int code = sasl_server_step(sasl_conn,
- response.c_str(), response.length(),
- &challenge, &challenge_len);
-
- processAuthenticationStep(code, challenge, challenge_len);
-}
-
-void CyrusAuthenticator::processAuthenticationStep(int code, const char *challenge, unsigned int challenge_len)
-{
- if (SASL_OK == code) {
- const void *uid;
-
- code = sasl_getprop(sasl_conn, SASL_USERNAME, &uid);
- if (SASL_OK != code) {
- QPID_LOG(info, "SASL: Authentication succeeded, username unavailable");
- // TODO: Change this to an exception signaling
- // authentication failure, when one is available
- throw ConnectionForcedException("Authenticated username unavailable");
- }
-
- QPID_LOG(info, "SASL: Authentication succeeded for: "
- << const_cast<char*>(static_cast<const char*>(uid)));
-
- connection.setUserId(const_cast<char*>(static_cast<const char*>(uid)));
-
- client.tune(framing::CHANNEL_MAX, connection.getFrameMax(), 0, 0);
- } else if (SASL_CONTINUE == code) {
- string challenge_str(challenge, challenge_len);
-
- QPID_LOG(debug, "SASL: sending challenge to client");
-
- client.secure(challenge_str);
- } else {
- QPID_LOG(info, "SASL: Authentication failed: " << sasl_errdetail(sasl_conn));
-
- // TODO: Change to more specific exceptions, when they are
- // available
- switch (code) {
- case SASL_NOMECH:
- throw ConnectionForcedException("Unsupported mechanism");
- break;
- case SASL_TRYAGAIN:
- throw ConnectionForcedException("Transient failure, try again");
- break;
- default:
- throw ConnectionForcedException("Authentication failed");
- break;
- }
- }
-}
-#endif
-
-}}