PROTON-749: Remove transport pointer from ssl and sasl structs
- Change means that API pn_ssl_t and pn_sasl_t pointers are really
pn_transport_t pointers and need to be cast internally on use
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/df029005
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/df029005
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/df029005
Branch: refs/heads/examples
Commit: df02900597cb25de9841b6d8c4763acdc0a40fad
Parents: 120639b
Author: Andrew Stitcher <astitcher@apache.org>
Authored: Thu Aug 14 18:22:39 2014 -0400
Committer: Andrew Stitcher <astitcher@apache.org>
Committed: Mon Nov 17 14:55:36 2014 -0500
----------------------------------------------------------------------
proton-c/src/engine/engine-internal.h | 7 +-
proton-c/src/sasl/sasl-internal.h | 4 +-
proton-c/src/sasl/sasl.c | 132 +++++++++------
proton-c/src/ssl/openssl.c | 258 ++++++++++++++++-------------
proton-c/src/ssl/ssl-internal.h | 4 +-
proton-c/src/transport/transport.c | 8 +-
proton-c/src/windows/schannel.c | 164 ++++++++++--------
7 files changed, 326 insertions(+), 251 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/df029005/proton-c/src/engine/engine-internal.h
----------------------------------------------------------------------
diff --git a/proton-c/src/engine/engine-internal.h b/proton-c/src/engine/engine-internal.h
index 40a839b..3960acf 100644
--- a/proton-c/src/engine/engine-internal.h
+++ b/proton-c/src/engine/engine-internal.h
@@ -108,10 +108,13 @@ typedef struct pn_io_layer_t {
extern const pn_io_layer_t pni_passthru_layer;
+typedef struct pni_sasl_t pni_sasl_t;
+typedef struct pni_ssl_t pni_ssl_t;
+
struct pn_transport_t {
pn_tracer_t tracer;
- pn_sasl_t *sasl;
- pn_ssl_t *ssl;
+ pni_sasl_t *sasl;
+ pni_ssl_t *ssl;
pn_connection_t *connection; // reference counted
pn_dispatcher_t *disp;
char *remote_container;
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/df029005/proton-c/src/sasl/sasl-internal.h
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/sasl-internal.h b/proton-c/src/sasl/sasl-internal.h
index e362547..15fd0b1 100644
--- a/proton-c/src/sasl/sasl-internal.h
+++ b/proton-c/src/sasl/sasl-internal.h
@@ -48,13 +48,13 @@ ssize_t pn_sasl_input(pn_sasl_t *sasl, const 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_trace(pn_transport_t *transport, pn_trace_t trace);
/** Destructor for the given SASL layer.
*
* @param[in] sasl the SASL object to free. No longer valid on
* return.
*/
-void pn_sasl_free(pn_sasl_t *sasl);
+void pn_sasl_free(pn_transport_t *transport);
#endif /* sasl-internal.h */
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/df029005/proton-c/src/sasl/sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/sasl.c b/proton-c/src/sasl/sasl.c
index 5034eb7..ffa310b 100644
--- a/proton-c/src/sasl/sasl.c
+++ b/proton-c/src/sasl/sasl.c
@@ -34,8 +34,7 @@
#include "util.h"
-struct pn_sasl_t {
- pn_transport_t *transport;
+struct pni_sasl_t {
pn_dispatcher_t *disp;
char *mechanisms;
char *remote_mechanisms;
@@ -53,6 +52,18 @@ struct pn_sasl_t {
bool output_bypass;
};
+static inline pn_transport_t *get_transport_internal(pn_sasl_t *sasl)
+{
+ // The external pn_sasl_t is really a pointer to the internal pni_transport_t
+ return ((pn_transport_t *)sasl);
+}
+
+static inline pni_sasl_t *get_sasl_internal(pn_sasl_t *sasl)
+{
+ // The external pn_sasl_t is really a pointer to the internal pni_transport_t
+ return sasl ? ((pn_transport_t *)sasl)->sasl : NULL;
+}
+
static ssize_t pn_input_read_sasl_header(pn_transport_t* transport, unsigned int layer, const char* bytes, size_t available);
static ssize_t pn_input_read_sasl(pn_transport_t *transport, unsigned int layer, const char *bytes, size_t available);
static ssize_t pn_output_write_sasl_header(pn_transport_t* transport, unsigned int layer, char* bytes, size_t size);
@@ -89,7 +100,7 @@ const pn_io_layer_t sasl_layer = {
pn_sasl_t *pn_sasl(pn_transport_t *transport)
{
if (!transport->sasl) {
- pn_sasl_t *sasl = (pn_sasl_t *) malloc(sizeof(pn_sasl_t));
+ pni_sasl_t *sasl = (pni_sasl_t *) malloc(sizeof(pni_sasl_t));
sasl->disp = pn_dispatcher(1, transport);
sasl->disp->batch = false;
@@ -109,15 +120,16 @@ pn_sasl_t *pn_sasl(pn_transport_t *transport)
sasl->output_bypass = false;
transport->sasl = sasl;
- sasl->transport = transport;
transport->io_layers[PN_IO_SASL] = &sasl_headers_layer;
}
- return transport->sasl;
+ // The actual external pn_sasl_t pointer is a pointer to its enclosing pn_transport_t
+ return (pn_sasl_t *)transport;
}
-pn_sasl_state_t pn_sasl_state(pn_sasl_t *sasl)
+pn_sasl_state_t pn_sasl_state(pn_sasl_t *sasl0)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (sasl) {
if (!sasl->configured) return PN_SASL_CONF;
if (sasl->outcome == PN_SASL_NONE) {
@@ -133,19 +145,22 @@ pn_sasl_state_t pn_sasl_state(pn_sasl_t *sasl)
}
}
-void pn_sasl_mechanisms(pn_sasl_t *sasl, const char *mechanisms)
+void pn_sasl_mechanisms(pn_sasl_t *sasl0, const char *mechanisms)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (!sasl) return;
sasl->mechanisms = pn_strdup(mechanisms);
}
-const char *pn_sasl_remote_mechanisms(pn_sasl_t *sasl)
+const char *pn_sasl_remote_mechanisms(pn_sasl_t *sasl0)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
return sasl ? sasl->remote_mechanisms : NULL;
}
-ssize_t pn_sasl_send(pn_sasl_t *sasl, const char *bytes, size_t size)
+ssize_t pn_sasl_send(pn_sasl_t *sasl0, const char *bytes, size_t size)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (sasl) {
if (pn_buffer_size(sasl->send_data)) {
// XXX: need better error
@@ -159,8 +174,9 @@ ssize_t pn_sasl_send(pn_sasl_t *sasl, const char *bytes, size_t size)
}
}
-size_t pn_sasl_pending(pn_sasl_t *sasl)
+size_t pn_sasl_pending(pn_sasl_t *sasl0)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (sasl && pn_buffer_size(sasl->recv_data)) {
return pn_buffer_size(sasl->recv_data);
} else {
@@ -168,8 +184,9 @@ 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_recv(pn_sasl_t *sasl0, char *bytes, size_t size)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (!sasl) return PN_ARG_ERR;
size_t bsize = pn_buffer_size(sasl->recv_data);
@@ -183,30 +200,34 @@ ssize_t pn_sasl_recv(pn_sasl_t *sasl, char *bytes, size_t size)
}
}
-void pn_sasl_client(pn_sasl_t *sasl)
+void pn_sasl_client(pn_sasl_t *sasl0)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (sasl) {
sasl->client = true;
sasl->configured = true;
}
}
-void pn_sasl_server(pn_sasl_t *sasl)
+void pn_sasl_server(pn_sasl_t *sasl0)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (sasl) {
sasl->client = false;
sasl->configured = true;
}
}
-void pn_sasl_allow_skip(pn_sasl_t *sasl, bool allow)
+void pn_sasl_allow_skip(pn_sasl_t *sasl0, bool allow)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (sasl)
sasl->allow_skip = allow;
}
-void pn_sasl_plain(pn_sasl_t *sasl, const char *username, const char *password)
+void pn_sasl_plain(pn_sasl_t *sasl0, const char *username, const char *password)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (!sasl) return;
const char *user = username ? username : "";
@@ -221,42 +242,47 @@ void pn_sasl_plain(pn_sasl_t *sasl, const char *username, const char *password)
iresp[usize + 1] = 0;
memmove(iresp + usize + 2, pass, psize);
- pn_sasl_mechanisms(sasl, "PLAIN");
- pn_sasl_send(sasl, iresp, size);
- pn_sasl_client(sasl);
+ pn_sasl_mechanisms(sasl0, "PLAIN");
+ pn_sasl_send(sasl0, iresp, size);
+ pn_sasl_client(sasl0);
free(iresp);
}
-void pn_sasl_done(pn_sasl_t *sasl, pn_sasl_outcome_t outcome)
+void pn_sasl_done(pn_sasl_t *sasl0, pn_sasl_outcome_t outcome)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
if (sasl) {
sasl->outcome = outcome;
}
}
-pn_sasl_outcome_t pn_sasl_outcome(pn_sasl_t *sasl)
+pn_sasl_outcome_t pn_sasl_outcome(pn_sasl_t *sasl0)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
return sasl ? sasl->outcome : PN_SASL_NONE;
}
-void pn_sasl_trace(pn_sasl_t *sasl, pn_trace_t trace)
+void pn_sasl_trace(pn_transport_t *transport, pn_trace_t trace)
{
- sasl->disp->trace = trace;
+ transport->sasl->disp->trace = trace;
}
-void pn_sasl_free(pn_sasl_t *sasl)
+void pn_sasl_free(pn_transport_t *transport)
{
- if (sasl) {
- free(sasl->mechanisms);
- free(sasl->remote_mechanisms);
- pn_buffer_free(sasl->send_data);
- pn_buffer_free(sasl->recv_data);
- pn_dispatcher_free(sasl->disp);
- free(sasl);
+ if (transport) {
+ pni_sasl_t *sasl = transport->sasl;
+ if (sasl) {
+ free(sasl->mechanisms);
+ free(sasl->remote_mechanisms);
+ pn_buffer_free(sasl->send_data);
+ pn_buffer_free(sasl->recv_data);
+ pn_dispatcher_free(sasl->disp);
+ free(sasl);
+ }
}
}
-void pn_client_init(pn_sasl_t *sasl)
+void pn_client_init(pni_sasl_t *sasl)
{
pn_buffer_memory_t bytes = pn_buffer_memory(sasl->send_data);
pn_post_frame(sasl->disp, 0, "DL[sz]", SASL_INIT, sasl->mechanisms,
@@ -264,7 +290,7 @@ void pn_client_init(pn_sasl_t *sasl)
pn_buffer_clear(sasl->send_data);
}
-void pn_server_init(pn_sasl_t *sasl)
+void pn_server_init(pni_sasl_t *sasl)
{
// XXX
char *mechs[16];
@@ -295,13 +321,15 @@ void pn_server_init(pn_sasl_t *sasl)
pn_post_frame(sasl->disp, 0, "DL[@T[*s]]", SASL_MECHANISMS, PN_SYMBOL, count, mechs);
}
-void pn_server_done(pn_sasl_t *sasl)
+void pn_server_done(pn_sasl_t *sasl0)
{
+ pni_sasl_t *sasl = get_sasl_internal(sasl0);
pn_post_frame(sasl->disp, 0, "DL[B]", SASL_OUTCOME, sasl->outcome);
}
-void pn_sasl_process(pn_sasl_t *sasl)
+void pn_sasl_process(pn_transport_t *transport)
{
+ pni_sasl_t *sasl = transport->sasl;
if (!sasl->configured) return;
if (!sasl->sent_init) {
@@ -321,7 +349,7 @@ void pn_sasl_process(pn_sasl_t *sasl)
}
if (!sasl->client && sasl->outcome != PN_SASL_NONE && !sasl->sent_done) {
- pn_server_done(sasl);
+ pn_server_done((pn_sasl_t *)transport);
sasl->sent_done = true;
}
@@ -335,15 +363,16 @@ void pn_sasl_process(pn_sasl_t *sasl)
}
}
-ssize_t pn_sasl_input(pn_sasl_t *sasl, const char *bytes, size_t available)
+ssize_t pn_sasl_input(pn_transport_t *transport, const char *bytes, size_t available)
{
+ pni_sasl_t *sasl = transport->sasl;
ssize_t n = pn_dispatcher_input(sasl->disp, bytes, available);
if (n < 0) return n;
- pn_sasl_process(sasl);
+ pn_sasl_process(transport);
if (sasl->rcvd_done) {
- if (pn_sasl_state(sasl) == PN_SASL_PASS) {
+ if (pn_sasl_state((pn_sasl_t *)transport) == PN_SASL_PASS) {
if (n) {
return n;
} else {
@@ -358,12 +387,13 @@ ssize_t pn_sasl_input(pn_sasl_t *sasl, const char *bytes, size_t available)
}
}
-ssize_t pn_sasl_output(pn_sasl_t *sasl, char *bytes, size_t size)
+ssize_t pn_sasl_output(pn_transport_t *transport, char *bytes, size_t size)
{
- pn_sasl_process(sasl);
+ pn_sasl_process(transport);
+ pni_sasl_t *sasl = transport->sasl;
if (sasl->disp->available == 0 && sasl->sent_done) {
- if (pn_sasl_state(sasl) == PN_SASL_PASS) {
+ if (pn_sasl_state((pn_sasl_t *)transport) == PN_SASL_PASS) {
return PN_EOS;
} else {
// XXX: should probably do something better here
@@ -376,7 +406,7 @@ ssize_t pn_sasl_output(pn_sasl_t *sasl, char *bytes, size_t size)
int pn_do_init(pn_dispatcher_t *disp)
{
- pn_sasl_t *sasl = disp->transport->sasl;
+ pni_sasl_t *sasl = disp->transport->sasl;
pn_bytes_t mech;
pn_bytes_t recv;
int err = pn_scan_args(disp, "D.[sz]", &mech, &recv);
@@ -389,14 +419,14 @@ int pn_do_init(pn_dispatcher_t *disp)
int pn_do_mechanisms(pn_dispatcher_t *disp)
{
- pn_sasl_t *sasl = disp->transport->sasl;
+ pni_sasl_t *sasl = disp->transport->sasl;
sasl->rcvd_init = true;
return 0;
}
int pn_do_recv(pn_dispatcher_t *disp)
{
- pn_sasl_t *sasl = disp->transport->sasl;
+ pni_sasl_t *sasl = disp->transport->sasl;
pn_bytes_t recv;
int err = pn_scan_args(disp, "D.[z]", &recv);
if (err) return err;
@@ -416,7 +446,7 @@ int pn_do_response(pn_dispatcher_t *disp)
int pn_do_outcome(pn_dispatcher_t *disp)
{
- pn_sasl_t *sasl = disp->transport->sasl;
+ pni_sasl_t *sasl = disp->transport->sasl;
uint8_t outcome;
int err = pn_scan_args(disp, "D.[B]", &outcome);
if (err) return err;
@@ -433,7 +463,7 @@ int pn_do_outcome(pn_dispatcher_t *disp)
static ssize_t pn_input_read_sasl_header(pn_transport_t* transport, unsigned int layer, const char* bytes, size_t available)
{
- pn_sasl_t *sasl = transport->sasl;
+ pni_sasl_t *sasl = transport->sasl;
if (available > 0) {
if (available < SASL_HEADER_LEN) {
if (memcmp(bytes, SASL_HEADER, available) == 0 ||
@@ -472,9 +502,9 @@ static ssize_t pn_input_read_sasl_header(pn_transport_t* transport, unsigned int
static ssize_t pn_input_read_sasl(pn_transport_t* transport, unsigned int layer, const char* bytes, size_t available)
{
- pn_sasl_t *sasl = transport->sasl;
+ pni_sasl_t *sasl = transport->sasl;
if (!sasl->input_bypass) {
- ssize_t n = pn_sasl_input(sasl, bytes, available);
+ ssize_t n = pn_sasl_input(transport, bytes, available);
if (n != PN_EOS) return n;
sasl->input_bypass = true;
@@ -486,7 +516,7 @@ static ssize_t pn_input_read_sasl(pn_transport_t* transport, unsigned int layer,
static ssize_t pn_output_write_sasl_header(pn_transport_t *transport, unsigned int layer, char *bytes, size_t size)
{
- pn_sasl_t *sasl = transport->sasl;
+ pni_sasl_t *sasl = transport->sasl;
if (sasl->disp->trace & PN_TRACE_FRM)
pn_transport_logf(transport, " -> %s", "SASL");
assert(size >= SASL_HEADER_LEN);
@@ -501,14 +531,14 @@ static ssize_t pn_output_write_sasl_header(pn_transport_t *transport, unsigned i
static ssize_t pn_output_write_sasl(pn_transport_t* transport, unsigned int layer, char* bytes, size_t available)
{
- pn_sasl_t *sasl = transport->sasl;
+ pni_sasl_t *sasl = transport->sasl;
if (!sasl->output_bypass) {
// this accounts for when pn_do_error is invoked, e.g. by idle timeout
ssize_t n;
if (transport->close_sent) {
n = PN_EOS;
} else {
- n = pn_sasl_output(sasl, bytes, available);
+ n = pn_sasl_output(transport, bytes, available);
}
if (n != PN_EOS) return n;
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/df029005/proton-c/src/ssl/openssl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/ssl/openssl.c b/proton-c/src/ssl/openssl.c
index 7202f7a..41e36b5 100644
--- a/proton-c/src/ssl/openssl.c
+++ b/proton-c/src/ssl/openssl.c
@@ -86,8 +86,7 @@ struct pn_ssl_domain_t {
};
-struct pn_ssl_t {
- pn_transport_t *transport;
+struct pni_ssl_t {
pn_ssl_domain_t *domain;
const char *session_id;
const char *peer_hostname;
@@ -117,6 +116,18 @@ struct pn_ssl_t {
bool write_blocked; // SSL blocked until data is written to network
};
+static inline pn_transport_t *get_transport_internal(pn_ssl_t *ssl)
+{
+ // The external pn_sasl_t is really a pointer to the internal pni_transport_t
+ return ((pn_transport_t *)ssl);
+}
+
+static inline pni_ssl_t *get_ssl_internal(pn_ssl_t *ssl)
+{
+ // The external pn_sasl_t is really a pointer to the internal pni_transport_t
+ return ssl ? ((pn_transport_t *)ssl)->ssl : NULL;
+}
+
struct pn_ssl_session_t {
const char *id;
SSL_SESSION *session;
@@ -139,53 +150,55 @@ static ssize_t process_output_unknown( pn_transport_t *transport, unsigned int l
static ssize_t process_input_done(pn_transport_t *transport, unsigned int layer, const char *input_data, size_t len);
static ssize_t process_output_done(pn_transport_t *transport, unsigned int layer, char *input_data, size_t len);
static connection_mode_t check_for_ssl_connection( const char *data, size_t len );
-static int init_ssl_socket( pn_ssl_t * );
-static void release_ssl_socket( pn_ssl_t * );
+static int init_ssl_socket(pn_transport_t *, pni_ssl_t *);
+static void release_ssl_socket( pni_ssl_t * );
static pn_ssl_session_t *ssn_cache_find( pn_ssl_domain_t *, const char * );
static void ssl_session_free( pn_ssl_session_t *);
static size_t buffered_output( pn_transport_t *transport );
// @todo: used to avoid littering the code with calls to printf...
-static void _log_error(pn_ssl_t *ssl, const char *fmt, ...)
+static void ssl_log(pn_transport_t *transport, const char *fmt, ...)
{
- va_list ap;
- va_start(ap, fmt);
- pn_transport_vlogf(ssl ? ssl->transport : NULL, fmt, ap);
- va_end(ap);
-}
-
-// @todo: used to avoid littering the code with calls to printf...
-static void _log(pn_ssl_t *ssl, const char *fmt, ...)
-{
- if (PN_TRACE_DRV & ssl->trace) {
+ if (PN_TRACE_DRV & transport->ssl->trace) {
va_list ap;
va_start(ap, fmt);
- pn_transport_vlogf(ssl->transport, fmt, ap);
+ pn_transport_vlogf(transport, fmt, ap);
va_end(ap);
}
}
-// log an error and dump the SSL error stack
-static void _log_ssl_error(pn_ssl_t *ssl, const char *fmt, ...)
+static void ssl_log_flush(pn_transport_t* transport)
{
char buf[128]; // see "man ERR_error_string_n()"
+ unsigned long err = ERR_get_error();
+ while (err) {
+ ERR_error_string_n(err, buf, sizeof(buf));
+ pn_transport_logf(transport, "%s", buf);
+ err = ERR_get_error();
+ }
+}
+
+// log an error and dump the SSL error stack
+static void ssl_log_error(const char *fmt, ...)
+{
va_list ap;
if (fmt) {
va_start(ap, fmt);
- pn_transport_vlogf(ssl ? ssl->transport : NULL, fmt, ap);
+ pn_transport_vlogf(NULL, fmt, ap);
va_end(ap);
}
+ char buf[128]; // see "man ERR_error_string_n()"
unsigned long err = ERR_get_error();
while (err) {
ERR_error_string_n(err, buf, sizeof(buf));
- _log_error(ssl, "%s", buf);
+ pn_transport_logf(NULL, "%s", buf);
err = ERR_get_error();
}
}
-static void _log_clear_data(pn_ssl_t *ssl, const char *data, size_t len)
+static void ssl_log_clear_data(pni_ssl_t *ssl, const char *data, size_t len)
{
if (PN_TRACE_RAW & ssl->trace) {
fprintf(stderr, "SSL decrypted data: \"");
@@ -195,9 +208,10 @@ static void _log_clear_data(pn_ssl_t *ssl, const char *data, size_t len)
}
// unrecoverable SSL failure occured, notify transport and generate error code.
-static int ssl_failed(pn_ssl_t *ssl)
+static int ssl_failed(pn_transport_t *transport)
{
- SSL_set_shutdown(ssl->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+ pni_ssl_t *ssl = transport->ssl;
+ SSL_set_shutdown(ssl->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
ssl->ssl_closed = true;
ssl->app_input_closed = ssl->app_output_closed = PN_EOS;
// fake a shutdown so the i/o processing code will close properly
@@ -208,8 +222,8 @@ static int ssl_failed(pn_ssl_t *ssl)
if (ssl_err) {
ERR_error_string_n( ssl_err, buf, sizeof(buf) );
}
- _log_ssl_error(ssl, NULL); // spit out any remaining errors to the log file
- pn_do_error(ssl->transport, "amqp:connection:framing-error", "SSL Failure: %s", buf);
+ ssl_log_flush(transport); // spit out any remaining errors to the log file
+ pn_do_error(transport, "amqp:connection:framing-error", "SSL Failure: %s", buf);
return PN_EOS;
}
@@ -280,23 +294,24 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
SSL *ssn = (SSL *) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
if (!ssn) {
- _log_error(NULL, "Error: unexpected error - SSL session info not available for peer verify!");
+ pn_transport_logf(NULL, "Error: unexpected error - SSL session info not available for peer verify!");
return 0; // fail connection
}
- pn_ssl_t *ssl = (pn_ssl_t *)SSL_get_ex_data(ssn, ssl_ex_data_index);
- if (!ssl) {
- _log_error(NULL, "Error: unexpected error - SSL context info not available for peer verify!");
+ pn_transport_t *transport = (pn_transport_t *)SSL_get_ex_data(ssn, ssl_ex_data_index);
+ if (!transport) {
+ pn_transport_logf(NULL, "Error: unexpected error - SSL context info not available for peer verify!");
return 0; // fail connection
}
+ pni_ssl_t *ssl = transport->ssl;
if (ssl->domain->verify_mode != PN_SSL_VERIFY_PEER_NAME) return preverify_ok;
if (!ssl->peer_hostname) {
- _log_error(ssl, "Error: configuration error: PN_SSL_VERIFY_PEER_NAME configured, but no peer hostname set!");
+ pn_transport_logf(transport, "Error: configuration error: PN_SSL_VERIFY_PEER_NAME configured, but no peer hostname set!");
return 0; // fail connection
}
- _log( ssl, "Checking identifying name in peer cert against '%s'", ssl->peer_hostname);
+ ssl_log(transport, "Checking identifying name in peer cert against '%s'", ssl->peer_hostname);
bool matched = false;
@@ -313,7 +328,7 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
unsigned char *str;
int len = ASN1_STRING_to_UTF8( &str, asn1 );
if (len >= 0) {
- _log( ssl, "SubjectAltName (dns) from peer cert = '%.*s'", len, str );
+ ssl_log(transport, "SubjectAltName (dns) from peer cert = '%.*s'", len, str );
matched = match_dns_pattern( ssl->peer_hostname, (const char *)str, len );
OPENSSL_free( str );
}
@@ -333,7 +348,7 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
unsigned char *str;
int len = ASN1_STRING_to_UTF8( &str, name_asn1);
if (len >= 0) {
- _log( ssl, "commonName from peer cert = '%.*s'", len, str );
+ ssl_log(transport, "commonName from peer cert = '%.*s'", len, str);
matched = match_dns_pattern( ssl->peer_hostname, (const char *)str, len );
OPENSSL_free(str);
}
@@ -341,14 +356,14 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
}
if (!matched) {
- _log( ssl, "Error: no name matching %s found in peer cert - rejecting handshake.",
+ ssl_log(transport, "Error: no name matching %s found in peer cert - rejecting handshake.",
ssl->peer_hostname);
preverify_ok = 0;
#ifdef X509_V_ERR_APPLICATION_VERIFICATION
X509_STORE_CTX_set_error( ctx, X509_V_ERR_APPLICATION_VERIFICATION );
#endif
} else {
- _log( ssl, "Name from peer cert matched - peer is valid." );
+ ssl_log(transport, "Name from peer cert matched - peer is valid.");
}
return preverify_ok;
}
@@ -460,7 +475,7 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
case PN_SSL_MODE_CLIENT:
domain->ctx = SSL_CTX_new(SSLv23_client_method()); // and TLSv1+
if (!domain->ctx) {
- _log_ssl_error(NULL, "Unable to initialize OpenSSL context.");
+ ssl_log_error("Unable to initialize OpenSSL context.");
free(domain);
return NULL;
}
@@ -469,14 +484,14 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
case PN_SSL_MODE_SERVER:
domain->ctx = SSL_CTX_new(SSLv23_server_method()); // and TLSv1+
if (!domain->ctx) {
- _log_ssl_error(NULL, "Unable to initialize OpenSSL context.");
+ ssl_log_error("Unable to initialize OpenSSL context.");
free(domain);
return NULL;
}
break;
default:
- _log_error(NULL, "Invalid value for pn_ssl_mode_t: %d", mode);
+ pn_transport_logf(NULL, "Invalid value for pn_ssl_mode_t: %d", mode);
free(domain);
return NULL;
}
@@ -489,7 +504,7 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
// by default, allow anonymous ciphers so certificates are not required 'out of the box'
if (!SSL_CTX_set_cipher_list( domain->ctx, CIPHERS_ANONYMOUS )) {
- _log_ssl_error(NULL, "Failed to set cipher list to %s", CIPHERS_ANONYMOUS);
+ ssl_log_error("Failed to set cipher list to %s", CIPHERS_ANONYMOUS);
pn_ssl_domain_free(domain);
return NULL;
}
@@ -538,7 +553,7 @@ int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
if (!domain || !domain->ctx) return -1;
if (SSL_CTX_use_certificate_chain_file(domain->ctx, certificate_file) != 1) {
- _log_ssl_error(NULL, "SSL_CTX_use_certificate_chain_file( %s ) failed", certificate_file);
+ ssl_log_error("SSL_CTX_use_certificate_chain_file( %s ) failed", certificate_file);
return -3;
}
@@ -549,12 +564,12 @@ int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
}
if (SSL_CTX_use_PrivateKey_file(domain->ctx, private_key_file, SSL_FILETYPE_PEM) != 1) {
- _log_ssl_error(NULL, "SSL_CTX_use_PrivateKey_file( %s ) failed", private_key_file);
+ ssl_log_error("SSL_CTX_use_PrivateKey_file( %s ) failed", private_key_file);
return -4;
}
if (SSL_CTX_check_private_key(domain->ctx) != 1) {
- _log_ssl_error(NULL, "The key file %s is not consistent with the certificate %s",
+ ssl_log_error("The key file %s is not consistent with the certificate %s",
private_key_file, certificate_file);
return -5;
}
@@ -565,7 +580,7 @@ int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
// cipher was negotiated. TLSv1 will reject such a request. Hack: once a cert is
// configured, allow only authenticated ciphers.
if (!SSL_CTX_set_cipher_list( domain->ctx, CIPHERS_AUTHENTICATE )) {
- _log_ssl_error(NULL, "Failed to set cipher list to %s", CIPHERS_AUTHENTICATE);
+ ssl_log_error("Failed to set cipher list to %s", CIPHERS_AUTHENTICATE);
return -6;
}
@@ -582,7 +597,7 @@ int pn_ssl_domain_set_trusted_ca_db(pn_ssl_domain_t *domain,
// to SSL_CTX_load_verify_locations()
struct stat sbuf;
if (stat( certificate_db, &sbuf ) != 0) {
- _log_error(NULL, "stat(%s) failed: %s", certificate_db, strerror(errno));
+ pn_transport_logf(NULL, "stat(%s) failed: %s", certificate_db, strerror(errno));
return -1;
}
@@ -597,7 +612,7 @@ int pn_ssl_domain_set_trusted_ca_db(pn_ssl_domain_t *domain,
}
if (SSL_CTX_load_verify_locations( domain->ctx, file, dir ) != 1) {
- _log_ssl_error(NULL, "SSL_CTX_load_verify_locations( %s ) failed", certificate_db);
+ ssl_log_error("SSL_CTX_load_verify_locations( %s ) failed", certificate_db);
return -1;
}
@@ -618,7 +633,7 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
case PN_SSL_VERIFY_PEER_NAME:
if (!domain->has_ca_db) {
- _log_error(NULL, "Error: cannot verify peer without a trusted CA configured.\n"
+ pn_transport_logf(NULL, "Error: cannot verify peer without a trusted CA configured.\n"
" Use pn_ssl_domain_set_trusted_ca_db()");
return -1;
}
@@ -627,11 +642,11 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
// openssl requires that server connections supply a list of trusted CAs which is
// sent to the client
if (!trusted_CAs) {
- _log_error(NULL, "Error: a list of trusted CAs must be provided.");
+ pn_transport_logf(NULL, "Error: a list of trusted CAs must be provided.");
return -1;
}
if (!domain->has_certificate) {
- _log_error(NULL, "Error: Server cannot verify peer without configuring a certificate.\n"
+ pn_transport_logf(NULL, "Error: Server cannot verify peer without configuring a certificate.\n"
" Use pn_ssl_domain_set_credentials()");
}
@@ -642,7 +657,7 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
if (cert_names != NULL)
SSL_CTX_set_client_CA_list(domain->ctx, cert_names);
else {
- _log_error(NULL, "Error: Unable to process file of trusted CAs: %s", trusted_CAs);
+ pn_transport_logf(NULL, "Error: Unable to process file of trusted CAs: %s", trusted_CAs);
return -1;
}
}
@@ -659,7 +674,7 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
break;
default:
- _log_error(NULL, "Invalid peer authentication mode given." );
+ pn_transport_logf(NULL, "Invalid peer authentication mode given." );
return -1;
}
@@ -702,21 +717,23 @@ const pn_io_layer_t ssl_closed_layer = {
buffered_output
};
-int pn_ssl_init( pn_ssl_t *ssl, pn_ssl_domain_t *domain, const char *session_id)
+int pn_ssl_init(pn_ssl_t *ssl0, pn_ssl_domain_t *domain, const char *session_id)
{
+ pn_transport_t *transport = get_transport_internal(ssl0);
+ pni_ssl_t *ssl = transport->ssl;
if (!ssl || !domain || ssl->domain) return -1;
ssl->domain = domain;
domain->ref_count++;
if (domain->allow_unsecured) {
- ssl->transport->io_layers[PN_IO_SSL] = &unknown_layer;
+ transport->io_layers[PN_IO_SSL] = &unknown_layer;
} else {
- ssl->transport->io_layers[PN_IO_SSL] = &ssl_layer;
+ transport->io_layers[PN_IO_SSL] = &ssl_layer;
}
if (session_id && domain->mode == PN_SSL_MODE_CLIENT)
ssl->session_id = pn_strdup(session_id);
- return init_ssl_socket(ssl);
+ return init_ssl_socket(transport, ssl);
}
@@ -724,7 +741,7 @@ int pn_ssl_domain_allow_unsecured_client(pn_ssl_domain_t *domain)
{
if (!domain) return -1;
if (domain->mode != PN_SSL_MODE_SERVER) {
- _log_error(NULL, "Cannot permit unsecured clients - not a server.");
+ pn_transport_log(NULL, "Cannot permit unsecured clients - not a server.");
return -1;
}
domain->allow_unsecured = true;
@@ -732,10 +749,11 @@ int pn_ssl_domain_allow_unsecured_client(pn_ssl_domain_t *domain)
}
-bool pn_ssl_get_cipher_name(pn_ssl_t *ssl, char *buffer, size_t size )
+bool pn_ssl_get_cipher_name(pn_ssl_t *ssl0, char *buffer, size_t size )
{
const SSL_CIPHER *c;
+ pni_ssl_t *ssl = get_ssl_internal(ssl0);
*buffer = '\0';
if (ssl->ssl && (c = SSL_get_current_cipher( ssl->ssl ))) {
const char *v = SSL_CIPHER_get_name(c);
@@ -747,10 +765,11 @@ bool pn_ssl_get_cipher_name(pn_ssl_t *ssl, char *buffer, size_t size )
return false;
}
-bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *buffer, size_t size )
+bool pn_ssl_get_protocol_name(pn_ssl_t *ssl0, char *buffer, size_t size )
{
const SSL_CIPHER *c;
+ pni_ssl_t *ssl = get_ssl_internal(ssl0);
*buffer = '\0';
if (ssl->ssl && (c = SSL_get_current_cipher( ssl->ssl ))) {
const char *v = SSL_CIPHER_get_version(c);
@@ -763,10 +782,11 @@ bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *buffer, size_t size )
}
-void pn_ssl_free( pn_ssl_t *ssl)
+void pn_ssl_free(pn_transport_t *transport)
{
+ pni_ssl_t *ssl = transport->ssl;
if (!ssl) return;
- _log( ssl, "SSL socket freed." );
+ ssl_log(transport, "SSL socket freed." );
release_ssl_socket( ssl );
if (ssl->domain) pn_ssl_domain_free(ssl->domain);
if (ssl->session_id) free((void *)ssl->session_id);
@@ -779,9 +799,9 @@ void pn_ssl_free( pn_ssl_t *ssl)
pn_ssl_t *pn_ssl(pn_transport_t *transport)
{
if (!transport) return NULL;
- if (transport->ssl) return transport->ssl;
+ if (transport->ssl) return (pn_ssl_t *) transport;
- pn_ssl_t *ssl = (pn_ssl_t *) calloc(1, sizeof(pn_ssl_t));
+ pni_ssl_t *ssl = (pni_ssl_t *) calloc(1, sizeof(pni_ssl_t));
if (!ssl) return NULL;
ssl->out_size = APP_BUF_SIZE;
uint32_t max_frame = pn_transport_get_max_frame(transport);
@@ -798,14 +818,11 @@ pn_ssl_t *pn_ssl(pn_transport_t *transport)
return NULL;
}
- ssl->transport = transport;
transport->ssl = ssl;
- transport->io_layers[PN_IO_SSL] = &pni_passthru_layer;
-
ssl->trace = (transport->disp) ? transport->disp->trace : PN_TRACE_OFF;
- return ssl;
+ return (pn_ssl_t *) transport;
}
@@ -819,10 +836,11 @@ static int keyfile_pw_cb(char *buf, int size, int rwflag, void *userdata)
}
-static int start_ssl_shutdown( pn_ssl_t *ssl )
+static int start_ssl_shutdown(pn_transport_t *transport)
{
+ pni_ssl_t *ssl = transport->ssl;
if (!ssl->ssl_shutdown) {
- _log(ssl, "Shutting down SSL connection...");
+ ssl_log(transport, "Shutting down SSL connection...");
if (ssl->session_id) {
// save the negotiated credentials before we close the connection
pn_ssl_session_t *ssn = (pn_ssl_session_t *)calloc( 1, sizeof(pn_ssl_session_t));
@@ -830,7 +848,7 @@ static int start_ssl_shutdown( pn_ssl_t *ssl )
ssn->id = pn_strdup( ssl->session_id );
ssn->session = SSL_get1_session( ssl->ssl );
if (ssn->session) {
- _log( ssl, "Saving SSL session as %s", ssl->session_id );
+ ssl_log(transport, "Saving SSL session as %s", ssl->session_id );
LL_ADD( ssl->domain, ssn_cache, ssn );
} else {
ssl_session_free( ssn );
@@ -858,10 +876,10 @@ static int setup_ssl_connection(pn_transport_t *transport, unsigned int layer)
// SSL socket and pass it to the application.
static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer, const char *input_data, size_t available)
{
- pn_ssl_t *ssl = transport->ssl;
- if (ssl->ssl == NULL && init_ssl_socket(ssl)) return PN_EOS;
+ pni_ssl_t *ssl = transport->ssl;
+ if (ssl->ssl == NULL && init_ssl_socket(transport, ssl)) return PN_EOS;
- _log( ssl, "process_input_ssl( data size=%d )",available );
+ ssl_log( transport, "process_input_ssl( data size=%d )",available );
ssize_t consumed = 0;
bool work_pending;
@@ -880,12 +898,12 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
consumed += written;
ssl->read_blocked = false;
work_pending = (available > 0);
- _log( ssl, "Wrote %d bytes to BIO Layer, %d left over", written, available );
+ ssl_log( transport, "Wrote %d bytes to BIO Layer, %d left over", written, available );
}
} else if (shutdown_input) {
// lower layer (caller) has closed. Close the WRITE side of the BIO. This will cause
// an EOF to be passed to SSL once all pending inbound data has been consumed.
- _log( ssl, "Lower layer closed - shutting down BIO write side");
+ ssl_log( transport, "Lower layer closed - shutting down BIO write side");
(void)BIO_shutdown_wr( ssl->bio_net_io );
shutdown_input = false;
}
@@ -895,8 +913,8 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
if (!ssl->ssl_closed && ssl->in_count < ssl->in_size) {
int read = BIO_read( ssl->bio_ssl, &ssl->inbuf[ssl->in_count], ssl->in_size - ssl->in_count );
if (read > 0) {
- _log( ssl, "Read %d bytes from SSL socket for app", read );
- _log_clear_data( ssl, &ssl->inbuf[ssl->in_count], read );
+ ssl_log( transport, "Read %d bytes from SSL socket for app", read );
+ ssl_log_clear_data( ssl, &ssl->inbuf[ssl->in_count], read );
ssl->in_count += read;
work_pending = true;
} else {
@@ -905,22 +923,22 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
switch (reason) {
case SSL_ERROR_ZERO_RETURN:
// SSL closed cleanly
- _log(ssl, "SSL connection has closed");
- start_ssl_shutdown(ssl); // KAG: not sure - this may not be necessary
+ ssl_log(transport, "SSL connection has closed");
+ start_ssl_shutdown(transport); // KAG: not sure - this may not be necessary
ssl->ssl_closed = true;
break;
default:
// unexpected error
- return (ssize_t)ssl_failed(ssl);
+ return (ssize_t)ssl_failed(transport);
}
} else {
if (BIO_should_write( ssl->bio_ssl )) {
ssl->write_blocked = true;
- _log(ssl, "Detected write-blocked");
+ ssl_log(transport, "Detected write-blocked");
}
if (BIO_should_read( ssl->bio_ssl )) {
ssl->read_blocked = true;
- _log(ssl, "Detected read-blocked");
+ ssl_log(transport, "Detected read-blocked");
}
}
}
@@ -936,22 +954,22 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
if (ssl->in_count)
memmove( ssl->inbuf, ssl->inbuf + consumed, ssl->in_count );
work_pending = true;
- _log( ssl, "Application consumed %d bytes from peer", (int) consumed );
+ ssl_log( transport, "Application consumed %d bytes from peer", (int) consumed );
} else if (consumed < 0) {
- _log(ssl, "Application layer closed its input, error=%d (discarding %d bytes)",
+ ssl_log(transport, "Application layer closed its input, error=%d (discarding %d bytes)",
(int) consumed, (int)ssl->in_count);
ssl->in_count = 0; // discard any pending input
ssl->app_input_closed = consumed;
if (ssl->app_output_closed && ssl->out_count == 0) {
// both sides of app closed, and no more app output pending:
- start_ssl_shutdown(ssl);
+ start_ssl_shutdown(transport);
}
} else {
// app did not consume any bytes, must be waiting for a full frame
if (ssl->in_count == ssl->in_size) {
// but the buffer is full, not enough room for a full frame.
// can we grow the buffer?
- uint32_t max_frame = pn_transport_get_max_frame(ssl->transport);
+ uint32_t max_frame = pn_transport_get_max_frame(transport);
if (!max_frame) max_frame = ssl->in_size * 2; // no limit
if (ssl->in_size < max_frame) {
// no max frame limit - grow it.
@@ -968,7 +986,7 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
// the application _must_ have enough data to process. If
// this is an oversized frame, the app _must_ handle it
// by returning an error code to SSL.
- _log_error(ssl, "Error: application unable to consume input.");
+ pn_transport_log(transport, "Error: application unable to consume input.");
}
}
}
@@ -998,15 +1016,15 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
transport->io_layers[layer] = &ssl_input_closed_layer;
}
}
- _log(ssl, "process_input_ssl() returning %d", (int) consumed);
+ ssl_log(transport, "process_input_ssl() returning %d", (int) consumed);
return consumed;
}
static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer, char *buffer, size_t max_len)
{
- pn_ssl_t *ssl = transport->ssl;
+ pni_ssl_t *ssl = transport->ssl;
if (!ssl) return PN_EOS;
- if (ssl->ssl == NULL && init_ssl_socket(ssl)) return PN_EOS;
+ if (ssl->ssl == NULL && init_ssl_socket(transport, ssl)) return PN_EOS;
ssize_t written = 0;
bool work_pending;
@@ -1020,10 +1038,10 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
if (app_bytes > 0) {
ssl->out_count += app_bytes;
work_pending = true;
- _log( ssl, "Gathered %d bytes from app to send to peer", app_bytes );
+ ssl_log(transport, "Gathered %d bytes from app to send to peer", app_bytes );
} else {
if (app_bytes < 0) {
- _log(ssl, "Application layer closed its output, error=%d (%d bytes pending send)",
+ ssl_log(transport, "Application layer closed its output, error=%d (%d bytes pending send)",
(int) app_bytes, (int) ssl->out_count);
ssl->app_output_closed = app_bytes;
}
@@ -1040,30 +1058,30 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
data += wrote;
ssl->out_count -= wrote;
work_pending = true;
- _log( ssl, "Wrote %d bytes from app to socket", wrote );
+ ssl_log( transport, "Wrote %d bytes from app to socket", wrote );
} else {
if (!BIO_should_retry(ssl->bio_ssl)) {
int reason = SSL_get_error( ssl->ssl, wrote );
switch (reason) {
case SSL_ERROR_ZERO_RETURN:
// SSL closed cleanly
- _log(ssl, "SSL connection has closed");
- start_ssl_shutdown(ssl); // KAG: not sure - this may not be necessary
+ ssl_log(transport, "SSL connection has closed");
+ start_ssl_shutdown(transport); // KAG: not sure - this may not be necessary
ssl->out_count = 0; // can no longer write to socket, so erase app output data
ssl->ssl_closed = true;
break;
default:
// unexpected error
- return (ssize_t)ssl_failed(ssl);
+ return (ssize_t)ssl_failed(transport);
}
} else {
if (BIO_should_read( ssl->bio_ssl )) {
ssl->read_blocked = true;
- _log(ssl, "Detected read-blocked");
+ ssl_log(transport, "Detected read-blocked");
}
if (BIO_should_write( ssl->bio_ssl )) {
ssl->write_blocked = true;
- _log(ssl, "Detected write-blocked");
+ ssl_log(transport, "Detected write-blocked");
}
}
}
@@ -1073,7 +1091,7 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
if (ssl->app_input_closed && ssl->app_output_closed) {
// application is done sending/receiving data, and all buffered output data has
// been written to the SSL socket
- start_ssl_shutdown(ssl);
+ start_ssl_shutdown(transport);
}
} else if (data != ssl->outbuf) {
memmove( ssl->outbuf, data, ssl->out_count );
@@ -1089,7 +1107,7 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
written += available;
ssl->write_blocked = false;
work_pending = work_pending || max_len > 0;
- _log( ssl, "Read %d bytes from BIO Layer", available );
+ ssl_log(transport, "Read %d bytes from BIO Layer", available );
}
}
@@ -1114,23 +1132,23 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
transport->io_layers[layer] = &ssl_output_closed_layer;
}
}
- _log(ssl, "process_output_ssl() returning %d", (int) written);
+ ssl_log(transport, "process_output_ssl() returning %d", (int) written);
return written;
}
-static int init_ssl_socket( pn_ssl_t *ssl )
+static int init_ssl_socket(pn_transport_t* transport, pni_ssl_t *ssl)
{
if (ssl->ssl) return 0;
if (!ssl->domain) return -1;
ssl->ssl = SSL_new(ssl->domain->ctx);
if (!ssl->ssl) {
- _log_error(ssl, "SSL socket setup failure." );
+ pn_transport_logf(transport, "SSL socket setup failure." );
return -1;
}
- // store backpointer to pn_ssl_t in SSL object:
- SSL_set_ex_data(ssl->ssl, ssl_ex_data_index, ssl);
+ // store backpointer to pn_transport_t in SSL object:
+ SSL_set_ex_data(ssl->ssl, ssl_ex_data_index, transport);
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
if (ssl->peer_hostname && ssl->domain->mode == PN_SSL_MODE_CLIENT) {
@@ -1142,10 +1160,10 @@ static int init_ssl_socket( pn_ssl_t *ssl )
if (ssl->session_id) {
pn_ssl_session_t *ssn = ssn_cache_find( ssl->domain, ssl->session_id );
if (ssn) {
- _log( ssl, "Restoring previous session id=%s", ssn->id );
+ ssl_log( transport, "Restoring previous session id=%s", ssn->id );
int rc = SSL_set_session( ssl->ssl, ssn->session );
if (rc != 1) {
- _log( ssl, "Session restore failed, id=%s", ssn->id );
+ ssl_log( transport, "Session restore failed, id=%s", ssn->id );
}
LL_REMOVE( ssl->domain, ssn_cache, ssn );
ssl_session_free( ssn );
@@ -1155,14 +1173,14 @@ static int init_ssl_socket( pn_ssl_t *ssl )
// now layer a BIO over the SSL socket
ssl->bio_ssl = BIO_new(BIO_f_ssl());
if (!ssl->bio_ssl) {
- _log_error(ssl, "BIO setup failure." );
+ pn_transport_log(transport, "BIO setup failure." );
return -1;
}
(void)BIO_set_ssl(ssl->bio_ssl, ssl->ssl, BIO_NOCLOSE);
// create the "lower" BIO "pipe", and attach it below the SSL layer
if (!BIO_new_bio_pair(&ssl->bio_ssl_io, 0, &ssl->bio_net_io, 0)) {
- _log_error(ssl, "BIO setup failure." );
+ pn_transport_log(transport, "BIO setup failure." );
return -1;
}
SSL_set_bio(ssl->ssl, ssl->bio_ssl_io, ssl->bio_ssl_io);
@@ -1170,16 +1188,16 @@ static int init_ssl_socket( pn_ssl_t *ssl )
if (ssl->domain->mode == PN_SSL_MODE_SERVER) {
SSL_set_accept_state(ssl->ssl);
BIO_set_ssl_mode(ssl->bio_ssl, 0); // server mode
- _log( ssl, "Server SSL socket created." );
+ ssl_log( transport, "Server SSL socket created." );
} else { // client mode
SSL_set_connect_state(ssl->ssl);
BIO_set_ssl_mode(ssl->bio_ssl, 1); // client mode
- _log( ssl, "Client SSL socket created." );
+ ssl_log( transport, "Client SSL socket created." );
}
return 0;
}
-static void release_ssl_socket( pn_ssl_t *ssl )
+static void release_ssl_socket(pni_ssl_t *ssl)
{
if (ssl->bio_ssl) BIO_free(ssl->bio_ssl);
if (ssl->ssl) {
@@ -1206,14 +1224,13 @@ static int setup_cleartext_connection(pn_transport_t *transport, unsigned int la
static ssize_t process_input_unknown(pn_transport_t *transport, unsigned int layer, const char *input_data, size_t len)
{
- pn_ssl_t *ssl = transport->ssl;
switch (check_for_ssl_connection( input_data, len )) {
case SSL_CONNECTION:
- _log( ssl, "SSL connection detected.\n");
+ ssl_log( transport, "SSL connection detected.");
setup_ssl_connection(transport, layer);
break;
case CLEAR_CONNECTION:
- _log( ssl, "Cleartext connection detected.\n");
+ ssl_log( transport, "Cleartext connection detected.");
setup_cleartext_connection(transport, layer);
break;
default:
@@ -1281,14 +1298,15 @@ static connection_mode_t check_for_ssl_connection( const char *data, size_t len
return UNKNOWN_CONNECTION;
}
-void pn_ssl_trace(pn_ssl_t *ssl, pn_trace_t trace)
+void pn_ssl_trace(pn_transport_t *transport, pn_trace_t trace)
{
- ssl->trace = trace;
+ transport->ssl->trace = trace;
}
-pn_ssl_resume_status_t pn_ssl_resume_status( pn_ssl_t *ssl )
+pn_ssl_resume_status_t pn_ssl_resume_status(pn_ssl_t *ssl0)
{
+ pni_ssl_t *ssl = get_ssl_internal(ssl0);
if (!ssl || !ssl->ssl) return PN_SSL_RESUME_UNKNOWN;
switch (SSL_session_reused( ssl->ssl )) {
case 0: return PN_SSL_RESUME_NEW;
@@ -1299,8 +1317,9 @@ pn_ssl_resume_status_t pn_ssl_resume_status( pn_ssl_t *ssl )
}
-int pn_ssl_set_peer_hostname( pn_ssl_t *ssl, const char *hostname )
+int pn_ssl_set_peer_hostname(pn_ssl_t *ssl0, const char *hostname)
{
+ pni_ssl_t *ssl = get_ssl_internal(ssl0);
if (!ssl) return -1;
if (ssl->peer_hostname) free((void *)ssl->peer_hostname);
@@ -1317,8 +1336,9 @@ int pn_ssl_set_peer_hostname( pn_ssl_t *ssl, const char *hostname )
return 0;
}
-int pn_ssl_get_peer_hostname( pn_ssl_t *ssl, char *hostname, size_t *bufsize )
+int pn_ssl_get_peer_hostname(pn_ssl_t *ssl0, char *hostname, size_t *bufsize)
{
+ pni_ssl_t *ssl = get_ssl_internal(ssl0);
if (!ssl) return -1;
if (!ssl->peer_hostname) {
*bufsize = 0;
@@ -1347,7 +1367,7 @@ static ssize_t process_output_done(pn_transport_t *transport, unsigned int layer
static size_t buffered_output(pn_transport_t *transport)
{
size_t count = 0;
- pn_ssl_t *ssl = transport->ssl;
+ pni_ssl_t *ssl = transport->ssl;
if (ssl) {
count += ssl->out_count;
if (ssl->bio_net_io) { // pick up any bytes waiting for network io
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/df029005/proton-c/src/ssl/ssl-internal.h
----------------------------------------------------------------------
diff --git a/proton-c/src/ssl/ssl-internal.h b/proton-c/src/ssl/ssl-internal.h
index c72e513..f1cd637 100644
--- a/proton-c/src/ssl/ssl-internal.h
+++ b/proton-c/src/ssl/ssl-internal.h
@@ -29,8 +29,8 @@
*/
// release the SSL context
-void pn_ssl_free( pn_ssl_t *ssl);
+void pn_ssl_free(pn_transport_t *transport);
-void pn_ssl_trace(pn_ssl_t *ssl, pn_trace_t trace);
+void pn_ssl_trace(pn_transport_t *transport, pn_trace_t trace);
#endif /* ssl-internal.h */
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/df029005/proton-c/src/transport/transport.c
----------------------------------------------------------------------
diff --git a/proton-c/src/transport/transport.c b/proton-c/src/transport/transport.c
index 2c086db..865f8c9 100644
--- a/proton-c/src/transport/transport.c
+++ b/proton-c/src/transport/transport.c
@@ -268,8 +268,8 @@ static void pn_transport_finalize(void *object)
{
pn_transport_t *transport = (pn_transport_t *) object;
- pn_ssl_free(transport->ssl);
- pn_sasl_free(transport->sasl);
+ pn_ssl_free(transport);
+ pn_sasl_free(transport);
pn_dispatcher_free(transport->disp);
free(transport->remote_container);
free(transport->remote_hostname);
@@ -1945,8 +1945,8 @@ ssize_t pn_transport_output(pn_transport_t *transport, char *bytes, size_t size)
void pn_transport_trace(pn_transport_t *transport, pn_trace_t trace)
{
- if (transport->sasl) pn_sasl_trace(transport->sasl, trace);
- if (transport->ssl) pn_ssl_trace(transport->ssl, trace);
+ if (transport->sasl) pn_sasl_trace(transport, trace);
+ if (transport->ssl) pn_ssl_trace(transport, trace);
transport->disp->trace = trace;
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/df029005/proton-c/src/windows/schannel.c
----------------------------------------------------------------------
diff --git a/proton-c/src/windows/schannel.c b/proton-c/src/windows/schannel.c
index 7f47745..231349c 100644
--- a/proton-c/src/windows/schannel.c
+++ b/proton-c/src/windows/schannel.c
@@ -80,8 +80,7 @@ struct pn_ssl_domain_t {
typedef enum { CREATED, CLIENT_HELLO, NEGOTIATING,
RUNNING, SHUTTING_DOWN, SSL_CLOSED } ssl_state_t;
-struct pn_ssl_t {
- pn_transport_t *transport;
+struct pni_ssl_t {
pn_ssl_domain_t *domain;
const char *session_id;
const char *peer_hostname;
@@ -127,6 +126,18 @@ struct pn_ssl_t {
SecPkgContext_StreamSizes sc_sizes;
};
+static inline pn_transport_t *get_transport_internal(pn_ssl_t *ssl)
+{
+ // The external pn_sasl_t is really a pointer to the internal pni_transport_t
+ return ((pn_transport_t *)ssl);
+}
+
+static inline pni_ssl_t *get_ssl_internal(pn_ssl_t *ssl)
+{
+ // The external pn_sasl_t is really a pointer to the internal pni_transport_t
+ return ssl ? ((pn_transport_t *)ssl)->ssl : NULL;
+}
+
struct pn_ssl_session_t {
const char *id;
// TODO
@@ -145,9 +156,9 @@ static connection_mode_t check_for_ssl_connection( const char *data, size_t len
static pn_ssl_session_t *ssn_cache_find( pn_ssl_domain_t *, const char * );
static void ssl_session_free( pn_ssl_session_t *);
static size_t buffered_output( pn_transport_t *transport );
-static void start_ssl_shutdown(pn_ssl_t *ssl);
-static void rewind_sc_inbuf(pn_ssl_t *ssl);
-static bool grow_inbuf2(pn_ssl_t *ssl, size_t minimum_size);
+static void start_ssl_shutdown(pn_transport_t *transport);
+static void rewind_sc_inbuf(pni_ssl_t *ssl);
+static bool grow_inbuf2(pn_transport_t *ssl, size_t minimum_size);
// @todo: used to avoid littering the code with calls to printf...
@@ -161,7 +172,7 @@ static void ssl_log_error(const char *fmt, ...)
}
// @todo: used to avoid littering the code with calls to printf...
-static void ssl_log(pn_ssl_t *ssl, const char *fmt, ...)
+static void ssl_log(pni_ssl_t *ssl, const char *fmt, ...)
{
if (PN_TRACE_DRV & ssl->trace) {
va_list ap;
@@ -192,7 +203,7 @@ static void ssl_log_error_status(HRESULT status, const char *fmt, ...)
fflush(stderr);
}
-static void ssl_log_clear_data(pn_ssl_t *ssl, const char *data, size_t len)
+static void ssl_log_clear_data(pni_ssl_t *ssl, const char *data, size_t len)
{
if (PN_TRACE_RAW & ssl->trace) {
fprintf(stderr, "SSL decrypted data: \"");
@@ -207,7 +218,7 @@ static size_t _pni_min(size_t a, size_t b)
}
// unrecoverable SSL failure occured, notify transport and generate error code.
-static int ssl_failed(pn_ssl_t *ssl, const char *reason)
+static int ssl_failed(pn_transport_t *transport, const char *reason)
{
char buf[512] = "Unknown error.";
if (!reason) {
@@ -217,10 +228,11 @@ static int ssl_failed(pn_ssl_t *ssl, const char *reason)
0, status, 0, buf, sizeof(buf), 0);
reason = buf;
}
+ pni_ssl_t *ssl = transport->ssl;
ssl->ssl_closed = true;
ssl->app_input_closed = ssl->app_output_closed = PN_EOS;
ssl->state = SSL_CLOSED;
- pn_do_error(ssl->transport, "amqp:connection:framing-error", "SSL Failure: %s", reason);
+ pn_do_error(transport, "amqp:connection:framing-error", "SSL Failure: %s", reason);
return PN_EOS;
}
@@ -383,18 +395,20 @@ const pn_io_layer_t ssl_closed_layer = {
buffered_output
};
-int pn_ssl_init(pn_ssl_t *ssl, pn_ssl_domain_t *domain, const char *session_id)
+int pn_ssl_init(pn_ssl_t *ssl0, pn_ssl_domain_t *domain, const char *session_id)
{
+ pn_transport_t *transport = get_transport_internal(ssl0);
+ pni_ssl_t *ssl = transport->ssl;
if (!ssl || !domain || ssl->domain) return -1;
if (ssl->state != CREATED) return -1;
ssl->domain = domain;
domain->ref_count++;
if (domain->allow_unsecured) {
- ssl->transport->io_layers[PN_IO_SSL] = &unknown_layer;
+ transport->io_layers[PN_IO_SSL] = &unknown_layer;
}
else {
- ssl->transport->io_layers[PN_IO_SSL] = &ssl_layer;
+ transport->io_layers[PN_IO_SSL] = &ssl_layer;
}
if (session_id && domain->mode == PN_SSL_MODE_CLIENT)
ssl->session_id = pn_strdup(session_id);
@@ -440,8 +454,9 @@ bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *buffer, size_t size )
}
-void pn_ssl_free( pn_ssl_t *ssl)
+void pn_ssl_free( pn_transport_t *transport)
{
+ pni_ssl_t *ssl = transport->ssl;
if (!ssl) return;
ssl_log( ssl, "SSL socket freed.\n" );
// clean up Windows per TLS session data before releasing the domain count
@@ -462,9 +477,9 @@ void pn_ssl_free( pn_ssl_t *ssl)
pn_ssl_t *pn_ssl(pn_transport_t *transport)
{
if (!transport) return NULL;
- if (transport->ssl) return transport->ssl;
+ if (transport->ssl) return (pn_ssl_t *)transport;
- pn_ssl_t *ssl = (pn_ssl_t *) calloc(1, sizeof(pn_ssl_t));
+ pni_ssl_t *ssl = (pni_ssl_t *) calloc(1, sizeof(pni_ssl_t));
if (!ssl) return NULL;
ssl->sc_out_size = ssl->sc_in_size = SSL_BUF_SIZE;
@@ -488,23 +503,20 @@ pn_ssl_t *pn_ssl(pn_transport_t *transport)
return NULL;
}
- ssl->transport = transport;
transport->ssl = ssl;
- transport->io_layers[PN_IO_SSL] = &pni_passthru_layer;
-
ssl->trace = (transport->disp) ? transport->disp->trace : PN_TRACE_OFF;
SecInvalidateHandle(&ssl->cred_handle);
SecInvalidateHandle(&ssl->ctxt_handle);
ssl->state = CREATED;
ssl->decrypting = true;
- return ssl;
+ return (pn_ssl_t *)transport;
}
-void pn_ssl_trace(pn_ssl_t *ssl, pn_trace_t trace)
+void pn_ssl_trace(pn_transport_t *transport, pn_trace_t trace)
{
- ssl->trace = trace;
+ transport->ssl->trace = trace;
}
@@ -515,8 +527,9 @@ pn_ssl_resume_status_t pn_ssl_resume_status( pn_ssl_t *ssl )
}
-int pn_ssl_set_peer_hostname( pn_ssl_t *ssl, const char *hostname )
+int pn_ssl_set_peer_hostname( pn_ssl_t *ssl0, const char *hostname )
{
+ pni_ssl_t *ssl = get_ssl_internal(ssl0);
if (!ssl) return -1;
if (ssl->peer_hostname) free((void *)ssl->peer_hostname);
@@ -528,8 +541,9 @@ int pn_ssl_set_peer_hostname( pn_ssl_t *ssl, const char *hostname )
return 0;
}
-int pn_ssl_get_peer_hostname( pn_ssl_t *ssl, char *hostname, size_t *bufsize )
+int pn_ssl_get_peer_hostname( pn_ssl_t *ssl0, char *hostname, size_t *bufsize )
{
+ pni_ssl_t *ssl = get_ssl_internal(ssl0);
if (!ssl) return -1;
if (!ssl->peer_hostname) {
*bufsize = 0;
@@ -548,7 +562,7 @@ int pn_ssl_get_peer_hostname( pn_ssl_t *ssl, char *hostname, size_t *bufsize )
/** SChannel specific: */
-const char *tls_version_check(pn_ssl_t *ssl)
+const char *tls_version_check(pni_ssl_t *ssl)
{
SecPkgContext_ConnectionInfo info;
QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_CONNECTION_INFO, &info);
@@ -558,7 +572,7 @@ const char *tls_version_check(pn_ssl_t *ssl)
"peer does not support TLS 1.0 security" : NULL;
}
-static void ssl_encrypt(pn_ssl_t *ssl, char *app_data, size_t count)
+static void ssl_encrypt(pni_ssl_t *ssl, char *app_data, size_t count)
{
// Get SChannel to encrypt exactly one Record.
SecBuffer buffs[4];
@@ -591,8 +605,9 @@ static void ssl_encrypt(pn_ssl_t *ssl, char *app_data, size_t count)
}
// Returns true if decryption succeeded (even for empty content)
-static bool ssl_decrypt(pn_ssl_t *ssl)
+static bool ssl_decrypt(pn_transport_t *transport)
{
+ pni_ssl_t *ssl = transport->ssl;
// Get SChannel to decrypt input. May have an incomplete Record,
// exactly one, or more than one. Check also for session ending,
// session renegotiation.
@@ -630,7 +645,7 @@ static bool ssl_decrypt(pn_ssl_t *ssl)
case SEC_I_RENEGOTIATE:
// TODO. Fall through for now.
default:
- ssl_failed(ssl, 0);
+ ssl_failed(transport, 0);
return false;
}
}
@@ -657,8 +672,9 @@ static bool ssl_decrypt(pn_ssl_t *ssl)
return true;
}
-static void client_handshake_init(pn_ssl_t *ssl)
+static void client_handshake_init(pn_transport_t *transport)
{
+ pni_ssl_t *ssl = transport->ssl;
// Tell SChannel to create the first handshake token (ClientHello)
// and place it in sc_outbuf
SEC_CHAR *host = const_cast<SEC_CHAR *>(ssl->peer_hostname);
@@ -689,11 +705,12 @@ static void client_handshake_init(pn_ssl_t *ssl)
ssl_log(ssl, "Sending client hello %d bytes\n", ssl->network_out_pending);
} else {
ssl_log_error_status(status, "InitializeSecurityContext failed");
- ssl_failed(ssl, 0);
+ ssl_failed(transport, 0);
}
}
-static void client_handshake( pn_ssl_t* ssl) {
+static void client_handshake( pn_transport_t* transport) {
+ pni_ssl_t *ssl = transport->ssl;
// Feed SChannel ongoing responses from the server until the handshake is complete.
SEC_CHAR *host = const_cast<SEC_CHAR *>(ssl->peer_hostname);
ULONG ctxt_requested = ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS;
@@ -766,11 +783,11 @@ static void client_handshake( pn_ssl_t* ssl) {
return;
}
if (send_buffs[0].cbBuffer != 0) {
- ssl_failed(ssl, "unexpected final server token");
+ ssl_failed(transport, "unexpected final server token");
break;
}
if (const char *err = tls_version_check(ssl)) {
- ssl_failed(ssl, err);
+ ssl_failed(transport, err);
break;
}
if (token_buffs[1].BufferType == SECBUFFER_EXTRA && token_buffs[1].cbBuffer > 0) {
@@ -787,8 +804,8 @@ static void client_handshake( pn_ssl_t* ssl) {
ssl_log_error("Buffer size mismatch have %d, need %d\n", (int) ssl->sc_out_size, (int) max);
ssl->state = SHUTTING_DOWN;
ssl->app_input_closed = ssl->app_output_closed = PN_ERR;
- start_ssl_shutdown(ssl);
- pn_do_error(ssl->transport, "amqp:connection:framing-error", "SSL Failure: buffer size");
+ start_ssl_shutdown(transport);
+ pn_do_error(transport, "amqp:connection:framing-error", "SSL Failure: buffer size");
break;
}
@@ -801,7 +818,7 @@ static void client_handshake( pn_ssl_t* ssl) {
// ended before we got going
default:
ssl_log(ssl, "client handshake failed %d\n", (int) status);
- ssl_failed(ssl, 0);
+ ssl_failed(transport, 0);
break;
}
ssl->decrypting = false;
@@ -809,28 +826,29 @@ static void client_handshake( pn_ssl_t* ssl) {
}
-static void ssl_handshake(pn_ssl_t* ssl) {
- if (ssl->domain->mode == PN_SSL_MODE_CLIENT)
- client_handshake(ssl);
+static void ssl_handshake(pn_transport_t* transport) {
+ if (transport->ssl->domain->mode == PN_SSL_MODE_CLIENT)
+ client_handshake(transport);
else {
- ssl_log( ssl, "TODO: server handshake.\n" );
- ssl_failed(ssl, "internal runtime error, not yet implemented");
+ ssl_log(transport->ssl, "TODO: server handshake.\n" );
+ ssl_failed(transport, "internal runtime error, not yet implemented");
}
}
-static bool grow_inbuf2(pn_ssl_t *ssl, size_t minimum_size) {
+static bool grow_inbuf2(pn_transport_t *transport, size_t minimum_size) {
+ pni_ssl_t *ssl = transport->ssl;
size_t old_capacity = pn_buffer_capacity(ssl->inbuf2);
size_t new_capacity = old_capacity ? old_capacity * 2 : 1024;
while (new_capacity < minimum_size)
new_capacity *= 2;
- uint32_t max_frame = pn_transport_get_max_frame(ssl->transport);
+ uint32_t max_frame = pn_transport_get_max_frame(transport);
if (max_frame != 0) {
if (old_capacity >= max_frame) {
// already big enough
- ssl_log(ssl, "Application expecting %d bytes (> negotiated maximum frame)\n", new_capacity);
- ssl_failed(ssl, "TLS: transport maximimum frame size error");
+ ssl_log(transport->ssl, "Application expecting %d bytes (> negotiated maximum frame)\n", new_capacity);
+ ssl_failed(transport, "TLS: transport maximimum frame size error");
return false;
}
}
@@ -839,7 +857,7 @@ static bool grow_inbuf2(pn_ssl_t *ssl, size_t minimum_size) {
int err = pn_buffer_ensure(ssl->inbuf2, extra_bytes);
if (err) {
ssl_log(ssl, "TLS memory allocation failed for %d bytes\n", max_frame);
- ssl_failed(ssl, "TLS memory allocation failed");
+ ssl_failed(transport, "TLS memory allocation failed");
return false;
}
return true;
@@ -851,8 +869,9 @@ static bool grow_inbuf2(pn_ssl_t *ssl, size_t minimum_size) {
// for the peer shutdown alert). Stop processing input immediately, and stop processing
// output once this is sent.
-static void start_ssl_shutdown(pn_ssl_t *ssl)
+static void start_ssl_shutdown(pn_transport_t *transport)
{
+ pni_ssl_t *ssl = transport->ssl;
assert(ssl->network_out_pending == 0);
if (ssl->queued_shutdown)
return;
@@ -871,7 +890,7 @@ static void start_ssl_shutdown(pn_ssl_t *ssl)
::ApplyControlToken(&ssl->ctxt_handle, &desc);
// Next handshake will generate the shudown alert token
- ssl_handshake(ssl);
+ ssl_handshake(transport);
}
static int setup_ssl_connection(pn_transport_t *transport, unsigned int layer)
@@ -880,7 +899,7 @@ static int setup_ssl_connection(pn_transport_t *transport, unsigned int layer)
return 0;
}
-static void rewind_sc_inbuf(pn_ssl_t *ssl)
+static void rewind_sc_inbuf(pni_ssl_t *ssl)
{
// Decrypted bytes have been drained or double buffered. Prepare for the next SSL Record.
assert(ssl->in_data_count == 0);
@@ -898,8 +917,9 @@ static void rewind_sc_inbuf(pn_ssl_t *ssl)
}
}
-static void app_inbytes_add(pn_ssl_t *ssl)
+static void app_inbytes_add(pn_transport_t *transport)
{
+ pni_ssl_t *ssl = transport->ssl;
if (!ssl->app_inbytes.start) {
ssl->app_inbytes.start = ssl->in_data;
ssl->app_inbytes.size = ssl->in_data_count;
@@ -908,7 +928,7 @@ static void app_inbytes_add(pn_ssl_t *ssl)
if (ssl->double_buffered) {
if (pn_buffer_available(ssl->inbuf2) == 0) {
- if (!grow_inbuf2(ssl, 1024))
+ if (!grow_inbuf2(transport, 1024))
// could not add room
return;
}
@@ -925,8 +945,9 @@ static void app_inbytes_add(pn_ssl_t *ssl)
}
-static void app_inbytes_progress(pn_ssl_t *ssl, size_t minimum)
+static void app_inbytes_progress(pn_transport_t *transport, size_t minimum)
{
+ pni_ssl_t *ssl = transport->ssl;
// Make more decrypted data available, if possible. Otherwise, move
// unread bytes to front of inbuf2 to make room for next bulk decryption.
// SSL may have chopped up data that app layer expects to be
@@ -947,7 +968,7 @@ static void app_inbytes_progress(pn_ssl_t *ssl, size_t minimum)
pn_buffer_trim(ssl->inbuf2, 0, consumed);
}
if (!pn_buffer_available(ssl->inbuf2)) {
- if (!grow_inbuf2(ssl, minimum))
+ if (!grow_inbuf2(transport, minimum))
// could not add room
return;
}
@@ -963,7 +984,7 @@ static void app_inbytes_progress(pn_ssl_t *ssl, size_t minimum)
ssl->double_buffered = true;
pn_buffer_clear(ssl->inbuf2);
if (!pn_buffer_available(ssl->inbuf2)) {
- if (!grow_inbuf2(ssl, minimum))
+ if (!grow_inbuf2(transport, minimum))
// could not add room
return;
}
@@ -981,11 +1002,12 @@ static void app_inbytes_progress(pn_ssl_t *ssl, size_t minimum)
}
-static void app_inbytes_advance(pn_ssl_t *ssl, size_t consumed)
+static void app_inbytes_advance(pn_transport_t *transport, size_t consumed)
{
+ pni_ssl_t *ssl = transport->ssl;
if (consumed == 0) {
// more contiguous bytes required
- app_inbytes_progress(ssl, ssl->app_inbytes.size + 1);
+ app_inbytes_progress(transport, ssl->app_inbytes.size + 1);
return;
}
assert(consumed <= ssl->app_inbytes.size);
@@ -996,12 +1018,12 @@ static void app_inbytes_advance(pn_ssl_t *ssl, size_t consumed)
ssl->in_data_count -= consumed;
}
if (ssl->app_inbytes.size == 0)
- app_inbytes_progress(ssl, 0);
+ app_inbytes_progress(transport, 0);
}
static void read_closed(pn_transport_t *transport, unsigned int layer, ssize_t error)
{
- pn_ssl_t *ssl = transport->ssl;
+ pni_ssl_t *ssl = transport->ssl;
if (ssl->app_input_closed)
return;
if (ssl->state == RUNNING && !error) {
@@ -1015,7 +1037,7 @@ static void read_closed(pn_transport_t *transport, unsigned int layer, ssize_t e
// both sides of app closed, and no more app output pending:
ssl->state = SHUTTING_DOWN;
if (ssl->network_out_pending == 0 && !ssl->queued_shutdown) {
- start_ssl_shutdown(ssl);
+ start_ssl_shutdown(transport);
}
}
}
@@ -1025,7 +1047,7 @@ static void read_closed(pn_transport_t *transport, unsigned int layer, ssize_t e
static ssize_t process_input_ssl(pn_transport_t *transport, unsigned int layer, const char *input_data, size_t available)
{
- pn_ssl_t *ssl = transport->ssl;
+ pni_ssl_t *ssl = transport->ssl;
ssl_log( ssl, "process_input_ssl( data size=%d )\n",available );
ssize_t consumed = 0;
ssize_t forwarded = 0;
@@ -1091,13 +1113,13 @@ static ssize_t process_input_ssl(pn_transport_t *transport, unsigned int layer,
if (ssl->sc_in_count > 0 && ssl->state <= SHUTTING_DOWN) {
if (ssl->state == NEGOTIATING) {
- ssl_handshake(ssl);
+ ssl_handshake(transport);
} else {
- if (ssl_decrypt(ssl)) {
+ if (ssl_decrypt(transport)) {
// Ignore TLS Record with 0 length data (does not mean EOS)
if (ssl->in_data_size > 0) {
new_app_input = true;
- app_inbytes_add(ssl);
+ app_inbytes_add(transport);
} else {
assert(ssl->decrypting == false);
rewind_sc_inbuf(ssl);
@@ -1109,7 +1131,7 @@ static ssize_t process_input_ssl(pn_transport_t *transport, unsigned int layer,
if (ssl->state == SHUTTING_DOWN) {
if (ssl->network_out_pending == 0 && !ssl->queued_shutdown) {
- start_ssl_shutdown(ssl);
+ start_ssl_shutdown(transport);
}
} else if (ssl->state == SSL_CLOSED) {
return consumed ? consumed : -1;
@@ -1124,11 +1146,11 @@ static ssize_t process_input_ssl(pn_transport_t *transport, unsigned int layer,
if (count > 0) {
forwarded += count;
// advance() can increase app_inbytes.size if double buffered
- app_inbytes_advance(ssl, count);
+ app_inbytes_advance(transport, count);
ssl_log(ssl, "Application consumed %d bytes from peer\n", (int) count);
} else if (count == 0) {
size_t old_size = ssl->app_inbytes.size;
- app_inbytes_advance(ssl, 0);
+ app_inbytes_advance(transport, 0);
if (ssl->app_inbytes.size == old_size) {
break; // no additional contiguous decrypted data available, get more network data
}
@@ -1136,13 +1158,13 @@ static ssize_t process_input_ssl(pn_transport_t *transport, unsigned int layer,
// count < 0
ssl_log(ssl, "Application layer closed its input, error=%d (discarding %d bytes)\n",
(int) count, (int)ssl->app_inbytes.size);
- app_inbytes_advance(ssl, ssl->app_inbytes.size); // discard
+ app_inbytes_advance(transport, ssl->app_inbytes.size); // discard
read_closed(transport, layer, count);
}
} else {
ssl_log(ssl, "Input closed discard %d bytes\n",
(int)ssl->app_inbytes.size);
- app_inbytes_advance(ssl, ssl->app_inbytes.size); // discard
+ app_inbytes_advance(transport, ssl->app_inbytes.size); // discard
}
}
}
@@ -1162,7 +1184,7 @@ static ssize_t process_input_ssl(pn_transport_t *transport, unsigned int layer,
static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer, char *buffer, size_t max_len)
{
- pn_ssl_t *ssl = transport->ssl;
+ pni_ssl_t *ssl = transport->ssl;
if (!ssl) return PN_EOS;
ssl_log( ssl, "process_output_ssl( max_len=%d )\n",max_len );
@@ -1172,7 +1194,7 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
if (ssl->state == CLIENT_HELLO) {
// output buffers eclusively for internal handshake use until negotiation complete
- client_handshake_init(ssl);
+ client_handshake_init(transport);
if (ssl->state == SSL_CLOSED)
return PN_EOS;
ssl->state = NEGOTIATING;
@@ -1227,7 +1249,7 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
if (ssl->network_out_pending == 0 && ssl->state == SHUTTING_DOWN) {
if (!ssl->queued_shutdown) {
- start_ssl_shutdown(ssl);
+ start_ssl_shutdown(transport);
work_pending = true;
} else {
ssl->state = SSL_CLOSED;
@@ -1348,7 +1370,7 @@ static ssize_t process_output_done(pn_transport_t *transport, unsigned int layer
static size_t buffered_output(pn_transport_t *transport)
{
size_t count = 0;
- pn_ssl_t *ssl = transport->ssl;
+ pni_ssl_t *ssl = transport->ssl;
if (ssl) {
count += ssl->network_out_pending;
if (count == 0 && ssl->state == SHUTTING_DOWN && ssl->queued_shutdown)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
|