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/11/28 15:14:05 UTC

svn commit: r1414712 - in /qpid/branches/0.20/qpid/cpp/src/qpid: amqp/ broker/amqp/ messaging/amqp/

Author: gsim
Date: Wed Nov 28 14:14:03 2012
New Revision: 1414712

URL: http://svn.apache.org/viewvc?rev=1414712&view=rev
Log:
QPID-4477: make sasl logic a bit smarter, to handle case where we transition input to tunnelled layer while output still has work for sasl

Modified:
    qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.cpp
    qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.h
    qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Sasl.cpp
    qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.cpp
    qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.h
    qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Translation.cpp
    qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp
    qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.h
    qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp
    qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.h

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.cpp?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.cpp (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.cpp Wed Nov 28 14:14:03 2012
@@ -540,5 +540,6 @@ CharSequence Decoder::readRawUuid()
 }
 
 size_t Decoder::getPosition() const { return position; }
+size_t Decoder::getSize() const { return size; }
 void Decoder::resetSize(size_t s) { size = s; }
 }} // namespace qpid::amqp

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.h
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.h?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.h (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Decoder.h Wed Nov 28 14:14:03 2012
@@ -71,6 +71,7 @@ class Decoder
     QPID_COMMON_EXTERN void advance(size_t);
     QPID_COMMON_EXTERN size_t getPosition() const;
     QPID_COMMON_EXTERN void resetSize(size_t size);
+    QPID_COMMON_EXTERN size_t getSize() const;
 
   private:
     const char* const start;

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Sasl.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Sasl.cpp?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Sasl.cpp (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/amqp/Sasl.cpp Wed Nov 28 14:14:03 2012
@@ -58,29 +58,35 @@ void Sasl::endFrame(void* frame)
 
 std::size_t Sasl::read(const char* data, size_t available)
 {
-    Decoder decoder(data, available);
-    //read frame-header
-    uint32_t frameSize = decoder.readUInt();
-    QPID_LOG(trace, "Reading SASL frame of size " << frameSize);
-    decoder.resetSize(frameSize);
-    uint8_t dataOffset = decoder.readUByte();
-    uint8_t frameType = decoder.readUByte();
-    if (frameType != 0x01) {
-        QPID_LOG(error, "Expected SASL frame; got type " << frameType);
-    }
-    uint16_t ignored = decoder.readUShort();
-    if (ignored) {
-        QPID_LOG(info, "Got non null bytes at end of SASL frame header");
-    }
+    size_t consumed = 0;
+    while (available - consumed > 4/*framesize*/) {
+        Decoder decoder(data+consumed, available-consumed);
+        //read frame-header
+        uint32_t frameSize = decoder.readUInt();
+        if (frameSize > decoder.getSize()) break;//don't have all the data for this frame yet
+
+        QPID_LOG(trace, "Reading SASL frame of size " << frameSize);
+        decoder.resetSize(frameSize);
+        uint8_t dataOffset = decoder.readUByte();
+        uint8_t frameType = decoder.readUByte();
+        if (frameType != 0x01) {
+            QPID_LOG(error, "Expected SASL frame; got type " << frameType);
+        }
+        uint16_t ignored = decoder.readUShort();
+        if (ignored) {
+            QPID_LOG(info, "Got non null bytes at end of SASL frame header");
+        }
 
-    //body is at offset 4*dataOffset from the start
-    size_t skip = dataOffset*4 - 8;
-    if (skip) {
-        QPID_LOG(info, "Offset for sasl frame was not as expected");
-        decoder.advance(skip);
+        //body is at offset 4*dataOffset from the start
+        size_t skip = dataOffset*4 - 8;
+        if (skip) {
+            QPID_LOG(info, "Offset for sasl frame was not as expected");
+            decoder.advance(skip);
+        }
+        decoder.read(*this);
+        consumed += decoder.getPosition();
     }
-    decoder.read(*this);
-    return decoder.getPosition();
+    return consumed;
 }
 
 std::size_t Sasl::write(char* data, size_t size)

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.cpp?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.cpp (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.cpp Wed Nov 28 14:14:03 2012
@@ -94,6 +94,7 @@ Message::Message(size_t size) : data(siz
 
     applicationProperties.init();
     body.init();
+    footer.init();
 }
 char* Message::getData() { return &data[0]; }
 const char* Message::getData() const { return &data[0]; }
@@ -140,6 +141,10 @@ qpid::amqp::CharSequence Message::getBod
 {
     return body;
 }
+qpid::amqp::CharSequence Message::getFooter() const
+{
+    return footer;
+}
 
 void Message::scan()
 {

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.h
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.h?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.h (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Message.h Wed Nov 28 14:14:03 2012
@@ -63,6 +63,7 @@ class Message : public qpid::broker::Mes
     qpid::amqp::CharSequence getApplicationProperties() const;
     qpid::amqp::CharSequence getBareMessage() const;
     qpid::amqp::CharSequence getBody() const;
+    qpid::amqp::CharSequence getFooter() const;
 
     Message(size_t size);
     char* getData();

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Translation.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Translation.cpp?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Translation.cpp (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/broker/amqp/Translation.cpp Wed Nov 28 14:14:03 2012
@@ -215,6 +215,9 @@ void Translation::write(Outgoing& out)
         //write bare message
         qpid::amqp::CharSequence bareMessage = message->getBareMessage();
         if (bareMessage.size) out.write(bareMessage.data, bareMessage.size);
+        //write footer:
+        qpid::amqp::CharSequence footer = message->getFooter();
+        if (footer.size) out.write(footer.data, footer.size);
     } else {
         const qpid::broker::amqp_0_10::MessageTransfer* transfer = dynamic_cast<const qpid::broker::amqp_0_10::MessageTransfer*>(&original.getEncoding());
         if (transfer) {

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.cpp Wed Nov 28 14:14:03 2012
@@ -53,7 +53,8 @@ ConnectionContext::ConnectionContext(con
       writeHeader(false),
       readHeader(false),
       haveOutput(false),
-      state(DISCONNECTED)
+      state(DISCONNECTED),
+      codecSwitch(*this)
 {
     if (pn_transport_bind(engine, connection)) {
         //error
@@ -563,13 +564,48 @@ bool ConnectionContext::useSasl()
 
 qpid::sys::Codec& ConnectionContext::getCodec()
 {
-    qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
-    if (sasl.get()) {
-        qpid::sys::Codec* c = sasl->getCodec();
-        if (c) return *c;
-        lock.notifyAll();
+    return codecSwitch;
+}
+
+ConnectionContext::CodecSwitch::CodecSwitch(ConnectionContext& p) : parent(p) {}
+std::size_t ConnectionContext::CodecSwitch::decode(const char* buffer, std::size_t size)
+{
+    qpid::sys::ScopedLock<qpid::sys::Monitor> l(parent.lock);
+    size_t decoded = 0;
+    if (parent.sasl.get() && !parent.sasl->authenticated()) {
+        decoded = parent.sasl->decode(buffer, size);
+        if (!parent.sasl->authenticated()) return decoded;
     }
-    return *this;
+    if (decoded < size) {
+        if (parent.sasl.get() && parent.sasl->getSecurityLayer()) decoded += parent.sasl->getSecurityLayer()->decode(buffer+decoded, size-decoded);
+        else decoded += parent.decode(buffer+decoded, size-decoded);
+    }
+    return decoded;
 }
+std::size_t ConnectionContext::CodecSwitch::encode(char* buffer, std::size_t size)
+{
+    qpid::sys::ScopedLock<qpid::sys::Monitor> l(parent.lock);
+    size_t encoded = 0;
+    if (parent.sasl.get() && parent.sasl->canEncode()) {
+        encoded += parent.sasl->encode(buffer, size);
+        if (!parent.sasl->authenticated()) return encoded;
+    }
+    if (encoded < size) {
+        if (parent.sasl.get() && parent.sasl->getSecurityLayer()) encoded += parent.sasl->getSecurityLayer()->encode(buffer+encoded, size-encoded);
+        else encoded += parent.encode(buffer+encoded, size-encoded);
+    }
+    return encoded;
+}
+bool ConnectionContext::CodecSwitch::canEncode()
+{
+    qpid::sys::ScopedLock<qpid::sys::Monitor> l(parent.lock);
+    if (parent.sasl.get()) {
+        if (parent.sasl->canEncode()) return true;
+        else if (!parent.sasl->authenticated()) return false;
+        else if (parent.sasl->getSecurityLayer()) return parent.sasl->getSecurityLayer()->canEncode();
+    }
+    return parent.canEncode();
+}
+
 
 }}} // namespace qpid::messaging::amqp

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.h
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.h?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.h (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/ConnectionContext.h Wed Nov 28 14:14:03 2012
@@ -123,6 +123,17 @@ class ConnectionContext : public qpid::s
         CONNECTED
     } state;
     std::auto_ptr<Sasl> sasl;
+    class CodecSwitch : public qpid::sys::Codec
+    {
+      public:
+        CodecSwitch(ConnectionContext&);
+        std::size_t decode(const char* buffer, std::size_t size);
+        std::size_t encode(char* buffer, std::size_t size);
+        bool canEncode();
+      private:
+        ConnectionContext& parent;
+    };
+    CodecSwitch codecSwitch;
 
     void wait();
     void wakeupDriver();

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.cpp Wed Nov 28 14:14:03 2012
@@ -58,7 +58,7 @@ std::size_t Sasl::encode(char* buffer, s
          encoded += writeProtocolHeader(buffer, size);
          writeHeader = !encoded;
     }
-    if (state == NONE && encoded < size) {
+    if (encoded < size) {
         encoded += write(buffer + encoded, size - encoded);
     }
     haveOutput = (encoded == size);
@@ -135,14 +135,9 @@ void Sasl::outcome(uint8_t result)
     context.activateOutput();
 }
 
-qpid::sys::Codec* Sasl::getCodec()
+qpid::sys::Codec* Sasl::getSecurityLayer()
 {
-    switch (state) {
-      case SUCCEEDED: return static_cast<qpid::sys::Codec*>(securityLayer.get());
-      case FAILED: throw qpid::messaging::UnauthorizedAccess("Failed to authenticate");
-      case NONE: return static_cast<qpid::sys::Codec*>(this);
-    }
-    return 0;
+    return securityLayer.get();
 }
 
 bool Sasl::authenticated()

Modified: qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.h
URL: http://svn.apache.org/viewvc/qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.h?rev=1414712&r1=1414711&r2=1414712&view=diff
==============================================================================
--- qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.h (original)
+++ qpid/branches/0.20/qpid/cpp/src/qpid/messaging/amqp/Sasl.h Wed Nov 28 14:14:03 2012
@@ -47,7 +47,7 @@ class Sasl : public qpid::sys::Codec, qp
     bool canEncode();
 
     bool authenticated();
-    qpid::sys::Codec* getCodec();
+    qpid::sys::Codec* getSecurityLayer();
     std::string getAuthenticatedUsername();
  private:
     ConnectionContext& context;



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