Author: gsim
Date: Mon Jul  7 19:44:42 2014
New Revision: 1608578

URL: http://svn.apache.org/r1608578
Log:
QPID-5882: fix authentication failure on 1.0 codepath

Modified:
    qpid/trunk/qpid/cpp/include/qpid/messaging/exceptions.h
    qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp
    qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp
    qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.h
    qpid/trunk/qpid/cpp/src/qpid/messaging/exceptions.cpp

Modified: qpid/trunk/qpid/cpp/include/qpid/messaging/exceptions.h
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/include/qpid/messaging/exceptions.h?rev=1608578&r1=1608577&r2=1608578&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/include/qpid/messaging/exceptions.h (original)
+++ qpid/trunk/qpid/cpp/include/qpid/messaging/exceptions.h Mon Jul  7 19:44:42 
2014
@@ -208,6 +208,11 @@ struct QPID_MESSAGING_CLASS_EXTERN Conne
     QPID_MESSAGING_EXTERN ConnectionError(const std::string&);
 };
 
+struct QPID_MESSAGING_CLASS_EXTERN AuthenticationFailure : public 
ConnectionError
+{
+    QPID_MESSAGING_EXTERN AuthenticationFailure(const std::string&);
+};
+
 /**
  * Thrown to indicate loss of underlying connection. When
  * auto-reconnect is used this will be caught by the library and used

Modified: qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp?rev=1608578&r1=1608577&r2=1608578&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp Mon Jul  
7 19:44:42 2014
@@ -851,13 +851,17 @@ std::size_t ConnectionContext::decode(co
 {
     qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
     size_t decoded = 0;
-    if (sasl.get() && !sasl->authenticated()) {
-        decoded = sasl->decode(buffer, size);
-        if (!sasl->authenticated()) return decoded;
-    }
-    if (decoded < size) {
-        if (sasl.get() && sasl->getSecurityLayer()) decoded += 
sasl->getSecurityLayer()->decode(buffer+decoded, size-decoded);
-        else decoded += decodePlain(buffer+decoded, size-decoded);
+    try {
+        if (sasl.get() && !sasl->authenticated()) {
+            decoded = sasl->decode(buffer, size);
+            if (!sasl->authenticated()) return decoded;
+        }
+        if (decoded < size) {
+            if (sasl.get() && sasl->getSecurityLayer()) decoded += 
sasl->getSecurityLayer()->decode(buffer+decoded, size-decoded);
+            else decoded += decodePlain(buffer+decoded, size-decoded);
+        }
+    } catch (const AuthenticationFailure&) {
+        transport->close();
     }
     return decoded;
 }
@@ -865,13 +869,17 @@ std::size_t ConnectionContext::encode(ch
 {
     qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
     size_t encoded = 0;
-    if (sasl.get() && sasl->canEncode()) {
-        encoded += sasl->encode(buffer, size);
-        if (!sasl->authenticated()) return encoded;
-    }
-    if (encoded < size) {
-        if (sasl.get() && sasl->getSecurityLayer()) encoded += 
sasl->getSecurityLayer()->encode(buffer+encoded, size-encoded);
-        else encoded += encodePlain(buffer+encoded, size-encoded);
+    try {
+        if (sasl.get() && sasl->canEncode()) {
+            encoded += sasl->encode(buffer, size);
+            if (!sasl->authenticated()) return encoded;
+        }
+        if (encoded < size) {
+            if (sasl.get() && sasl->getSecurityLayer()) encoded += 
sasl->getSecurityLayer()->encode(buffer+encoded, size-encoded);
+            else encoded += encodePlain(buffer+encoded, size-encoded);
+        }
+    } catch (const AuthenticationFailure&) {
+        transport->close();
     }
     return encoded;
 }
@@ -879,9 +887,14 @@ bool ConnectionContext::canEncode()
 {
     qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
     if (sasl.get()) {
-        if (sasl->canEncode()) return true;
-        else if (!sasl->authenticated()) return false;
-        else if (sasl->getSecurityLayer()) return 
sasl->getSecurityLayer()->canEncode();
+        try {
+            if (sasl->canEncode()) return true;
+            else if (!sasl->authenticated()) return false;
+            else if (sasl->getSecurityLayer()) return 
sasl->getSecurityLayer()->canEncode();
+        } catch (const AuthenticationFailure&) {
+            transport->close();
+            return false;
+        }
     }
     return canEncodePlain();
 }

Modified: qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp?rev=1608578&r1=1608577&r2=1608578&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp Mon Jul  7 19:44:42 
2014
@@ -93,21 +93,29 @@ void Sasl::mechanisms(const std::string&
         mechanisms = offered;
     }
 
-    if (sasl->start(mechanisms, response, 
context.getTransportSecuritySettings())) {
-        init(sasl->getMechanism(), &response, hostname.size() ? &hostname : 0);
-    } else {
-        init(sasl->getMechanism(), 0, hostname.size() ? &hostname : 0);
+    try {
+        if (sasl->start(mechanisms, response, 
context.getTransportSecuritySettings())) {
+            init(sasl->getMechanism(), &response, hostname.size() ? &hostname 
: 0);
+        } else {
+            init(sasl->getMechanism(), 0, hostname.size() ? &hostname : 0);
+        }
+        haveOutput = true;
+        context.activateOutput();
+    } catch (const std::exception& e) {
+        failed(e.what());
     }
-    haveOutput = true;
-    context.activateOutput();
 }
 void Sasl::challenge(const std::string& challenge)
 {
     QPID_LOG_CAT(debug, protocol, id << " Received SASL-CHALLENGE(" << 
challenge.size() << " bytes)");
-    std::string r = sasl->step(challenge);
-    response(&r);
-    haveOutput = true;
-    context.activateOutput();
+    try {
+        std::string r = sasl->step(challenge);
+        response(&r);
+        haveOutput = true;
+        context.activateOutput();
+    } catch (const std::exception& e) {
+        failed(e.what());
+    }
 }
 namespace {
 const std::string EMPTY;
@@ -115,8 +123,12 @@ const std::string EMPTY;
 void Sasl::challenge()
 {
     QPID_LOG_CAT(debug, protocol, id << " Received SASL-CHALLENGE(null)");
-    std::string r = sasl->step(EMPTY);
-    response(&r);
+    try {
+        std::string r = sasl->step(EMPTY);
+        response(&r);
+    } catch (const std::exception& e) {
+        failed(e.what());
+    }
 }
 void Sasl::outcome(uint8_t result, const std::string& extra)
 {
@@ -146,15 +158,26 @@ qpid::sys::Codec* Sasl::getSecurityLayer
     return securityLayer.get();
 }
 
+namespace {
+const std::string DEFAULT_ERROR("Authentication failed");
+}
+
 bool Sasl::authenticated()
 {
     switch (state) {
       case SUCCEEDED: return true;
-      case FAILED: throw qpid::messaging::UnauthorizedAccess("Failed to 
authenticate");
+      case FAILED: throw qpid::messaging::AuthenticationFailure(error.size() ? 
error : DEFAULT_ERROR);
       case NONE: default: return false;
     }
 }
 
+void Sasl::failed(const std::string& text)
+{
+    QPID_LOG_CAT(info, client, id << " Failure during authentication: " << 
text);
+    error = text;
+    state = FAILED;
+}
+
 std::string Sasl::getAuthenticatedUsername()
 {
     return sasl->getUserId();

Modified: qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.h
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.h?rev=1608578&r1=1608577&r2=1608578&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/messaging/amqp/Sasl.h Mon Jul  7 19:44:42 2014
@@ -61,12 +61,14 @@ class Sasl : public qpid::sys::Codec, qp
         NONE, FAILED, SUCCEEDED
     } state;
     std::auto_ptr<qpid::sys::SecurityLayer> securityLayer;
+    std::string error;
 
     void mechanisms(const std::string&);
     void challenge(const std::string&);
     void challenge(); //null != empty string
     void outcome(uint8_t result, const std::string&);
     void outcome(uint8_t result);
+    void failed(const std::string&);
   protected:
     bool stopReading();
 };

Modified: qpid/trunk/qpid/cpp/src/qpid/messaging/exceptions.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/messaging/exceptions.cpp?rev=1608578&r1=1608577&r2=1608578&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/messaging/exceptions.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/messaging/exceptions.cpp Mon Jul  7 19:44:42 
2014
@@ -56,6 +56,7 @@ TransactionAborted::TransactionAborted(c
 UnauthorizedAccess::UnauthorizedAccess(const std::string& msg) : 
SessionError(msg) {}
 
 ConnectionError::ConnectionError(const std::string& msg) : 
MessagingException(msg) {}
+AuthenticationFailure::AuthenticationFailure(const std::string& msg) : 
ConnectionError(msg) {}
 
 TransportFailure::TransportFailure(const std::string& msg) : 
MessagingException(msg) {}
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to