diff options
Diffstat (limited to 'src/uscxml/server')
-rw-r--r-- | src/uscxml/server/HTTPServer.cpp | 160 | ||||
-rw-r--r-- | src/uscxml/server/HTTPServer.h | 3 |
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 }; |