Author: rhs
Date: Thu Oct  4 11:08:33 2012
New Revision: 1393985

URL: http://svn.apache.org/viewvc?rev=1393985&view=rev
Log:
applied patch from PROTON-56 and fixed challenge/response to work properly

Modified:
    qpid/proton/trunk/proton-c/bindings/python/proton.py
    qpid/proton/trunk/proton-c/bindings/python/python.i
    qpid/proton/trunk/proton-c/src/sasl/sasl.c
    qpid/proton/trunk/tests/proton_tests/sasl.py

Modified: qpid/proton/trunk/proton-c/bindings/python/proton.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/python/proton.py?rev=1393985&r1=1393984&r2=1393985&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/python/proton.py (original)
+++ qpid/proton/trunk/proton-c/bindings/python/proton.py Thu Oct  4 11:08:33 
2012
@@ -1526,6 +1526,9 @@ class Transport(object):
     else:
       return self._check(n)
 
+class SASLException(TransportException):
+  pass
+
 class SASL(object):
 
   OK = PN_SASL_OK
@@ -1534,6 +1537,13 @@ class SASL(object):
   def __init__(self, transport):
     self._sasl = pn_sasl(transport._trans)
 
+  def _check(self, err):
+    if err < 0:
+      exc = EXCEPTIONS.get(err, SASLException)
+      raise exc("[%s]" % (err))
+    else:
+      return err
+
   def mechanisms(self, mechs):
     pn_sasl_mechanisms(self._sasl, mechs)
 
@@ -1543,6 +1553,25 @@ class SASL(object):
   def server(self):
     pn_sasl_server(self._sasl)
 
+  def plain(self, user, password):
+    pn_sasl_plain(self._sasl, user, password)
+
+  def send(self, data):
+    self._check(pn_sasl_send(self._sasl, data, len(data)))
+
+  def recv(self):
+    sz = 16
+    while True:
+      n, data = pn_sasl_recv(self._sasl, sz)
+      if n == PN_OVERFLOW:
+        sz *= 2
+        continue
+      elif n == PN_EOS:
+        return None
+      else:
+        self._check(n)
+        return data
+
   @property
   def outcome(self):
     outcome = pn_sasl_outcome(self._sasl)

Modified: qpid/proton/trunk/proton-c/bindings/python/python.i
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/python/python.i?rev=1393985&r1=1393984&r2=1393985&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/python/python.i (original)
+++ qpid/proton/trunk/proton-c/bindings/python/python.i Thu Oct  4 11:08:33 2012
@@ -375,5 +375,19 @@ ssize_t pn_data_decode(pn_data_t *data, 
 %}
 %ignore pn_data_encode;
 
+%rename(pn_sasl_recv) wrap_pn_sasl_recv;
+%inline %{
+  int wrap_pn_sasl_recv(pn_sasl_t *sasl, char *OUTPUT, size_t *OUTPUT_SIZE) {
+    ssize_t sz = pn_sasl_recv(sasl, OUTPUT, *OUTPUT_SIZE);
+    if (sz >= 0) {
+      *OUTPUT_SIZE = sz;
+    } else {
+      *OUTPUT_SIZE = 0;
+    }
+    return sz;
+  }
+%}
+%ignore pn_sasl_recv;
+
 
 %include "proton/cproton.i"

Modified: qpid/proton/trunk/proton-c/src/sasl/sasl.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/sasl/sasl.c?rev=1393985&r1=1393984&r2=1393985&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/sasl/sasl.c (original)
+++ qpid/proton/trunk/proton-c/src/sasl/sasl.c Thu Oct  4 11:08:33 2012
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <proton/buffer.h>
 #include <proton/framing.h>
 #include <proton/engine.h> // XXX: just needed for PN_EOS
 #include <proton/sasl.h>
@@ -38,8 +39,8 @@ struct pn_sasl_t {
   bool configured;
   char *mechanisms;
   char *remote_mechanisms;
-  pn_bytes_t send_data;
-  pn_bytes_t recv_data;
+  pn_buffer_t *send_data;
+  pn_buffer_t *recv_data;
   pn_sasl_outcome_t outcome;
   bool sent_init;
   bool rcvd_init;
@@ -70,8 +71,8 @@ pn_sasl_t *pn_sasl(pn_transport_t *trans
     sasl->configured = false;
     sasl->mechanisms = NULL;
     sasl->remote_mechanisms = NULL;
-    sasl->send_data = (pn_bytes_t) {0, NULL};
-    sasl->recv_data = (pn_bytes_t) {0, NULL};
+    sasl->send_data = pn_buffer(16);
+    sasl->recv_data = pn_buffer(16);
     sasl->outcome = PN_SASL_NONE;
     sasl->sent_init = false;
     sasl->rcvd_init = false;
@@ -117,11 +118,12 @@ const char *pn_sasl_remote_mechanisms(pn
 ssize_t pn_sasl_send(pn_sasl_t *sasl, const char *bytes, size_t size)
 {
   if (sasl) {
-    if (sasl->send_data.start) {
+    if (pn_buffer_size(sasl->send_data)) {
       // XXX: need better error
       return PN_STATE_ERR;
     }
-    sasl->send_data = pn_bytes_dup(size, bytes);
+    int err = pn_buffer_append(sasl->send_data, bytes, size);
+    if (err) return err;
     return size;
   } else {
     return PN_ARG_ERR;
@@ -130,8 +132,8 @@ ssize_t pn_sasl_send(pn_sasl_t *sasl, co
 
 size_t pn_sasl_pending(pn_sasl_t *sasl)
 {
-  if (sasl && sasl->recv_data.start) {
-    return sasl->recv_data.size;
+  if (sasl && pn_buffer_size(sasl->recv_data)) {
+    return pn_buffer_size(sasl->recv_data);
   } else {
     return 0;
   }
@@ -141,12 +143,12 @@ ssize_t pn_sasl_recv(pn_sasl_t *sasl, ch
 {
   if (!sasl) return PN_ARG_ERR;
 
-  if (sasl->recv_data.start) {
-    if (sasl->recv_data.size > size) return PN_OVERFLOW;
-    memmove(bytes, sasl->recv_data.start, sasl->recv_data.size);
-    free(sasl->recv_data.start);
-    sasl->recv_data = pn_bytes(0, NULL);
-    return sasl->recv_data.size;
+  size_t bsize = pn_buffer_size(sasl->recv_data);
+  if (bsize) {
+    if (bsize > size) return PN_OVERFLOW;
+    pn_buffer_get(sasl->recv_data, 0, bsize, bytes);
+    pn_buffer_clear(sasl->recv_data);
+    return bsize;
   } else {
     return PN_EOS;
   }
@@ -211,8 +213,8 @@ void pn_sasl_free(pn_sasl_t *sasl)
   if (sasl) {
     free(sasl->mechanisms);
     free(sasl->remote_mechanisms);
-    free(sasl->send_data.start);
-    free(sasl->recv_data.start);
+    pn_buffer_free(sasl->send_data);
+    pn_buffer_free(sasl->recv_data);
     pn_dispatcher_free(sasl->disp);
     free(sasl);
   }
@@ -220,12 +222,10 @@ void pn_sasl_free(pn_sasl_t *sasl)
 
 void pn_client_init(pn_sasl_t *sasl)
 {
+  pn_bytes_t bytes = pn_buffer_bytes(sasl->send_data);
   pn_post_frame(sasl->disp, 0, "DL[sz]", SASL_INIT, sasl->mechanisms,
-                sasl->send_data.size, sasl->send_data.start);
-  if (sasl->send_data.start) {
-    free(sasl->send_data.start);
-    sasl->send_data = pn_bytes(0, NULL);
-  }
+                bytes.size, bytes.start);
+  pn_buffer_clear(sasl->send_data);
 }
 
 void pn_server_init(pn_sasl_t *sasl)
@@ -277,6 +277,13 @@ void pn_sasl_process(pn_sasl_t *sasl)
     sasl->sent_init = true;
   }
 
+  if (pn_buffer_size(sasl->send_data)) {
+    pn_bytes_t bytes = pn_buffer_bytes(sasl->send_data);
+    pn_post_frame(sasl->disp, 0, "DL[z]", sasl->client ? SASL_RESPONSE : 
SASL_CHALLENGE,
+                  bytes.size, bytes.start);
+    pn_buffer_clear(sasl->send_data);
+  }
+
   if (!sasl->client && sasl->outcome != PN_SASL_NONE && !sasl->sent_done) {
     pn_server_done(sasl);
     sasl->sent_done = true;
@@ -339,7 +346,7 @@ int pn_do_init(pn_dispatcher_t *disp)
   int err = pn_scan_args(disp, "D.[sz]", &mech, &recv);
   if (err) return err;
   sasl->remote_mechanisms = pn_strndup(mech.start, mech.size);
-  sasl->recv_data = pn_bytes_dup(recv.size, recv.start);
+  pn_buffer_append(sasl->recv_data, recv.start, recv.size);
   sasl->rcvd_init = true;
   return 0;
 }
@@ -351,14 +358,24 @@ int pn_do_mechanisms(pn_dispatcher_t *di
   return 0;
 }
 
+int pn_do_recv(pn_dispatcher_t *disp)
+{
+  pn_sasl_t *sasl = disp->context;
+  pn_bytes_t recv;
+  int err = pn_scan_args(disp, "D.[z]", &recv);
+  if (err) return err;
+  pn_buffer_append(sasl->recv_data, recv.start, recv.size);
+  return 0;
+}
+
 int pn_do_challenge(pn_dispatcher_t *disp)
 {
-  return PN_ERR;
+  return pn_do_recv(disp);
 }
 
-int pn_do_response(pn_dispatcher_t *resp)
+int pn_do_response(pn_dispatcher_t *disp)
 {
-  return PN_ERR;
+  return pn_do_recv(disp);
 }
 
 int pn_do_outcome(pn_dispatcher_t *disp)

Modified: qpid/proton/trunk/tests/proton_tests/sasl.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/proton_tests/sasl.py?rev=1393985&r1=1393984&r2=1393985&view=diff
==============================================================================
--- qpid/proton/trunk/tests/proton_tests/sasl.py (original)
+++ qpid/proton/trunk/tests/proton_tests/sasl.py Thu Oct  4 11:08:33 2012
@@ -25,29 +25,62 @@ class Test(common.Test):
 
 class SaslTest(Test):
 
-  def testPipelined(self):
-    cli = Transport()
-    cli_auth = SASL(cli)
-    cli_auth.mechanisms("ANONYMOUS")
-    cli_auth.client()
-
-    assert cli_auth.outcome is None
-
-    srv = Transport()
-    srv_auth = SASL(srv)
-    srv_auth.mechanisms("ANONYMOUS")
-    srv_auth.server()
-    srv_auth.done(SASL.OK)
+  def setup(self):
+    self.t1 = Transport()
+    self.s1 = SASL(self.t1)
+    self.t2 = Transport()
+    self.s2 = SASL(self.t2)
+
+  def pump(self):
+    while True:
+      out1 = self.t1.output(1024)
+      out2 = self.t2.output(1024)
+      if out1: self.t2.input(out1)
+      if out2: self.t1.input(out2)
+      if not out1 and not out2: break
 
-    cli_out = cli.output(1024)
-    srv_out = srv.output(1024)
-
-    n = srv.input(cli_out)
-    assert n == len(cli_out), (n, cli_out)
-
-    assert cli_auth.outcome is None
+  def testPipelined(self):
+    self.s1.mechanisms("ANONYMOUS")
+    self.s1.client()
 
-    n = cli.input(srv_out)
-    assert n == len(srv_out), n
+    assert self.s1.outcome is None
 
-    assert cli_auth.outcome == SASL.OK
+    self.s2.mechanisms("ANONYMOUS")
+    self.s2.server()
+    self.s2.done(SASL.OK)
+
+    out1 = self.t1.output(1024)
+    out2 = self.t2.output(1024)
+
+    n = self.t2.input(out1)
+    assert n == len(out1), (n, out1)
+
+    assert self.s1.outcome is None
+
+    n = self.t1.input(out2)
+    assert n == len(out2), (n, out2)
+
+    assert self.s2.outcome == SASL.OK
+
+  def testChallengeResponse(self):
+    self.s1.mechanisms("FAKE_MECH")
+    self.s1.client()
+    self.s2.mechanisms("FAKE_MECH")
+    self.s2.server()
+    self.pump()
+    challenge = "Who goes there!"
+    self.s2.send(challenge)
+    self.pump()
+    ch = self.s1.recv()
+    assert ch == challenge, ch
+
+    response = "It is I, Secundus!"
+    self.s1.send(response)
+    self.pump()
+    re = self.s2.recv()
+    assert re == response, re
+
+  def testInitialResponse(self):
+    self.s1.plain("secundus", "trustno1")
+    self.pump()
+    assert self.s2.recv() == "\x00secundus\x00trustno1"



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

Reply via email to