diff --git a/config.m4 b/config.m4 index 60f34ce..b33ed72 100644 --- a/config.m4 +++ b/config.m4 @@ -5,6 +5,25 @@ PHP_ARG_ENABLE(stomp, whether to enable stomp support, Make sure that the comment is aligned: [ --enable-stomp Enable stomp support]) +PHP_ARG_WITH(openssl-dir,OpenSSL dir for stomp, +[ --with-openssl-dir[=DIR] stomp: openssl install prefix], no, no) + if test "$PHP_STOMP" != "no"; then PHP_NEW_EXTENSION(stomp, stomp.c php_stomp.c, $ext_shared) + + test -z "$PHP_OPENSSL" && PHP_OPENSSL=no + + if test "$PHP_OPENSSL" != "no" || test "$PHP_OPENSSL_DIR" != "no"; then + PHP_SETUP_OPENSSL(STOMP_SHARED_LIBADD, + [ + AC_DEFINE(HAVE_STOMP_SSL,1,[ ]) + ], [ + AC_MSG_ERROR([OpenSSL libraries not found. + + Check the path given to --with-openssl-dir and output in config.log) + ]) + ]) + + PHP_SUBST(STOMP_SHARED_LIBADD) + fi fi diff --git a/package.xml b/package.xml index 7c7f803..107e705 100644 --- a/package.xml +++ b/package.xml @@ -4,7 +4,7 @@ pecl.php.net Stomp client extension -This extension allows php applications to comunicate with any Stomp compliant Message Brokers through easy object oriented and procedural interfaces. +This extension allows php applications to communicate with any Stomp compliant Message Brokers through easy object oriented and procedural interfaces. Pierrick Charron diff --git a/php_stomp.c b/php_stomp.c index 8ab68a5..1cc5c50 100755 --- a/php_stomp.c +++ b/php_stomp.c @@ -373,7 +373,11 @@ PHP_FUNCTION(stomp_connect) char *broker = NULL, *username = NULL, *password = NULL; int broker_len = 0, username_len = 0, password_len = 0; struct timeval tv; - php_url *url_parts; + php_url *url_parts; + +#ifdef HAVE_STOMP_SSL + int use_ssl = 0; +#endif tv.tv_sec = 2; tv.tv_usec = 0; @@ -394,16 +398,30 @@ PHP_FUNCTION(stomp_connect) php_url_free(url_parts); return; } - - if (url_parts->scheme && strcmp(url_parts->scheme, "tcp") != 0) { - STOMP_ERROR(0, PHP_STOMP_ERR_INVALID_BROKER_URI_SCHEME); - php_url_free(url_parts); - return; + + if (url_parts->scheme) { + if (strcmp(url_parts->scheme, "ssl") == 0) { +#if HAVE_STOMP_SSL + use_ssl = 1; +#else + STOMP_ERROR(0, "SSL DISABLED"); + php_url_free(url_parts); + return; +#endif + } else if (strcmp(url_parts->scheme, "tcp") != 0) { + STOMP_ERROR(0, PHP_STOMP_ERR_INVALID_BROKER_URI_SCHEME); + php_url_free(url_parts); + return; + } } stomp = stomp_new(url_parts->host, url_parts->port ? url_parts->port : 61613, STOMP_G(timeout_sec), STOMP_G(timeout_usec) TSRMLS_CC); php_url_free(url_parts); +#if HAVE_STOMP_SSL + stomp->use_ssl = use_ssl; +#endif + if ((stomp->status = stomp_connect(stomp TSRMLS_CC))) { stomp_frame_t *res; stomp_frame_t frame = {0}; diff --git a/stomp.c b/stomp.c index 00013e4..f01bb2e 100644 --- a/stomp.c +++ b/stomp.c @@ -50,6 +50,11 @@ stomp_t *stomp_new(const char *host, unsigned short port, long timeout_sec, long stomp->timeout_usec = timeout_usec; stomp->session = NULL; +#if HAVE_STOMP_SSL + stomp->ssl_handle = NULL; + stomp->use_ssl = 0; +#endif + return stomp; } /* }}} */ @@ -102,6 +107,32 @@ int stomp_connect(stomp_t *stomp TSRMLS_DC) FD_SET(stomp->fd, &rfds); if (select(stomp->fd + 1, NULL, &rfds, NULL, &tv) > 0) { +#if HAVE_STOMP_SSL + if (stomp->use_ssl) { + SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); + if (NULL == ctx) { + stomp_set_error(stomp, "failed to create the SSL context", 0); + return 0; + } + + SSL_CTX_set_options(ctx, SSL_OP_ALL); + + stomp->ssl_handle = SSL_new(ctx); + if (stomp->ssl_handle == NULL) { + stomp_set_error(stomp, "failed to create the SSL handle", 0); + SSL_CTX_free(ctx); + return 0; + } + + SSL_set_fd(stomp->ssl_handle, stomp->fd); + + if (SSL_connect(stomp->ssl_handle) <= 0) { + stomp_set_error(stomp, "SSL/TLS handshake failed", 0); + SSL_shutdown(stomp->ssl_handle); + return 0; + } + } +#endif return 1; } else { snprintf(error, sizeof(error), "Unable to connect to %s:%ld", stomp->host, stomp->port); @@ -120,6 +151,11 @@ int stomp_close(stomp_t *stomp TSRMLS_DC) } if (stomp->fd != -1) { +#if HAVE_STOMP_SSL + if(stomp->ssl_handle) { + SSL_shutdown(stomp->ssl_handle); + } +#endif closesocket(stomp->fd); } if (stomp->host) { @@ -182,9 +218,19 @@ int stomp_send(stomp_t *stomp, stomp_frame_t *frame TSRMLS_DC) smart_str_appends(&buf, frame->body); } - if (-1 == send(stomp->fd, buf.c, buf.len, 0) || -1 == send(stomp->fd, "\0\n", 2, 0)) { - return 0; +#ifdef HAVE_STOMP_SSL + if (stomp->use_ssl) { + if (-1 == SSL_write(stomp->ssl_handle, buf.c, buf.len) || -1 == SSL_write(stomp->ssl_handle, "\0\n", 2)) { + return 0; + } + } else { +#endif + if (-1 == send(stomp->fd, buf.c, buf.len, 0) || -1 == send(stomp->fd, "\0\n", 2, 0)) { + return 0; + } +#ifdef HAVE_STOMP_SSL } +#endif smart_str_free(&buf); @@ -192,6 +238,22 @@ int stomp_send(stomp_t *stomp, stomp_frame_t *frame TSRMLS_DC) } /* }}} */ +/* {{{ stomp_recv + */ +int stomp_recv(stomp_t *stomp, char *msg, size_t length) +{ +#if HAVE_STOMP_SSL + if(stomp->use_ssl) { + return SSL_read(stomp->ssl_handle, msg, length); + } else { +#endif + return recv(stomp->fd, msg, length, 0); +#if HAVE_STOMP_SSL + } +#endif +} +/* }}} */ + /* {{{ stomp_read_buffer */ static int stomp_read_buffer(stomp_t *stomp, char **data) diff --git a/stomp.h b/stomp.h index 272516c..f254f63 100755 --- a/stomp.h +++ b/stomp.h @@ -23,6 +23,10 @@ #include "php_network.h" +#if HAVE_STOMP_SSL +#include +#endif + #define STOMP_BUFSIZE 4096 #define INIT_STOMP_FRAME(f) \ @@ -31,8 +35,6 @@ ALLOC_HASHTABLE(f->headers); \ zend_hash_init(f->headers, 0, NULL, NULL, 0); -#define stomp_recv(c,b,l) recv((c)->fd, b, l, 0) - typedef struct _stomp { php_socket_t fd; php_sockaddr_storage localaddr; @@ -44,6 +46,10 @@ typedef struct _stomp { long timeout_sec; long timeout_usec; char *session; +#if HAVE_STOMP_SSL + SSL *ssl_handle; + int use_ssl; +#endif } stomp_t; typedef struct _stomp_frame {