From cfa566ab882b416396aba38252992903658f2a8b Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Thu, 1 Jun 2017 16:20:31 +0200 Subject: SSL support on Win32 --- CMakeLists.txt | 12 +++- README.md | 20 +++++- contrib/cmake/BuildLibCurl.cmake | 31 ++++----- contrib/cmake/BuildLibEvent.cmake | 24 +++++-- contrib/patches/libevent/Makefile.nmake | 82 +++++++++++++++++++++++ src/uscxml/Interpreter.cpp | 9 ++- src/uscxml/plugins/datamodel/CMakeLists.txt | 2 +- src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp | 5 +- src/uscxml/server/HTTPServer.cpp | 20 +++--- test/src/test-serialization.cpp | 2 +- test/src/test-snippets.cpp | 9 ++- 11 files changed, 172 insertions(+), 44 deletions(-) create mode 100644 contrib/patches/libevent/Makefile.nmake diff --git a/CMakeLists.txt b/CMakeLists.txt index c8a3545..2cd37de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -253,8 +253,10 @@ else() endif() endif() + #OpenSSL find_package(OpenSSL) +# https://slproweb.com/products/Win32OpenSSL.html if (OPENSSL_FOUND) include_directories(${OPENSSL_INCLUDE_DIR}) list (APPEND USCXML_CORE_LIBS ${OPENSSL_LIBRARIES}) @@ -331,6 +333,7 @@ if (";${LIBEVENT_LIBRARIES};" MATCHES "openssl") set(EVENT_SSL_FOUND ON) endif() + if (UNIX) list (APPEND USCXML_CORE_LIBS "pthread") endif() @@ -413,10 +416,13 @@ OPTION(WITH_DM_LUA "Do search for the Lua libraries" ON) if (WITH_DM_LUA) if (WIN32) # LuaForWindows https://code.google.com/archive/p/luaforwindows/downloads - set(ENV{LUA_DIR} "C:/Program Files (x86)/Lua/5.1/") + # set(ENV{LUA_DIR} "C:/Program Files (x86)/Lua/5.1/") + + # http://luabinaries.sourceforge.net/download.html + set(ENV{LUA_DIR} "C:/Program Files (x86)/Lua/5.3/") endif() - find_package(Lua51) - if (LUA51_FOUND) + find_package(Lua) + if (LUA_FOUND) include_directories (${LUA_INCLUDE_DIR}) include_directories(${PROJECT_SOURCE_DIR}/contrib/src/LuaBridge) list (APPEND USCXML_OPT_LIBS ${LUA_LIBRARIES}) diff --git a/README.md b/README.md index a3e1943..f76c544 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # uSCXML ReadMe -[![Build Status](https://travis-ci.org/tklab-tud/uscxml.png?branch=master)](https://travis-ci.org/tklab-tud/uscxml)[![Build status](https://ci.appveyor.com/api/projects/status/b3mwo7w2qhtjal6f/branch/master?svg=true)](https://ci.appveyor.com/project/sradomski/uscxml/branch/master)[![Build status](https://scan.coverity.com/projects/11688/badge.svg)](https://scan.coverity.com/projects/tklab-tud-uscxml) +[![Build Status](https://travis-ci.org/tklab-tud/uscxml.png?branch=master)](https://travis-ci.org/tklab-tud/uscxml)[![Build status](https://ci.appveyor.com/api/projects/status/b3mwo7w2qhtjal6f/branch/master?svg=true)](https://ci.appveyor.com/project/sradomski/uscxml/branch/master)[![Build status](https://scan.coverity.com/projects/11688/badge.svg)](https://scan.coverity.com/projects/tklab-tud-uscxml)[![Coverage Status](https://coveralls.io/repos/github/tklab-tud/uscxml/badge.svg?branch=master)](https://coveralls.io/github/tklab-tud/uscxml?branch=master) #### Quick Links @@ -55,6 +55,17 @@ For more detailled information, refer to the [documentation](http://tklab-tud.gi ... } +**Examples:** + +* [uscxml-browser.cpp](https://github.com/tklab-tud/uscxml/blob/master/apps/uscxml-browser.cpp) (**C++**) +* [test-state-pass.cpp](https://github.com/tklab-tud/uscxml/blob/master/test/src/test-state-pass.cpp) (**C++**) +* [TestStatePass.cs](https://github.com/tklab-tud/uscxml/blob/master/contrib/csharp/bindings/TestStatePass.cs) (**C#**) +* [test-state-pass.py](https://github.com/tklab-tud/uscxml/blob/master/contrib/python/bindings/test-state-pass.py) (**Python**) +* [JexlDataModelTest.java](https://github.com/tklab-tud/uscxml/blob/master/contrib/java/bindings/org/uscxml/tests/JexlDataModelTest.java) (**Java**) + + + + ### On the Command-line # interpret state-chart from url $ uscxml-browser https://raw.githubusercontent.com/tklab-tud/uscxml/master/test/w3c/null/test436.scxml @@ -62,3 +73,10 @@ For more detailled information, refer to the [documentation](http://tklab-tud.gi ### For Transformations # transform given SCXML document into ANSI-C fragment $ uscxml-transform -tc -i https://raw.githubusercontent.com/tklab-tud/uscxml/master/test/w3c/null/test436.scxml + +**Examples:** + +* [test-gen-c.cpp](https://github.com/tklab-tud/uscxml/blob/master/test/src/test-gen-c.cpp) (**C++**) +* [WaterPump.cxx](https://github.com/tklab-tud/uscxml/blob/master/apps/arduino/WaterPump.cxx) (**C++ on Arduino**) + + diff --git a/contrib/cmake/BuildLibCurl.cmake b/contrib/cmake/BuildLibCurl.cmake index 54bfe4a..c7251fe 100644 --- a/contrib/cmake/BuildLibCurl.cmake +++ b/contrib/cmake/BuildLibCurl.cmake @@ -26,27 +26,20 @@ if (MSVC) set(VC_VERSION 12) endif() + SET(MACHINE_ARCH "x86") if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - externalproject_add(libcurl - URL https://curl.haxx.se/download/curl-7.48.0.tar.gz - URL_MD5 b2cac71029d28cb989150bac72aafab5 - BUILD_IN_SOURCE 1 - PREFIX ${CMAKE_BINARY_DIR}/deps/libcurl - CONFIGURE_COMMAND "" - BUILD_COMMAND cd winbuild && nmake /f Makefile.vc mode=static MACHINE=x64 VC=${VC_VERSION} - INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory builds/libcurl-vc${VC_VERSION}-x64-release-static-ipv6-sspi-winssl ${CMAKE_BINARY_DIR}/deps/libcurl/ - ) - else() - externalproject_add(libcurl - URL https://curl.haxx.se/download/curl-7.48.0.tar.gz - URL_MD5 b2cac71029d28cb989150bac72aafab5 - BUILD_IN_SOURCE 1 - PREFIX ${CMAKE_BINARY_DIR}/deps/libcurl - CONFIGURE_COMMAND "" - BUILD_COMMAND cd winbuild && nmake /f Makefile.vc mode=static MACHINE=x86 VC=${VC_VERSION} - INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory builds/libcurl-vc${VC_VERSION}-x86-release-static-ipv6-sspi-winssl ${CMAKE_BINARY_DIR}/deps/libcurl/ - ) + SET(MACHINE_ARCH "x64") endif() + + externalproject_add(libcurl + URL https://curl.haxx.se/download/curl-7.48.0.tar.gz + URL_MD5 b2cac71029d28cb989150bac72aafab5 + BUILD_IN_SOURCE 1 + PREFIX ${CMAKE_BINARY_DIR}/deps/libcurl + CONFIGURE_COMMAND "" + BUILD_COMMAND cd winbuild && nmake /f Makefile.vc mode=static MACHINE=${MACHINE_ARCH} VC=${VC_VERSION} + INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory builds/libcurl-vc${VC_VERSION}-${MACHINE_ARCH}-release-static-ipv6-sspi-winssl ${CMAKE_BINARY_DIR}/deps/libcurl/ + ) else() externalproject_add(libcurl URL https://curl.haxx.se/download/curl-7.48.0.tar.gz diff --git a/contrib/cmake/BuildLibEvent.cmake b/contrib/cmake/BuildLibEvent.cmake index 80e425a..26b9a42 100644 --- a/contrib/cmake/BuildLibEvent.cmake +++ b/contrib/cmake/BuildLibEvent.cmake @@ -2,24 +2,36 @@ # see http://tools.cinemapub.be/opendcp/opendcp-0.19-src/contrib/CMakeLists.txt find_package(OpenSSL) +if (OPENSSL_FOUND) + string(REGEX REPLACE "/include$" "" OPENSSL_ROOT_DIR ${OPENSSL_INCLUDE_DIR}) + set(OPENSSL_ROOT_DIR "OPENSSL_DIR=${OPENSSL_ROOT_DIR}") + set(COPY_LIBEVENT_SSL "libevent_openssl.lib") +else() + # essentially a noop to work around externalproject_add syntax + set(COPY_LIBEVENT_SSL "libevent.lib") +endif() include(ExternalProject) if (MSVC) externalproject_add(libevent - URL https://github.com/libevent/libevent/releases/download/release-2.0.22-stable/libevent-2.0.22-stable.tar.gz - URL_MD5 c4c56f986aa985677ca1db89630a2e11 + URL https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz + URL_MD5 f3eeaed018542963b7d2416ef1135ecc BUILD_IN_SOURCE 1 PREFIX ${CMAKE_BINARY_DIR}/deps/libevent CONFIGURE_COMMAND "" - BUILD_COMMAND nmake -f Makefile.nmake + PATCH_COMMAND + ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/contrib/patches/libevent/Makefile.nmake" /Makefile.nmake + + BUILD_COMMAND nmake ${OPENSSL_ROOT_DIR} -f Makefile.nmake INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/deps/libevent/lib && ${CMAKE_COMMAND} -E copy libevent.lib ${CMAKE_BINARY_DIR}/deps/libevent/lib/ && ${CMAKE_COMMAND} -E copy libevent_core.lib ${CMAKE_BINARY_DIR}/deps/libevent/lib/ && ${CMAKE_COMMAND} -E copy libevent_extras.lib ${CMAKE_BINARY_DIR}/deps/libevent/lib/ && + ${CMAKE_COMMAND} -E copy ${COPY_LIBEVENT_SSL} ${CMAKE_BINARY_DIR}/deps/libevent/lib/ && ${CMAKE_COMMAND} -E copy_directory include ${CMAKE_BINARY_DIR}/deps/libevent/include && - ${CMAKE_COMMAND} -E copy Win32-Code/event2/event-config.h ${CMAKE_BINARY_DIR}/deps/libevent/include/event2/ + ${CMAKE_COMMAND} -E copy Win32-Code/nmake/event2/event-config.h ${CMAKE_BINARY_DIR}/deps/libevent/include/event2/ ) else () if (UNIX) @@ -57,6 +69,10 @@ elseif (UNIX) endif() elseif(WIN32) set(LIBEVENT_LIBRARIES ${CMAKE_BINARY_DIR}/deps/libevent/lib/libevent.lib) + if (OPENSSL_FOUND) + list (APPEND LIBEVENT_LIBRARIES ${CMAKE_BINARY_DIR}/deps/libevent/lib/libevent_openssl.lib) + endif() + else() message(FATAL_ERROR "Unknown platform!") endif() diff --git a/contrib/patches/libevent/Makefile.nmake b/contrib/patches/libevent/Makefile.nmake new file mode 100644 index 0000000..b941a67 --- /dev/null +++ b/contrib/patches/libevent/Makefile.nmake @@ -0,0 +1,82 @@ +# WATCH OUT! This makefile is a work in progress. -*- makefile -*- +# +# I'm not very knowledgeable about MSVC and nmake beyond their most basic +# aspects. If anything here looks wrong to you, please let me know. + +# If OPENSSL_DIR is not set, builds without OpenSSL support. If you want +# OpenSSL support, you can set the OPENSSL_DIR variable to where you +# installed OpenSSL. This can be done in the environment: +# set OPENSSL_DIR=c:\openssl +# Or on the nmake command line: +# nmake OPENSSL_DIR=C:\openssl -f Makefile.nmake +# Or by uncommenting the following line here in the makefile... + +# OPENSSL_DIR=c:\openssl + +!IFDEF OPENSSL_DIR +SSL_CFLAGS=/I$(OPENSSL_DIR)\include /DEVENT__HAVE_OPENSSL +!ELSE +SSL_CFLAGS= +!ENDIF + +# Needed for correctness +CFLAGS=/IWIN32-Code /IWIN32-Code/nmake /Iinclude /Icompat /DHAVE_CONFIG_H /I. $(SSL_CFLAGS) + +# For optimization and warnings +CFLAGS=$(CFLAGS) /Ox /W3 /wd4996 /nologo + +# XXXX have a debug mode + +LIBFLAGS=/nologo + +CORE_OBJS=event.obj buffer.obj bufferevent.obj bufferevent_sock.obj \ + bufferevent_pair.obj listener.obj evmap.obj log.obj evutil.obj \ + strlcpy.obj signal.obj bufferevent_filter.obj evthread.obj \ + bufferevent_ratelim.obj evutil_rand.obj evutil_time.obj +WIN_OBJS=win32select.obj evthread_win32.obj buffer_iocp.obj \ + event_iocp.obj bufferevent_async.obj +EXTRA_OBJS=event_tagging.obj http.obj evdns.obj evrpc.obj + +!IFDEF OPENSSL_DIR +SSL_OBJS=bufferevent_openssl.obj +SSL_LIBS=libevent_openssl.lib +!ELSE +SSL_OBJS= +SSL_LIBS= +!ENDIF + +ALL_OBJS=$(CORE_OBJS) $(WIN_OBJS) $(EXTRA_OBJS) $(SSL_OBJS) +STATIC_LIBS=libevent_core.lib libevent_extras.lib libevent.lib $(SSL_LIBS) + + +all: static_libs + +static_libs: $(STATIC_LIBS) + +libevent_core.lib: $(CORE_OBJS) $(WIN_OBJS) + lib $(LIBFLAGS) $(CORE_OBJS) $(WIN_OBJS) /out:libevent_core.lib + +libevent_extras.lib: $(EXTRA_OBJS) + lib $(LIBFLAGS) $(EXTRA_OBJS) /out:libevent_extras.lib + +libevent.lib: $(CORE_OBJS) $(WIN_OBJS) $(EXTRA_OBJS) + lib $(LIBFLAGS) $(CORE_OBJS) $(EXTRA_OBJS) $(WIN_OBJS) /out:libevent.lib + +libevent_openssl.lib: $(SSL_OBJS) + lib $(LIBFLAGS) $(SSL_OBJS) /out:libevent_openssl.lib + +clean: + del $(ALL_OBJS) + del $(STATIC_LIBS) + cd test + $(MAKE) /F Makefile.nmake clean + cd .. + +tests: + cd test +!IFDEF OPENSSL_DIR + $(MAKE) OPENSSL_DIR=$(OPENSSL_DIR) /F Makefile.nmake +!ELSE + $(MAKE) /F Makefile.nmake +!ENDIF + cd .. diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 1a79a63..0758cd1 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -98,7 +98,7 @@ Interpreter Interpreter::fromXML(const std::string& xml, const std::string& base Interpreter Interpreter::fromElement(XERCESC_NS::DOMElement* scxml, const std::string& baseURL) { URL absUrl = normalizeURL(baseURL); - + std::shared_ptr interpreterImpl(new InterpreterImpl()); Interpreter interpreter(interpreterImpl); @@ -147,6 +147,13 @@ Interpreter Interpreter::fromDocument(XERCESC_NS::DOMDocument* dom, const std::s Interpreter Interpreter::fromURL(const std::string& url) { URL absUrl = normalizeURL(url); +#ifdef _WIN32 + // Xercesc is hard to build with SSL on windows, whereas curl uses winssl + if (absUrl.scheme() == "https") { + return fromXML(absUrl.getInContent(), absUrl); + } +#endif + std::shared_ptr interpreterImpl(new InterpreterImpl()); Interpreter interpreter(interpreterImpl); diff --git a/src/uscxml/plugins/datamodel/CMakeLists.txt b/src/uscxml/plugins/datamodel/CMakeLists.txt index e70598e..a03e7c8 100644 --- a/src/uscxml/plugins/datamodel/CMakeLists.txt +++ b/src/uscxml/plugins/datamodel/CMakeLists.txt @@ -72,7 +72,7 @@ if (V8_FOUND) endif() -if (LUA51_FOUND AND WITH_DM_LUA) +if (LUA_FOUND AND WITH_DM_LUA) set(USCXML_DATAMODELS "lua ${USCXML_DATAMODELS}") # Lua ecmascript datamodel file(GLOB LUA_DATAMODEL diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp index 4f78e7d..92866ee 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp @@ -163,9 +163,10 @@ static luabridge::LuaRef getDataAsLua(lua_State* _luaState, const Data& data) { luaData = luabridge::newTable(_luaState); std::map::const_iterator compoundIter = data.compound.begin(); while(compoundIter != data.compound.end()) { - if (isInteger(compoundIter->first.c_str(), 10) && strTo(compoundIter->first) > 0) { + if (isInteger(compoundIter->first.c_str(), 10) && strTo(compoundIter->first) > 0) { // it makes a difference whether we pass a numeric string or a proper number! - luaData[strTo(compoundIter->first)] = getDataAsLua(_luaState, compoundIter->second); + // MSVC throws assertion with LuaBridge for size_t instead of int + luaData[strTo(compoundIter->first)] = getDataAsLua(_luaState, compoundIter->second); } else { luaData[compoundIter->first] = getDataAsLua(_luaState, compoundIter->second); } diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp index 367df21..e9a1039 100644 --- a/src/uscxml/server/HTTPServer.cpp +++ b/src/uscxml/server/HTTPServer.cpp @@ -49,6 +49,10 @@ extern "C" { #include // for gethostname //#include //#include +#else +#ifdef HTTPS_ENABLED +#define EVENT__HAVE_OPENSSL +#endif #endif #ifdef HTTPS_ENABLED @@ -125,6 +129,7 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss SSL_library_init (); SSL_load_error_strings (); + ERR_load_crypto_strings(); OpenSSL_add_all_algorithms (); SSL_CTX *ctx = SSL_CTX_new (SSLv23_server_method ()); @@ -135,31 +140,26 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss 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); + LOGD(USCXML_ERROR) << ("EC_KEY_new_by_curve_name") << ERR_error_string(ERR_get_error(), NULL); 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); + LOGD(USCXML_ERROR) << ("SSL_CTX_set_tmp_ecdh") << ERR_error_string(ERR_get_error(), NULL); goto FAIL_SSL_SETUP; } 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); + LOGD(USCXML_ERROR) << ("SSL_CTX_use_certificate_chain_file") << ERR_error_string(ERR_get_error(), NULL); goto FAIL_SSL_SETUP; } 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); + LOGD(USCXML_ERROR) << ("SSL_CTX_use_PrivateKey_file") << ERR_error_string(ERR_get_error(), NULL); goto FAIL_SSL_SETUP; } if (1 != SSL_CTX_check_private_key(ctx)) { - LOGD(USCXML_ERROR) << ("SSL_CTX_check_private_key"); - ERR_print_errors_fp(stderr); + LOGD(USCXML_ERROR) << ("SSL_CTX_check_private_key") << ERR_error_string(ERR_get_error(), NULL); goto FAIL_SSL_SETUP; } diff --git a/test/src/test-serialization.cpp b/test/src/test-serialization.cpp index a833eef..968bae3 100644 --- a/test/src/test-serialization.cpp +++ b/test/src/test-serialization.cpp @@ -30,7 +30,7 @@ class StatusMonitor : public uscxml::StateTransitionMonitor { void printUsageAndExit() { printf("test-serialization version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n"); printf("Usage\n"); - printf("\ttest-stress"); + printf("\ttest-serialization"); #ifdef BUILD_AS_PLUGINS printf(" [-p pluginPath]"); #endif diff --git a/test/src/test-snippets.cpp b/test/src/test-snippets.cpp index 40b581b..581a258 100644 --- a/test/src/test-snippets.cpp +++ b/test/src/test-snippets.cpp @@ -32,6 +32,11 @@ void microstep_snippet() { } int main(int argc, char** argv) { - Logger::getDefault().log(USCXML_FATAL) << "Foo!" << " BAR?" << std::endl; - microstep_snippet(); + try { + Logger::getDefault().log(USCXML_FATAL) << "Foo!" << " BAR?" << std::endl; + microstep_snippet(); + } + catch (...) { + exit(EXIT_FAILURE); + } } -- cgit v0.12