You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rh...@apache.org on 2012/04/05 21:03:43 UTC
svn commit: r1310014 - in /qpid/proton/trunk/proton-c: ./ include/proton/
src/ src/codec/ src/engine/ src/sasl/ src/types/
Author: rhs
Date: Thu Apr 5 19:03:42 2012
New Revision: 1310014
URL: http://svn.apache.org/viewvc?rev=1310014&view=rev
Log:
updated sasl interface to permit full challenge/response sequence
Added:
qpid/proton/trunk/proton-c/include/proton/errors.h
Removed:
qpid/proton/trunk/proton-c/src/sasl/sasl-internal.h
Modified:
qpid/proton/trunk/proton-c/cproton.i
qpid/proton/trunk/proton-c/include/proton/codec.h
qpid/proton/trunk/proton-c/include/proton/driver.h
qpid/proton/trunk/proton-c/include/proton/engine.h
qpid/proton/trunk/proton-c/include/proton/sasl.h
qpid/proton/trunk/proton-c/include/proton/value.h
qpid/proton/trunk/proton-c/src/codec/codec.c
qpid/proton/trunk/proton-c/src/driver.c
qpid/proton/trunk/proton-c/src/engine/engine.c
qpid/proton/trunk/proton-c/src/proton.c
qpid/proton/trunk/proton-c/src/sasl/sasl.c
qpid/proton/trunk/proton-c/src/types/array.c
qpid/proton/trunk/proton-c/src/types/binary.c
qpid/proton/trunk/proton-c/src/types/value.c
qpid/proton/trunk/proton-c/src/util.c
Modified: qpid/proton/trunk/proton-c/cproton.i
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/cproton.i?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/cproton.i (original)
+++ qpid/proton/trunk/proton-c/cproton.i Thu Apr 5 19:03:42 2012
@@ -160,6 +160,7 @@ ssize_t pn_send(pn_link_t *transport, ch
%ignore pn_connector_destroy;
/* Parse the header file to generate wrappers */
+%include "proton/errors.h"
%include "proton/engine.h"
%include "proton/message.h"
%include "proton/sasl.h"
Modified: qpid/proton/trunk/proton-c/include/proton/codec.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/codec.h?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/codec.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/codec.h Thu Apr 5 19:03:42 2012
@@ -26,6 +26,7 @@
#include <stdint.h>
#include <unistd.h>
#include <wchar.h>
+#include <proton/errors.h>
int pn_write_descriptor(char **pos, char *limit);
int pn_write_null(char **pos, char *limit);
Modified: qpid/proton/trunk/proton-c/include/proton/driver.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/driver.h?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/driver.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/driver.h Thu Apr 5 19:03:42 2012
@@ -22,6 +22,7 @@
*
*/
+#include <proton/errors.h>
#include <proton/engine.h>
#include <proton/sasl.h>
@@ -54,6 +55,7 @@ pn_sasl_t *pn_connector_sasl(pn_connecto
pn_connection_t *pn_connector_connection(pn_connector_t *ctor);
void *pn_connector_context(pn_connector_t *ctor);
void pn_connector_set_context(pn_connector_t *ctor, void *context);
+void pn_connector_eos(pn_connector_t *ctor);
void pn_connector_close(pn_connector_t *ctor);
bool pn_connector_closed(pn_connector_t *ctor);
void pn_connector_destroy(pn_connector_t *ctor);
Modified: qpid/proton/trunk/proton-c/include/proton/engine.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/engine.h?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/engine.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/engine.h Thu Apr 5 19:03:42 2012
@@ -25,6 +25,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <sys/types.h>
+#include <proton/errors.h>
typedef struct pn_error_t pn_error_t;
typedef struct pn_transport_t pn_transport_t;
@@ -88,8 +89,6 @@ void pn_connection_close(pn_connection_t
void pn_connection_destroy(pn_connection_t *connection);
// transport
-#define PN_EOS (-1)
-#define PN_ERR (-2)
pn_state_t pn_transport_state(pn_transport_t *transport);
pn_error_t *pn_transport_error(pn_transport_t *transport);
ssize_t pn_input(pn_transport_t *transport, char *bytes, size_t available);
@@ -136,7 +135,6 @@ ssize_t pn_send(pn_link_t *sender, const
//void pn_abort(pn_sender_t *sender);
// receiver
-#define PN_EOM (-1)
void pn_flow(pn_link_t *receiver, int credits);
ssize_t pn_recv(pn_link_t *receiver, char *bytes, size_t n);
Added: qpid/proton/trunk/proton-c/include/proton/errors.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/errors.h?rev=1310014&view=auto
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/errors.h (added)
+++ qpid/proton/trunk/proton-c/include/proton/errors.h Thu Apr 5 19:03:42 2012
@@ -0,0 +1,31 @@
+#ifndef _PROTON_ERRORS_H
+#define _PROTON_ERRORS_H 1
+
+/*
+ *
+ * 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.
+ *
+ */
+
+#define PN_EOS (-1)
+#define PN_ERR (-2)
+#define PN_OVERFLOW (-3)
+#define PN_STATE_ERR (-4)
+#define PN_ARG_ERR (-5)
+
+#endif /* errors.h */
Modified: qpid/proton/trunk/proton-c/include/proton/sasl.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/sasl.h?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/sasl.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/sasl.h Thu Apr 5 19:03:42 2012
@@ -28,21 +28,39 @@
typedef struct pn_sasl_t pn_sasl_t;
-typedef enum {SASL_NONE=-1, SASL_OK=0, SASL_AUTH=1, SASL_SYS=2, SASL_PERM=3,
- SASL_TEMP=4} pn_sasl_outcome_t;
+typedef enum {
+ PN_SASL_NONE=-1,
+ PN_SASL_OK=0,
+ PN_SASL_AUTH=1,
+ PN_SASL_SYS=2,
+ PN_SASL_PERM=3,
+ PN_SASL_TEMP=4
+} pn_sasl_outcome_t;
+
+typedef enum {
+ PN_SASL_CONF,
+ PN_SASL_IDLE,
+ PN_SASL_STEP,
+ PN_SASL_PASS,
+ PN_SASL_FAIL
+} pn_sasl_state_t;
pn_sasl_t *pn_sasl();
-void pn_sasl_client(pn_sasl_t *sasl, const char *mechanism, const char *username, const char *password);
+pn_sasl_state_t pn_sasl_state(pn_sasl_t *sasl);
+void pn_sasl_mechanisms(pn_sasl_t *sasl, const char *mechanisms);
+const char *pn_sasl_remote_mechanisms(pn_sasl_t *sasl);
+void pn_sasl_client(pn_sasl_t *sasl);
void pn_sasl_server(pn_sasl_t *sasl);
-void pn_sasl_auth(pn_sasl_t *sasl, pn_sasl_outcome_t outcome);
-bool pn_sasl_init(pn_sasl_t *sasl);
-const char *pn_sasl_mechanism(pn_sasl_t *sasl);
-pn_binary_t *pn_sasl_challenge(pn_sasl_t *sasl);
-pn_binary_t *pn_sasl_response(pn_sasl_t *sasl);
+void pn_sasl_plain(pn_sasl_t *sasl, const char *username, const char *password);
+size_t pn_sasl_pending(pn_sasl_t *sasl);
+ssize_t pn_sasl_recv(pn_sasl_t *sasl, char *bytes, size_t size);
+ssize_t pn_sasl_send(pn_sasl_t *sasl, const char *bytes, size_t size);
+void pn_sasl_done(pn_sasl_t *sasl, pn_sasl_outcome_t outcome);
pn_sasl_outcome_t pn_sasl_outcome(pn_sasl_t *sasl);
ssize_t pn_sasl_input(pn_sasl_t *sasl, char *bytes, size_t available);
ssize_t pn_sasl_output(pn_sasl_t *sasl, char *bytes, size_t size);
void pn_sasl_trace(pn_sasl_t *sasl, pn_trace_t trace);
void pn_sasl_destroy(pn_sasl_t *sasl);
+
#endif /* sasl.h */
Modified: qpid/proton/trunk/proton-c/include/proton/value.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/value.h?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/value.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/value.h Thu Apr 5 19:03:42 2012
@@ -104,6 +104,7 @@ pn_map_t *pn_to_map(pn_value_t v);
pn_tag_t *pn_to_tag(pn_value_t v);
void *pn_to_ref(pn_value_t v);
+pn_value_t pn_from_array(pn_array_t *a);
pn_value_t pn_from_list(pn_list_t *l);
pn_value_t pn_from_map(pn_map_t *m);
pn_value_t pn_from_tag(pn_tag_t *t);
@@ -193,10 +194,12 @@ pn_binary_t *pn_binary(const char *bytes
size_t pn_binary_size(pn_binary_t *b);
const char *pn_binary_bytes(pn_binary_t *b);
pn_binary_t *pn_binary_dup(pn_binary_t *b);
+ssize_t pn_binary_get(pn_binary_t *b, char *bytes, size_t size);
/* arrays */
pn_array_t *pn_array(enum TYPE type, int capacity);
+int pn_array_add(pn_array_t *a, pn_value_t v);
pn_value_t pn_array_get(pn_array_t *a, int index);
size_t pn_encode_sizeof_array(pn_array_t *a);
size_t pn_encode_array(pn_array_t *array, char *out);
Modified: qpid/proton/trunk/proton-c/src/codec/codec.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/codec/codec.c?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/codec/codec.c (original)
+++ qpid/proton/trunk/proton-c/src/codec/codec.c Thu Apr 5 19:03:42 2012
@@ -41,7 +41,7 @@ typedef union {
static int pn_write_code(char **pos, char *limit, uint8_t code) {
char *dst = *pos;
if (limit - dst < 1) {
- return -1;
+ return PN_OVERFLOW;
} else {
dst[0] = code;
*pos += 1;
@@ -58,7 +58,7 @@ int pn_write_null(char **pos, char *limi
static int pn_write_fixed8(char **pos, char *limit, uint8_t v, uint8_t code) {
char *dst = *pos;
if (limit - dst < 2) {
- return -1;
+ return PN_OVERFLOW;
} else {
dst[0] = code;
dst[1] = v;
@@ -81,7 +81,7 @@ static int pn_write_fixed16(char **pos,
uint8_t code) {
char *dst = *pos;
if (limit - dst < 3) {
- return -1;
+ return PN_OVERFLOW;
} else {
dst[0] = code;
*((uint16_t *) (dst + 1)) = htons(v);
@@ -99,7 +99,7 @@ int pn_write_short(char **pos, char *lim
static int pn_write_fixed32(char **pos, char *limit, uint32_t v, uint8_t code) {
char *dst = *pos;
if (limit - dst < 5) {
- return -1;
+ return PN_OVERFLOW;
} else {
dst[0] = code;
*((uint32_t *) (dst + 1)) = htonl(v);
@@ -125,7 +125,7 @@ int pn_write_float(char **pos, char *lim
static int pn_write_fixed64(char **pos, char *limit, uint64_t v, uint8_t code) {
char *dst = *pos;
if (limit - dst < 9) {
- return -1;
+ return PN_OVERFLOW;
} else {
dst[0] = code;
uint32_t hi = v >> 32;
@@ -162,7 +162,7 @@ static int pn_write_variable(char **pos,
return n;
}
- if (limit - *pos < size) return -1;
+ if (limit - *pos < size) return PN_OVERFLOW;
memmove(*pos, src, size);
*pos += size;
@@ -181,7 +181,7 @@ int pn_write_symbol(char **pos, char *li
int pn_write_start(char **pos, char *limit, char **start) {
char *dst = *pos;
if (limit - dst < 9) {
- return -1;
+ return PN_OVERFLOW;
} else {
*start = dst;
*pos += 9;
@@ -238,7 +238,7 @@ ssize_t pn_read_encoding(const char *byt
switch (code)
{
case PNE_DESCRIPTOR:
- return -8;
+ return PN_ARG_ERR;
case PNE_NULL:
cb->on_null(ctx);
return offset;
@@ -313,7 +313,7 @@ ssize_t pn_read_encoding(const char *byt
cb->on_double(ctx, conv.d);
break;
default:
- return -1;
+ return PN_ARG_ERR;
}
return offset;
@@ -341,7 +341,7 @@ ssize_t pn_read_encoding(const char *byt
offset += 4;
break;
default:
- return -2;
+ return PN_ARG_ERR;
}
{
@@ -358,7 +358,7 @@ ssize_t pn_read_encoding(const char *byt
cb->on_symbol(ctx, size, start);
break;
default:
- return -3;
+ return PN_ARG_ERR;
}
}
@@ -394,7 +394,7 @@ ssize_t pn_read_encoding(const char *byt
offset += 4;
break;
default:
- return -4;
+ return PN_ARG_ERR;
}
switch (code)
@@ -425,7 +425,7 @@ ssize_t pn_read_encoding(const char *byt
cb->start_map(ctx, count);
break;
default:
- return -5;
+ return PN_ARG_ERR;
}
for (int i = 0; i < count; i++)
@@ -446,13 +446,13 @@ ssize_t pn_read_encoding(const char *byt
cb->stop_map(ctx, count);
break;
default:
- return -6;
+ return PN_ARG_ERR;
}
return offset;
default:
printf("Unrecognised typecode: %u\n", code);
- return -7;
+ return PN_ARG_ERR;
}
}
Modified: qpid/proton/trunk/proton-c/src/driver.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/driver.c?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/driver.c (original)
+++ qpid/proton/trunk/proton-c/src/driver.c Thu Apr 5 19:03:42 2012
@@ -197,7 +197,6 @@ static pn_connector_t *pn_listener_accep
}
}
-
void pn_listener_close(pn_listener_t *l)
{
if (!l) return;
@@ -272,6 +271,7 @@ static ssize_t pn_connector_write_sasl_h
static ssize_t pn_connector_write_sasl(pn_connector_t *ctor);
static ssize_t pn_connector_write_amqp_header(pn_connector_t *ctor);
static ssize_t pn_connector_write_amqp(pn_connector_t *ctor);
+static ssize_t pn_connector_write_eos(pn_connector_t *ctor);
pn_connector_t *pn_connector_fd(pn_driver_t *driver, int fd, void *context)
{
@@ -336,6 +336,13 @@ pn_listener_t *pn_connector_listener(pn_
return ctor ? ctor->listener : NULL;
}
+void pn_connector_eos(pn_connector_t *ctor)
+{
+ if (!ctor) return;
+
+ ctor->process_input = pn_connector_write_eos;
+}
+
void pn_connector_close(pn_connector_t *ctor)
{
// XXX: should probably signal engine and callback here
@@ -465,7 +472,7 @@ static void pn_connector_write(pn_connec
} else if (n == 0) {
break;
} else {
- if (n != PN_EOS) fprintf(stderr, "error in process_output: %zi", n);
+ if (n != PN_EOS) fprintf(stderr, "error in process_output: %zi\n", n);
pn_connector_close(ctor);
return;
}
@@ -525,6 +532,11 @@ static ssize_t pn_connector_write_amqp(p
return pn_output(transport, pn_connector_output(ctor), pn_connector_available(ctor));
}
+static ssize_t pn_connector_write_eos(pn_connector_t *ctor)
+{
+ return PN_EOS;
+}
+
static time_t pn_connector_tick(pn_connector_t *ctor, time_t now)
{
// XXX: should probably have a function pointer for this and switch it with different layers
Modified: qpid/proton/trunk/proton-c/src/engine/engine.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/engine/engine.c?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/engine/engine.c (original)
+++ qpid/proton/trunk/proton-c/src/engine/engine.c Thu Apr 5 19:03:42 2012
@@ -1553,11 +1553,11 @@ ssize_t pn_recv(pn_link_t *receiver, cha
delivery->size -= size;
return size;
} else {
- return PN_EOM;
+ return PN_EOS;
}
} else {
// XXX: ?
- return PN_EOM;
+ return PN_EOS;
}
}
Modified: qpid/proton/trunk/proton-c/src/proton.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/proton.c?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/proton.c (original)
+++ qpid/proton/trunk/proton-c/src/proton.c Thu Apr 5 19:03:42 2012
@@ -85,29 +85,31 @@ void server_callback(pn_connector_t *cto
{
pn_sasl_t *sasl = pn_connector_sasl(ctor);
- if (!pn_sasl_init(sasl)) {
- pn_sasl_server(sasl);
- }
-
- switch (pn_sasl_outcome(sasl)) {
- case SASL_NONE:
- {
- const char *mech = pn_sasl_mechanism(sasl);
- if (mech && (!strcmp(mech, "PLAIN") || !strcmp(mech, "ANONYMOUS"))) {
- pn_binary_t *response = pn_sasl_response(sasl);
- char buf[1024];
- pn_format(buf, 1024, pn_from_binary(response));
- printf("response = %s\n", buf);
- pn_sasl_auth(sasl, SASL_OK);
- break;
- } else {
- return;
+ while (pn_sasl_state(sasl) != PN_SASL_PASS) {
+ switch (pn_sasl_state(sasl)) {
+ case PN_SASL_IDLE:
+ return;
+ case PN_SASL_CONF:
+ pn_sasl_mechanisms(sasl, "PLAIN ANONYMOUS");
+ pn_sasl_server(sasl);
+ break;
+ case PN_SASL_STEP:
+ {
+ size_t n = pn_sasl_pending(sasl);
+ char iresp[n];
+ pn_sasl_recv(sasl, iresp, n);
+ printf(pn_sasl_remote_mechanisms(sasl));
+ printf(" response = ");
+ pn_print_data(iresp, n);
+ printf("\n");
+ pn_sasl_done(sasl, PN_SASL_OK);
}
+ break;
+ case PN_SASL_PASS:
+ break;
+ case PN_SASL_FAIL:
+ return;
}
- case SASL_OK:
- break;
- default:
- return;
}
pn_connection_t *conn = pn_connector_connection(ctor);
@@ -152,7 +154,7 @@ void server_callback(pn_connector_t *cto
printf(" payload = \"");
while (true) {
ssize_t n = pn_recv(link, msg, 1024);
- if (n == PN_EOM) {
+ if (n == PN_EOS) {
pn_advance(link);
pn_disposition(delivery, PN_ACCEPTED);
break;
@@ -214,21 +216,38 @@ struct client_context {
void client_callback(pn_connector_t *ctor)
{
struct client_context *ctx = pn_connector_context(ctor);
+ if (pn_connector_closed(ctor)) {
+ ctx->done = true;
+ }
pn_sasl_t *sasl = pn_connector_sasl(ctor);
- if (!pn_sasl_init(sasl)) {
- pn_sasl_client(sasl, ctx->mechanism, ctx->username, ctx->password);
- }
- switch (pn_sasl_outcome(sasl)) {
- case SASL_NONE:
- return;
- case SASL_OK:
- break;
- default:
- fprintf(stderr, "auth failed\n");
- ctx->done = true;
- return;
+ while (pn_sasl_state(sasl) != PN_SASL_PASS) {
+ pn_sasl_state_t st = pn_sasl_state(sasl);
+ switch (st) {
+ case PN_SASL_IDLE:
+ return;
+ case PN_SASL_CONF:
+ if (ctx->mechanism && !strcmp(ctx->mechanism, "PLAIN")) {
+ pn_sasl_plain(sasl, ctx->username, ctx->password);
+ } else {
+ pn_sasl_mechanisms(sasl, ctx->mechanism);
+ pn_sasl_client(sasl);
+ }
+ break;
+ case PN_SASL_STEP:
+ if (pn_sasl_pending(sasl)) {
+ fprintf(stderr, "challenge failed\n");
+ ctx->done = true;
+ }
+ return;
+ case PN_SASL_FAIL:
+ fprintf(stderr, "authentication failed\n");
+ ctx->done = true;
+ return;
+ case PN_SASL_PASS:
+ break;
+ }
}
pn_connection_t *connection = pn_connector_connection(ctor);
@@ -287,7 +306,7 @@ void client_callback(pn_connector_t *cto
printf(" payload = \"");
while (true) {
size_t n = pn_recv(link, msg, 1024);
- if (n == PN_EOM) {
+ if (n == PN_EOS) {
pn_advance(link);
pn_disposition(delivery, PN_ACCEPTED);
pn_settle(delivery);
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=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/sasl/sasl.c (original)
+++ qpid/proton/trunk/proton-c/src/sasl/sasl.c Thu Apr 5 19:03:42 2012
@@ -25,16 +25,47 @@
#include <proton/framing.h>
#include <proton/value.h>
#include <proton/engine.h> // XXX: just needed for PN_EOS
-#include "sasl-internal.h"
+#include <proton/sasl.h>
#include "protocol.h"
+#include "../dispatcher/dispatcher.h"
#include "../util.h"
+#define SCRATCH (1024)
+
+struct pn_sasl_t {
+ pn_dispatcher_t *disp;
+ bool client;
+ bool configured;
+ char *mechanisms;
+ char *remote_mechanisms;
+ pn_binary_t *send_data;
+ pn_binary_t *recv_data;
+ pn_sasl_outcome_t outcome;
+ bool sent_init;
+ bool rcvd_init;
+ bool sent_done;
+ bool rcvd_done;
+ char scratch[SCRATCH];
+};
+
void pn_do_init(pn_dispatcher_t *disp);
void pn_do_mechanisms(pn_dispatcher_t *disp);
void pn_do_challenge(pn_dispatcher_t *disp);
void pn_do_response(pn_dispatcher_t *disp);
void pn_do_outcome(pn_dispatcher_t *disp);
+#define strdup my_strdup
+
+char *my_strdup(const char *s)
+{
+ if (!s) return NULL;
+ size_t size = strlen(s);
+ char *r = malloc(size + 1);
+ memcpy(r, s, size);
+ r[size] = '\0';
+ return r;
+}
+
pn_sasl_t *pn_sasl()
{
pn_sasl_t *sasl = malloc(sizeof(pn_sasl_t));
@@ -46,53 +77,108 @@ pn_sasl_t *pn_sasl()
pn_dispatcher_action(sasl->disp, SASL_RESPONSE, "SASL-RESPONSE", pn_do_response);
pn_dispatcher_action(sasl->disp, SASL_OUTCOME, "SASL-OUTCOME", pn_do_outcome);
- sasl->init = false;
- sasl->outcome = SASL_NONE;
- sasl->mechanism = NULL;
- sasl->challenge = NULL;
- sasl->response = NULL;
+ sasl->client = false;
+ sasl->configured = false;
+ sasl->mechanisms = NULL;
+ sasl->remote_mechanisms = NULL;
+ sasl->send_data = NULL;
+ sasl->recv_data = NULL;
+ sasl->outcome = PN_SASL_NONE;
+ sasl->sent_init = false;
+ sasl->rcvd_init = false;
+ sasl->sent_done = false;
+ sasl->rcvd_done = false;
return sasl;
}
-void pn_sasl_mechanism_set(pn_sasl_t *sasl, const char *mechanism)
+pn_sasl_state_t pn_sasl_state(pn_sasl_t *sasl)
{
- if (sasl->mechanism) pn_free_symbol(sasl->mechanism);
- sasl->mechanism = pn_symbol(mechanism);
+ if (sasl) {
+ if (!sasl->configured) return PN_SASL_CONF;
+ if (sasl->outcome == PN_SASL_NONE) {
+ return sasl->rcvd_init ? PN_SASL_STEP : PN_SASL_IDLE;
+ } else {
+ return sasl->outcome == PN_SASL_OK ? PN_SASL_PASS : PN_SASL_FAIL;
+ }
+ // if (sasl->rcvd_init && sasl->outcome == PN_SASL_NONE) return PN_SASL_STEP;
+ //if (sasl->outcome == PN_SASL_OK) return PN_SASL_PASS;
+ //else return PN_SASL_FAIL;
+ } else {
+ return PN_SASL_FAIL;
+ }
}
-const char *pn_sasl_mechanism(pn_sasl_t *sasl)
+void pn_sasl_mechanisms(pn_sasl_t *sasl, const char *mechanisms)
{
- if (sasl->mechanism)
- return pn_symbol_name(sasl->mechanism);
- else
- return NULL;
+ if (!sasl) return;
+ sasl->mechanisms = strdup(mechanisms);
}
-void pn_sasl_challenge_set(pn_sasl_t *sasl, pn_binary_t *challenge)
+const char *pn_sasl_remote_mechanisms(pn_sasl_t *sasl)
{
- if (sasl->challenge) pn_free_binary(sasl->challenge);
- sasl->challenge = pn_binary_dup(challenge);
+ return sasl ? sasl->remote_mechanisms : NULL;
}
-pn_binary_t *pn_sasl_challenge(pn_sasl_t *sasl)
+ssize_t pn_sasl_send(pn_sasl_t *sasl, const char *bytes, size_t size)
{
- return sasl->challenge;
+ if (sasl) {
+ if (sasl->send_data) {
+ // XXX: need better error
+ return PN_STATE_ERR;
+ }
+ sasl->send_data = pn_binary(bytes, size);
+ return size;
+ } else {
+ return PN_ARG_ERR;
+ }
}
-void pn_sasl_response_set(pn_sasl_t *sasl, pn_binary_t *response)
+size_t pn_sasl_pending(pn_sasl_t *sasl)
{
- if (sasl->response) pn_free_binary(sasl->response);
- sasl->response = pn_binary_dup(response);
+ if (sasl && sasl->recv_data) {
+ return pn_binary_size(sasl->recv_data);
+ } else {
+ return 0;
+ }
}
-pn_binary_t *pn_sasl_response(pn_sasl_t *sasl)
+ssize_t pn_sasl_recv(pn_sasl_t *sasl, char *bytes, size_t size)
{
- return sasl->response;
+ if (!sasl) return PN_ARG_ERR;
+
+ if (sasl->recv_data) {
+ ssize_t result = pn_binary_get(sasl->recv_data, bytes, size);
+ if (result >= 0) {
+ pn_free_binary(sasl->recv_data);
+ sasl->recv_data = NULL;
+ }
+ return result;
+ } else {
+ return PN_EOS;
+ }
}
-void pn_sasl_client(pn_sasl_t *sasl, const char *mechanism, const char *username, const char *password)
+void pn_sasl_client(pn_sasl_t *sasl)
{
+ if (sasl) {
+ sasl->client = true;
+ sasl->configured = true;
+ }
+}
+
+void pn_sasl_server(pn_sasl_t *sasl)
+{
+ if (sasl) {
+ sasl->client = false;
+ sasl->configured = true;
+ }
+}
+
+void pn_sasl_plain(pn_sasl_t *sasl, const char *username, const char *password)
+{
+ if (!sasl) return;
+
const char *user = username ? username : "";
const char *pass = password ? password : "";
size_t usize = strlen(user);
@@ -105,34 +191,21 @@ void pn_sasl_client(pn_sasl_t *sasl, con
iresp[usize + 1] = 0;
memmove(iresp + usize + 2, pass, psize);
- pn_init_frame(sasl->disp);
- pn_field(sasl->disp, SASL_INIT_MECHANISM, pn_from_symbol(pn_symbol(mechanism)));
- pn_field(sasl->disp, SASL_INIT_INITIAL_RESPONSE, pn_from_binary(pn_binary(iresp, size)));
- pn_post_frame(sasl->disp, 0, SASL_INIT);
- sasl->init = true;
-}
-
-void pn_sasl_server(pn_sasl_t *sasl)
-{
- pn_init_frame(sasl->disp);
- pn_field(sasl->disp, SASL_MECHANISMS_SASL_SERVER_MECHANISMS,
- pn_value("@s[ss]", "PLAIN", "ANONYMOUS"));
- pn_post_frame(sasl->disp, 0, SASL_MECHANISMS);
- sasl->init = true;
+ pn_sasl_mechanisms(sasl, "PLAIN");
+ pn_sasl_send(sasl, iresp, size);
+ pn_sasl_client(sasl);
}
-void pn_sasl_auth(pn_sasl_t *sasl, pn_sasl_outcome_t outcome)
+void pn_sasl_done(pn_sasl_t *sasl, pn_sasl_outcome_t outcome)
{
- sasl->outcome = outcome;
-
- pn_init_frame(sasl->disp);
- pn_field(sasl->disp, SASL_OUTCOME_CODE, pn_value("B", outcome));
- pn_post_frame(sasl->disp, 0, SASL_OUTCOME);
+ if (sasl) {
+ sasl->outcome = outcome;
+ }
}
-bool pn_sasl_init(pn_sasl_t *sasl)
+pn_sasl_outcome_t pn_sasl_outcome(pn_sasl_t *sasl)
{
- return sasl->init;
+ return sasl ? sasl->outcome : PN_SASL_NONE;
}
void pn_sasl_trace(pn_sasl_t *sasl, pn_trace_t trace)
@@ -142,17 +215,92 @@ void pn_sasl_trace(pn_sasl_t *sasl, pn_t
void pn_sasl_destroy(pn_sasl_t *sasl)
{
- pn_sasl_mechanism_set(sasl, NULL);
- pn_sasl_challenge_set(sasl, NULL);
- pn_sasl_response_set(sasl, NULL);
+ free(sasl->mechanisms);
+ free(sasl->remote_mechanisms);
+ pn_free_binary(sasl->send_data);
+ pn_free_binary(sasl->recv_data);
pn_dispatcher_destroy(sasl->disp);
free(sasl);
}
+void pn_client_init(pn_sasl_t *sasl)
+{
+ pn_init_frame(sasl->disp);
+ pn_field(sasl->disp, SASL_INIT_MECHANISM, pn_from_symbol(pn_symbol(sasl->mechanisms)));
+ if (sasl->send_data) {
+ pn_field(sasl->disp, SASL_INIT_INITIAL_RESPONSE, pn_from_binary(sasl->send_data));
+ sasl->send_data = NULL;
+ }
+ pn_post_frame(sasl->disp, 0, SASL_INIT);
+}
+
+void pn_server_init(pn_sasl_t *sasl)
+{
+ // XXX
+ pn_array_t *mechs = pn_array(SYMBOL, 16);
+ if (sasl->mechanisms) {
+ char *start = sasl->mechanisms;
+ char *end = start;
+
+ while (*end) {
+ if (*end == ' ') {
+ if (start != end) {
+ *end = '\0';
+ pn_array_add(mechs, pn_value("s", start));
+ }
+ end++;
+ start = end;
+ } else {
+ end++;
+ }
+ }
+
+ if (start != end) {
+ pn_array_add(mechs, pn_value("s", start));
+ }
+ }
+
+ pn_init_frame(sasl->disp);
+ pn_field(sasl->disp, SASL_MECHANISMS_SASL_SERVER_MECHANISMS, pn_from_array(mechs));
+ pn_post_frame(sasl->disp, 0, SASL_MECHANISMS);
+}
+
+void pn_server_done(pn_sasl_t *sasl)
+{
+ pn_init_frame(sasl->disp);
+ pn_field(sasl->disp, SASL_OUTCOME_CODE, pn_value("B", sasl->outcome));
+ pn_post_frame(sasl->disp, 0, SASL_OUTCOME);
+}
+
+void pn_sasl_process(pn_sasl_t *sasl)
+{
+ if (!sasl->configured) return;
+
+ if (!sasl->sent_init) {
+ if (sasl->client) {
+ pn_client_init(sasl);
+ } else {
+ pn_server_init(sasl);
+ }
+ sasl->sent_init = true;
+ }
+
+ if (!sasl->client && sasl->outcome != PN_SASL_NONE && !sasl->sent_done) {
+ pn_server_done(sasl);
+ sasl->sent_done = true;
+ sasl->rcvd_done = true;
+ }
+}
+
ssize_t pn_sasl_input(pn_sasl_t *sasl, char *bytes, size_t available)
{
- if (sasl->outcome != SASL_NONE) {
- return PN_EOS;
+ if (sasl->rcvd_done) {
+ if (pn_sasl_state(sasl) == PN_SASL_PASS) {
+ return PN_EOS;
+ } else {
+ // XXX: should probably do something better here
+ return PN_ERR;
+ }
} else {
return pn_dispatcher_input(sasl->disp, bytes, available);
}
@@ -160,30 +308,33 @@ ssize_t pn_sasl_input(pn_sasl_t *sasl, c
ssize_t pn_sasl_output(pn_sasl_t *sasl, char *bytes, size_t size)
{
- if (sasl->disp->available == 0 && sasl->outcome != SASL_NONE) {
- return PN_EOS;
+ pn_sasl_process(sasl);
+
+ if (sasl->disp->available == 0 && sasl->sent_done) {
+ if (pn_sasl_state(sasl) == PN_SASL_PASS) {
+ return PN_EOS;
+ } else {
+ // XXX: should probably do something better here
+ return PN_ERR;
+ }
} else {
return pn_dispatcher_output(sasl->disp, bytes, size);
}
}
-pn_sasl_outcome_t pn_sasl_outcome(pn_sasl_t *sasl)
-{
- return sasl->outcome;
-}
-
void pn_do_init(pn_dispatcher_t *disp)
{
pn_sasl_t *sasl = disp->context;
pn_symbol_t *mech = pn_to_symbol(pn_list_get(disp->args, SASL_INIT_MECHANISM));
- pn_sasl_mechanism_set(sasl, pn_symbol_name(mech));
- pn_sasl_response_set(sasl, pn_to_binary(pn_list_get(disp->args, SASL_INIT_INITIAL_RESPONSE)));
+ sasl->remote_mechanisms = strdup(pn_symbol_name(mech));
+ sasl->recv_data = pn_binary_dup(pn_to_binary(pn_list_get(disp->args, SASL_INIT_INITIAL_RESPONSE)));
+ sasl->rcvd_init = true;
}
void pn_do_mechanisms(pn_dispatcher_t *disp)
{
- //pn_sasl_t *sasl = disp->context;
-
+ pn_sasl_t *sasl = disp->context;
+ sasl->rcvd_init = true;
}
void pn_do_challenge(pn_dispatcher_t *disp)
@@ -200,4 +351,6 @@ void pn_do_outcome(pn_dispatcher_t *disp
{
pn_sasl_t *sasl = disp->context;
sasl->outcome = pn_to_uint8(pn_list_get(disp->args, SASL_OUTCOME_CODE));
+ sasl->rcvd_done = true;
+ sasl->sent_done = true;
}
Modified: qpid/proton/trunk/proton-c/src/types/array.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/types/array.c?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/types/array.c (original)
+++ qpid/proton/trunk/proton-c/src/types/array.c Thu Apr 5 19:03:42 2012
@@ -21,6 +21,7 @@
#include <proton/util.h>
#include <arpa/inet.h>
+#include <stdio.h>
#include <stdlib.h>
#include "encodings.h"
#include "value-internal.h"
@@ -90,6 +91,17 @@ pn_array_t *pn_array(enum TYPE type, int
return l;
}
+int pn_array_add(pn_array_t *a, pn_value_t v)
+{
+ if (a->capacity <= a->size) {
+ fprintf(stderr, "wah!\n");
+ return -1;
+ }
+
+ a->values[a->size++] = v;
+ return 0;
+}
+
void pn_free_array(pn_array_t *a)
{
free(a);
Modified: qpid/proton/trunk/proton-c/src/types/binary.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/types/binary.c?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/types/binary.c (original)
+++ qpid/proton/trunk/proton-c/src/types/binary.c Thu Apr 5 19:03:42 2012
@@ -19,6 +19,7 @@
*
*/
+#include <proton/errors.h>
#include <proton/codec.h>
#include <string.h>
#include <stdlib.h>
@@ -49,6 +50,16 @@ const char *pn_binary_bytes(pn_binary_t
return b->bytes;
}
+ssize_t pn_binary_get(pn_binary_t *b, char *bytes, size_t size)
+{
+ if (size < b->size) {
+ return PN_OVERFLOW;
+ } else {
+ memmove(bytes, b->bytes, b->size);
+ return b->size;
+ }
+}
+
uintptr_t pn_hash_binary(pn_binary_t *b)
{
uintptr_t hash = 0;
Modified: qpid/proton/trunk/proton-c/src/types/value.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/types/value.c?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/types/value.c (original)
+++ qpid/proton/trunk/proton-c/src/types/value.c Thu Apr 5 19:03:42 2012
@@ -358,6 +358,11 @@ void *pn_to_ref(pn_value_t v)
return v.u.as_ref;
}
+pn_value_t pn_from_array(pn_array_t *a)
+{
+ return (pn_value_t) {.type = ARRAY, .u.as_array = a};
+}
+
pn_value_t pn_from_list(pn_list_t *l)
{
return (pn_value_t) {.type = LIST, .u.as_list = l};
@@ -572,6 +577,7 @@ size_t pn_format_sizeof(pn_value_t v)
}
}
+// XXX: this should delegate to stuff in codec
size_t pn_encode_sizeof(pn_value_t v)
{
switch (v.type)
Modified: qpid/proton/trunk/proton-c/src/util.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/util.c?rev=1310014&r1=1310013&r2=1310014&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/util.c (original)
+++ qpid/proton/trunk/proton-c/src/util.c Thu Apr 5 19:03:42 2012
@@ -28,9 +28,7 @@
#include <stdint.h>
#include <ctype.h>
#include <string.h>
-
-// XXX: should centralize error codes
-#define PN_OVERFLOW (-1)
+#include <proton/errors.h>
ssize_t pn_quote_data(char *dst, size_t capacity, const char *src, size_t size)
{
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org