summaryrefslogtreecommitdiffstats
path: root/src/uscxml
diff options
context:
space:
mode:
authorStefan Radomski <github@mintwerk.de>2017-05-30 19:10:39 (GMT)
committerStefan Radomski <github@mintwerk.de>2017-05-30 19:10:39 (GMT)
commitca31d356e44e19649eeb8340eb1451ea3f477cfa (patch)
tree50651a664c6c463d0921b15e90464b289118f922 /src/uscxml
parent91c81948221cac182e6f64a939983af2bb7a91b0 (diff)
downloaduscxml-ca31d356e44e19649eeb8340eb1451ea3f477cfa.zip
uscxml-ca31d356e44e19649eeb8340eb1451ea3f477cfa.tar.gz
uscxml-ca31d356e44e19649eeb8340eb1451ea3f477cfa.tar.bz2
Reintroduced HTTPS support
Diffstat (limited to 'src/uscxml')
-rw-r--r--src/uscxml/server/HTTPServer.cpp160
-rw-r--r--src/uscxml/server/HTTPServer.h3
2 files changed, 67 insertions, 96 deletions
diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp
index 5c56a8d..b180371 100644
--- a/src/uscxml/server/HTTPServer.cpp
+++ b/src/uscxml/server/HTTPServer.cpp
@@ -51,6 +51,13 @@ extern "C" {
//#include <arpa/inet.h>
#endif
+#if (defined EVENT_SSL_FOUND && defined LIBEVENT_HAS_BEVCB && defined OPENSSL_FOUND)
+extern "C" {
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <event2/bufferevent_ssl.h>
+}
+#endif
#include "uscxml/util/Convenience.h" // for toStr
@@ -108,55 +115,86 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss
}
}
-#if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES)
+#if (defined EVENT_SSL_FOUND && defined LIBEVENT_HAS_BEVCB && defined OPENSSL_FOUND)
// have another look here https://github.com/ppelleti/https-example/blob/master/https-server.c
- _sslHandle = NULL;
- _https = NULL;
+
if (!sslConf) {
_sslPort = 0;
} else {
_sslPort = sslConf->port;
- // Initialize OpenSSL
- SSL_library_init();
- ERR_load_crypto_strings();
- SSL_load_error_strings();
- OpenSSL_add_all_algorithms();
+ SSL_library_init ();
+ SSL_load_error_strings ();
+ OpenSSL_add_all_algorithms ();
+
+ SSL_CTX *ctx = SSL_CTX_new (SSLv23_server_method ());
+ SSL_CTX_set_options (ctx,
+ SSL_OP_SINGLE_DH_USE |
+ SSL_OP_SINGLE_ECDH_USE |
+ SSL_OP_NO_SSLv2);
+
+ EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
+ if (! ecdh) {
+ LOGD(USCXML_ERROR) << ("EC_KEY_new_by_curve_name");
+ ERR_print_errors_fp(stderr);
+ goto FAIL_SSL_SETUP;
+ }
+ if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh)) {
+ LOGD(USCXML_ERROR) << ("SSL_CTX_set_tmp_ecdh");
+ ERR_print_errors_fp(stderr);
+ goto FAIL_SSL_SETUP;
+ }
- _https = evhttp_new(_base);
- evhttp_set_allowed_methods(_https, allowedMethods); // allow all methods
+ if (1 != SSL_CTX_use_certificate_chain_file(ctx, sslConf->publicKey.c_str())) {
+ LOGD(USCXML_ERROR) << ("SSL_CTX_use_certificate_chain_file");
+ ERR_print_errors_fp(stderr);
+ goto FAIL_SSL_SETUP;
+ }
- SSL_CTX* ctx = SSL_CTX_new (SSLv23_server_method ());
- SSL_CTX_set_options(ctx,
- SSL_OP_SINGLE_DH_USE |
- SSL_OP_SINGLE_ECDH_USE |
- SSL_OP_NO_SSLv2);
+ if (1 != SSL_CTX_use_PrivateKey_file(ctx, sslConf->privateKey.c_str(), SSL_FILETYPE_PEM)) {
+ LOGD(USCXML_ERROR) << ("SSL_CTX_use_PrivateKey_file");
+ ERR_print_errors_fp(stderr);
+ goto FAIL_SSL_SETUP;
+ }
- EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
- SSL_CTX_set_tmp_ecdh (ctx, ecdh);
+ if (1 != SSL_CTX_check_private_key(ctx)) {
+ LOGD(USCXML_ERROR) << ("SSL_CTX_check_private_key");
+ ERR_print_errors_fp(stderr);
+ goto FAIL_SSL_SETUP;
+ }
- SSL_CTX_use_certificate_chain_file(ctx, sslConf->publicKey.c_str());
- SSL_CTX_use_PrivateKey_file(ctx, sslConf->privateKey.c_str(), SSL_FILETYPE_PEM);
- SSL_CTX_check_private_key(ctx);
+ _https = evhttp_new (_base);
+ if (! _https) {
+ LOGD(USCXML_ERROR) << ("Could not create evhttp for https");
+ goto FAIL_SSL_SETUP;
+ }
+ /* This is the magic that lets evhttp use SSL. */
evhttp_set_bevcb(_https, sslBufferEventCallback, ctx);
- evhttp_set_gencb(_https, sslGeneralBufferEventCallback, NULL);
+
+ /* This is the callback that gets called when a request comes in. */
+ evhttp_set_gencb(_https, httpRecvReqCallback, NULL);
if (_sslPort > 0) {
- _sslHandle = evhttp_bind_socket_with_handle(_https, INADDR_ANY, _sslPort);
+ _sslHandle = evhttp_bind_socket_with_handle(_https, "0.0.0.0", _sslPort);
if (_sslHandle) {
- LOG(USCXML_INFO) << "HTTPS server listening on tcp/" << _wsPort << std::endl;
+ LOGD(USCXML_INFO) << "HTTPS server listening on tcp/" << _sslPort << std::endl;
} else {
- LOG(USCXML_ERROR) << "HTTPS server cannot bind to tcp/" << _wsPort << std::endl;
+ LOGD(USCXML_ERROR) << "HTTPS server cannot bind to tcp/" << _sslPort << std::endl;
}
}
+
+
}
+
+FAIL_SSL_SETUP:
+ ;
#endif
// evhttp_set_timeout(_http, 5);
- // generic callback
+ // generic http callbacks
evhttp_set_gencb(_http, HTTPServer::httpRecvReqCallback, NULL);
evws_set_gencb(_evws, HTTPServer::wsRecvReqCallback, NULL);
}
@@ -185,7 +223,7 @@ HTTPServer* HTTPServer::getInstance(unsigned short port, unsigned short wsPort,
_instance = new HTTPServer(port, wsPort, sslConf);
// only start if we have something to do!
-#if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES)
+#if (defined EVENT_SSL_FOUND && defined LIBEVENT_HAS_BEVCB && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES)
if (_instance->_httpHandle || _instance->_wsHandle || _instance->_sslHandle)
#else
if (_instance->_httpHandle || _instance->_wsHandle)
@@ -431,7 +469,6 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD
HTTPServer::getInstance()->processByMatchingServlet(request);
}
-
void HTTPServer::processByMatchingServlet(const Request& request) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
@@ -677,7 +714,7 @@ std::string HTTPServer::getBaseURL(ServerType type) {
case HTTP:
servletURL << "http://" << INSTANCE->_address << ":" << INSTANCE->_port;
break;
-#if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES)
+#if (defined EVENT_SSL_FOUND && defined LIBEVENT_HAS_BEVCB && defined OPENSSL_FOUND)
case HTTPS:
servletURL << "https://" << INSTANCE->_address << ":" << INSTANCE->_sslPort;
break;
@@ -711,7 +748,7 @@ void HTTPServer::determineAddress() {
}
-#if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES)
+#if (defined EVENT_SSL_FOUND && defined LIBEVENT_HAS_BEVCB && defined OPENSSL_FOUND)
// see https://github.com/ppelleti/https-example/blob/master/https-server.c
struct bufferevent* HTTPServer::sslBufferEventCallback(struct event_base *base, void *arg) {
struct bufferevent* r;
@@ -723,71 +760,6 @@ struct bufferevent* HTTPServer::sslBufferEventCallback(struct event_base *base,
BEV_OPT_CLOSE_ON_FREE);
return r;
}
-
-
-void HTTPServer::sslGeneralBufferEventCallback (struct evhttp_request *req, void *arg) {
- struct evbuffer *evb = NULL;
- const char *uri = evhttp_request_get_uri (req);
- struct evhttp_uri *decoded = NULL;
-
- /* We only handle POST requests. */
- if (evhttp_request_get_command (req) != EVHTTP_REQ_POST) {
- evhttp_send_reply (req, 200, "OK", NULL);
- return;
- }
-
- printf ("Got a POST request for <%s>\n", uri);
-
- /* Decode the URI */
- decoded = evhttp_uri_parse (uri);
- if (! decoded) {
- printf ("It's not a good URI. Sending BADREQUEST\n");
- evhttp_send_error (req, HTTP_BADREQUEST, 0);
- return;
- }
-
- /* Decode the payload */
- struct evkeyvalq kv;
- memset (&kv, 0, sizeof (kv));
- struct evbuffer *buf = evhttp_request_get_input_buffer (req);
- evbuffer_add (buf, "", 1); /* NUL-terminate the buffer */
- char *payload = (char *) evbuffer_pullup (buf, -1);
- if (0 != evhttp_parse_query_str (payload, &kv)) {
- printf ("Malformed payload. Sending BADREQUEST\n");
- evhttp_send_error (req, HTTP_BADREQUEST, 0);
- return;
- }
-
- /* Determine peer */
- char *peer_addr;
- ev_uint16_t peer_port;
- struct evhttp_connection *con = evhttp_request_get_connection (req);
- evhttp_connection_get_peer (con, &peer_addr, &peer_port);
-
- /* Extract passcode */
- const char *passcode = evhttp_find_header (&kv, "passcode");
- char response[256];
- evutil_snprintf (response, sizeof (response),
- "Hi %s! I %s your passcode.\n", peer_addr,
- (0 == strcmp (passcode, "R23")
- ? "liked"
- : "didn't like"));
- evhttp_clear_headers (&kv); /* to free memory held by kv */
-
- /* This holds the content we're sending. */
- evb = evbuffer_new ();
-
- evhttp_add_header (evhttp_request_get_output_headers (req),
- "Content-Type", "application/x-yaml");
- evbuffer_add (evb, response, strlen (response));
-
- evhttp_send_reply (req, 200, "OK", evb);
-
- if (decoded)
- evhttp_uri_free (decoded);
- if (evb)
- evbuffer_free (evb);
-}
#endif
}
diff --git a/src/uscxml/server/HTTPServer.h b/src/uscxml/server/HTTPServer.h
index a584360..6486770 100644
--- a/src/uscxml/server/HTTPServer.h
+++ b/src/uscxml/server/HTTPServer.h
@@ -187,13 +187,12 @@ private:
friend class HTTPServlet;
friend class WebSocketServlet;
-#if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES)
+#if (defined EVENT_SSL_FOUND && defined LIBEVENT_HAS_BEVCB && defined OPENSSL_FOUND)
struct evhttp* _https;
struct evhttp_bound_socket* _sslHandle;
unsigned short _sslPort;
static struct bufferevent* sslBufferEventCallback(struct event_base *base, void *arg);
- static void sslGeneralBufferEventCallback (struct evhttp_request *req, void *arg);
#endif
};