diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e30913..0b6717a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.6) project (uts-server) include(ExternalProject) -set(VERSION 0.1.7) +set(VERSION 0.1.8) option(DEBUG "compile with debug symbol" OFF) option(BUNDLE_CIVETWEB "bundle civetweb with uts-server" OFF) @@ -32,7 +32,9 @@ IF(LINK_PTHREAD) set(PTHREAD_LIBRARIES 'pthread') ENDIF(LINK_PTHREAD) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=700") +set (CMAKE_C_STANDARD 11) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=700") if(DEBUG) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g") @@ -50,22 +52,36 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUTS_VERSION='\"${VERSION}\"'") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") find_package(OpenSSL REQUIRED) +find_package(LibreSSL) + MESSAGE(STATUS "OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}") MESSAGE(STATUS "OpenSSL libraries: ${OPENSSL_LIBRARIES}") MESSAGE(STATUS "OpenSSL version: ${OPENSSL_VERSION}") +MESSAGE(STATUS "LibreSSL Detected: ${IS_LIBRESSL}") +MESSAGE(STATUS "OS Detected: ${CMAKE_SYSTEM_NAME}") -if(${OPENSSL_VERSION} VERSION_GREATER 1.0.99) - set(OPENSSL_API_1_1 ON) -else() - set(OPENSSL_API_1_1 OFF) + +if(NOT(DEFINED OPENSSL_API_1_1)) + if(${OPENSSL_VERSION} VERSION_GREATER 1.0.99 AND NOT(IS_LIBRESSL)) + set(OPENSSL_API_1_1 ON) + else() + set(OPENSSL_API_1_1 OFF) + endif() endif() + IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") set(SED_FREEBSD "*.c.bak") find_package(argp REQUIRED) add_definitions(-DBSD) ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") +IF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") + find_package(argp REQUIRED) + add_definitions(-DBSD) +ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") + + if(BUNDLE_CIVETWEB) ExternalProject_Add( civetweb GIT_REPOSITORY https://github.com/kakwa/civetweb @@ -87,7 +103,11 @@ if(BUNDLE_CIVETWEB) ) set(LIBCIVETWEB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/usr/include") set(LIBCIVETWEB_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/vendor/usr/lib/libcivetweb.a") - set (CMAKE_C_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lpthread -lrt") + IF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") + set (CMAKE_C_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lpthread") + ELSE(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") + set (CMAKE_C_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lpthread -lrt") + ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") else(BUNDLE_CIVETWEB) find_package(libcivetweb REQUIRED) endif(BUNDLE_CIVETWEB) diff --git a/ChangeLog.rst b/ChangeLog.rst index 5a2fd4c..a87bd12 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,6 +1,11 @@ Changelogs ========== +0.1.8 + +* [impr] add OpenBSD support +* [impr] add LibreSSL support + 0.1.7 ----- diff --git a/cmake/FindLibreSSL.cmake b/cmake/FindLibreSSL.cmake new file mode 100644 index 0000000..ec3e2cc --- /dev/null +++ b/cmake/FindLibreSSL.cmake @@ -0,0 +1,57 @@ +#.rst +# FindLibreSSL +# ------------ +# +# Detect if OpenSSL is in fact LibreSSL, and recovers LibreSSL version. +# +# Requires running FindOpenSSL previously +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# ``LIBRESSL_VERSION`` +# This is set to ``$major.$minor.$revision$patch`` (e.g. ``2.3.1f``). +# +# ``IS_LIBRESSL`` +# Boolean, set to TRUE if LibreSSL, FALSE otherwise +# + +# just copy/pasted from OpenSSL module with a few substitutions +if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") + file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" libressl_version_str + REGEX "^#[\t ]*define[\t ]+LIBRESSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*") + + if(libressl_version_str) + # The version number is encoded as 0xMNNFFPPS: major minor fix patch status + # The status gives if this is a developer or prerelease and is ignored here. + # Major, minor, and fix directly translate into the version numbers shown in + # the string. The patch field translates to the single character suffix that + # indicates the bug fix state, which 00 -> nothing, 01 -> a, 02 -> b and so + # on. + + string(REGEX REPLACE "^.*LIBRESSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$" + "\\1;\\2;\\3;\\4;\\5" LIBRESSL_VERSION_LIST "${libressl_version_str}") + list(GET LIBRESSL_VERSION_LIST 0 LIBRESSL_VERSION_MAJOR) + list(GET LIBRESSL_VERSION_LIST 1 LIBRESSL_VERSION_MINOR) + from_hex("${LIBRESSL_VERSION_MINOR}" LIBRESSL_VERSION_MINOR) + list(GET LIBRESSL_VERSION_LIST 2 LIBRESSL_VERSION_FIX) + from_hex("${LIBRESSL_VERSION_FIX}" LIBRESSL_VERSION_FIX) + list(GET LIBRESSL_VERSION_LIST 3 LIBRESSL_VERSION_PATCH) + + if (NOT LIBRESSL_VERSION_PATCH STREQUAL "00") + from_hex("${LIBRESSL_VERSION_PATCH}" _tmp) + # 96 is the ASCII code of 'a' minus 1 + math(EXPR LIBRESSL_VERSION_PATCH_ASCII "${_tmp} + 96") + unset(_tmp) + # Once anyone knows how OpenSSL would call the patch versions beyond 'z' + # this should be updated to handle that, too. This has not happened yet + # so it is simply ignored here for now. + string(ASCII "${LIBRESSL_VERSION_PATCH_ASCII}" LIBRESSL_VERSION_PATCH_STRING) + endif () + + set(LIBRESSL_VERSION "${LIBRESSL_VERSION_MAJOR}.${LIBRESSL_VERSION_MINOR}.${LIBRESSL_VERSION_FIX}${LIBRESSL_VERSION_PATCH_STRING}") + set(IS_LIBRESSL TRUE) + else () + set(IS_LIBRESSL FALSE) + endif () +endif () diff --git a/docs/install.rst b/docs/install.rst index f623a42..1eb5181 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -8,6 +8,7 @@ List of dependencies uts-server relies on to run: * `OpenSSL `_. * `civetweb `_. +* on none GNU LibC, `argp-standalone ` Build dependencies ------------------ @@ -58,3 +59,60 @@ uts-server is compiled using cmake: * having an external download in a build process is a bad idea * recovering the master branch ensures that the build may break randomly * a build proccess should be reproductible which is not the case with this option + +OS specific tips +================ + +Debian +------ + +The installation requires installing the following packages: + +.. sourcecode:: bash + + # build dependencies + $ apt-get install libssl-dev cmake clang + +CentOS/RHEL +----------- + +The installation requires installing the following packages: + +.. sourcecode:: bash + + # build dependencies + $ yum insall cmake gcc gcc-c++ openssl-devel + +FreeBSD +------- + +The installation requires installing the following packages: + +.. sourcecode:: bash + + # build dependencies + $ pkg add argp-standalone cmake + +OpenBSD +------- + +The installation requires installing the following packages: + +.. sourcecode:: bash + + # build dependencies + $ pkg_add gcc g++ argp-standalone cmake + + # for the test scripts + $ pkg_add python curl + +To build you must egcc and eg++ (not the old 4.2 gcc in the base system) + +.. sourcecode:: bash + + # set compilers + $ export CC=/usr/local/bin/egcc + $ export CXX=/usr/local/bin/ec++ + + # then build normally + $ cmake . -DBUNDLE_CIVETWEB=ON && make diff --git a/inc/rfc3161.h b/inc/rfc3161.h index bcb7810..0f88494 100644 --- a/inc/rfc3161.h +++ b/inc/rfc3161.h @@ -16,6 +16,20 @@ #if OPENSSL_VERSION_NUMBER < 0x10000000L #error OpenSSL version too old #endif + +/* LibreSSL is really annoying + * the OPENSSL_VERSION_NUMBER #define in opensslv.h + * is 0x20000000L but the API is that of openssl 1.0. + * That breaks version matching to determine which API + * to use. + * So, special case here for LibreSSL... + * (why didn't you just keep 0x100000L LibreSSL?) + */ +#ifdef LIBRESSL_VERSION_NUMBER +// for now, LibreSSL is 1.0 API only +#define OPENSSL_API_1_0 +#else +// for OpenSSL, we must differenciate between 1.0 and 1.1 #if OPENSSL_VERSION_NUMBER < 0x10100000L && \ OPENSSL_VERSION_NUMBER >= 0x10000000L #define OPENSSL_API_1_0 @@ -23,6 +37,7 @@ #if OPENSSL_VERSION_NUMBER >= 0x10100000L #define OPENSSL_API_1_1 #endif +#endif /* Name of config entry that defines the OID file. */ #define OID_SECTION "oids" diff --git a/inc/utils.h b/inc/utils.h index 961936d..e2a9e87 100644 --- a/inc/utils.h +++ b/inc/utils.h @@ -16,6 +16,7 @@ void log_hex(rfc3161_context *ct, int priority, char *id, int set_params(rfc3161_context *ct, char *conf_file, char *conf_wd); static char *rand_string(char *str, size_t size); void free_uts_context(rfc3161_context *ct); +const char *null_undef(const char * in); // some global variable to handle signals int g_uts_sig_up; diff --git a/src/lib/http.c b/src/lib/http.c index e43ea64..87c2e98 100644 --- a/src/lib/http.c +++ b/src/lib/http.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include @@ -54,20 +54,20 @@ void log_request_debug(const struct mg_request_info *request_info, for (int i = 0; i < request_info->num_headers; i++) { uts_logger(context, LOG_DEBUG, "Request[%s], Header[%s]: %s", request_id, request_info->http_headers[i].name, - request_info->http_headers[i].value); + null_undef(request_info->http_headers[i].value)); } uts_logger(context, LOG_DEBUG, "Request[%s], request_method: %s", - request_id, request_info->request_method); + request_id, null_undef(request_info->request_method)); uts_logger(context, LOG_DEBUG, "Request[%s], request_uri: %s", request_id, - request_info->request_uri); + null_undef(request_info->request_uri)); uts_logger(context, LOG_DEBUG, "Request[%s], local_uri: %s", request_id, - request_info->local_uri); + null_undef(request_info->local_uri)); uts_logger(context, LOG_DEBUG, "Request[%s], http_version: %s", request_id, - request_info->http_version); + null_undef(request_info->http_version)); uts_logger(context, LOG_DEBUG, "Request[%s], query_string: %s", request_id, - request_info->query_string); + null_undef(request_info->query_string)); uts_logger(context, LOG_DEBUG, "Request[%s], remote_addr: %s", request_id, - request_info->remote_addr); + null_undef(request_info->remote_addr)); uts_logger(context, LOG_DEBUG, "Request[%s], is_ssl: %d", request_id, request_info->is_ssl); uts_logger(context, LOG_DEBUG, "Request[%s], content_length: %d", @@ -97,9 +97,10 @@ void log_request(const struct mg_request_info *request_info, char *request_id, uts_logger(context, LOG_INFO, "Request[%s], remote_addr[%s] ssl[%d] " "uri[%s] http_resp_code[%d] duration[%d us] " "user-agent[%s] content-type[%s]", - request_id, request_info->remote_addr, request_info->is_ssl, - request_info->local_uri, response_code, timer, user_agent, - content_type); + request_id, null_undef(request_info->remote_addr), + request_info->is_ssl, null_undef(request_info->local_uri), + response_code, timer, null_undef(user_agent), + null_undef(content_type)); } // This function will be called by civetweb on every new request. diff --git a/src/lib/utils.c b/src/lib/utils.c index 6699cb2..6bb717e 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -202,6 +202,12 @@ void uts_logger(rfc3161_context *ct, int priority, char *fmt, ...) { free(out); } +const char *null_undef(const char * in){ + if(in == NULL) + return ""; + return in; +} + // OpenSSL file openner (use for opening the configuration file static BIO *bio_open_default(rfc3161_context *ct, const char *filename, int format) { @@ -281,7 +287,7 @@ int set_params(rfc3161_context *ct, char *conf_file, char *conf_wd) { if (value == NULL) { uts_logger(ct, LOG_NOTICE, "configuration param['%s'] not set, using default: '%s'", - name, default_value); + name, null_undef(default_value)); value = default_value; } switch (type) { @@ -307,11 +313,11 @@ int set_params(rfc3161_context *ct, char *conf_file, char *conf_wd) { if (value == NULL) { uts_logger(ct, LOG_NOTICE, "configuration param['%s'] not set, using default: '%s'", - name, default_value); + name, null_undef(default_value)); value = default_value; } uts_logger(ct, LOG_DEBUG, "configuration param['%s'] = '%s'", name, - value); + null_undef(value)); switch (type) { // if it's an http (civetweb) option, put it in the http_options buffer // like civetweb is expected it.