diff --git a/.travis.yml b/.travis.yml index b331ca15..f34ea2a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,11 @@ os: language: generic install: - ./scripts/travis_install.sh +# - ./travis-tool.sh github_package jimhester/covr + +#after_success: +# - Rscript -e 'covr::coveralls()' + script: - if [ "$COVERITY_SCAN_BRANCH" != 1 -a "$TRAVIS_OS_NAME" = "osx" ]; then mkdir build && cd build && cmake -DOPENSSL_ROOT_DIR="/usr/local/opt/openssl" $CMAKE_ARGS .. && cmake --build .; else if [ "$COVERITY_SCAN_BRANCH" != 1 -a "$TRAVIS_OS_NAME" = "linux" ]; then mkdir build && cd build && cmake $CMAKE_ARGS .. && cmake --build .; fi ; fi sudo: required diff --git a/CMakeLists.txt b/CMakeLists.txt index 433c315a..b84c9a7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,12 +20,12 @@ option(LWS_IPV6 "Compile with support for ipv6" OFF) option(LWS_UNIX_SOCK "Compile with support for UNIX domain socket" OFF) option(LWS_WITH_PLUGINS "Support plugins for protocols and extensions" OFF) option(LWS_WITH_HTTP_PROXY "Support for rewriting HTTP proxying (requires libhubbub)" OFF) -option(LWS_WITH_ZIP_FOPS "Support serving pre-zipped files" ON) +option(LWS_WITH_ZIP_FOPS "Support serving pre-zipped files" OFF) option(LWS_WITH_SOCKS5 "Allow use of SOCKS5 proxy on client connections" OFF) option(LWS_WITH_GENERIC_SESSIONS "With the Generic Sessions plugin" OFF) option(LWS_WITH_PEER_LIMITS "Track peers and restrict resources a single peer can allocate" OFF) option(LWS_WITH_ACCESS_LOG "Support generating Apache-compatible access logs" OFF) -option(LWS_WITH_RANGES "Support http ranges (RFC7233)" ON) +option(LWS_WITH_RANGES "Support http ranges (RFC7233)" OFF) option(LWS_WITH_SERVER_STATUS "Support json + jscript server monitoring" OFF) option(LWS_WITH_ACME "Enable support for ACME automatic cert acquisition + maintenance (letsencrypt etc)" OFF) # @@ -71,8 +71,8 @@ option(LWS_WITHOUT_TEST_FRAGGLE "Don't build the ping test application" OFF) # # Extensions (permessage-deflate) # -option(LWS_WITHOUT_EXTENSIONS "Don't compile with extensions" OFF) -option(LWS_WITH_ZLIB "Include zlib support (required for extensions)" ON) +option(LWS_WITHOUT_EXTENSIONS "Don't compile with extensions" ON) +option(LWS_WITH_ZLIB "Include zlib support (required for extensions)" OFF) option(LWS_WITH_BUNDLED_ZLIB "Use bundled zlib version (Windows only)" ${LWS_WITH_BUNDLED_ZLIB_DEFAULT}) # # Helpers + misc @@ -91,7 +91,10 @@ option(LWS_WITH_NO_LOGS "Disable all logging from being compiled in" OFF) option(LWS_AVOID_SIGPIPE_IGN "Android 7+ reportedly needs this" OFF) option(LWS_WITH_STATS "Keep statistics of lws internal operations" OFF) option(LWS_WITH_JWS "JSON Web Signature (RFC7515) API" OFF) +option(LWS_WITH_GENHASH "Enable support for Generic Hash (SHA1 + SHA2 with api independent of TLS backend)" OFF) +option(LWS_WITH_GENRSA "Enable support for Generic RSA (RSA with api independent of TLS backend)" OFF) option(LWS_WITH_SELFTESTS "Selftests run at context creation" OFF) +option(LWS_WITH_GCOV "Build with gcc gcov coverage instrumentation" OFF) # # End of user settings # @@ -176,6 +179,8 @@ endif() if (LWS_WITH_JWS) set(LWS_WITH_LEJP 1) + set(LWS_WITH_GENHASH 1) + set(LWS_WITH_GENRSA 1) endif() if (LWS_WITH_PLUGINS AND NOT LWS_WITH_LIBUV) @@ -188,6 +193,12 @@ message(STATUS "LWS_WITH_SMTP --> Enabling LWS_WITH_LIBUV") set(LWS_WITH_LIBUV 1) endif() +if (LWS_WITH_PLUGINS OR LWS_WITH_CGI) + # sshd plugin + set(LWS_WITH_GENHASH 1) + set(LWS_WITH_GENRSA 1) +endif() + if (LWS_WITH_GENERIC_SESSIONS) set(LWS_WITH_SQLITE3 1) set(LWS_WITH_SMTP 1) @@ -271,10 +282,8 @@ if (NOT (LWS_WITH_STATIC OR LWS_WITH_SHARED)) message(FATAL_ERROR "Makes no sense to compile with neither static nor shared libraries.") endif() -if (NOT LWS_WITHOUT_EXTENSIONS) - if (NOT LWS_WITH_ZLIB) - message(FATAL_ERROR "zlib is required for extensions.") - endif() +if (NOT LWS_WITHOUT_EXTENSIONS OR LWS_WITH_ZIP_FOPS) + set(LWS_WITH_ZLIB 1) endif() set(LWS_ZLIB_LIBRARIES CACHE PATH "Path to the zlib library") @@ -728,15 +737,31 @@ if (LWS_WITH_SSL) if (LWS_WITH_MBEDTLS) list(APPEND SOURCES lib/tls/mbedtls/ssl.c - lib/tls/mbedtls/lws-genhash.c - lib/tls/mbedtls/lws-genrsa.c ) + if (LWS_WITH_GENHASH) + list(APPEND SOURCES + lib/tls/mbedtls/lws-genhash.c + ) + endif() + if (LWS_WITH_GENRSA) + list(APPEND SOURCES + lib/tls/mbedtls/lws-genrsa.c + ) + endif() else() list(APPEND SOURCES lib/tls/openssl/ssl.c - lib/tls/openssl/lws-genhash.c - lib/tls/openssl/lws-genrsa.c ) + if (LWS_WITH_GENHASH) + list(APPEND SOURCES + lib/tls/openssl/lws-genhash.c + ) + endif() + if (LWS_WITH_GENRSA) + list(APPEND SOURCES + lib/tls/openssl/lws-genrsa.c + ) + endif() endif() if (NOT LWS_WITHOUT_SERVER) @@ -744,10 +769,10 @@ if (LWS_WITH_SSL) lib/server/ssl-server.c) if (LWS_WITH_MBEDTLS) list(APPEND SOURCES - lib/tls/mbedtls/server.c) + lib/tls/mbedtls/mbedtls-server.c) else() list(APPEND SOURCES - lib/tls/openssl/server.c) + lib/tls/openssl/openssl-server.c) endif() endif() if (NOT LWS_WITHOUT_CLIENT) @@ -755,10 +780,10 @@ if (LWS_WITH_SSL) lib/client/ssl-client.c) if (LWS_WITH_MBEDTLS) list(APPEND SOURCES - lib/tls/mbedtls/client.c) + lib/tls/mbedtls/mbedtls-client.c) else() list(APPEND SOURCES - lib/tls/openssl/client.c) + lib/tls/openssl/openssl-client.c) endif() endif() @@ -908,10 +933,13 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_C_COMPILER_ID if (LWS_HAVE_VISIBILITY) set(VISIBILITY_FLAG -fvisibility=hidden) endif() + if (LWS_WITH_GCOV) + set (GCOV_FLAGS "-fprofile-arcs -ftest-coverage -O0") + endif() if ((UNIX OR LWS_WITH_ESP8266) AND NOT LWS_WITH_ESP32) - set(CMAKE_C_FLAGS "-Wall -Wsign-compare -Wignored-qualifiers -Wtype-limits -Wuninitialized -Werror ${VISIBILITY_FLAG} -Wundef ${CMAKE_C_FLAGS}" ) + set(CMAKE_C_FLAGS "-Wall -Wsign-compare -Wignored-qualifiers -Wtype-limits -Wuninitialized -Werror ${VISIBILITY_FLAG} -Wundef ${GCOV_FLAGS} ${CMAKE_C_FLAGS}" ) else() - set(CMAKE_C_FLAGS "-Wall ${VISIBILITY_FLAG} ${CMAKE_C_FLAGS}" ) + set(CMAKE_C_FLAGS "-Wall -Wsign-compare -Wignored-qualifiers -Wtype-limits -Wuninitialized -Werror ${VISIBILITY_FLAG} ${GCOV_FLAGS} ${CMAKE_C_FLAGS}" ) endif() endif () diff --git a/READMEs/README.build.md b/READMEs/README.build.md index b92c557f..f97317aa 100644 --- a/READMEs/README.build.md +++ b/READMEs/README.build.md @@ -431,14 +431,25 @@ Testing with h2spec (https://github.com/summerwind/h2spec) $ h2spec -h 127.0.0.1 -p 7681 -t -k -v -o 1 ``` -At the time of writing, http/2 support is not fully complete; however all the -h2spec tests pass. - ``` -145 tests, 144 passed, 1 skipped, 0 failed +145 tests, 145 passed, 0 skipped, 0 failed ``` +@section coverage Automated Coverage Testing + +./test-apps/attack.sh contains scripted tests that are the basis +of the automated test coverage assessment available for gcc and clang. + +To reproduce + + $ cd build + $ cmake .. -DLWS_WITH_GCOV=1 -DCMAKE_BUILD_TYPE=DEBUG + $ ../scripts/build-gcov.sh + $ ../test-apps/attack.sh + $ ../scripts/gcov.sh +... +Lines executed:51.24% of 8279 @section windowsprebuilt Using Windows binary builds on Appveyor diff --git a/cmake/lws_config.h.in b/cmake/lws_config.h.in index e47b5674..d6ddd3c5 100644 --- a/cmake/lws_config.h.in +++ b/cmake/lws_config.h.in @@ -148,6 +148,7 @@ #cmakedefine LWS_HAVE__STAT32I64 #cmakedefine LWS_WITH_JWS +#cmakedefine LWS_WITH_ACME #cmakedefine LWS_WITH_SELFTESTS /* OpenSSL various APIs */ diff --git a/component.mk b/component.mk index 7cc5d7b1..9afdeb6f 100644 --- a/component.mk +++ b/component.mk @@ -28,7 +28,10 @@ build: -DLWS_MBEDTLS_INCLUDE_DIRS="${IDF_PATH}/components/openssl/include;${IDF_PATH}/components/mbedtls/include;${IDF_PATH}/components/mbedtls/port/include" \ -DLWS_WITH_STATS=0 \ -DLWS_WITH_HTTP2=1 \ + -DLWS_WITH_RANGES=1 \ -DLWS_WITH_ACME=1 \ + -DLWS_WITH_ZLIB=1 \ + -DLWS_WITH_ZIP_FOPS=1 \ -DZLIB_LIBRARY=$(BUILD_DIR_BASE)/zlib/libzlib.a \ -DZLIB_INCLUDE_DIR=$(COMPONENT_PATH)/../zlib \ -DLWS_WITH_ESP32=1 \ diff --git a/lib/tls/mbedtls/client.c b/lib/tls/mbedtls/mbedtls-client.c similarity index 100% rename from lib/tls/mbedtls/client.c rename to lib/tls/mbedtls/mbedtls-client.c diff --git a/lib/tls/mbedtls/server.c b/lib/tls/mbedtls/mbedtls-server.c similarity index 99% rename from lib/tls/mbedtls/server.c rename to lib/tls/mbedtls/mbedtls-server.c index 88970890..fb74d71c 100644 --- a/lib/tls/mbedtls/server.c +++ b/lib/tls/mbedtls/mbedtls-server.c @@ -328,6 +328,7 @@ lws_tls_server_accept(struct lws *wsi) return LWS_SSL_CAPABLE_ERROR; } +#if defined(LWS_WITH_ACME) /* * mbedtls doesn't support SAN for cert creation. So we use a known-good * tls-sni-01 cert from OpenSSL that worked on Let's Encrypt, and just replace @@ -620,4 +621,4 @@ fail: return -1; } #endif - +#endif diff --git a/lib/tls/mbedtls/ssl.c b/lib/tls/mbedtls/ssl.c index 391b01aa..f46eabaa 100644 --- a/lib/tls/mbedtls/ssl.c +++ b/lib/tls/mbedtls/ssl.c @@ -278,8 +278,9 @@ lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost) if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx) SSL_CTX_free(vhost->ssl_client_ctx); - +#if defined(LWS_WITH_ACME) lws_tls_acme_sni_cert_destroy(vhost); +#endif } void diff --git a/lib/tls/openssl/client.c b/lib/tls/openssl/openssl-client.c similarity index 100% rename from lib/tls/openssl/client.c rename to lib/tls/openssl/openssl-client.c diff --git a/lib/tls/openssl/server.c b/lib/tls/openssl/openssl-server.c similarity index 99% rename from lib/tls/openssl/server.c rename to lib/tls/openssl/openssl-server.c index f4a62b47..a3cf45ac 100644 --- a/lib/tls/openssl/server.c +++ b/lib/tls/openssl/openssl-server.c @@ -493,6 +493,7 @@ lws_tls_server_accept(struct lws *wsi) return LWS_SSL_CAPABLE_ERROR; } +#if defined(LWS_WITH_ACME) static int lws_tls_openssl_rsa_new_key(RSA **rsa, int bits) { @@ -818,3 +819,4 @@ bail0: return ret; } +#endif diff --git a/lib/tls/openssl/ssl.c b/lib/tls/openssl/ssl.c index 7dbd3efa..249a1db2 100644 --- a/lib/tls/openssl/ssl.c +++ b/lib/tls/openssl/ssl.c @@ -416,8 +416,9 @@ lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost) if (!vhost->user_supplied_ssl_ctx && vhost->ssl_client_ctx) SSL_CTX_free(vhost->ssl_client_ctx); - +#if defined(LWS_WITH_ACME) lws_tls_acme_sni_cert_destroy(vhost); +#endif } void diff --git a/lib/tls/tls.c b/lib/tls/tls.c index fcc829d0..2572434b 100644 --- a/lib/tls/tls.c +++ b/lib/tls/tls.c @@ -21,35 +21,6 @@ #include "private-libwebsockets.h" -int -lws_alloc_vfs_file(struct lws_context *context, const char *filename, - uint8_t **buf, lws_filepos_t *amount) -{ - lws_filepos_t len; - lws_fop_flags_t flags = LWS_O_RDONLY; - lws_fop_fd_t fops_fd = lws_vfs_file_open( - lws_get_fops(context), filename, &flags); - int ret = 1; - - if (!fops_fd) - return 1; - - len = lws_vfs_get_length(fops_fd); - - *buf = lws_malloc((size_t)len, "lws_alloc_vfs_file"); - if (!*buf) - goto bail; - - if (lws_vfs_file_read(fops_fd, amount, *buf, len)) - goto bail; - - ret = 0; -bail: - lws_vfs_file_close(&fops_fd); - - return ret; -} - int lws_ssl_anybody_has_buffered_read_tsi(struct lws_context *context, int tsi) { diff --git a/scripts/build-gcov.sh b/scripts/build-gcov.sh new file mode 100755 index 00000000..1db1d6c5 --- /dev/null +++ b/scripts/build-gcov.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +cmake .. -DLWS_WITH_GCOV=1 && \ +make clean && \ +rm -f `find . -name "*.gcno" -o -name "*.gcda"` && \ +make -j16 && sudo make install diff --git a/scripts/gcov.sh b/scripts/gcov.sh new file mode 100755 index 00000000..ee71cc0f --- /dev/null +++ b/scripts/gcov.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +gcov `find . -name *.c.gcno | grep -v test-apps` -b | sed "/\.h.\$/,/^$/d" diff --git a/test-apps/attack.sh b/test-apps/attack.sh index 4314579a..0ce1004b 100755 --- a/test-apps/attack.sh +++ b/test-apps/attack.sh @@ -2,6 +2,8 @@ # # attack the test server and try to make it fall over # +# Requires the library to have been built with cmake .. -DCMAKE_BUILD_TYPE=DEBUG + SERVER=127.0.0.1 PORT=7681 LOG=/tmp/lwslog @@ -777,6 +779,16 @@ echo echo "--- survived OK ---" kill -2 $CPID +# coverage... +# run the test client against mirror for one period and exit +libwebsockets-test-server -s 2>> $LOG & +CPID=$! + +libwebsockets-test-client 127.0.0.1 -s -O +curl -v -F text=hello -F send=SEND -F upload=@../README.md https://127.0.0.1:7681/formtest -k + +kill -2 $CPID + exit 0 diff --git a/test-apps/test-client.c b/test-apps/test-client.c index db02f47c..872c3996 100644 --- a/test-apps/test-client.c +++ b/test-apps/test-client.c @@ -43,7 +43,7 @@ struct lws_poly_gen { #define block_size (3 * 4096) -static int deny_deflate, longlived, mirror_lifetime, test_post; +static int deny_deflate, longlived, mirror_lifetime, test_post, once; static struct lws *wsi_dumb, *wsi_mirror; static struct lws *wsi_multi[3]; static volatile int force_exit; @@ -360,7 +360,7 @@ callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason, "rxb %d, rx_count %d\n", mirror_lifetime, rxb, rx_count); wsi_mirror = NULL; - if (flag_echo) + if (flag_echo || once) force_exit = 1; break; @@ -536,6 +536,7 @@ static struct option options[] = { { "justmirror", no_argument, NULL, 'j' }, { "longlived", no_argument, NULL, 'l' }, { "post", no_argument, NULL, 'o' }, + { "once", no_argument, NULL, 'O' }, { "pingpong-secs", required_argument, NULL, 'P' }, { "ssl-cert", required_argument, NULL, 'C' }, { "ssl-key", required_argument, NULL, 'K' }, @@ -584,7 +585,7 @@ int main(int argc, char **argv) goto usage; while (n >= 0) { - n = getopt_long(argc, argv, "Sjnuv:hsp:d:lC:K:A:P:moe", options, + n = getopt_long(argc, argv, "Sjnuv:hsp:d:lC:K:A:P:moeO", options, NULL); if (n < 0) continue; @@ -628,6 +629,9 @@ int main(int argc, char **argv) case 'o': test_post = 1; break; + case 'O': + once = 1; + break; case 'n': flag_no_mirror_traffic = 1; lwsl_notice("Disabled sending mirror data (for pingpong testing)\n");