diff --git a/.cirrus.yml b/.cirrus.yml index 9f78ff9..fd3a34c 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,11 +1,12 @@ freebsd_task: matrix: - - name: FreeBSD 11.4 + - name: FreeBSD 13.3 freebsd_instance: - image: freebsd-11-4-release-amd64 - - name: FreeBSD 12.2 + image: freebsd-13-3-release-amd64 + - name: FreeBSD 14.1 freebsd_instance: - image: freebsd-12-2-release-amd64 + image_family: freebsd-14-1 + env: HOME: /home/testuser @@ -35,8 +36,8 @@ freebsd_task: linux_mbedtls_task: # use master branch of libevent to support mbedtls container: matrix: - - image: ubuntu:18.04 - - image: ubuntu:20.04 + - image: ubuntu:24.04 + - image: ubuntu:22.04 install_script: - apt update && apt upgrade -y @@ -62,11 +63,40 @@ linux_mbedtls_task: # use master branch of libevent to support mbedtls - make - make test +linux_mbedtls_v3_task: # use master branch of libevent to support mbedtls + container: + matrix: + - image: ubuntu:24.04 + + install_script: + - apt update && apt upgrade -y + - DEBIAN_FRONTEND=noninteractive apt install -y unzip git cmake build-essential curl libssl-dev libmbedtls-dev libpcre3-dev python3-dev + prepare_script: + - git submodule update --init + - curl -L https://github.com/libevent/libevent/archive/refs/heads/master.zip -o libevent.zip + - unzip libevent.zip + - cd libevent-master && cmake -DCMAKE_BUILD_TYPE=Release . && make install && cd .. + - curl -L https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v3.5.2.zip -o mbedtls.zip + - unzip mbedtls.zip + - cd mbedtls-3.5.2 && cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTING=OFF -DENABLE_PROGRAMS=OFF . && make install && cd .. + build_default_test_script: + - mkdir -p build/default + - cd build/default + - cmake -DUSE_MBEDTLS=ON ../.. + - make + - make test + build_acl_test_script: + - mkdir -p build/acl + - cd build/acl + - cmake -DUSE_MBEDTLS=ON -DWITH_ACL=ON ../.. + - make + - make test + linux_openssl_task: container: matrix: - - image: ubuntu:18.04 - - image: ubuntu:20.04 + - image: ubuntu:22.04 + - image: ubuntu:24.04 install_script: - apt update && apt upgrade -y diff --git a/CMakeLists.txt b/CMakeLists.txt index b9fcc72..897f5b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,8 +117,8 @@ endif() find_package(Libevent2 REQUIRED) include_directories(${LIBEVENT2_INCLUDE_DIR}) -list(APPEND THIRDPARTY_LIBS ${LIBEVENT2_LIBRARIES}) - +list(APPEND THIRDPARTY_LIBS ${LIBEVENT2_LIBRARIES} ${LIBEVENT2_CORE} ${LIBEVENT2_EXTRA} ${LIBEVENT2_PTHREADS_LIBRARIES}) + if(USE_MBEDTLS) find_package(MbedTLS REQUIRED) @@ -132,7 +132,7 @@ if(USE_MBEDTLS) src/ssl/mbedtls.c src/crypto/mbedtls.c ) - list(APPEND THIRDPARTY_LIBS ${LIBEVENT2_MBEDTLS_LIBRARIES} ${MBEDTLS_LIBRARIES}) + list(APPEND THIRDPARTY_LIBS ${MBEDTLS_LIBRARIES}) else() find_package(OpenSSLx REQUIRED) include_directories(${OPENSSL_INCLUDE_DIR}) @@ -332,6 +332,7 @@ if(NOT ${A2X_EXECUTABLE} STREQUAL A2X_EXECUTABLE-NOTFOUND) endif() # tests +list(APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure") enable_testing() add_subdirectory(test) diff --git a/cmake/FindLibevent2.cmake b/cmake/FindLibevent2.cmake index d107c2d..7ee1cd5 100644 --- a/cmake/FindLibevent2.cmake +++ b/cmake/FindLibevent2.cmake @@ -1,51 +1,53 @@ # -# https://github.com/sipwise/sems/blob/master/cmake/FindLibevent2.cmake -# -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - FIND_PATH(LIBEVENT2_INCLUDE_DIR event2/event.h) +# found in on openssl site and made some changes GPL 2.0 licenced + +IF(NOT WITH_LIBEVENT) + SET(WITH_LIBEVENT system) +ENDIF() - list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .imp) - list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .imp.lib) +IF(WITH_LIBEVENT STREQUAL "system" OR WITH_LIBEVENT STREQUAL "yes") + IF(NOT WIN32) + SET(LIBEVENT2_INCLUDE_PATH /usr/local/include /opt/local/include) + SET(LIBEVENT2_LIB_PATHS /usr/local/lib /opt/local/lib) + ENDIF() - if(CMAKE_CL_64) - FIND_LIBRARY(LIBEVENT2_LIBRARIES NAMES libevent-x64-v120-mt-2_1_4_0 event libevent ) - else() - FIND_LIBRARY(LIBEVENT2_LIBRARIES NAMES libevent-x86-v120-mt-2_1_4_0 event libevent ) - endif() -else() - set(LIBEVENT2_INCLUDE_DIR_SEARCH_PATHS /usr/local/include /usr/include) - set(LIBEVENT2_LIB_SEARCH_PATHS /usr/local/lib /usr/lib) -if(DEFINED Libevent2_ROOT) - set(LIBEVENT2_INCLUDE_DIR_SEARCH_PATHS ${Libevent2_ROOT}/include ${LIBEVENT2_INCLUDE_DIR_SEARCH_PATHS}) - set(LIBEVENT2_LIB_SEARCH_PATHS ${Libevent2_ROOT}/lib ${LIBEVENT2_LIB_SEARCH_PATHS}) -endif() - # -levent -levent_core -levent_extra -levent_openssl - FIND_PATH(LIBEVENT2_INCLUDE_DIR event2/event.h PATHS ${LIBEVENT2_INCLUDE_DIR_SEARCH_PATHS} NO_CMAKE_SYSTEM_PATH) - # OpenBSD issue, lookup from /usr/local/lib to avoid lib mismatch - FIND_LIBRARY(LIBEVENT2_LIBRARIES NAMES event libevent PATHS ${LIBEVENT2_LIB_SEARCH_PATHS} NO_CMAKE_SYSTEM_PATH) - FIND_LIBRARY(LIBEVENT2_CORE_LIBRARIES NAMES event_core libevent_core PATHS ${LIBEVENT2_LIB_SEARCH_PATHS} NO_CMAKE_SYSTEM_PATH) - FIND_LIBRARY(LIBEVENT2_EXTRA_LIBRARIES NAMES event_extra libevent_extra PATHS ${LIBEVENT2_LIB_SEARCH_PATHS} NO_CMAKE_SYSTEM_PATH) - FIND_LIBRARY(LIBEVENT2_SSL_LIBRARIES NAMES event_openssl libevent_openssl PATHS ${LIBEVENT2_LIB_SEARCH_PATHS} NO_CMAKE_SYSTEM_PATH) - FIND_LIBRARY(LIBEVENT2_MBEDTLS_LIBRARIES NAMES event_mbedtls libevent_mbedtls PATHS ${LIBEVENT2_LIB_SEARCH_PATHS}b NO_CMAKE_SYSTEM_PATH) -endif() + # use default paths + SET(HOW_TO_FIND) +ELSEIF(WITH_LIBEVENT STREQUAL "bundled") + MESSAGE(FATAL_ERROR "bundled libevent isn't support") +ELSE() + # make the users path for libevent absolute + GET_FILENAME_COMPONENT(LIBEVENT_ABS_DIR "${WITH_LIBEVENT}" ABSOLUTE) + SET(LIBEVENT2_INCLUDE_PATH ${LIBEVENT_ABS_DIR}/include) + SET(LIBEVENT2_LIB_PATHS ${LIBEVENT_ABS_DIR}/lib) + # if path specified, use that path only + SET(HOW_TO_FIND NO_DEFAULT_PATH) +ENDIF() -IF(LIBEVENT2_INCLUDE_DIR AND LIBEVENT2_LIBRARIES) - SET(LIBEVENT2_FOUND TRUE) -ENDIF(LIBEVENT2_INCLUDE_DIR AND LIBEVENT2_LIBRARIES) +FIND_PATH(LIBEVENT2_INCLUDE_DIR event2/event.h PATHS ${LIBEVENT2_INCLUDE_PATH} ${HOW_TO_FIND}) +IF(WIN32) + ## libevent-2.0.22 on windows is only 'event.lib' and 'event.dll' + FIND_LIBRARY(LIBEVENT2_CORE NAMES event PATHS ${LIBEVENT2_LIB_PATHS} ${HOW_TO_FIND}) + SET(LIBEVENT2_EXTRA) +ELSE() + FIND_LIBRARY(LIBEVENT2_CORE NAMES event_core libevent_core PATHS ${LIBEVENT2_LIB_PATHS} ${HOW_TO_FIND}) + FIND_LIBRARY(LIBEVENT2_EXTRA NAMES event_extra libevent_extra PATHS ${LIBEVENT2_LIB_PATHS} ${HOW_TO_FIND}) + FIND_LIBRARY(LIBEVENT2_SSL_LIBRARIES NAMES event_openssl libevent_openssl PATHS ${LIBEVENT2_LIB_PATHS} ${HOW_TO_FIND}) + FIND_LIBRARY(LIBEVENT2_PTHREADS_LIBRARIES NAMES event_pthreads libevent_pthreads PATHS ${LIBEVENT2_LIB_PATHS} ${HOW_TO_FIND}) +ENDIF() -IF(LIBEVENT2_FOUND) - IF (NOT Libevent2_FIND_QUIETLY) - MESSAGE(STATUS "Found libevent2 includes: ${LIBEVENT2_INCLUDE_DIR}/event2/event.h") - MESSAGE(STATUS "Found libevent2 library: ${LIBEVENT2_LIBRARIES}") - MESSAGE(STATUS "Found libevent2 core library: ${LIBEVENT2_CORE_LIBRARIES}") - MESSAGE(STATUS "Found libevent2 extra library: ${LIBEVENT2_EXTRA_LIBRARIES}") - MESSAGE(STATUS "Found libevent2 openssl library: ${LIBEVENT2_SSL_LIBRARIES}") - MESSAGE(STATUS "Found libevent2 mbedtls library: ${LIBEVENT2_MBEDTLS_LIBRARIES}") - ENDIF (NOT Libevent2_FIND_QUIETLY) -ELSE(LIBEVENT2_FOUND) - IF (Libevent2_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could NOT find libevent2 development files: ${LIBEVENT2_INCLUDE_DIR} :: ${LIBEVENT2_LIBRARIES}") - ENDIF (Libevent2_FIND_REQUIRED) -ENDIF(LIBEVENT2_FOUND) +IF (LIBEVENT2_INCLUDE_DIR AND LIBEVENT2_CORE) + SET(LibEvent2_FOUND TRUE) +ELSE() + SET(LibEvent2_FOUND FALSE) +ENDIF() +# don't expose them in the cmake UI +MARK_AS_ADVANCED( + LIBEVENT2_INCLUDE_DIR + LIBEVENT2_CORE + LIBEVENT2_EXTRA + LIBEVENT2_SSL_LIBRARIES + LIBEVENT2_PTHREADS_LIBRARIES +) diff --git a/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake index 7052143..f116916 100644 --- a/cmake/FindMbedTLS.cmake +++ b/cmake/FindMbedTLS.cmake @@ -1,159 +1,86 @@ -# Copyright 2017-2019 AVSystem +# Find the mbedTLS library # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Input variables: # -# http://www.apache.org/licenses/LICENSE-2.0 +# - `MBEDTLS_INCLUDE_DIR`: The mbedTLS include directory. +# - `MBEDTLS_LIBRARY`: Path to `mbedtls` library. +# - `MBEDX509_LIBRARY`: Path to `mbedx509` library. +# - `MBEDCRYPTO_LIBRARY`: Path to `mbedcrypto` library. # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#.rst: -# FindMbedTLS -# ----------- -# -# Find the mbedTLS encryption library. -# -# Imported Targets -# ^^^^^^^^^^^^^^^^ -# -# This module defines the following :prop_tgt:`IMPORTED` targets: -# -# ``mbedtls`` -# The mbedTLS ``mbedtls`` library, if found. -# ``mbedcrypto`` -# The mbedtls ``crypto`` library, if found. -# ``mbedx509`` -# The mbedtls ``x509`` library, if found. -# -# Result Variables -# ^^^^^^^^^^^^^^^^ -# -# This module will set the following variables in your project: +# Result variables: # -# ``MBEDTLS_FOUND`` -# System has the mbedTLS library. -# ``MBEDTLS_INCLUDE_DIR`` -# The mbedTLS include directory. -# ``MBEDTLS_LIBRARY`` -# The mbedTLS SSL library. -# ``MBEDTLS_CRYPTO_LIBRARY`` -# The mbedTLS crypto library. -# ``MBEDTLS_X509_LIBRARY`` -# The mbedTLS x509 library. -# ``MBEDTLS_LIBRARIES`` -# All mbedTLS libraries. -# ``MBEDTLS_VERSION`` -# This is set to ``$major.$minor.$patch``. -# ``MBEDTLS_VERSION_MAJOR`` -# Set to major mbedTLS version number. -# ``MBEDTLS_VERSION_MINOR`` -# Set to minor mbedTLS version number. -# ``MBEDTLS_VERSION_PATCH`` -# Set to patch mbedTLS version number. -# -# Hints -# ^^^^^ -# -# Set ``MBEDTLS_ROOT_DIR`` to the root directory of an mbedTLS installation. -# Set ``MBEDTLS_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries. - -if(MBEDTLS_ROOT_DIR) - # Disable re-rooting paths in find_path/find_library. - # This assumes MBEDTLS_ROOT_DIR is an absolute path. - set(_EXTRA_FIND_ARGS "NO_CMAKE_FIND_ROOT_PATH") +# - `MBEDTLS_FOUND`: System has mbedTLS. +# - `MBEDTLS_INCLUDE_DIRS`: The mbedTLS include directories. +# - `MBEDTLS_LIBRARIES`: The mbedTLS library names. +# - `MBEDTLS_LIBRARY_DIRS`: The mbedTLS library directories. +# - `MBEDTLS_PC_REQUIRES`: The mbedTLS pkg-config packages. +# - `MBEDTLS_CFLAGS`: Required compiler flags. +# - `MBEDTLS_VERSION`: Version of mbedTLS. + +if(DEFINED MBEDTLS_INCLUDE_DIRS AND NOT DEFINED MBEDTLS_INCLUDE_DIR) + message(WARNING "MBEDTLS_INCLUDE_DIRS is deprecated, use MBEDTLS_INCLUDE_DIR instead.") + set(MBEDTLS_INCLUDE_DIR "${MBEDTLS_INCLUDE_DIRS}") + unset(MBEDTLS_INCLUDE_DIRS) endif() -find_path(MBEDTLS_INCLUDE_DIR - NAMES mbedtls/ssl.h - PATH_SUFFIXES include - HINTS ${MBEDTLS_ROOT_DIR} - ${_EXTRA_FIND_ARGS}) - -# based on https://github.com/ARMmbed/mbedtls/issues/298 -if(MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h") - file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h" VERSION_STRING_LINE REGEX "^#define MBEDTLS_VERSION_STRING[ \\t\\n\\r]+\"[^\"]*\"$") - file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h" VERSION_MAJOR_LINE REGEX "^#define MBEDTLS_VERSION_MAJOR[ \\t\\n\\r]+[0-9]+$") - file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h" VERSION_MINOR_LINE REGEX "^#define MBEDTLS_VERSION_MINOR[ \\t\\n\\r]+[0-9]+$") - file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h" VERSION_PATCH_LINE REGEX "^#define MBEDTLS_VERSION_PATCH[ \\t\\n\\r]+[0-9]+$") - - string(REGEX REPLACE "^#define MBEDTLS_VERSION_STRING[ \\t\\n\\r]+\"([^\"]*)\"$" "\\1" MBEDTLS_VERSION "${VERSION_STRING_LINE}") - string(REGEX REPLACE "^#define MBEDTLS_VERSION_MAJOR[ \\t\\n\\r]+([0-9]+)$" "\\1" MBEDTLS_VERSION_MAJOR "${VERSION_MAJOR_LINE}") - string(REGEX REPLACE "^#define MBEDTLS_VERSION_MINOR[ \\t\\n\\r]+([0-9]+)$" "\\1" MBEDTLS_VERSION_MINOR "${VERSION_MINOR_LINE}") - string(REGEX REPLACE "^#define MBEDTLS_VERSION_PATCH[ \\t\\n\\r]+([0-9]+)$" "\\1" MBEDTLS_VERSION_PATCH "${VERSION_PATCH_LINE}") +if(CURL_USE_PKGCONFIG AND + NOT DEFINED MBEDTLS_INCLUDE_DIR AND + NOT DEFINED MBEDTLS_LIBRARY AND + NOT DEFINED MBEDX509_LIBRARY AND + NOT DEFINED MBEDCRYPTO_LIBRARY) + find_package(PkgConfig QUIET) + pkg_check_modules(MBEDTLS "mbedtls") + pkg_check_modules(MBEDX509 "mbedx509") + pkg_check_modules(MBEDCRYPTO "mbedcrypto") endif() - -if(MBEDTLS_USE_STATIC_LIBS) - set(_MBEDTLS_LIB_NAME libmbedtls.a) - set(_MBEDTLS_CRYPTO_LIB_NAME libmbedcrypto.a) - set(_MBEDTLS_X509_LIB_NAME libmbedx509.a) +if(MBEDTLS_FOUND AND MBEDX509_FOUND AND MBEDCRYPTO_FOUND) + list(APPEND MBEDTLS_LIBRARIES ${MBEDX509_LIBRARIES} ${MBEDCRYPTO_LIBRARIES}) + list(REMOVE_DUPLICATES MBEDTLS_LIBRARIES) + set(MBEDTLS_PC_REQUIRES "mbedtls") + string(REPLACE ";" " " MBEDTLS_CFLAGS "${MBEDTLS_CFLAGS}") + message(STATUS "Found MbedTLS (via pkg-config): ${MBEDTLS_INCLUDE_DIRS} (found version \"${MBEDTLS_VERSION}\")") else() - set(_MBEDTLS_LIB_NAME mbedtls) - set(_MBEDTLS_CRYPTO_LIB_NAME mbedcrypto) - set(_MBEDTLS_X509_LIB_NAME mbedx509) -endif() - -find_library(MBEDTLS_LIBRARY - NAMES ${_MBEDTLS_LIB_NAME} - PATH_SUFFIXES lib - HINTS ${MBEDTLS_ROOT_DIR} - ${_EXTRA_FIND_ARGS}) - -find_library(MBEDTLS_CRYPTO_LIBRARY - NAMES ${_MBEDTLS_CRYPTO_LIB_NAME} - PATH_SUFFIXES lib - HINTS ${MBEDTLS_ROOT_DIR} - ${_EXTRA_FIND_ARGS}) - -find_library(MBEDTLS_X509_LIBRARY - NAMES ${_MBEDTLS_X509_LIB_NAME} - PATH_SUFFIXES lib - HINTS ${MBEDTLS_ROOT_DIR} - ${_EXTRA_FIND_ARGS}) - -set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDTLS_X509_LIBRARY} ${MBEDTLS_CRYPTO_LIBRARY}) - -if(MBEDTLS_INCLUDE_DIR) - set(MBEDTLS_FOUND TRUE) -endif() - - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(MbedTLS - FOUND_VAR MBEDTLS_FOUND - REQUIRED_VARS - MBEDTLS_INCLUDE_DIR - MBEDTLS_LIBRARY - MBEDTLS_CRYPTO_LIBRARY - MBEDTLS_X509_LIBRARY - MBEDTLS_LIBRARIES - MBEDTLS_VERSION - VERSION_VAR MBEDTLS_VERSION) - - -if(NOT TARGET mbedtls) - add_library(mbedtls UNKNOWN IMPORTED) - set_target_properties(mbedtls PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${MBEDTLS_INCLUDE_DIR}" - IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${MBEDTLS_LIBRARY}") -endif() - -if(NOT TARGET mbedcrypto) - add_library(mbedcrypto UNKNOWN IMPORTED) - set_target_properties(mbedcrypto PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${MBEDTLS_CRYPTO_LIBRARY}") -endif() - -if(NOT TARGET mbedx509) - add_library(mbedx509 UNKNOWN IMPORTED) - set_target_properties(mbedx509 PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${MBEDTLS_X509_LIBRARY}") + find_path(MBEDTLS_INCLUDE_DIR NAMES "mbedtls/ssl.h") + find_library(MBEDTLS_LIBRARY NAMES "mbedtls" "libmbedtls") + find_library(MBEDX509_LIBRARY NAMES "mbedx509" "libmbedx509") + find_library(MBEDCRYPTO_LIBRARY NAMES "mbedcrypto" "libmbedcrypto") + + unset(MBEDTLS_VERSION CACHE) + if(MBEDTLS_INCLUDE_DIR) + if(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h") # 3.x + set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h") + elseif(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h") # 2.x + set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h") + else() + unset(_version_header) + endif() + if(_version_header) + set(_version_regex "#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"([0-9.]+)\"") + file(STRINGS "${_version_header}" _version_str REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") + set(MBEDTLS_VERSION "${_version_str}") + unset(_version_regex) + unset(_version_str) + unset(_version_header) + endif() + endif() + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(MbedTLS + REQUIRED_VARS + MBEDTLS_INCLUDE_DIR + MBEDTLS_LIBRARY + MBEDX509_LIBRARY + MBEDCRYPTO_LIBRARY + VERSION_VAR + MBEDTLS_VERSION + ) + + if(MBEDTLS_FOUND) + set(MBEDTLS_INCLUDE_DIRS ${MBEDTLS_INCLUDE_DIR}) + set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY}) + endif() + + mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) endif() diff --git a/include/pegasocks/ssl.h b/include/pegasocks/ssl.h index e224a7b..b6df10d 100644 --- a/include/pegasocks/ssl.h +++ b/include/pegasocks/ssl.h @@ -3,11 +3,32 @@ #include "config.h" +#ifdef USE_MBEDTLS +#include +#include +#include +#else #include +#endif struct pgs_ssl_ctx_s; +#ifdef USE_MBEDTLS +typedef struct pgs_ssl_ctx_s { + mbedtls_ssl_config conf; + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_x509_crt cacert; +} pgs_ssl_ctx_t; + +typedef struct { + mbedtls_ssl_context *ssl; + void *cb_ctx; +} pgs_bev_ctx_t; + +#else typedef struct pgs_ssl_ctx_s pgs_ssl_ctx_t; +#endif pgs_ssl_ctx_t *pgs_ssl_ctx_new(pgs_config_t *config); void pgs_ssl_ctx_free(pgs_ssl_ctx_t *ctx); diff --git a/src/crypto/mbedtls.c b/src/crypto/mbedtls.c index b1c0cc1..0be9661 100644 --- a/src/crypto/mbedtls.c +++ b/src/crypto/mbedtls.c @@ -10,6 +10,7 @@ #include #include #include +#include static const mbedtls_cipher_type_t get_mbedtls_cipher(pgs_cryptor_type_t cipher); @@ -194,6 +195,7 @@ void sha224(const uint8_t *input, uint64_t input_len, uint8_t *res, *res_len = 0; } +#if MBEDTLS_VERSION_NUMBER < 0x03000000 void md5(const uint8_t *input, uint64_t input_len, uint8_t *res) { mbedtls_md5_ret(input, input_len, res); @@ -204,6 +206,21 @@ void sha1(const uint8_t *input, uint64_t input_len, uint8_t *res) mbedtls_sha1_ret(input, input_len, res); } +#else + +void md5(const uint8_t *input, uint64_t input_len, uint8_t *res) +{ + mbedtls_md5(input, input_len, res); +} + +void sha1(const uint8_t *input, uint64_t input_len, uint8_t *res) +{ + mbedtls_sha1(input, input_len, res); +} + +#endif + + void hmac_md5(const uint8_t *key, uint64_t key_len, const uint8_t *data, uint64_t data_len, uint8_t *out, uint64_t *out_len) { @@ -419,6 +436,8 @@ static bool pgs_cryptor_decrypt_aes(pgs_cryptor_t *ptr, return true; } +#if MBEDTLS_VERSION_NUMBER < 0x03000000 + static bool pgs_cryptor_encrypt_gcm(pgs_cryptor_t *ptr, const uint8_t *plaintext, size_t plaintext_len, uint8_t *tag, @@ -457,6 +476,74 @@ static bool pgs_cryptor_decrypt_gcm(pgs_cryptor_t *ptr, return true; } +#else + +static bool pgs_cryptor_encrypt_gcm(pgs_cryptor_t *ptr, + const uint8_t *plaintext, + size_t plaintext_len, uint8_t *tag, + uint8_t *ciphertext, size_t *ciphertext_len) +{ + size_t out_len = 0; + + // Start the GCM operation + if (mbedtls_gcm_starts(ptr->ctx, MBEDTLS_GCM_ENCRYPT, ptr->iv, + ptr->iv_len)) { + return false; + } + + // Pass associated data if any (in this case, NULL and 0 since not used here) + if (mbedtls_gcm_update_ad(ptr->ctx, NULL, 0)) { + return false; + } + + // Encrypt the plaintext + if (mbedtls_gcm_update(ptr->ctx, plaintext, plaintext_len, ciphertext, plaintext_len, &out_len)) { + return false; + } + + // Finalize the operation and generate the tag + if (mbedtls_gcm_finish(ptr->ctx, NULL, 0, &out_len, tag, ptr->tag_len)) { + return false; + } + + *ciphertext_len = plaintext_len; // The ciphertext length matches the plaintext length + return true; +} + +static bool pgs_cryptor_decrypt_gcm(pgs_cryptor_t *ptr, + const uint8_t *ciphertext, + size_t ciphertext_len, const uint8_t *tag, + uint8_t *plaintext, size_t *plaintext_len) +{ + size_t out_len = 0; + + // Start the GCM operation + if (mbedtls_gcm_starts(ptr->ctx, MBEDTLS_GCM_DECRYPT, ptr->iv, + ptr->iv_len)) { + return false; + } + + // Pass associated data if any (in this case, NULL and 0 since not used here) + if (mbedtls_gcm_update_ad(ptr->ctx, NULL, 0)) { + return false; + } + + // Decrypt the ciphertext + if (mbedtls_gcm_update(ptr->ctx, ciphertext, ciphertext_len, plaintext, ciphertext_len, &out_len)) { + return false; + } + + // Finalize the operation + if (mbedtls_gcm_finish(ptr->ctx, NULL, 0, &out_len, (unsigned char *)tag, ptr->tag_len)) { + return false; + } + + *plaintext_len = ciphertext_len; // The plaintext length matches the ciphertext length + return true; +} + +#endif + static bool pgs_cryptor_encrypt_chachapoly(pgs_cryptor_t *ptr, const uint8_t *plaintext, size_t plaintext_len, uint8_t *tag, diff --git a/src/server/metrics.c b/src/server/metrics.c index b44c5b7..c7e4fed 100644 --- a/src/server/metrics.c +++ b/src/server/metrics.c @@ -7,6 +7,10 @@ #include "applet.h" #endif +#ifdef USE_MBEDTLS +#include "ssl.h" +#endif + const unsigned char g204_cmd[] = { 0x05, 0x01, 0x00, 0x03, 0x0d, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6e, 0x00, 0x50 }; @@ -48,7 +52,12 @@ static double elapse(struct timeval start_at) static void on_trojan_g204_event(struct bufferevent *bev, short events, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif if (events & BEV_EVENT_TIMEOUT) { pgs_logger_error(mctx->logger, "(%s)%s:%d g204 timeout", mctx->config->server_type, @@ -68,7 +77,12 @@ static void on_trojan_g204_event(struct bufferevent *bev, short events, static void on_trojan_g204_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif const pgs_config_extra_trojan_t *tconfig = mctx->config->extra; if (tconfig->websocket.enabled) { on_trojan_ws_g204_read(bev, ctx); @@ -80,7 +94,13 @@ static void on_trojan_g204_read(struct bufferevent *bev, void *ctx) static void on_v2ray_g204_event(struct bufferevent *bev, short events, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + if (events & BEV_EVENT_TIMEOUT) { pgs_logger_error(mctx->logger, "v2ray g204 timeout"); if (mctx) @@ -97,7 +117,12 @@ static void on_v2ray_g204_event(struct bufferevent *bev, short events, static void on_v2ray_g204_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif const pgs_config_extra_v2ray_t *vconfig = mctx->config->extra; if (vconfig->websocket.enabled) { on_v2ray_ws_g204_read(bev, ctx); @@ -182,7 +207,13 @@ get_metrics_g204_connect(int idx, const pgs_config_t *gconfig, static void on_ws_g204_event(struct bufferevent *bev, short events, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + if (events & BEV_EVENT_CONNECTED) do_ws_remote_request(bev, ctx); if (events & BEV_EVENT_ERROR) @@ -197,7 +228,13 @@ static void on_ws_g204_event(struct bufferevent *bev, short events, void *ctx) static void on_trojan_ws_g204_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + pgs_logger_debug(mctx->logger, "remote read triggered"); struct evbuffer *output = bufferevent_get_output(bev); struct evbuffer *input = bufferevent_get_input(bev); @@ -256,7 +293,13 @@ static void v2ray_ws_vmess_write_cb(struct evbuffer *writer, uint8_t *data, static void on_v2ray_ws_g204_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + struct evbuffer *output = bufferevent_get_output(bev); struct evbuffer *input = bufferevent_get_input(bev); @@ -300,7 +343,13 @@ static void on_v2ray_ws_g204_read(struct bufferevent *bev, void *ctx) static void on_trojan_gfw_g204_read(struct bufferevent *bev, void *ctx) { // with data +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + double g204_time = elapse(mctx->start_at); pgs_logger_debug(mctx->logger, "g204: %f", g204_time); pgs_metrics_update(&mctx->sm->server_stats[mctx->server_idx], @@ -311,7 +360,13 @@ static void on_trojan_gfw_g204_event(struct bufferevent *bev, short events, void *ctx) { // connect time and error handling +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + if (events & BEV_EVENT_CONNECTED) { // set connected pgs_outbound_ctx_trojan_t *sctx = mctx->outbound->ctx; @@ -343,7 +398,13 @@ static void on_trojan_gfw_g204_event(struct bufferevent *bev, short events, } static void on_v2ray_tcp_g204_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + double g204_time = elapse(mctx->start_at); pgs_logger_debug(mctx->logger, "g204: %f", g204_time); pgs_metrics_update(&mctx->sm->server_stats[mctx->server_idx], @@ -354,7 +415,13 @@ static void on_v2ray_tcp_g204_read(struct bufferevent *bev, void *ctx) static void on_ss_g204_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + double g204_time = elapse(mctx->start_at); pgs_logger_debug(mctx->logger, "g204: %f", g204_time); pgs_metrics_update(&mctx->sm->server_stats[mctx->server_idx], @@ -365,7 +432,13 @@ static void on_ss_g204_read(struct bufferevent *bev, void *ctx) static void on_ss_g204_event(struct bufferevent *bev, short events, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + if (events & BEV_EVENT_TIMEOUT) { pgs_logger_error(mctx->logger, "shadowsocks g204 timeout"); if (mctx) @@ -403,7 +476,13 @@ static void on_ss_g204_event(struct bufferevent *bev, short events, void *ctx) static void on_v2ray_tcp_g204_event(struct bufferevent *bev, short events, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else pgs_metrics_task_ctx_t *mctx = ctx; +#endif + if (events & BEV_EVENT_CONNECTED) { // set connected pgs_outbound_ctx_v2ray_t *sctx = mctx->outbound->ctx; @@ -433,7 +512,13 @@ static void on_v2ray_tcp_g204_event(struct bufferevent *bev, short events, static void do_ws_remote_request(struct bufferevent *bev, void *ctx) { - pgs_metrics_task_ctx_t *mctx = (pgs_metrics_task_ctx_t *)ctx; +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + pgs_metrics_task_ctx_t *mctx = bev_ctx->cb_ctx; +#else + pgs_metrics_task_ctx_t *mctx = ctx; +#endif + const pgs_server_config_t *config = mctx->outbound->config; const pgs_config_ws_t *ws_config = config->extra; diff --git a/src/session/outbound.c b/src/session/outbound.c index 0840988..4482140 100644 --- a/src/session/outbound.c +++ b/src/session/outbound.c @@ -6,7 +6,11 @@ #include #include +#ifdef USE_MBEDTLS +#include "ssl.h" +#else #include +#endif #include #include @@ -287,6 +291,7 @@ void pgs_session_outbound_free(pgs_session_outbound_t *ptr) #ifdef USE_MBEDTLS bool is_be_ssl = false; const pgs_server_config_t *config = ptr->config; + if (IS_V2RAY_SERVER(config->server_type)) { pgs_config_extra_v2ray_t *vconf = (pgs_config_extra_v2ray_t *)config->extra; @@ -294,23 +299,36 @@ void pgs_session_outbound_free(pgs_session_outbound_t *ptr) is_be_ssl = true; } } + if (IS_TROJAN_SERVER(config->server_type)) { is_be_ssl = true; } + int fd = bufferevent_getfd(ptr->bev); if (is_be_ssl) { - mbedtls_ssl_context *ssl = - bufferevent_mbedtls_get_ssl(ptr->bev); + // Retrieve and clean up the SSL context + pgs_bev_ctx_t *bev_ctx = NULL; + bufferevent_getcb(ptr->bev, NULL, NULL, NULL, (void *)&bev_ctx); + + mbedtls_ssl_context *ssl = bev_ctx->ssl; + if (ssl != NULL) { + mbedtls_ssl_free(ssl); + free(ssl); + } + + if (bev_ctx != NULL) { + free(bev_ctx); + } + bufferevent_free(ptr->bev); - mbedtls_ssl_free(ssl); - free(ssl); } else { bufferevent_free(ptr->bev); } - if (fd) + if (fd) { evutil_closesocket(fd); + } #else bufferevent_free(ptr->bev); #endif @@ -364,7 +382,15 @@ bool pgs_session_trojan_outbound_init( goto error; assert(event_cb && read_cb && ptr->bev); +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = NULL; + bufferevent_getcb(ptr->bev, NULL, NULL, NULL, (void *)&bev_ctx); + bev_ctx->cb_ctx = cb_ctx; + + bufferevent_setcb(ptr->bev, read_cb, NULL, event_cb, bev_ctx); +#else bufferevent_setcb(ptr->bev, read_cb, NULL, event_cb, cb_ctx); +#endif return true; @@ -552,6 +578,10 @@ bool pgs_session_outbound_init(pgs_session_outbound_t *ptr, bool is_udp, static void on_bypass_remote_event(struct bufferevent *bev, short events, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + ctx = bev_ctx->cb_ctx; +#endif pgs_session_t *session = (pgs_session_t *)ctx; if (events & BEV_EVENT_CONNECTED) { @@ -571,6 +601,10 @@ static void on_bypass_remote_event(struct bufferevent *bev, short events, static void on_bypass_remote_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + ctx = bev_ctx->cb_ctx; +#endif pgs_session_t *session = (pgs_session_t *)ctx; pgs_session_debug(session, "remote read triggered"); struct evbuffer *input = bufferevent_get_input(bev); @@ -597,6 +631,10 @@ static void on_bypass_remote_read(struct bufferevent *bev, void *ctx) static void on_trojan_remote_event(struct bufferevent *bev, short events, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + ctx = bev_ctx->cb_ctx; +#endif pgs_session_t *session = (pgs_session_t *)ctx; if (events & BEV_EVENT_CONNECTED) { @@ -657,6 +695,10 @@ static void on_trojan_remote_event(struct bufferevent *bev, short events, */ static void on_trojan_remote_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + ctx = bev_ctx->cb_ctx; +#endif pgs_session_t *session = (pgs_session_t *)ctx; pgs_session_debug(session, "remote read triggered"); struct evbuffer *output = bufferevent_get_output(bev); @@ -771,6 +813,10 @@ static void on_trojan_remote_read(struct bufferevent *bev, void *ctx) static void on_v2ray_remote_event(struct bufferevent *bev, short events, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + ctx = bev_ctx->cb_ctx; +#endif pgs_session_t *session = (pgs_session_t *)ctx; if (events & BEV_EVENT_CONNECTED) { @@ -821,6 +867,10 @@ static void on_v2ray_remote_event(struct bufferevent *bev, short events, } static void on_v2ray_remote_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + ctx = bev_ctx->cb_ctx; +#endif pgs_session_t *session = (pgs_session_t *)ctx; pgs_session_debug(session, "remote read triggered"); const pgs_server_config_t *config = session->outbound->config; @@ -942,6 +992,10 @@ static void on_v2ray_remote_read(struct bufferevent *bev, void *ctx) */ static void on_ss_remote_event(struct bufferevent *bev, short events, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + ctx = bev_ctx->cb_ctx; +#endif pgs_session_t *session = (pgs_session_t *)ctx; if (events & BEV_EVENT_CONNECTED) { @@ -960,6 +1014,10 @@ static void on_ss_remote_event(struct bufferevent *bev, short events, void *ctx) static void on_ss_remote_read(struct bufferevent *bev, void *ctx) { +#ifdef USE_MBEDTLS + pgs_bev_ctx_t *bev_ctx = ctx; + ctx = bev_ctx->cb_ctx; +#endif pgs_session_t *session = (pgs_session_t *)ctx; pgs_session_debug(session, "ss remote read triggered"); struct evbuffer *input = bufferevent_get_input(bev); diff --git a/src/ssl/mbedtls.c b/src/ssl/mbedtls.c index 058f457..da2c263 100644 --- a/src/ssl/mbedtls.c +++ b/src/ssl/mbedtls.c @@ -8,12 +8,14 @@ #include +/* struct pgs_ssl_ctx_s { mbedtls_ssl_config conf; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_x509_crt cacert; }; +*/ pgs_ssl_ctx_t *pgs_ssl_ctx_new(pgs_config_t *config) { @@ -87,27 +89,40 @@ int pgs_session_outbound_ssl_bev_init(struct bufferevent **bev, int fd, pgs_ssl_ctx_t *ssl_ctx, const char *sni) { // notice: should be freed when bev is freed + // Allocate and initialize the mbedTLS SSL context mbedtls_ssl_context *ssl = malloc(sizeof(mbedtls_ssl_context)); - + if (!ssl) { + return -1; // Memory allocation failure + } mbedtls_ssl_init(ssl); + // Set up the mbedTLS SSL context int ret = 0; if ((ret = mbedtls_ssl_setup(ssl, &ssl_ctx->conf)) != 0) { + mbedtls_ssl_free(ssl); + free(ssl); return -1; } if ((ret = mbedtls_ssl_set_hostname(ssl, sni)) != 0) { + mbedtls_ssl_free(ssl); + free(ssl); + return -1; + } + + // Create a new bufferevent with the initialized mbedTLS SSL context + *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); + if (!*bev) { + mbedtls_ssl_free(ssl); + free(ssl); return -1; } - *bev = bufferevent_mbedtls_socket_new(base, fd, ssl, - BUFFEREVENT_SSL_CONNECTING, - BEV_OPT_DEFER_CALLBACKS); -#ifdef BUFFEREVENT_SSL_BATCH_WRITE - bufferevent_ssl_set_flags(*bev, BUFFEREVENT_SSL_DIRTY_SHUTDOWN | - BUFFEREVENT_SSL_BATCH_WRITE); -#else - bufferevent_mbedtls_set_allow_dirty_shutdown(*bev, 1); -#endif + // Set callbacks and associate mbedTLS SSL context as the cbarg + pgs_bev_ctx_t *bev_ctx = malloc(sizeof(pgs_bev_ctx_t)); + bev_ctx->ssl = ssl; + bev_ctx->cb_ctx = NULL; + + bufferevent_setcb(*bev, NULL, NULL, NULL, bev_ctx); return 0; }