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 {