You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2012/10/19 19:15:39 UTC

svn commit: r1400176 - in /qpid/trunk/qpid/cpp/src: CMakeLists.txt Makefile.am qpid/NullSaslServer.cpp qpid/NullSaslServer.h qpid/Sasl.h qpid/SaslFactory.cpp qpid/SaslFactory.h qpid/SaslServer.h

Author: gsim
Date: Fri Oct 19 17:15:38 2012
New Revision: 1400176

URL: http://svn.apache.org/viewvc?rev=1400176&view=rev
Log:
QPID-4368: Define SASL server role that is free from the AMQP 0-10 handshake

Added:
    qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.cpp
    qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.h
      - copied, changed from r1400175, qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h
    qpid/trunk/qpid/cpp/src/qpid/SaslServer.h
      - copied, changed from r1400175, qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h
Modified:
    qpid/trunk/qpid/cpp/src/CMakeLists.txt
    qpid/trunk/qpid/cpp/src/Makefile.am
    qpid/trunk/qpid/cpp/src/qpid/Sasl.h
    qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp
    qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h

Modified: qpid/trunk/qpid/cpp/src/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/CMakeLists.txt?rev=1400176&r1=1400175&r2=1400176&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/CMakeLists.txt (original)
+++ qpid/trunk/qpid/cpp/src/CMakeLists.txt Fri Oct 19 17:15:38 2012
@@ -902,6 +902,7 @@ set (qpidcommon_SOURCES
      qpid/StringUtils.cpp
      qpid/Url.cpp
      qpid/UrlArray.cpp
+     qpid/NullSaslServer.cpp
      qpid/amqp_0_10/SessionHandler.cpp
      qpid/framing/AccumulatedAck.cpp
      qpid/framing/AMQBody.cpp

Modified: qpid/trunk/qpid/cpp/src/Makefile.am
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/Makefile.am?rev=1400176&r1=1400175&r2=1400176&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ qpid/trunk/qpid/cpp/src/Makefile.am Fri Oct 19 17:15:38 2012
@@ -359,6 +359,9 @@ libqpidcommon_la_SOURCES +=			\
   qpid/Sasl.h                                   \
   qpid/SaslFactory.cpp                          \
   qpid/SaslFactory.h                            \
+  qpid/SaslServer.h                             \
+  qpid/NullSaslServer.h                         \
+  qpid/NullSaslServer.cpp                       \
   qpid/Serializer.h				\
   qpid/SessionId.cpp				\
   qpid/SessionState.cpp				\

Added: qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.cpp?rev=1400176&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.cpp Fri Oct 19 17:15:38 2012
@@ -0,0 +1,82 @@
+/*
+ *
+ * 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.
+ *
+ */
+#include "NullSaslServer.h"
+#include "qpid/log/Statement.h"
+#include <assert.h>
+#include <boost/format.hpp>
+
+namespace qpid {
+NullSaslServer::NullSaslServer(const std::string& r) : realm(r) {}
+NullSaslServer::Status NullSaslServer::start(const std::string& mechanism, const std::string* response, std::string& /*challenge*/)
+{
+    if (mechanism == "PLAIN") {
+        if (response) {
+            std::string uid;
+            std::string::size_type i = response->find((char)0);
+            if (i == 0 && response->size() > 1) {
+                //no authorization id; use authentication id
+                i = response->find((char)0, 1);
+                if (i != std::string::npos) uid = response->substr(1, i-1);
+            } else if (i != std::string::npos) {
+                //authorization id is first null delimited field
+                uid = response->substr(0, i);
+            }//else not a valid SASL PLAIN response, throw error?
+            if (!uid.empty()) {
+                //append realm if it has not already been added
+                i = uid.find(realm);
+                if (i == std::string::npos || realm.size() + i < uid.size()) {
+                    uid = boost::str(boost::format("%1%@%2%") % uid % realm);
+                }
+                userid = uid;
+            }
+            return OK;
+        } else {
+            QPID_LOG(error, "Invalid PLAIN request, expected response containing user credentials");
+            return FAIL;
+        }
+    } else if (mechanism == "ANONYMOUS") {
+        userid = "anonymous";
+        return OK;
+    } else {
+        return FAIL;
+    }
+}
+
+NullSaslServer::Status NullSaslServer::step(const std::string* /*response*/, std::string& /*challenge*/)
+{
+    assert(false);
+    return FAIL;
+}
+std::string NullSaslServer::getMechanisms()
+{
+    return std::string("ANONYMOUS PLAIN");
+}
+std::string NullSaslServer::getUserid()
+{
+    return userid;
+}
+
+std::auto_ptr<qpid::sys::SecurityLayer> NullSaslServer::getSecurityLayer(size_t)
+{
+    return std::auto_ptr<qpid::sys::SecurityLayer>();
+}
+
+} // namespace qpid

Copied: qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.h (from r1400175, qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.h?p2=qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.h&p1=qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h&r1=1400175&r2=1400176&rev=1400176&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/NullSaslServer.h Fri Oct 19 17:15:38 2012
@@ -1,5 +1,5 @@
-#ifndef QPID_SASLFACTORY_H
-#define QPID_SASLFACTORY_H
+#ifndef QPID_NULLSASLSERVER_H
+#define QPID_NULLSASLSERVER_H
 
 /*
  *
@@ -10,9 +10,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
@@ -21,27 +21,29 @@
  * under the License.
  *
  */
-#include "qpid/Sasl.h"
-#include "qpid/sys/Mutex.h"
-#include <memory>
+#include "qpid/SaslServer.h"
 
 namespace qpid {
 
 /**
- * Factory for instances of the Sasl interface through which Sasl
- * support is provided to a ConnectionHandler.
+ * Dummy implementation of the SASL server role. This will advertise
+ * ANONYMOUS and PLAIN, and parse the reponse data for those
+ * accordingly, but will make no attempt to actually authenticate
+ * users.
  */
-class SaslFactory
+class NullSaslServer : public SaslServer
 {
   public:
-    QPID_COMMON_EXTERN std::auto_ptr<Sasl> create(const std::string & userName, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf, bool allowInteraction=true );
-    QPID_COMMON_EXTERN static SaslFactory& getInstance();
-    QPID_COMMON_EXTERN ~SaslFactory();
+    NullSaslServer(const std::string& realm);
+    Status start(const std::string& mechanism, const std::string* response, std::string& challenge);
+    Status step(const std::string* response, std::string& challenge);
+    std::string getMechanisms();
+    std::string getUserid();
+    std::auto_ptr<qpid::sys::SecurityLayer> getSecurityLayer(size_t);
   private:
-    SaslFactory();
-    static qpid::sys::Mutex lock;
-    static std::auto_ptr<SaslFactory> instance;
+    std::string realm;
+    std::string userid;
 };
 } // namespace qpid
 
-#endif  /*!QPID_SASLFACTORY_H*/
+#endif  /*!QPID_NULLSASLSERVER_H*/

Modified: qpid/trunk/qpid/cpp/src/qpid/Sasl.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/Sasl.h?rev=1400176&r1=1400175&r2=1400176&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/Sasl.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/Sasl.h Fri Oct 19 17:15:38 2012
@@ -34,7 +34,7 @@ struct SecuritySettings;
 }
 
 /**
- * Interface to SASL support. This class is implemented by platform-specific
+ * Interface to support for the SASL client role. This class is implemented by platform-specific
  * SASL providers.
  */
 class Sasl

Modified: qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp?rev=1400176&r1=1400175&r2=1400176&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp Fri Oct 19 17:15:38 2012
@@ -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
@@ -18,7 +18,9 @@
  * under the License.
  *
  */
-#include "qpid//SaslFactory.h"
+#include "qpid/SaslFactory.h"
+#include "qpid/SaslServer.h"
+#include "qpid/NullSaslServer.h"
 #include <map>
 #include <string.h>
 
@@ -32,6 +34,7 @@ namespace qpid {
 
 //Null implementation
 
+
 SaslFactory::SaslFactory() {}
 
 SaslFactory::~SaslFactory() {}
@@ -50,6 +53,12 @@ std::auto_ptr<Sasl> SaslFactory::create(
     return std::auto_ptr<Sasl>();
 }
 
+std::auto_ptr<SaslServer> SaslFactory::createServer(const std::string& realm, bool /*encryptionRequired*/, const qpid::sys::SecuritySettings&)
+{
+    std::auto_ptr<SaslServer> server(new NullSaslServer(realm));
+    return server;
+}
+
 qpid::sys::Mutex SaslFactory::lock;
 std::auto_ptr<SaslFactory> SaslFactory::instance;
 
@@ -140,6 +149,22 @@ typedef int CallbackProc();
 qpid::sys::Mutex SaslFactory::lock;
 std::auto_ptr<SaslFactory> SaslFactory::instance;
 
+class CyrusSaslServer : public SaslServer
+{
+  public:
+    CyrusSaslServer(const std::string& realm, bool encryptionRequired, const qpid::sys::SecuritySettings& external);
+    ~CyrusSaslServer();
+    Status start(const std::string& mechanism, const std::string* response, std::string& challenge);
+    Status step(const std::string* response, std::string& challenge);
+    std::string getMechanisms();
+    std::string getUserid();
+    std::auto_ptr<qpid::sys::SecurityLayer> getSecurityLayer(size_t);
+  private:
+    std::string realm;
+    std::string userid;
+    sasl_conn_t *sasl_conn;
+};
+
 SaslFactory::SaslFactory()
 {
     sasl_callback_t* callbacks = 0;
@@ -169,6 +194,12 @@ std::auto_ptr<Sasl> SaslFactory::create(
     return sasl;
 }
 
+std::auto_ptr<SaslServer> SaslFactory::createServer(const std::string& realm, bool encryptionRequired, const qpid::sys::SecuritySettings& external)
+{
+    std::auto_ptr<SaslServer> server(new CyrusSaslServer(realm, encryptionRequired, external));
+    return server;
+}
+
 CyrusSasl::CyrusSasl(const std::string & username, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf, bool allowInteraction)
     : conn(0), settings(username, password, serviceName, hostName, minSsf, maxSsf), allowInteraction(allowInteraction)
 {
@@ -382,6 +413,179 @@ std::auto_ptr<SecurityLayer> CyrusSasl::
     return securityLayer;
 }
 
+CyrusSaslServer::CyrusSaslServer(const std::string& r, bool encryptionRequired, const qpid::sys::SecuritySettings& external) : realm(r), sasl_conn(0)
+{
+    int code = sasl_server_new(BROKER_SASL_NAME, /* Service name */
+                               NULL, /* Server FQDN, gethostname() */
+                               realm.c_str(), /* 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(error, "SASL: Connection creation failed: [" << code << "] " << sasl_errdetail(sasl_conn));
+
+        // TODO: Change this to an exception signaling
+        // server error, when one is available
+        throw qpid::framing::ConnectionForcedException("Unable to perform authentication");
+    }
+
+    sasl_security_properties_t secprops;
+
+    //TODO: should the actual SSF values be configurable here?
+    secprops.min_ssf = encryptionRequired ? 10: 0;
+    secprops.max_ssf = 256;
+
+    // If the transport provides encryption, notify the SASL library of
+    // the key length and set the ssf range to prevent double encryption.
+    QPID_LOG(debug, "External ssf=" << external.ssf << " and auth=" << external.authid);
+    sasl_ssf_t external_ssf = (sasl_ssf_t) external.ssf;
+    if (external_ssf) {
+        int result = sasl_setprop(sasl_conn, SASL_SSF_EXTERNAL, &external_ssf);
+        if (result != SASL_OK) {
+            throw framing::InternalErrorException(QPID_MSG("SASL error: unable to set external SSF: " << result));
+        }
+
+        secprops.max_ssf = secprops.min_ssf = 0;
+    }
+
+    QPID_LOG(debug, "min_ssf: " << secprops.min_ssf <<
+             ", max_ssf: " << secprops.max_ssf <<
+             ", external_ssf: " << external_ssf );
+
+    if (!external.authid.empty()) {
+        const char* external_authid = external.authid.c_str();
+        int result = sasl_setprop(sasl_conn, SASL_AUTH_EXTERNAL, external_authid);
+        if (result != SASL_OK) {
+            throw framing::InternalErrorException(QPID_MSG("SASL error: unable to set external auth: " << result));
+        }
+
+        QPID_LOG(debug, "external auth detected and set to " << external_authid);
+    }
+    secprops.maxbufsize = 65535;
+    secprops.property_names = 0;
+    secprops.property_values = 0;
+    secprops.security_flags = 0; /* or SASL_SEC_NOANONYMOUS etc as appropriate */
+    /*
+     * The nodict flag restricts SASL authentication mechanisms
+     * to those that are not susceptible to dictionary attacks.
+     * They are:
+     *   SRP
+     *   PASSDSS-3DES-1
+     *   EXTERNAL
+     */
+    if (external.nodict) secprops.security_flags |= SASL_SEC_NODICTIONARY;
+    int result = sasl_setprop(sasl_conn, SASL_SEC_PROPS, &secprops);
+    if (result != SASL_OK) {
+        throw framing::InternalErrorException(QPID_MSG("SASL error: " << result));
+    }
+}
+
+CyrusSaslServer::~CyrusSaslServer()
+{
+    if (sasl_conn) {
+        sasl_dispose(&sasl_conn);
+        sasl_conn = 0;
+    }
+}
+
+CyrusSaslServer::Status CyrusSaslServer::start(const std::string& mechanism, const std::string* response, std::string& chllng)
+{
+    const char *challenge;
+    unsigned int challenge_len;
+
+    // This should be at same debug level as mech list in getMechanisms().
+    QPID_LOG(info, "SASL: Starting authentication with mechanism: " << mechanism);
+    int code = sasl_server_start(sasl_conn,
+                                 mechanism.c_str(),
+                                 (response ? response->c_str() : 0), (response ? response->size() : 0),
+                                 &challenge, &challenge_len);
+    switch (code) {
+      case SASL_OK:
+        return SaslServer::OK;
+      case SASL_CONTINUE:
+        chllng = std::string(challenge, challenge_len);
+        return SaslServer::CHALLENGE;
+      case SASL_NOMECH:
+        QPID_LOG(info, "Unsupported mechanism: " << mechanism);
+      default:
+        return SaslServer::FAIL;
+    }
+}
+
+CyrusSaslServer::Status CyrusSaslServer::step(const std::string* response, std::string& chllng)
+{
+    const char *challenge;
+    unsigned int challenge_len;
+
+    int code = sasl_server_step(sasl_conn,
+                                (response ? response->c_str() : 0), (response ? response->size() : 0),
+                                &challenge, &challenge_len);
+
+    switch (code) {
+      case SASL_OK:
+        return SaslServer::OK;
+      case SASL_CONTINUE:
+        chllng = std::string(challenge, challenge_len);
+        return SaslServer::CHALLENGE;
+      default:
+        return SaslServer::FAIL;
+    }
+
+}
+std::string CyrusSaslServer::getMechanisms()
+{
+    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 qpid::framing::ConnectionForcedException("Mechanism listing failed");
+    } else {
+        std::string mechanisms(list, list_len);
+        QPID_LOG(info, "SASL: Mechanism list: " << mechanisms);
+        return mechanisms;
+    }
+}
+std::string CyrusSaslServer::getUserid()
+{
+    const void* ptr;
+    int code = sasl_getprop(sasl_conn, SASL_USERNAME, &ptr);
+    if (SASL_OK == code) {
+        userid = static_cast<const char*>(ptr);
+    } else {
+        QPID_LOG(warning, "Failed to retrieve sasl username");
+    }
+    return userid;
+}
+
+std::auto_ptr<SecurityLayer> CyrusSaslServer::getSecurityLayer(size_t maxFrameSize)
+{
+    const void* value(0);
+    int result = sasl_getprop(sasl_conn, SASL_SSF, &value);
+    if (result != SASL_OK) {
+        throw framing::InternalErrorException(QPID_MSG("SASL error: " << sasl_errdetail(sasl_conn)));
+    }
+    uint ssf = *(reinterpret_cast<const unsigned*>(value));
+    std::auto_ptr<SecurityLayer> securityLayer;
+    if (ssf) {
+        securityLayer = std::auto_ptr<SecurityLayer>(new CyrusSecurityLayer(sasl_conn, maxFrameSize, ssf));
+    }
+    return securityLayer;
+}
+
 int getUserFromSettings(void* context, int /*id*/, const char** result, unsigned* /*len*/)
 {
     if (context) {
@@ -428,7 +632,6 @@ int getPasswordFromSettings(sasl_conn_t*
         return SASL_FAIL;
     }
 }
-
 } // namespace qpid
 
 #endif

Modified: qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h?rev=1400176&r1=1400175&r2=1400176&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h Fri Oct 19 17:15:38 2012
@@ -26,7 +26,7 @@
 #include <memory>
 
 namespace qpid {
-
+class SaslServer;
 /**
  * Factory for instances of the Sasl interface through which Sasl
  * support is provided to a ConnectionHandler.
@@ -35,6 +35,7 @@ class SaslFactory
 {
   public:
     QPID_COMMON_EXTERN std::auto_ptr<Sasl> create(const std::string & userName, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf, bool allowInteraction=true );
+    QPID_COMMON_EXTERN std::auto_ptr<SaslServer> createServer(const std::string& realm, bool encryptionRequired, const qpid::sys::SecuritySettings&);
     QPID_COMMON_EXTERN static SaslFactory& getInstance();
     QPID_COMMON_EXTERN ~SaslFactory();
   private:

Copied: qpid/trunk/qpid/cpp/src/qpid/SaslServer.h (from r1400175, qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/SaslServer.h?p2=qpid/trunk/qpid/cpp/src/qpid/SaslServer.h&p1=qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h&r1=1400175&r2=1400176&rev=1400176&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/SaslServer.h Fri Oct 19 17:15:38 2012
@@ -1,5 +1,5 @@
-#ifndef QPID_SASLFACTORY_H
-#define QPID_SASLFACTORY_H
+#ifndef QPID_SASLSERVER_H
+#define QPID_SASLSERVER_H
 
 /*
  *
@@ -10,9 +10,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
@@ -21,27 +21,28 @@
  * under the License.
  *
  */
-#include "qpid/Sasl.h"
-#include "qpid/sys/Mutex.h"
+#include <string>
 #include <memory>
 
 namespace qpid {
-
+namespace sys {
+class SecurityLayer;
+}
 /**
- * Factory for instances of the Sasl interface through which Sasl
- * support is provided to a ConnectionHandler.
+ *
  */
-class SaslFactory
+class SaslServer
 {
   public:
-    QPID_COMMON_EXTERN std::auto_ptr<Sasl> create(const std::string & userName, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf, bool allowInteraction=true );
-    QPID_COMMON_EXTERN static SaslFactory& getInstance();
-    QPID_COMMON_EXTERN ~SaslFactory();
+    typedef enum {OK, FAIL, CHALLENGE} Status;
+    virtual ~SaslServer() {}
+    virtual Status start(const std::string& mechanism, const std::string* response, std::string& challenge) = 0;
+    virtual Status step(const std::string* response, std::string& challenge) = 0;
+    virtual std::string getMechanisms() = 0;
+    virtual std::string getUserid() = 0;
+    virtual std::auto_ptr<qpid::sys::SecurityLayer> getSecurityLayer(size_t) = 0;
   private:
-    SaslFactory();
-    static qpid::sys::Mutex lock;
-    static std::auto_ptr<SaslFactory> instance;
 };
 } // namespace qpid
 
-#endif  /*!QPID_SASLFACTORY_H*/
+#endif  /*!QPID_SASLSERVER_H*/



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org