├── .gitignore ├── bctoolbox.pc.in ├── bctoolbox-tester.pc.in ├── src ├── utils.h ├── utils │ ├── ios_utils_app.hh │ ├── ios_utils_stub.hh │ ├── regex.cc │ ├── ios_utils_app.mm │ ├── exception.cc │ ├── ios_utils.mm │ └── utils.cc ├── conversion │ ├── charconv_android.cc │ ├── charconv_encoding.cc │ ├── charconv.cc │ └── charconv_windows.cc ├── param_string.c ├── vfs │ ├── vfs_encryption_module.hh │ ├── vfs_encryption_module_dummy.hh │ ├── vfs_encryption_module_aes256gcm_sha256.hh │ ├── vfs_standard.c │ └── vfs_encryption_module_aes256gcm_sha256.cc ├── parser.c ├── logging │ └── log-tags.cc ├── crypto │ └── crypto.c └── vconnect.c ├── cmake ├── gitversion.h.in ├── MakeArchive.cmake ├── ConfigureSpecfile.cmake ├── BCGitVersion.cmake ├── FindDecaf.cmake ├── BCToolboxConfig.cmake.in ├── FindBCUnit.cmake └── FindMbedTLS.cmake ├── .clang-format ├── include ├── bctoolbox │ ├── vfs_standard.h │ ├── defs.h │ ├── regex.h │ ├── compiler.h │ ├── ios_utils.hh │ ├── param_string.h │ ├── exception.hh │ ├── utils.hh │ ├── parser.h │ ├── ownership.hh │ ├── list.h │ ├── charconv.h │ ├── map.h │ ├── vconnect.h │ └── vfs_encrypted.hh └── CMakeLists.txt ├── config.h.cmake ├── tester ├── ios_utils.cc ├── bctoolbox_tester.h ├── parser.c ├── CMakeLists.txt ├── param_string.c ├── bctoolbox_tester.c ├── logger.cc └── containers.cc ├── CHANGELOG.md ├── README.md ├── .github └── ISSUE_TEMPLATE │ └── bug_report.yml └── CMakeLists.txt /.gitignore: -------------------------------------------------------------------------------- 1 | bctoolbox.spec 2 | .*.swp 3 | -------------------------------------------------------------------------------- /bctoolbox.pc.in: -------------------------------------------------------------------------------- 1 | # This is a comment 2 | prefix=@CMAKE_INSTALL_PREFIX@ 3 | exec_prefix=@CMAKE_INSTALL_PREFIX@ 4 | 5 | Name: bctoolbox 6 | Description: A common set of tools used by Belledonne Communication's softwares 7 | Version: @PROJECT_VERSION@ 8 | Libs: -L@CMAKE_INSTALL_FULL_LIBDIR@ -lbctoolbox 9 | Libs.private: @LIBS_PRIVATE@ 10 | Cflags: -I@CMAKE_INSTALL_FULL_INCLUDEDIR@ 11 | -------------------------------------------------------------------------------- /bctoolbox-tester.pc.in: -------------------------------------------------------------------------------- 1 | # This is a comment 2 | prefix=@CMAKE_INSTALL_PREFIX@ 3 | exec_prefix=@CMAKE_INSTALL_PREFIX@ 4 | Name: bctoolbox-tester 5 | Description: A common set of tester wrappers used by Belledonne Communications's softwares 6 | Requires.private: @TESTER_REQUIRES_PRIVATE@ 7 | Version: @PROJECT_VERSION@ 8 | Libs: -L@CMAKE_INSTALL_FULL_LIBDIR@ -lbctoolbox-tester 9 | Cflags: -I@CMAKE_INSTALL_FULL_INCLUDEDIR@ 10 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "bctoolbox/port.h" -------------------------------------------------------------------------------- /cmake/gitversion.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | linphone 3 | Copyright (C) 2010-2017 Belledonne Communications SARL 4 | 5 | This program is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU General Public License 7 | as published by the Free Software Foundation; either version 2 8 | of the License, or (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | 21 | #define @PREFIX_GIT_VERSION@_GIT_VERSION "@PROJECT_GIT_VERSION@" -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010-2023 Belledonne Communications SARL. 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU Affero General Public License as 5 | # published by the Free Software Foundation, either version 3 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU Affero General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU Affero General Public License 14 | # along with this program. If not, see . 15 | 16 | --- 17 | Language: Cpp 18 | BasedOnStyle: LLVM 19 | AccessModifierOffset: -4 20 | AllowShortFunctionsOnASingleLine: None 21 | AllowShortIfStatementsOnASingleLine: AllIfsAndElse 22 | AlwaysBreakTemplateDeclarations: Yes 23 | BinPackParameters: false 24 | ColumnLimit: 120 25 | PointerAlignment: Right 26 | IndentCaseLabels: true 27 | IndentWidth: 4 28 | Standard: c++14 29 | TabWidth: 4 30 | UseTab: ForIndentation 31 | ... 32 | -------------------------------------------------------------------------------- /include/bctoolbox/vfs_standard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_VFS_STANDARD_H 21 | #define BCTBX_VFS_STANDARD_H 22 | 23 | #include "bctoolbox/port.h" 24 | #include "bctoolbox/vfs.h" 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /** 31 | * Virtual File sytem provided 32 | */ 33 | extern BCTBX_PUBLIC bctbx_vfs_t bcStandardVfs; 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif /* BCTBX_VFS_STANDARD_H */ 40 | -------------------------------------------------------------------------------- /src/utils/ios_utils_app.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2019 Belledonne Communications SARL. 3 | * 4 | * This file is part of Liblinphone. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "bctoolbox/ios_utils.hh" 23 | 24 | namespace bctoolbox { 25 | 26 | class IOSUtilsApp : public IOSUtilsInterface { 27 | public: 28 | unsigned long beginBackgroundTask(const char *name, std::function cb) override; 29 | void endBackgroundTask(unsigned long id) override; 30 | bool isApplicationStateActive() override; 31 | }; 32 | 33 | } // namespace bctoolbox 34 | -------------------------------------------------------------------------------- /src/utils/ios_utils_stub.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2019 Belledonne Communications SARL. 3 | * 4 | * This file is part of Liblinphone. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "bctoolbox/ios_utils.hh" 23 | 24 | namespace bctoolbox { 25 | 26 | class IOSUtilsStub : public IOSUtilsInterface { 27 | public: 28 | unsigned long beginBackgroundTask(const char *name, std::function cb) override; 29 | void endBackgroundTask(unsigned long id) override; 30 | bool isApplicationStateActive() override; 31 | }; 32 | 33 | } // namespace bctoolbox 34 | -------------------------------------------------------------------------------- /config.h.cmake: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * config.h.cmake 3 | * Copyright (C) 2010-2022 Belledonne Communications, Grenoble France 4 | * 5 | **************************************************************************** 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | * 21 | ****************************************************************************/ 22 | 23 | #cmakedefine HAVE_DTLS_SRTP 1 24 | #cmakedefine HAVE_DECAF 1 25 | #cmakedefine HAVE_MBEDTLS 1 26 | #cmakedefine HAVE_OPENSSL 1 27 | #cmakedefine HAVE_CTR_DRGB_FREE 1 28 | #cmakedefine HAVE_CU_GET_SUITE 1 29 | #cmakedefine HAVE_CU_CURSES 1 30 | #cmakedefine HAVE_CU_SET_TRACE_HANDLER 1 31 | #cmakedefine ENABLE_DEFAULT_LOG_HANDLER 1 32 | 33 | #cmakedefine HAVE_LIBRT 1 34 | 35 | #cmakedefine HAVE_EXECINFO 36 | -------------------------------------------------------------------------------- /tester/ios_utils.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "bctoolbox/ios_utils.hh" 21 | #include "bctoolbox_tester.h" 22 | #include 23 | 24 | using namespace bctoolbox; 25 | 26 | static void ios_utils_return_values(void) { 27 | auto &iOSUtils = IOSUtils::getUtils(); 28 | BC_ASSERT_EQUAL(iOSUtils.beginBackgroundTask(nullptr, nullptr), 0, unsigned long, "%lu"); 29 | BC_ASSERT_EQUAL(iOSUtils.isApplicationStateActive(), false, bool, "%d"); 30 | } 31 | 32 | static test_t ios_utils_tests[] = { 33 | TEST_NO_TAG("Return values for stubbed functions", ios_utils_return_values), 34 | }; 35 | 36 | test_suite_t ios_utils_test_suite = { 37 | "iOS Utilities", NULL, NULL, NULL, NULL, sizeof(ios_utils_tests) / sizeof(ios_utils_tests[0]), ios_utils_tests, 0}; 38 | -------------------------------------------------------------------------------- /include/bctoolbox/defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_DEFS_H_ 21 | #define BCTBX_DEFS_H_ 22 | 23 | /* Macro telling GCC that a 'break' statement has been deliberately omitted 24 | * in switch block */ 25 | #ifndef BCTBX_NO_BREAK 26 | #if defined(__GNUC__) && __GNUC__ >= 7 27 | #define BCTBX_NO_BREAK __attribute__((fallthrough)) 28 | #else 29 | #define BCTBX_NO_BREAK 30 | #endif // __GNUC__ 31 | #endif // BCTBX_NO_BREAK 32 | 33 | #ifndef BCTBX_UNUSED 34 | #if (!defined(_WIN32) && (defined(__GNUC__) || defined(__clang__))) 35 | #define BCTBX_UNUSED(x) x __attribute__((__unused__)) 36 | #else 37 | #define BCTBX_UNUSED(x) x 38 | #endif //(!defined(_MSC_VER) && (defined(__GNUC__) || defined(__clang__))) 39 | #endif // BCTBX_UNUSED 40 | 41 | #endif /* BCTBX_DEFS_H_ */ 42 | -------------------------------------------------------------------------------- /include/bctoolbox/regex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_REGEX_H 21 | #define BCTBX_REGEX_H 22 | 23 | #include "bctoolbox/port.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | BCTBX_PUBLIC bool_t bctbx_is_matching_regex(const char *entry, const char *regex); 30 | BCTBX_PUBLIC bool_t bctbx_is_matching_regex_log(const char *entry, const char *regex, bool_t show_log); 31 | BCTBX_PUBLIC bool_t bctbx_is_matching_regex_log_context(const char *entry, 32 | const char *regex, 33 | bool_t show_log, 34 | const char *context); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif /* BCTBX_REGEX_H */ 41 | -------------------------------------------------------------------------------- /cmake/MakeArchive.cmake: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # MakeArchive.cmake 3 | # Copyright (C) 2010-2019 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | 23 | include("${BCToolbox_CMAKE_UTILS}") 24 | bc_compute_full_version(version) 25 | set(archive_name "${CPACK_PACKAGE_NAME}-${version}") 26 | set(archive_path "${PROJECT_BINARY_DIR}/${archive_name}.tar.gz") 27 | 28 | find_program(TAR tar) 29 | 30 | set(EXCLUDE_ARGS ) 31 | foreach (pattern ${EXCLUDE_PATTERNS}) 32 | list(APPEND EXCLUDE_ARGS "--exclude=${pattern}") 33 | endforeach() 34 | 35 | execute_process(COMMAND ${TAR} -C "${PROJECT_SOURCE_DIR}" -cz -f "${archive_path}" "--transform" "s,^\\.,${archive_name}," ${EXCLUDE_ARGS} .) 36 | -------------------------------------------------------------------------------- /tester/bctoolbox_tester.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef _BCTOOLBOX_TESTER_H 21 | #define _BCTOOLBOX_TESTER_H 22 | 23 | #include "bctoolbox/logging.h" 24 | #include "bctoolbox/tester.h" 25 | 26 | #ifdef __cplusplus 27 | 28 | #define SLOGD BCTBX_SLOGD("bctoolbox-tester") 29 | #define SLOGI BCTBX_SLOGI("bctoolbox-tester") 30 | #define SLOGW BCTBX_SLOGW("bctoolbox-tester") 31 | #define SLOGE BCTBX_SLOGE("bctoolbox-tester") 32 | 33 | extern "C" { 34 | #endif 35 | 36 | extern test_suite_t containers_test_suite; 37 | extern test_suite_t utils_test_suite; 38 | extern test_suite_t crypto_test_suite; 39 | extern test_suite_t parser_test_suite; 40 | extern test_suite_t ios_utils_test_suite; 41 | extern test_suite_t encrypted_vfs_test_suite; 42 | extern test_suite_t param_string_test_suite; 43 | extern test_suite_t vfs_test_suite; 44 | extern test_suite_t logger_test_suite; 45 | 46 | #ifdef __cplusplus 47 | }; 48 | #endif 49 | 50 | #endif /* _BCTOOLBOX_TESTER_H */ 51 | -------------------------------------------------------------------------------- /cmake/ConfigureSpecfile.cmake: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # ConfigureSpecfile.cmake 3 | # Copyright (C) 2010-2019 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | 23 | include("${BCToolbox_CMAKE_UTILS}") 24 | 25 | set(FULL_VERSION ) 26 | bc_compute_full_version(FULL_VERSION) 27 | 28 | set(version_major ) 29 | set(version_minor ) 30 | set(version_patch ) 31 | set(identifiers ) 32 | set(metadata ) 33 | 34 | bc_parse_full_version("${FULL_VERSION}" version_major version_minor version_patch identifiers metadata) 35 | 36 | set(RPM_VERSION ${version_major}.${version_minor}.${version_patch}) 37 | if (NOT identifiers) 38 | set(RPM_RELEASE 1) 39 | else() 40 | string(SUBSTRING "${identifiers}" 1 -1 identifiers) 41 | set(RPM_RELEASE "0.${identifiers}${metadata}") 42 | endif() 43 | 44 | configure_file("${SRC}" "${DEST}") 45 | -------------------------------------------------------------------------------- /include/bctoolbox/compiler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef COMPILER_H 21 | #define COMPILER_H 22 | 23 | #ifdef __has_feature 24 | #if __has_feature(address_sanitizer) 25 | #define BCTBX_ASAN_ENABLED 26 | #endif // if __has_feature(address_sanitizer) 27 | #elif defined(__SANITIZE_ADDRESS__) 28 | #define BCTBX_ASAN_ENABLED 29 | #endif // ifdef __has_feature 30 | 31 | #ifdef BCTBX_ASAN_ENABLED 32 | #define BCTBX_DISABLE_ASAN __attribute__((no_sanitize_address)) 33 | #else 34 | #define BCTBX_DISABLE_ASAN 35 | #endif // ifdef BCTBX_ASAN_ENABLED 36 | 37 | #ifdef __has_attribute 38 | #if __has_attribute(no_sanitize) 39 | #define BCTBX_DISABLE_UBSAN __attribute__((no_sanitize("undefined"))) 40 | #else 41 | #define BCTBX_DISABLE_UBSAN 42 | #endif // __has_attribute(no_sanitize) 43 | #elif defined(__GNUC__) && !defined(__MINGW32__) && GCC_VERSION >= 40900 44 | #define BCTBX_DISABLE_UBSAN __attribute__((no_sanitize_undefined)) 45 | #else 46 | #define BCTBX_DISABLE_UBSAN 47 | #endif // ifdef __has_attribute 48 | 49 | #endif // ifdef COMPILER_H 50 | -------------------------------------------------------------------------------- /tester/parser.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "bctoolbox/parser.h" 21 | #include "bctoolbox_tester.h" 22 | 23 | static void simple_escaping(void) { 24 | char *my_escaped_string; 25 | bctbx_noescape_rules_t my_rules = {0}; 26 | bctbx_noescape_rules_add_alfanums(my_rules); 27 | my_escaped_string = bctbx_escape("François", my_rules); 28 | BC_ASSERT_TRUE(strcmp("Fran%c3%a7ois", my_escaped_string) == 0); 29 | bctbx_free(my_escaped_string); 30 | } 31 | 32 | static void simple_unescaping(void) { 33 | char *my_unescaped_string; 34 | my_unescaped_string = bctbx_unescaped_string("Fran%c3%a7ois"); 35 | BC_ASSERT_TRUE(strcmp("François", my_unescaped_string) == 0); 36 | bctbx_free(my_unescaped_string); 37 | } 38 | 39 | static test_t container_tests[] = { 40 | TEST_NO_TAG("simple escaping", simple_escaping), 41 | TEST_NO_TAG("simple unescaping", simple_unescaping), 42 | }; 43 | 44 | 45 | test_suite_t parser_test_suite = { 46 | "Parsing", NULL, NULL, NULL, NULL, sizeof(container_tests) / sizeof(container_tests[0]), container_tests, 0}; 47 | -------------------------------------------------------------------------------- /include/bctoolbox/ios_utils.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2019 Belledonne Communications SARL. 3 | * 4 | * This file is part of Liblinphone. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | namespace bctoolbox { 25 | 26 | class IOSUtilsInterface { 27 | public: 28 | virtual unsigned long beginBackgroundTask(const char *name, std::function cb) = 0; 29 | virtual void endBackgroundTask(unsigned long id) = 0; 30 | virtual bool isApplicationStateActive() = 0; 31 | 32 | virtual ~IOSUtilsInterface() = default; 33 | }; 34 | 35 | class IOSUtils { 36 | public: 37 | unsigned long beginBackgroundTask(const char *name, std::function cb); 38 | void endBackgroundTask(unsigned long id); 39 | bool isApplicationStateActive(); 40 | bool isApp(); 41 | int getOSMajorVersion() const; 42 | static IOSUtils &getUtils(); 43 | 44 | IOSUtils(const IOSUtils &) = delete; 45 | IOSUtils &operator=(const IOSUtils &) = delete; 46 | ~IOSUtils(); 47 | 48 | private: 49 | void *mHandle; 50 | IOSUtilsInterface *mUtils; 51 | bool mIsApp; 52 | static std::unique_ptr sInstance; 53 | IOSUtils(); 54 | 55 | void openDynamicLib(); 56 | void *loadSymbol(const char *symbol); 57 | }; 58 | 59 | } // namespace bctoolbox 60 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # Copyright (C) 2016 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | 23 | set(HEADER_FILES 24 | charconv.h 25 | compiler.h 26 | defs.h 27 | exception.hh 28 | utils.hh 29 | list.h 30 | logging.h 31 | map.h 32 | ownership.hh 33 | parser.h 34 | port.h 35 | regex.h 36 | vconnect.h 37 | vfs.h 38 | vfs_standard.h 39 | vfs_encrypted.hh 40 | param_string.h 41 | ) 42 | 43 | if(APPLE) 44 | list(APPEND HEADER_FILES ios_utils.hh) 45 | endif() 46 | 47 | if(MbedTLS_FOUND OR OPENSSL_FOUND) 48 | list(APPEND HEADER_FILES crypto.h) 49 | list(APPEND HEADER_FILES crypto.hh) 50 | endif() 51 | 52 | if(ENABLE_TESTS_COMPONENT) 53 | list(APPEND HEADER_FILES tester.h) 54 | endif() 55 | 56 | set(BCTOOLBOX_HEADER_FILES ) 57 | foreach(HEADER_FILE ${HEADER_FILES}) 58 | list(APPEND BCTOOLBOX_HEADER_FILES "${CMAKE_CURRENT_LIST_DIR}/bctoolbox/${HEADER_FILE}") 59 | endforeach() 60 | set(BCTOOLBOX_HEADER_FILES ${BCTOOLBOX_HEADER_FILES} PARENT_SCOPE) 61 | 62 | install(FILES ${BCTOOLBOX_HEADER_FILES} 63 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/bctoolbox 64 | PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ 65 | ) 66 | -------------------------------------------------------------------------------- /src/conversion/charconv_android.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include "bctoolbox/charconv.h" 25 | #include "bctoolbox/defs.h" 26 | #include "bctoolbox/logging.h" 27 | #include "bctoolbox/port.h" 28 | 29 | char *bctbx_locale_to_utf8(const char *str) { 30 | // TODO remove this part when the NDK will contain a usable iconv 31 | return bctbx_strdup(str); 32 | } 33 | 34 | char *bctbx_utf8_to_locale(const char *str) { 35 | // TODO remove this part when the NDK will contain a usable iconv 36 | return bctbx_strdup(str); 37 | } 38 | 39 | char *bctbx_convert_any_to_utf8(const char *str, BCTBX_UNUSED(const char *encoding)) { 40 | // TODO change this part when the NDK will contain a usable iconv 41 | return bctbx_strdup(str); 42 | } 43 | 44 | char *bctbx_convert_utf8_to_any(const char *str, BCTBX_UNUSED(const char *encoding)) { 45 | // TODO change this part when the NDK will contain a usable iconv 46 | return bctbx_strdup(str); 47 | } 48 | 49 | char * 50 | bctbx_convert_string(const char *str, BCTBX_UNUSED(const char *from_encoding), BCTBX_UNUSED(const char *to_encoding)) { 51 | // TODO change this part when the NDK will contain a usable iconv 52 | return bctbx_strdup(str); 53 | } 54 | 55 | unsigned int bctbx_get_code_page(BCTBX_UNUSED(const char *encoding)) { 56 | bctbx_error("Getting code page is not implemented"); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /cmake/BCGitVersion.cmake: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # BCGitVersion.cmake 3 | # Copyright (C) 2017-2023 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | 23 | if(GIT_EXECUTABLE) 24 | macro(GIT_COMMAND OUTPUT_VAR) 25 | set(GIT_ARGS ${ARGN}) 26 | execute_process( 27 | COMMAND ${GIT_EXECUTABLE} ${ARGN} 28 | WORKING_DIRECTORY ${WORK_DIR} 29 | OUTPUT_VARIABLE ${OUTPUT_VAR} 30 | OUTPUT_STRIP_TRAILING_WHITESPACE 31 | ) 32 | endmacro() 33 | 34 | GIT_COMMAND(GIT_DESCRIBE describe --always) 35 | GIT_COMMAND(GIT_TAG describe --abbrev=0) 36 | GIT_COMMAND(GIT_REVISION rev-parse HEAD) 37 | endif() 38 | 39 | string(TOUPPER "${PROJECT_NAME}" PREFIX_GIT_VERSION) 40 | string(REPLACE "-" "_" PREFIX_GIT_VERSION "${PREFIX_GIT_VERSION}") 41 | if(GIT_DESCRIBE) 42 | if(NOT GIT_TAG STREQUAL PROJECT_VERSION) 43 | message(WARNING "Project version (${PROJECT_VERSION}) and git tag (${GIT_TAG}) differ. Please put them identical") 44 | endif() 45 | set(PROJECT_GIT_VERSION "${GIT_DESCRIBE}") 46 | configure_file("${TEMPLATE_DIR}/gitversion.h.in" "${OUTPUT_DIR}/gitversion.h" @ONLY) 47 | elseif(GIT_REVISION) 48 | set(PROJECT_GIT_VERSION "${LINPHONE_VERSION}_${GIT_REVISION}") 49 | configure_file("${TEMPLATE_DIR}/gitversion.h.in" "${OUTPUT_DIR}/gitversion.h" @ONLY) 50 | else() 51 | if(NOT EXISTS "${OUTPUT_DIR}/gitversion.h") 52 | execute_process(COMMAND ${CMAKE_COMMAND} -E touch "${OUTPUT_DIR}/gitversion.h") 53 | endif() 54 | endif() 55 | -------------------------------------------------------------------------------- /src/conversion/charconv_encoding.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #ifdef __APPLE__ 25 | #include "TargetConditionals.h" 26 | #endif 27 | 28 | #include "bctoolbox/charconv.h" 29 | #include "bctoolbox/logging.h" 30 | #include "bctoolbox/port.h" 31 | 32 | #include 33 | #include 34 | 35 | namespace { 36 | std::string &defaultEncodingPrivate() { 37 | static std::string defaultEncoding; 38 | return defaultEncoding; 39 | } 40 | } // namespace 41 | 42 | void bctbx_set_default_encoding(const char *encoding) { 43 | defaultEncodingPrivate() = encoding; 44 | } 45 | 46 | const char *bctbx_get_default_encoding(void) { 47 | if (!defaultEncodingPrivate().empty()) return defaultEncodingPrivate().c_str(); 48 | 49 | #if defined(__ANDROID__) || TARGET_OS_IPHONE 50 | return "UTF-8"; 51 | #else 52 | return "locale"; 53 | #endif 54 | } 55 | 56 | wchar_t *bctbx_string_to_wide_string(const char *str) { 57 | wchar_t *wstr; 58 | size_t sz = mbstowcs(NULL, str, 0); 59 | if (sz == (size_t)-1) { 60 | return NULL; 61 | } 62 | sz += 1; 63 | wstr = (wchar_t *)bctbx_malloc(sz * sizeof(wchar_t)); 64 | sz = mbstowcs(wstr, str, sz); 65 | if (sz == (size_t)-1) { 66 | bctbx_free(wstr); 67 | return NULL; 68 | } 69 | return wstr; 70 | } 71 | 72 | char *bctbx_wide_string_to_string(const wchar_t *wstr) { 73 | size_t sz; 74 | char *str; 75 | sz = wcstombs(NULL, wstr, 0); 76 | if (sz == (size_t)-1) { 77 | return NULL; 78 | } 79 | sz += 1; 80 | str = (char *)bctbx_malloc(sz); 81 | sz = wcstombs(str, wstr, sz); 82 | if (sz == (size_t)-1) { 83 | bctbx_free(str); 84 | return NULL; 85 | } 86 | return str; 87 | } 88 | -------------------------------------------------------------------------------- /include/bctoolbox/param_string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_PARAM_STRING_H_ 21 | #define BCTBX_PARAM_STRING_H_ 22 | 23 | #include "bctoolbox/port.h" 24 | 25 | // This file provides string manipulation utility when handling a parameter string of the from 26 | // "param1;param2=120;param3=true" 27 | 28 | /** 29 | * Parses a fmtp string such as "profile=0;level=10", finds the value matching 30 | * parameter param_name, and writes it into result. 31 | * If a parameter name is found multiple times, only the value of the last occurence is returned. 32 | * @param paramString the fmtp line (format parameters) 33 | * @param param_name the parameter to search for 34 | * @param result the value given for the parameter (if found) 35 | * @param result_len the size allocated to hold the result string 36 | * @return TRUE if the parameter was found, else FALSE. 37 | **/ 38 | BCTBX_PUBLIC bool_t bctbx_param_string_get_value(const char *paramString, 39 | const char *param_name, 40 | char *result, 41 | size_t result_len); 42 | 43 | /** 44 | * Parses a fmtp string such as "profile=0;level=10". If the value is "true" or "false", returns the corresponding 45 | *boolean 46 | * @param paramString the fmtp line (format parameters) 47 | * @param param_name the parameter to search for 48 | * @return FALSE if parameter was not found, else TRUE if the parameter value was "true", FALSE if it was "false" 49 | **/ 50 | BCTBX_PUBLIC bool_t bctbx_param_string_get_bool_value(const char *paramString, const char *param_name); 51 | #endif /*BCTBX_PARAM_STRING_H_*/ 52 | -------------------------------------------------------------------------------- /cmake/FindDecaf.cmake: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # FindDecaf.cmake 3 | # Copyright (C) 2017-2023 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | # 23 | # Find the decaf library. 24 | # 25 | # Targets 26 | # ^^^^^^^ 27 | # 28 | # The following targets may be defined: 29 | # 30 | # decaf - If the decaf library has been found 31 | # 32 | # 33 | # Result variables 34 | # ^^^^^^^^^^^^^^^^ 35 | # 36 | # This module will set the following variables in your project: 37 | # 38 | # Decaf_FOUND - The decaf library has been found 39 | # Decaf_TARGET - The name of the CMake target for the decaf library 40 | 41 | 42 | if(TARGET decaf OR TARGET decaf-static) 43 | 44 | if(TARGET decaf-static) 45 | set(Decaf_TARGET decaf-static) 46 | elseif(TARGET decaf) 47 | set(Decaf_TARGET decaf) 48 | endif() 49 | 50 | include(FindPackageHandleStandardArgs) 51 | find_package_handle_standard_args(Decaf 52 | DEFAULT_MSG 53 | Decaf_TARGET 54 | ) 55 | mark_as_advanced(Decaf_TARGET) 56 | 57 | else() 58 | 59 | set(_OPTIONS CONFIG) 60 | if(Decaf_FIND_REQUIRED) 61 | list(APPEND _OPTIONS REQUIRED) 62 | endif() 63 | if(Decaf_FIND_QUIETLY) 64 | list(APPEND _OPTIONS QUIET) 65 | endif() 66 | if(Decaf_FIND_VERSION) 67 | list(PREPEND _OPTIONS "${Decaf_FIND_VERSION}") 68 | endif() 69 | if(Decaf_FIND_EXACT) 70 | list(APPEND _OPTIONS EXACT) 71 | endif() 72 | 73 | find_package(Decaf ${_OPTIONS}) 74 | 75 | if(TARGET decaf-static) 76 | set(Decaf_TARGET decaf-static) 77 | elseif(TARGET decaf) 78 | set(Decaf_TARGET decaf) 79 | endif() 80 | 81 | endif() 82 | -------------------------------------------------------------------------------- /tester/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # Copyright (C) 2020 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | 23 | if(ENABLE_UNIT_TESTS AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" AND NOT ANDROID) 24 | set(TESTER_SOURCES 25 | bctoolbox_tester.c 26 | bctoolbox_tester.h 27 | containers.cc 28 | logger.cc 29 | port.c 30 | parser.c 31 | param_string.c 32 | vfs.c 33 | ) 34 | if(MbedTLS_FOUND OR OPENSSL_FOUND) 35 | list(APPEND TESTER_SOURCES 36 | crypto.cc 37 | encrypted_vfs.cc) 38 | endif() 39 | if(APPLE) 40 | list(APPEND TESTER_SOURCES ios_utils.cc) 41 | endif() 42 | 43 | bc_apply_compile_flags(TESTER_SOURCE STRICT_OPTIONS_CPP STRICT_OPTIONS_C) 44 | add_executable(bctoolbox-tester-exe ${TESTER_SOURCES}) 45 | set_target_properties(bctoolbox-tester-exe PROPERTIES OUTPUT_NAME bctoolbox-tester) 46 | target_link_libraries(bctoolbox-tester-exe PRIVATE bctoolbox bctoolbox-tester) 47 | if(MbedTLS_FOUND) 48 | target_link_libraries(bctoolbox-tester-exe PRIVATE ${MbedTLS_TARGET}) 49 | endif() 50 | set_target_properties(bctoolbox-tester-exe PROPERTIES XCODE_ATTRIBUTE_WARNING_CFLAGS "") 51 | add_test(NAME bctoolbox_tester COMMAND bctoolbox_tester --verbose) 52 | if(NOT IOS) 53 | install(TARGETS bctoolbox-tester-exe 54 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 55 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 56 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 57 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 58 | ) 59 | endif() 60 | endif() 61 | -------------------------------------------------------------------------------- /include/bctoolbox/exception.hh: -------------------------------------------------------------------------------- 1 | /* 2 | bctoolbox 3 | Copyright (C) 2016 Belledonne Communications SARL. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Affero General Public License as 7 | published by the Free Software Foundation, either version 3 of the 8 | License, or (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Affero General Public License for more details. 14 | 15 | You should have received a copy of the GNU Affero General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef exception_h 20 | #define exception_h 21 | 22 | #include 23 | #include 24 | 25 | #include "bctoolbox/port.h" 26 | 27 | #ifdef _WIN32 28 | #pragma warning(push) 29 | #pragma warning(disable : 4275 4251) 30 | #endif 31 | 32 | /** 33 | * @brief General pupose exception saving backtrace. 34 | * 35 | * sample of use: 36 | * try { 37 | * throw BCTBX_EXCEPTION << "Hello, this is my exception"; 38 | * } catch (BctbxException e&) { 39 | * BCTOOLBOX_SLOGD("mylogdomain") << "Exception cauth"<< e; 40 | * } 41 | * 42 | * 43 | */ 44 | class BCTBX_PUBLIC BctbxException : public std::exception { 45 | public: 46 | BctbxException(const std::string &message = ""); 47 | BctbxException(const BctbxException &other); 48 | virtual ~BctbxException() = default; 49 | 50 | /** 51 | * print stack strace to stderr 52 | * */ 53 | void printStackTrace() const; 54 | 55 | void printStackTrace(std::ostream &os) const; 56 | 57 | const char *what() const noexcept override; 58 | 59 | const std::string &str() const; 60 | 61 | /* same as osstringstream, but as osstream does not have cp contructor, BctbxException can't inherit from 62 | * osstream*/ 63 | template 64 | BctbxException &operator<<(const T2 &val) { 65 | mOs << val; 66 | return *this; 67 | } 68 | 69 | private: 70 | void *mArray[20]; 71 | size_t mSize; 72 | std::ostringstream mOs; 73 | mutable std::string mMessage; 74 | }; 75 | 76 | BCTBX_PUBLIC std::ostream &operator<<(std::ostream &__os, const BctbxException &e); 77 | 78 | #define BCTBX_EXCEPTION BctbxException() << " " << __FILE__ << ":" << __LINE__ << " " 79 | 80 | #ifdef _WIN32 81 | #pragma warning(pop) 82 | #endif 83 | 84 | #endif /* exception_h */ 85 | -------------------------------------------------------------------------------- /tester/param_string.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "bctoolbox/param_string.h" 21 | #include "bctoolbox_tester.h" 22 | 23 | static void get_value_test(void) { 24 | size_t result_len = 10; 25 | char *result = bctbx_malloc(result_len); 26 | 27 | char *paramString = ""; 28 | BC_ASSERT_FALSE(bctbx_param_string_get_value(paramString, "param", result, result_len)); 29 | 30 | paramString = "param=true"; 31 | BC_ASSERT_TRUE(bctbx_param_string_get_value(paramString, "param", result, result_len)); 32 | BC_ASSERT_TRUE(strcmp(result, "true") == 0); 33 | BC_ASSERT_FALSE(bctbx_param_string_get_value(paramString, "notparam", result, result_len)); 34 | 35 | paramString = "test;param=true;test"; 36 | BC_ASSERT_TRUE(bctbx_param_string_get_value(paramString, "param", result, result_len)); 37 | BC_ASSERT_TRUE(strcmp(result, "true") == 0); 38 | BC_ASSERT_FALSE(bctbx_param_string_get_value(paramString, "notparam", result, result_len)); 39 | 40 | bctbx_free(result); 41 | } 42 | 43 | static void get_bool_value_test(void) { 44 | char *paramString = ""; 45 | BC_ASSERT_FALSE(bctbx_param_string_get_bool_value(paramString, "param")); 46 | paramString = "param=false"; 47 | BC_ASSERT_FALSE(bctbx_param_string_get_bool_value(paramString, "param")); 48 | paramString = "param=42"; 49 | BC_ASSERT_FALSE(bctbx_param_string_get_bool_value(paramString, "param")); 50 | paramString = "param=true"; 51 | BC_ASSERT_TRUE(bctbx_param_string_get_bool_value(paramString, "param")); 52 | } 53 | 54 | static test_t param_string_tests[] = {TEST_NO_TAG("Get value", get_value_test), 55 | TEST_NO_TAG("Get bool value", get_bool_value_test)}; 56 | 57 | test_suite_t param_string_test_suite = { 58 | "Param string", NULL, NULL, NULL, NULL, sizeof(param_string_tests) / sizeof(param_string_tests[0]), 59 | param_string_tests, 0}; -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | 8 | ## [5.4.0] - 2025-03-11 9 | 10 | ### Added 11 | - Now requires mbedtls 3.6/ 12 | - Added support for openssl as an alternative to mbedtls. 13 | 14 | ### Changed 15 | - List copy optimisations. 16 | 17 | ### Removed 18 | - Crypto: remove polarssl support. 19 | 20 | 21 | ## [5.3.68] - 2024-07-10 22 | 23 | ### Added 24 | - Use locale encoding from setlocale() on Windows and fallback to CP_APC if not found. 25 | 26 | ## [5.2.0] - 2022-11-14 27 | 28 | ### Added 29 | - Crypto: add support for post-quantum algorithms. 30 | - Crash handler and backtrace logger for Windows. 31 | 32 | ### Changed 33 | - minor changes. 34 | 35 | 36 | ## [5.1.0] - 2022-02-14 37 | 38 | ### Added 39 | - new vfs read2/write2 functions without offset parameter, to easy mapping with standard libc functions. 40 | 41 | ### Changed 42 | - optimized C++ logging macros. 43 | 44 | 45 | ## [5.0.0] - 2021-07-08 46 | 47 | ### Added 48 | - Tester API: add API to set maximum number of failed tests. 49 | 50 | ### Fixed 51 | - Few bugfixes (see git log) 52 | 53 | 54 | ## [4.5.0] - 2021-03-29 55 | 56 | ### Added 57 | - Encrypted VFS API. 58 | 59 | ### Changed 60 | - Callback for client certificate query is now passed with the full list of subjects. 61 | - miscellaneous small things, see git commits for details. 62 | 63 | 64 | ## [4.4.0] - 2020-6-09 65 | 66 | ### Changed 67 | - Version number now follows linphone-sdk's versionning. 68 | 69 | ### Removed 70 | - Polarssl 1.2 support. 71 | 72 | 73 | ## [0.6.0] - 2017-07-20 74 | ### Added 75 | - Add API to escape/unescape strings (SIP, VCARD). 76 | 77 | 78 | ## [0.5.1] - 2017-02-22 79 | ### Added 80 | - "const char * to void *" map feature 81 | 82 | ### Fixed 83 | - security bugfix: TLS session could be successfully established whereas the common 84 | name did not match the server name. 85 | 86 | ## [0.2.0] - 2016-08-08 87 | ### Added 88 | - Creating a Virtual File System bctbx_vfs allowing direct file access and I/Os. 89 | - integrate OS abstraction layer, list API, logging API from oRTP 90 | - integrate getaddrinfo() abstraction api, in order to provide consistent getaddrinfo() support on all platforms. 91 | 92 | 93 | ## [0.0.1] - 2016-01-01 94 | ### Added 95 | - Initial release. 96 | 97 | ### Changed 98 | 99 | ### Removed 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **CAUTION: this git repository is no longer updated. The project has been merged into the linphone-sdk ([Gitlab](https://gitlab.linphone.org/BC/public/linphone-sdk), [Github](https://github.com/BelledonneCommunications/linphone-sdk)) git repository and will continue his life there.** 2 | 3 | **Versions up to 5.4 (included) are still kept into this repository, that will remain active on 'release/5.4' branch until the end of life of release 5.4.** 4 | 5 | [![pipeline status](https://gitlab.linphone.org/BC/public/bctoolbox/badges/master/pipeline.svg)](https://gitlab.linphone.org/BC/public/bctoolbox/commits/master) 6 | 7 | BcToolbox 8 | ========= 9 | 10 | Utilities library used by Belledonne Communications softwares like belle-sip, mediastreamer2 and liblinphone. 11 | 12 | 13 | Depends 14 | ------- 15 | 16 | - **mbedtls[1]**: implementation of TLS interface of BcToolbox. For backward 17 | compatibility, support of mbedtlsv2 is also provided. 18 | - **bcunit[2]** for unitary test tools. (optional) 19 | - **openssl[3]** alternate TLS and crypto implementation. (optional) 20 | 21 | 22 | To compile 23 | ---------- 24 | 25 | cmake . -DCMAKE_INSTALL_PREFIX= -DCMAKE_PREFIX_PATH= 26 | 27 | make 28 | make install 29 | 30 | 31 | To make an rpm package 32 | ---------------------- 33 | 34 | cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCPACK_GENERATOR="RPM" 35 | 36 | make package 37 | 38 | 39 | Options 40 | ------- 41 | 42 | - `CMAKE_INSTALL_PREFIX=`: install prefix. 43 | - `CMAKE_PREFIX_PATH=`: search path prefix for dependencies e.g. mbedtls. 44 | - `ENABLE_MBEDTLS=NO`: do not look for mbedtls. 45 | - `ENABLE_OPENSSL=NO`: do not look for openssl. 46 | - `ENABLE_STRICT=NO`: do not build with strict compilator flags e.g. `-Wall -Werror`. 47 | - `ENABLE_UNIT_TESTS=NO`: do not build testing binaries. 48 | - `ENABLE_TESTS_COMPONENT=NO`: do not build libbctoolbox-tester. 49 | 50 | 51 | Notes 52 | ----- 53 | 54 | For backward compatibility with distributions not having the required 2.8.12 cmake version, an automake/autoconf build system is also available. 55 | It is maintained as a best effort and then should be used only in last resort. 56 | 57 | 58 | Note for packagers 59 | ------------------ 60 | 61 | Our CMake scripts may automatically add some paths into research paths of generated binaries. 62 | To ensure that the installed binaries are striped of any rpath, use `-DCMAKE_SKIP_INSTALL_RPATH=ON` 63 | while you invoke cmake. 64 | 65 | -------------------- 66 | 67 | - [1] 68 | - [2] git://git.linphone.org/bctoolbox.git or 69 | - [3] 70 | 71 | -------------------------------------------------------------------------------- /include/bctoolbox/utils.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_UTILS_H 21 | #define BCTBX_UTILS_H 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "bctoolbox/port.h" 28 | 29 | namespace bctoolbox { 30 | 31 | namespace Utils { 32 | BCTBX_PUBLIC std::vector split(const std::string &str, const std::string &delimiter); 33 | 34 | BCTBX_PUBLIC inline std::vector split(const std::string &str, char delimiter) { 35 | return split(str, std::string(1, delimiter)); 36 | } 37 | 38 | template 39 | inline const T &getEmptyConstRefObject() { 40 | static const T object{}; 41 | return object; 42 | } 43 | 44 | BCTBX_PUBLIC std::string fold(const std::string &str); 45 | BCTBX_PUBLIC std::string unfold(const std::string &str); 46 | 47 | // Replace all "from" by "to" in source. Use 'recursive' to avoid replacing what has been replaced. 48 | BCTBX_PUBLIC void 49 | replace(std::string &source, const std::string &from, const std::string &to, const bool recursive = true); 50 | 51 | // Return the current state of memory as a string. This is currently implemented only for Windows. 52 | BCTBX_PUBLIC std::string getMemoryReportAsString(); 53 | 54 | // Replace const_cast in order to be adapted from types. Be carefull when using it. 55 | template 56 | class auto_cast { 57 | public: 58 | explicit constexpr auto_cast(From const &t) noexcept : val{t} { 59 | } 60 | 61 | template 62 | constexpr operator To() const noexcept(noexcept(const_cast(std::declval()))) { 63 | return const_cast(val); 64 | } 65 | 66 | private: 67 | From const &val; 68 | }; 69 | 70 | // Checks if the executable is installed by looking if the resource exists at 71 | // /../share// 72 | BCTBX_PUBLIC bool isExecutableInstalled(const std::string &executable, const std::string &resource); 73 | 74 | } // namespace Utils 75 | 76 | } // namespace bctoolbox 77 | 78 | #endif /* BCTBX_UTILS_H */ 79 | -------------------------------------------------------------------------------- /src/param_string.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "bctoolbox/param_string.h" 21 | #include "bctoolbox/port.h" 22 | 23 | static const char *find_param_occurence_of(const char *fmtp, const char *param) { 24 | const char *pos = fmtp; 25 | int param_len = (int)strlen(param); 26 | do { 27 | pos = strstr(pos, param); 28 | if (pos) { 29 | /*check that the occurence found is not a subword of a parameter name*/ 30 | if (pos == fmtp) { 31 | if (pos[param_len] == '=') break; /* found it */ 32 | } else if ((pos[-1] == ';' || pos[-1] == ' ') && pos[param_len] == '=') { 33 | break; /* found it */ 34 | } 35 | pos += strlen(param); 36 | } 37 | } while (pos != NULL); 38 | return pos; 39 | } 40 | 41 | static const char *find_last_param_occurence_of(const char *fmtp, const char *param) { 42 | const char *pos = fmtp; 43 | const char *lastpos = NULL; 44 | do { 45 | pos = find_param_occurence_of(pos, param); 46 | if (pos) { 47 | lastpos = pos; 48 | pos += strlen(param); 49 | } 50 | } while (pos != NULL); 51 | return lastpos; 52 | } 53 | 54 | bool_t bctbx_param_string_get_value(const char *paramString, const char *param_name, char *result, size_t result_len) { 55 | const char *pos = find_last_param_occurence_of(paramString, param_name); 56 | memset(result, '\0', result_len); 57 | if (pos) { 58 | const char *equal = strchr(pos, '='); 59 | if (equal) { 60 | int copied; 61 | const char *end = strchr(equal + 1, ';'); 62 | if (end == NULL) end = paramString + strlen(paramString); /*assuming this is the last param */ 63 | copied = MIN((int)(result_len - 1), (int)(end - (equal + 1))); 64 | strncpy(result, equal + 1, copied); 65 | result[copied] = '\0'; 66 | return TRUE; 67 | } 68 | } 69 | return FALSE; 70 | } 71 | 72 | bool_t bctbx_param_string_get_bool_value(const char *paramString, const char *param_name) { 73 | size_t result_len = 5; 74 | char *result = bctbx_malloc(result_len); 75 | // True if param is found, false if not 76 | bool_t res = bctbx_param_string_get_value(paramString, param_name, result, result_len); 77 | res = res && strcmp(result, "true") == 0; 78 | free(result); 79 | return res; 80 | } 81 | -------------------------------------------------------------------------------- /cmake/BCToolboxConfig.cmake.in: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # BCToolboxConfig.cmake 3 | # Copyright (C) 2010-2023 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | # 23 | # Config file for the bctoolbox package. 24 | # 25 | # Components 26 | # ^^^^^^^^^^ 27 | # 28 | # This config file will define the component: tester. 29 | # 30 | # 31 | # Targets 32 | # ^^^^^^^ 33 | # 34 | # The following targets are always defined: 35 | # bctoolbox - The bctoolbox library target 36 | # 37 | # The following targets may be defined according to the asked components: 38 | # bctoolbox-tester - The bctoolbox-tester library target (defined if the tester is asked for) 39 | # 40 | # 41 | # Result variables 42 | # ^^^^^^^^^^^^^^^^ 43 | # 44 | # This config file will set the following variables in your project: 45 | # 46 | # BCToolbox_FOUND - The bctoolbox library has been found 47 | # BCToolbox_TARGET - The name of the CMake target for the bctoolbox library 48 | # BCToolbox_CMAKE_DIR - The bctoolbox CMake directory 49 | # BCToolbox_CMAKE_UTILS - The path to the bctoolbox CMake utils script 50 | # BCToolbox_tester_FOUND - The bctoolbox-tester library has been found 51 | # BCToolbox_tester_TARGET - The name of the CMake target for the bctoolbox-tester library 52 | 53 | @PACKAGE_INIT@ 54 | 55 | include(CMakeFindDependencyMacro) 56 | include("${CMAKE_CURRENT_LIST_DIR}/BCToolboxTargets.cmake") 57 | 58 | set(BCToolbox_TARGET bctoolbox) 59 | 60 | if(@ENABLE_TESTS_COMPONENT@) 61 | set(BCToolbox_tester_FOUND TRUE) 62 | set(BCToolbox_tester_TARGET bctoolbox-tester) 63 | endif() 64 | 65 | # We must propagate the public dependencies and the private dependencies for static build 66 | include(CMakeFindDependencyMacro) 67 | if(@BUILD_SHARED_LIBS@) 68 | else() 69 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") 70 | if(@Iconv_FOUND@) 71 | find_dependency(Iconv) 72 | endif() 73 | if(@MbedTLS_FOUND@) 74 | find_dependency(MbedTLS) 75 | endif() 76 | if(@Decaf_FOUND@) 77 | find_dependency(Decaf) 78 | endif() 79 | find_dependency(BCUnit) 80 | endif() 81 | 82 | set_and_check(BCToolbox_CMAKE_DIR "@PACKAGE_CMAKE_MODULES_INSTALL_DIR@") 83 | set_and_check(BCToolbox_CMAKE_UTILS "@PACKAGE_CMAKE_MODULES_INSTALL_DIR@/BCToolboxCMakeUtils.cmake") 84 | include("${BCToolbox_CMAKE_UTILS}") 85 | 86 | check_required_components(BCToolbox) 87 | -------------------------------------------------------------------------------- /cmake/FindBCUnit.cmake: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # FindBCUnit.cmake 3 | # Copyright (C) 2017-2023 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | # 23 | # Find the bcunit library. 24 | # 25 | # Targets 26 | # ^^^^^^^ 27 | # 28 | # The following targets may be defined: 29 | # 30 | # bcunit - If the bcunit library has been found 31 | # 32 | # 33 | # Result variables 34 | # ^^^^^^^^^^^^^^^^ 35 | # 36 | # This module will set the following variables in your project: 37 | # 38 | # BCUnit_FOUND - The bcunit library has been found 39 | # BCUnit_TARGET - The name of the CMake target for the bcunit library 40 | # HAVE_CU_GET_SUITE - If the bcunit library includes the CU_get_suite symbol 41 | # HAVE_CU_CURSES - If the bcunit library includes the CU_curses_run_tests symbol 42 | # HAVE_CU_SET_TRACE_HANDLER - If the bcunit library includes the CU_set_trace_handler symbol 43 | 44 | 45 | if(TARGET bcunit) 46 | 47 | include(FindPackageHandleStandardArgs) 48 | set(BCUnit_TARGET bcunit) 49 | set(HAVE_CU_GET_SUITE TRUE) 50 | set(HAVE_CU_CURSES ${ENABLE_BCUNIT_CURSES}) 51 | set(HAVE_CU_SET_TRACE_HANDLER ${ENABLE_BCUNIT_BASIC}) 52 | set(_BCUnit_REQUIRED_VARS BCUnit_TARGET HAVE_CU_GET_SUITE) 53 | set(_BCUnit_CACHE_VARS 54 | ${_BCUnit_REQUIRED_VARS} HAVE_CU_CURSES HAVE_CU_SET_TRACE_HANDLER 55 | ) 56 | find_package_handle_standard_args(BCUnit 57 | REQUIRED_VARS ${_BCUnit_REQUIRED_VARS} 58 | ) 59 | mark_as_advanced(${_BCUnit_CACHE_VARS}) 60 | 61 | else() 62 | 63 | set(_OPTIONS CONFIG) 64 | if(BCUnit_FIND_REQUIRED) 65 | list(APPEND _OPTIONS REQUIRED) 66 | endif() 67 | if(BCUnit_FIND_QUIETLY) 68 | list(APPEND _OPTIONS QUIET) 69 | endif() 70 | if(BCUnit_FIND_VERSION) 71 | list(PREPEND _OPTIONS "${BCUnit_FIND_VERSION}") 72 | endif() 73 | if(BCUnit_FIND_EXACT) 74 | list(APPEND _OPTIONS EXACT) 75 | endif() 76 | 77 | find_package(BCUnit ${_OPTIONS}) 78 | 79 | cmake_push_check_state(RESET) 80 | get_target_property(BCUnit_INCLUDE_DIRS "${BCUnit_TARGET}" INTERFACE_INCLUDE_DIRECTORIES) 81 | list(APPEND CMAKE_REQUIRED_INCLUDES ${BCUnit_INCLUDE_DIRS}) 82 | list(APPEND CMAKE_REQUIRED_LIBRARIES "${BCUnit_TARGET}") 83 | check_symbol_exists("CU_get_suite" "BCUnit/BCUnit.h" HAVE_CU_GET_SUITE) 84 | check_symbol_exists("CU_curses_run_tests" "BCUnit/BCUnit.h" HAVE_CU_CURSES) 85 | check_symbol_exists("CU_set_trace_handler" "BCUnit/Util.h" HAVE_CU_SET_TRACE_HANDLER) 86 | cmake_pop_check_state() 87 | 88 | endif() 89 | -------------------------------------------------------------------------------- /src/utils/regex.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include 25 | 26 | #include "bctoolbox/logging.h" 27 | #include "bctoolbox/regex.h" 28 | 29 | /* 30 | This part is needed since CentOS7 have an old gcc compiler. 31 | TODO: Remove this code when all supported platorms have gcc 4.9.0 or more 32 | */ 33 | #if __cplusplus >= 201103L && \ 34 | (!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \ 35 | (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || defined(_GLIBCXX_REGEX_STATE_LIMIT) || \ 36 | (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE > 4))) && \ 37 | !defined(__ANDROID__) || \ 38 | defined(_WIN32) 39 | #define HAVE_WORKING_REGEX 1 40 | #else 41 | #define HAVE_WORKING_REGEX 0 42 | #include 43 | #endif 44 | 45 | extern "C" bool_t 46 | bctbx_is_matching_regex_log_context(const char *entry, const char *regex, bool_t show_log, const char *context) { 47 | #if HAVE_WORKING_REGEX 48 | try { 49 | std::regex entry_regex(regex, std::regex_constants::extended | std::regex_constants::nosubs); 50 | std::cmatch m; 51 | return std::regex_match(entry, m, entry_regex); 52 | } catch (const std::regex_error &e) { 53 | if (show_log) 54 | bctbx_error("Could not compile regex '%s'%s: %s", regex, 55 | (context ? ("[" + std::string(context) + "]").c_str() : ""), e.what()); 56 | return FALSE; 57 | } 58 | #else 59 | regex_t regex_pattern; 60 | char err_msg[256]; 61 | int res; 62 | res = regcomp(®ex_pattern, regex, REG_EXTENDED | REG_NOSUB); 63 | if (res != 0) { 64 | if (show_log) { 65 | regerror(res, ®ex_pattern, err_msg, sizeof(err_msg)); 66 | bctbx_error("Could not compile regex '%s'%s: %s", regex, 67 | (context ? ("[" + std::string(context) + "]").c_str() : ""), err_msg); 68 | } 69 | return FALSE; 70 | } 71 | res = regexec(®ex_pattern, entry, 0, NULL, 0); 72 | regfree(®ex_pattern); 73 | return (res != REG_NOMATCH); 74 | #endif 75 | } 76 | 77 | extern "C" bool_t bctbx_is_matching_regex_log(const char *entry, const char *regex, bool_t show_log) { 78 | return bctbx_is_matching_regex_log_context(entry, regex, show_log, NULL); 79 | } 80 | 81 | extern "C" bool_t bctbx_is_matching_regex(const char *entry, const char *regex) { 82 | return bctbx_is_matching_regex_log(entry, regex, TRUE); 83 | } 84 | -------------------------------------------------------------------------------- /src/vfs/vfs_encryption_module.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_VFS_ENCRYPTION_MODULE_HH 21 | #define BCTBX_VFS_ENCRYPTION_MODULE_HH 22 | 23 | #include "bctoolbox/vfs_encrypted.hh" 24 | 25 | namespace bctoolbox { 26 | /** 27 | * Define the interface any encryption suite must provide 28 | */ 29 | class VfsEncryptionModule { 30 | public: 31 | /** 32 | * @return the size in bytes of the chunk header 33 | */ 34 | virtual size_t getChunkHeaderSize() const noexcept = 0; 35 | /** 36 | * @return the size in bytes of file header module data 37 | */ 38 | virtual size_t getModuleFileHeaderSize() const noexcept = 0; 39 | /** 40 | * @return the encryptionSuite implemented by the module 41 | */ 42 | virtual EncryptionSuite getEncryptionSuite() const noexcept = 0; 43 | 44 | /** 45 | * Get from the module the data to store in the file header 46 | */ 47 | virtual const std::vector getModuleFileHeader(const VfsEncryption &fileContext) const = 0; 48 | 49 | /** 50 | * Set in the module, the secret material used for encryption 51 | */ 52 | virtual void setModuleSecretMaterial(const std::vector &secret) = 0; 53 | 54 | /** 55 | * Get the size of the secret material needed by this module 56 | */ 57 | virtual size_t getSecretMaterialSize() const noexcept = 0; 58 | 59 | /** 60 | * Decrypt a data chunk 61 | * @param[in] a vector which size shall be chunkHeaderSize + chunkSize holding the raw data read from disk 62 | * @return the decrypted data chunk 63 | */ 64 | virtual std::vector decryptChunk(const uint32_t chunkIndex, const std::vector &rawChunk) = 0; 65 | 66 | /** 67 | * ReEncrypt a data chunk 68 | * @param[in/out] rawChunk The existing encrypted chunk 69 | * @param[in] plainData The plain text to be encrypted 70 | */ 71 | virtual void 72 | encryptChunk(const uint32_t chunkIndex, std::vector &rawChunk, const std::vector &plainData) = 0; 73 | /** 74 | * Encrypt a new data chunk 75 | * @param[in] chunkIndex The chunk index 76 | * @param[in] plainData The plain text to be encrypted 77 | * @return the encrypted chunk 78 | */ 79 | virtual std::vector encryptChunk(const uint32_t chunkIndex, const std::vector &plainData) = 0; 80 | 81 | /** 82 | * Check the integrity over the whole file 83 | * @param[in] fileContext a way to access the file content 84 | * 85 | * @return true if the integrity check successfully passed, false otherwise 86 | */ 87 | virtual bool checkIntegrity(const VfsEncryption &fileContext) = 0; 88 | 89 | virtual ~VfsEncryptionModule(){}; 90 | }; 91 | 92 | } // namespace bctoolbox 93 | #endif // BCTBX_VFS_ENCRYPTION_MODULE_HH 94 | -------------------------------------------------------------------------------- /src/utils/ios_utils_app.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2019 Belledonne Communications SARL. 3 | * 4 | * This file is part of Liblinphone. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | 22 | #if TARGET_OS_IPHONE 23 | 24 | #include 25 | #include 26 | #include "ios_utils_app.hh" 27 | #include "bctoolbox/logging.h" 28 | 29 | namespace bctoolbox { 30 | 31 | unsigned long IOSUtilsApp::beginBackgroundTask(const char *name, std::function cb) { 32 | __block UIBackgroundTaskIdentifier bgid = UIBackgroundTaskInvalid; 33 | 34 | UIApplication *app=[UIApplication sharedApplication]; 35 | 36 | @try { 37 | if (cb==nullptr){ 38 | bctbx_error("belle_sip_begin_background_task(): the callback must not be NULL. Application must be aware that the background task needs to be terminated."); 39 | bgid = UIBackgroundTaskInvalid; 40 | @throw([NSException exceptionWithName:@"LinphoneCoreException" reason:@"Background task has no callback" userInfo:nil]); 41 | } 42 | 43 | void (^handler)() = ^{ 44 | cb(); 45 | }; 46 | 47 | if([app respondsToSelector:@selector(beginBackgroundTaskWithName:expirationHandler:)]){ 48 | bgid = [app beginBackgroundTaskWithName:[NSString stringWithUTF8String:name] expirationHandler:handler]; 49 | } else { 50 | bgid = [app beginBackgroundTaskWithExpirationHandler:handler]; 51 | } 52 | 53 | if (bgid==UIBackgroundTaskInvalid){ 54 | bctbx_error("Could not start background task %s.", name); 55 | bgid = 0; 56 | @throw([NSException exceptionWithName:@"LinphoneCoreException" reason:@"Could not start background task" userInfo:nil]); 57 | } 58 | 59 | // backgroundTimeRemaining is properly set only when running background... but not immediately! 60 | // removed app.applicationState check because not thread safe 61 | if (app.backgroundTimeRemaining == DBL_MAX) { 62 | bctbx_message("Background task %s started. Unknown remaining time since application is not fully in background.", name); 63 | } else { 64 | bctbx_message("Background task %s started. Remaining time %.1f secs", name, app.backgroundTimeRemaining); 65 | } 66 | } 67 | @catch (NSException*) { 68 | // do nothing 69 | } 70 | 71 | return (unsigned long)bgid; 72 | } 73 | 74 | void IOSUtilsApp::endBackgroundTask(unsigned long id) { 75 | UIApplication *app=[UIApplication sharedApplication]; 76 | if (id != UIBackgroundTaskInvalid){ 77 | [app endBackgroundTask:(UIBackgroundTaskIdentifier)id]; 78 | } 79 | } 80 | 81 | bool IOSUtilsApp::isApplicationStateActive() { 82 | return ([UIApplication sharedApplication].applicationState == UIApplicationStateActive); 83 | } 84 | 85 | } //namespace bctoolbox 86 | 87 | extern "C" { 88 | bctoolbox::IOSUtilsInterface *bctbx_create_ios_utils_app() { 89 | return new bctoolbox::IOSUtilsApp; 90 | } 91 | 92 | void bctbx_destroy_ios_utils_app(bctoolbox::IOSUtilsInterface* p) { 93 | delete p; 94 | } 95 | } 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /src/utils/exception.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif // ifdef HAVE_CONFIG_H 23 | 24 | #ifdef HAVE_EXECINFO 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #endif 31 | 32 | #include "bctoolbox/exception.hh" 33 | #include "bctoolbox/logging.h" 34 | 35 | using namespace std; 36 | 37 | #ifdef HAVE_EXECINFO 38 | static void uncaught_handler() { 39 | std::exception_ptr p = current_exception(); 40 | try { 41 | rethrow_exception(p); 42 | } catch (BctbxException &e) { 43 | BCTBX_SLOGE << e; 44 | } catch (std::exception &ee) { 45 | BCTBX_SLOGE << "Unexpected exception [" << ee.what() << " ] use BctbxException for better debug"; 46 | } 47 | abort(); 48 | } 49 | #endif 50 | 51 | BctbxException::BctbxException(const std::string &message) : mSize(0) { 52 | #ifdef HAVE_EXECINFO 53 | mSize = backtrace(mArray, sizeof(mArray) / sizeof(void *)); 54 | #else 55 | mSize = 0; 56 | #endif 57 | if (!message.empty()) mOs << message; 58 | #ifdef HAVE_EXECINFO 59 | #if __clang 60 | if (get_terminate() != uncaught_handler) 61 | #endif 62 | set_terminate(uncaught_handler); // invoke in case of uncautch exception for this thread 63 | #endif 64 | 65 | #ifndef HAVE_EXECINFO 66 | /* Warn about exception as soon as it is created. Exceptions are not usual events and may be difficult to locate if 67 | * stacktrace is not available. */ 68 | BCTBX_SLOGW << "BctbxException occurred at : " << mOs.str(); 69 | #endif 70 | } 71 | 72 | BctbxException::BctbxException(const BctbxException &other) : mSize(other.mSize) { 73 | memcpy(mArray, other.mArray, sizeof(mArray)); 74 | mOs << other.str(); 75 | } 76 | 77 | void BctbxException::printStackTrace() const { 78 | #ifdef HAVE_EXECINFO 79 | backtrace_symbols_fd(mArray + 1, mSize - 1, STDERR_FILENO); 80 | #else 81 | std::cerr << "stack trace not available on this platform" << std::endl; 82 | #endif 83 | } 84 | 85 | void BctbxException::printStackTrace(std::ostream &os) const { 86 | #ifdef HAVE_EXECINFO 87 | char **bt = backtrace_symbols(mArray, mSize); 88 | int position = 0; 89 | for (unsigned int i = 1; i < mSize; ++i) { 90 | Dl_info info; 91 | char *demangled = NULL; 92 | int status = -1; 93 | if (dladdr(mArray[i], &info) && info.dli_sname) { 94 | demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); 95 | os << position++ << setw(20) << basename((char *)info.dli_fname) << setw(16) << info.dli_saddr; 96 | os << " "; 97 | if (demangled) { 98 | os << demangled; 99 | free(demangled); 100 | } else { 101 | os << info.dli_sname; 102 | } 103 | } else { 104 | os << bt[i]; 105 | } 106 | os << std::endl; 107 | } 108 | free(bt); 109 | #else 110 | os << "[stack trace not available on this platform]"; 111 | #endif 112 | } 113 | 114 | const char *BctbxException::what() const noexcept { 115 | return str().c_str(); 116 | } 117 | 118 | const std::string &BctbxException::str() const { 119 | mMessage = mOs.str(); 120 | return mMessage; 121 | } 122 | 123 | std::ostream &operator<<(std::ostream &__os, const BctbxException &e) { 124 | __os << e.str() << std::endl; 125 | e.printStackTrace(__os); 126 | return __os; 127 | } 128 | -------------------------------------------------------------------------------- /src/vfs/vfs_encryption_module_dummy.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_VFS_ENCRYPTION_MODULE_DUMMY_HH 21 | #define BCTBX_VFS_ENCRYPTION_MODULE_DUMMY_HH 22 | #include "bctoolbox/vfs_encrypted.hh" 23 | #include "vfs_encryption_module.hh" 24 | 25 | namespace bctoolbox { 26 | class VfsEncryptionModuleDummy : public VfsEncryptionModule { 27 | private: 28 | /** 29 | * Store the file header and secret 30 | */ 31 | std::vector mFileHeader; 32 | std::vector mFileHeaderIntegrity; 33 | std::vector mSecret; 34 | 35 | /** 36 | * Compute the integrity tag in the given chunk 37 | */ 38 | std::vector chunkIntegrityTag(const std::vector &chunk) const; 39 | 40 | /** 41 | * Get the chunk index from the given chunk 42 | */ 43 | uint32_t getChunkIndex(const std::vector &chunk) const; 44 | 45 | /** 46 | * Get global IV. Part of IV common to all chunks 47 | * The last 8 bytes of the file header 48 | */ 49 | std::vector globalIV() const; 50 | 51 | public: 52 | /** 53 | * @return the size in bytes of file header module data 54 | */ 55 | static size_t moduleFileHeaderSize() noexcept; 56 | 57 | /** 58 | * @return the size in bytes of the chunk header 59 | */ 60 | size_t getChunkHeaderSize() const noexcept override; 61 | 62 | /** 63 | * @return the size in bytes of file header module data 64 | */ 65 | size_t getModuleFileHeaderSize() const noexcept override; 66 | 67 | /** 68 | * @return the EncryptionSuite provided by this module 69 | */ 70 | EncryptionSuite getEncryptionSuite() const noexcept override { 71 | return EncryptionSuite::dummy; 72 | } 73 | 74 | /** 75 | * @return the secret material size 76 | */ 77 | size_t getSecretMaterialSize() const noexcept override; 78 | 79 | /** 80 | * Decrypt a chunk of data 81 | * @param[in] a vector which size shall be chunkHeaderSize + chunkSize holding the raw data read from disk 82 | * @return the decrypted data chunk 83 | */ 84 | std::vector decryptChunk(const uint32_t chunkIndex, const std::vector &rawChunk) override; 85 | 86 | void encryptChunk(const uint32_t chunkIndex, 87 | std::vector &rawChunk, 88 | const std::vector &plainData) override; 89 | std::vector encryptChunk(const uint32_t chunkIndex, const std::vector &plainData) override; 90 | 91 | const std::vector getModuleFileHeader(const VfsEncryption &fileContext) const override; 92 | 93 | void setModuleSecretMaterial(const std::vector &secret) override; 94 | 95 | /** 96 | * Check the integrity over the whole file 97 | * @param[in] fileContext a way to access the file content 98 | * 99 | * @return true if the integrity check successfully passed, false otherwise 100 | */ 101 | bool checkIntegrity(const VfsEncryption &fileContext) override; 102 | 103 | /** 104 | * constructors 105 | */ 106 | // At file creation 107 | VfsEncryptionModuleDummy(); 108 | // Opening an existing file 109 | VfsEncryptionModuleDummy(const std::vector &moduleFileHeader); 110 | 111 | ~VfsEncryptionModuleDummy(){}; 112 | }; 113 | 114 | } // namespace bctoolbox 115 | #endif // BCTBX_VFS_ENCRYPTION_MODULE_DUMMY 116 | -------------------------------------------------------------------------------- /src/parser.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include "bctoolbox/logging.h" 25 | #include "bctoolbox/parser.h" 26 | #include "bctoolbox/port.h" 27 | 28 | char *bctbx_escape(const char *buff, const bctbx_noescape_rules_t noescapes) { 29 | size_t outbuf_size = strlen(buff); 30 | size_t orig_size = outbuf_size; 31 | char *output_buff = (char *)bctbx_malloc(outbuf_size + 1); 32 | int i; 33 | size_t out_buff_index = 0; 34 | 35 | for (i = 0; buff[i] != '\0'; i++) { 36 | int c = ((unsigned char *)buff)[i]; 37 | if (outbuf_size < out_buff_index + 3) { 38 | // we will possibly add 3 chars 39 | outbuf_size += MAX(orig_size / 2, 3); 40 | output_buff = bctbx_realloc(output_buff, outbuf_size + 1); 41 | } 42 | if (noescapes[c] == 1) { 43 | output_buff[out_buff_index++] = c; 44 | } else { 45 | // this will write 3 characters 46 | out_buff_index += snprintf(output_buff + out_buff_index, outbuf_size + 1 - out_buff_index, "%%%02x", c); 47 | } 48 | } 49 | output_buff[out_buff_index] = '\0'; 50 | return output_buff; 51 | } 52 | 53 | void bctbx_noescape_rules_add_list(bctbx_noescape_rules_t noescapes, const char *allowed) { 54 | while (*allowed) { 55 | noescapes[(unsigned int)*allowed] = 1; 56 | ++allowed; 57 | } 58 | } 59 | 60 | void bctbx_noescape_rules_add_range(bctbx_noescape_rules_t noescapes, char first, char last) { 61 | memset(noescapes + (unsigned int)first, 1, last - first + 1); 62 | } 63 | 64 | void bctbx_noescape_rules_add_alfanums(bctbx_noescape_rules_t noescapes) { 65 | bctbx_noescape_rules_add_range(noescapes, '0', '9'); 66 | bctbx_noescape_rules_add_range(noescapes, 'A', 'Z'); 67 | bctbx_noescape_rules_add_range(noescapes, 'a', 'z'); 68 | } 69 | 70 | static int is_escaped_char(const char *a) { 71 | return a[0] == '%' && a[1] != '\0' && a[2] != '\0'; 72 | } 73 | 74 | size_t bctbx_get_char(const char *a, char *out) { 75 | if (is_escaped_char(a)) { 76 | unsigned int tmp; 77 | sscanf(a + 1, "%02x", &tmp); 78 | *out = (char)tmp; 79 | return 3; 80 | } else { 81 | *out = *a; 82 | return 1; 83 | } 84 | } 85 | 86 | char *bctbx_unescaped_string(const char *buff) { 87 | char *output_buff = bctbx_malloc(strlen(buff) + 1); 88 | size_t i; 89 | size_t out_buff_index = 0; 90 | 91 | for (i = 0; buff[i] != '\0'; out_buff_index++) { 92 | i += bctbx_get_char(buff + i, output_buff + out_buff_index); 93 | } 94 | 95 | output_buff[out_buff_index] = '\0'; 96 | return output_buff; 97 | } 98 | 99 | char *bctbx_unescaped_string_only_chars_in_rules(const char *buff, const bctbx_noescape_rules_t unescape) { 100 | size_t max_len = strlen(buff) + 1; 101 | char *output_buff = bctbx_malloc(max_len); 102 | size_t i; 103 | size_t out_buff_index = 0; 104 | 105 | for (i = 0; buff[i] != '\0';) { 106 | i += bctbx_get_char(buff + i, output_buff + out_buff_index); 107 | 108 | int c = ((unsigned char *)output_buff)[out_buff_index]; 109 | if (unescape[c] == 0 && is_escaped_char(buff + i)) { 110 | // we unescaped a character that should stay escaped 111 | max_len += 3; 112 | output_buff = bctbx_realloc(output_buff, max_len); 113 | out_buff_index += snprintf(output_buff + out_buff_index, max_len - out_buff_index, "%%%02x", c); 114 | } else { 115 | out_buff_index += 1; 116 | } 117 | } 118 | 119 | output_buff[out_buff_index] = '\0'; 120 | return output_buff; 121 | } -------------------------------------------------------------------------------- /tester/bctoolbox_tester.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #ifdef HAVE_CONFIG_H 20 | #include "config.h" 21 | #endif 22 | #include "bctoolbox/logging.h" 23 | #include "bctoolbox_tester.h" 24 | 25 | static const char *log_domain = "bctoolbox-tester"; 26 | 27 | static void log_handler(int lev, const char *fmt, va_list args) { 28 | #ifdef _WIN32 29 | /* We must use stdio to avoid log formatting (for autocompletion etc.) */ 30 | vfprintf(lev == BCTBX_LOG_ERROR ? stderr : stdout, fmt, args); 31 | fprintf(lev == BCTBX_LOG_ERROR ? stderr : stdout, "\n"); 32 | #else 33 | va_list cap; 34 | va_copy(cap, args); 35 | vfprintf(lev == BCTBX_LOG_ERROR ? stderr : stdout, fmt, cap); 36 | fprintf(lev == BCTBX_LOG_ERROR ? stderr : stdout, "\n"); 37 | va_end(cap); 38 | #endif 39 | 40 | bctbx_logv(log_domain, lev, fmt, args); 41 | } 42 | 43 | void bctoolbox_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list args)) { 44 | bc_tester_init(log_handler, BCTBX_LOG_MESSAGE, BCTBX_LOG_ERROR, NULL); 45 | bc_tester_add_suite(&containers_test_suite); 46 | bc_tester_add_suite(&utils_test_suite); 47 | #if (HAVE_MBEDTLS || HAVE_OPENSSL) 48 | bc_tester_add_suite(&crypto_test_suite); 49 | bc_tester_add_suite(&encrypted_vfs_test_suite); 50 | #endif 51 | bc_tester_add_suite(&parser_test_suite); 52 | #ifdef __APPLE__ 53 | bc_tester_add_suite(&ios_utils_test_suite); 54 | #endif 55 | bc_tester_add_suite(¶m_string_test_suite); 56 | bc_tester_add_suite(&vfs_test_suite); 57 | bc_tester_add_suite(&logger_test_suite); 58 | } 59 | 60 | void bctoolbox_tester_uninit(void) { 61 | bc_tester_uninit(); 62 | } 63 | 64 | void bctoolbox_tester_before_each() { 65 | } 66 | 67 | int bctoolbox_tester_set_log_file(const char *filename) { 68 | int res = 0; 69 | char *dir = bctbx_dirname(filename); 70 | char *base = bctbx_basename(filename); 71 | bctbx_message("Redirecting traces to file [%s]", filename); 72 | bctbx_log_handler_t *filehandler = bctbx_create_file_log_handler(0, dir, base); 73 | if (filehandler == NULL) { 74 | res = -1; 75 | goto end; 76 | } 77 | bctbx_add_log_handler(filehandler); 78 | 79 | end: 80 | bctbx_free(dir); 81 | bctbx_free(base); 82 | return res; 83 | } 84 | 85 | #if !defined(__ANDROID__) && !(defined(BCTBX_WINDOWS_PHONE) || defined(BCTBX_WINDOWS_UNIVERSAL)) 86 | 87 | static const char *bctoolbox_helper = "\t\t\t--verbose\n" 88 | "\t\t\t--silent\n" 89 | "\t\t\t--log-file \n"; 90 | 91 | int main(int argc, char *argv[]) { 92 | int i; 93 | int ret; 94 | 95 | bctbx_init_logger(TRUE); 96 | bctoolbox_tester_init(NULL); 97 | 98 | for (i = 1; i < argc; ++i) { 99 | if (strcmp(argv[i], "--verbose") == 0) { 100 | bctbx_set_log_level(log_domain, BCTBX_LOG_DEBUG); 101 | bctbx_set_log_level(BCTBX_LOG_DOMAIN, BCTBX_LOG_DEBUG); 102 | } else if (strcmp(argv[i], "--silent") == 0) { 103 | bctbx_set_log_level(log_domain, BCTBX_LOG_FATAL); 104 | } else if (strcmp(argv[i], "--log-file") == 0) { 105 | CHECK_ARG("--log-file", ++i, argc); 106 | if (bctoolbox_tester_set_log_file(argv[i]) < 0) return -2; 107 | } else { 108 | int ret = bc_tester_parse_args(argc, argv, i); 109 | if (ret > 0) { 110 | i += ret - 1; 111 | continue; 112 | } else if (ret < 0) { 113 | bc_tester_helper(argv[0], bctoolbox_helper); 114 | } 115 | return ret; 116 | } 117 | } 118 | ret = bc_tester_start(argv[0]); 119 | bctoolbox_tester_uninit(); 120 | bctbx_uninit_logger(); 121 | return ret; 122 | } 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /src/conversion/charconv.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "bctoolbox/charconv.h" 31 | #include "bctoolbox/defs.h" 32 | #include "bctoolbox/logging.h" 33 | #include "bctoolbox/port.h" 34 | 35 | static char *convert_from_to(const char *str, const char *from, const char *to) { 36 | if (!from || !to) return NULL; 37 | 38 | if (strcasecmp(from, to) == 0) return bctbx_strdup(str); 39 | 40 | char *in_buf = (char *)str; 41 | char *out_buf, *ptr; 42 | size_t in_left = strlen(str) + 1; 43 | size_t out_left = in_left + in_left / 10; // leave a marge of 10% 44 | iconv_t cd; 45 | 46 | setlocale(LC_CTYPE, ""); 47 | 48 | const char *r_from = strcasecmp("locale", from) == 0 ? nl_langinfo(CODESET) : from; 49 | const char *r_to = strcasecmp("locale", to) == 0 ? nl_langinfo(CODESET) : to; 50 | 51 | if (strcasecmp(r_from, r_to) == 0) { 52 | return bctbx_strdup(str); 53 | } 54 | 55 | cd = iconv_open(r_to, r_from); 56 | 57 | if (cd != (iconv_t)-1) { 58 | size_t ret; 59 | size_t out_len = out_left; 60 | 61 | out_buf = (char *)bctbx_malloc(out_left); 62 | ptr = out_buf; // Keep a pointer to the beginning of this buffer to be able to realloc 63 | 64 | ret = iconv(cd, &in_buf, &in_left, &out_buf, &out_left); 65 | while (ret == (size_t)-1 && errno == E2BIG) { 66 | ptr = (char *)bctbx_realloc(ptr, out_len * 2); 67 | out_left = out_len; 68 | out_buf = ptr + out_left; 69 | out_len *= 2; 70 | 71 | ret = iconv(cd, &in_buf, &in_left, &out_buf, &out_left); 72 | } 73 | iconv_close(cd); 74 | 75 | if (ret == (size_t)-1 && errno != E2BIG) { 76 | bctbx_error("Error while converting a string from '%s' to '%s': %s", from, to, strerror(errno)); 77 | bctbx_free(ptr); 78 | 79 | return bctbx_strdup(str); 80 | } 81 | } else { 82 | bctbx_error("Unable to open iconv content descriptor from '%s' to '%s': %s", from, to, strerror(errno)); 83 | 84 | return bctbx_strdup(str); 85 | } 86 | 87 | return ptr; 88 | } 89 | 90 | char *bctbx_locale_to_utf8(const char *str) { 91 | const char *default_encoding = bctbx_get_default_encoding(); 92 | 93 | if (!strcmp(default_encoding, "UTF-8")) return bctbx_strdup(str); 94 | 95 | return convert_from_to(str, default_encoding, "UTF-8"); 96 | } 97 | 98 | char *bctbx_utf8_to_locale(const char *str) { 99 | const char *default_encoding = bctbx_get_default_encoding(); 100 | 101 | if (!strcmp(default_encoding, "UTF-8")) return bctbx_strdup(str); 102 | 103 | return convert_from_to(str, "UTF-8", default_encoding); 104 | } 105 | 106 | char *bctbx_convert_any_to_utf8(const char *str, const char *encoding) { 107 | return convert_from_to(str, (encoding ? encoding : "LOCALE"), "UTF-8"); 108 | } 109 | 110 | char *bctbx_convert_utf8_to_any(const char *str, const char *encoding) { 111 | return convert_from_to(str, "UTF-8", (encoding ? encoding : "LOCALE")); 112 | } 113 | 114 | char *bctbx_convert_string(const char *str, const char *from_encoding, const char *to_encoding) { 115 | if ((from_encoding && to_encoding && !strcmp(from_encoding, to_encoding)) || (!from_encoding && !to_encoding)) 116 | return bctbx_strdup(str); 117 | return convert_from_to(str, (from_encoding ? from_encoding : "LOCALE"), (to_encoding ? to_encoding : "LOCALE")); 118 | } 119 | 120 | unsigned int bctbx_get_code_page(BCTBX_UNUSED(const char *encoding)) { 121 | bctbx_error("Getting code page is not implemented"); 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /tester/logger.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2023 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "bctoolbox/crypto.h" 25 | #include "bctoolbox/tester.h" 26 | #include "bctoolbox_tester.h" 27 | 28 | static void assert_tag_presence(const std::list &expected) { 29 | const bctbx_list_t *tags = bctbx_get_log_tags(); 30 | std::ostringstream expected_tags_str; 31 | std::ostringstream current_tags_str; 32 | for (auto expected_tag : expected) { 33 | expected_tags_str << "[" << expected_tag << "]"; 34 | } 35 | for (; tags != NULL; tags = tags->next) { 36 | const char *expected_tag = (const char *)tags->data; 37 | current_tags_str << "[" << expected_tag << "]"; 38 | } 39 | 40 | const std::string ¤tTags = current_tags_str.str(); 41 | const std::string &expectedTags = expected_tags_str.str(); 42 | BC_ASSERT_STRING_EQUAL(currentTags.c_str(), expectedTags.c_str()); 43 | } 44 | 45 | static void test_tags(void) { 46 | const char *sometag = "doing-something"; 47 | const char *someothertag = "doing-something-else"; 48 | bctbx_init_logger(1); 49 | 50 | bctbx_error("Some error"); 51 | bctbx_push_log_tag(sometag, "test1"); 52 | bctbx_error("Error again"); 53 | assert_tag_presence({"test1"}); 54 | bctbx_pop_log_tag(sometag); 55 | bctbx_error("Error again, no tags expected here"); 56 | assert_tag_presence({}); 57 | 58 | bctbx_push_log_tag(sometag, "test1"); 59 | bctbx_error("Error again with tag expected"); 60 | assert_tag_presence({"test1"}); 61 | bctbx_push_log_tag(sometag, "test2"); 62 | assert_tag_presence({"test2"}); 63 | bctbx_error("Error again with new tag value expected"); 64 | 65 | bctbx_push_log_tag(someothertag, "yes"); 66 | assert_tag_presence({"test2", "yes"}); 67 | bctbx_error("Error again with 2 tags simulatenously."); 68 | bctbx_pop_log_tag(sometag); 69 | assert_tag_presence({"test1", "yes"}); 70 | bctbx_error("Error again with first tag restored to previous value"); 71 | bctbx_pop_log_tag(sometag); 72 | assert_tag_presence({"yes"}); 73 | bctbx_error("Error with the 2nd tag only"); 74 | bctbx_pop_log_tag(someothertag); 75 | 76 | bctbx_uninit_logger(); 77 | } 78 | 79 | class LogContextualizer { 80 | public: 81 | LogContextualizer(const char *tagValue) { 82 | bctbx_push_log_tag(sTagIdentifier, tagValue); 83 | } 84 | LogContextualizer(const std::string &tagValue) { 85 | bctbx_push_log_tag(sTagIdentifier, tagValue.c_str()); 86 | } 87 | ~LogContextualizer() { 88 | bctbx_pop_log_tag(sTagIdentifier); 89 | } 90 | 91 | private: 92 | static constexpr char sTagIdentifier[] = "my-identifier"; 93 | }; 94 | 95 | static void test_cpp_tags(void) { 96 | bctbx_init_logger(1); 97 | 98 | bctbx_error("Some error"); 99 | { 100 | LogContextualizer lc("hey"); 101 | bctbx_error("Error again"); 102 | assert_tag_presence({"hey"}); 103 | } 104 | bctbx_error("Error again, no tags expected here"); 105 | assert_tag_presence({}); 106 | 107 | { 108 | LogContextualizer lc("hello"); 109 | bctbx_error("Error again with tag expected"); 110 | assert_tag_presence({"hello"}); 111 | { 112 | LogContextualizer lc("hi"); 113 | bctbx_error("Error again with new tag expected"); 114 | assert_tag_presence({"hi"}); 115 | } 116 | bctbx_error("Error again with previous expected"); 117 | assert_tag_presence({"hello"}); 118 | } 119 | bctbx_uninit_logger(); 120 | } 121 | 122 | static test_t logger_tests[] = {TEST_NO_TAG("Log tags", test_tags), TEST_NO_TAG("C++ log tags", test_cpp_tags)}; 123 | 124 | test_suite_t logger_test_suite = {"Logging", NULL, NULL, NULL, NULL, sizeof(logger_tests) / sizeof(logger_tests[0]), 125 | logger_tests, 0}; 126 | -------------------------------------------------------------------------------- /src/utils/ios_utils.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2019 Belledonne Communications SARL. 3 | * 4 | * This file is part of Liblinphone. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef __APPLE__ 21 | 22 | #include 23 | 24 | #import 25 | #include 26 | 27 | #include "bctoolbox/defs.h" 28 | #include "bctoolbox/ios_utils.hh" 29 | #include "bctoolbox/exception.hh" 30 | #include "bctoolbox/logging.h" 31 | #include "ios_utils_stub.hh" 32 | 33 | #if TARGET_OS_IPHONE 34 | #import 35 | #endif 36 | 37 | 38 | namespace bctoolbox { 39 | 40 | std::unique_ptr IOSUtils::sInstance = nullptr; 41 | 42 | IOSUtils& IOSUtils::getUtils() { 43 | if (!sInstance) { 44 | sInstance = std::unique_ptr(new IOSUtils); 45 | } 46 | 47 | return *sInstance; 48 | } 49 | 50 | IOSUtils::IOSUtils() { 51 | mIsApp = [[[NSBundle mainBundle] bundlePath] hasSuffix:@".app"]; 52 | if (mIsApp) { 53 | openDynamicLib(); 54 | using create_t = IOSUtilsInterface *(*)(); 55 | auto createUtils = reinterpret_cast(loadSymbol("bctbx_create_ios_utils_app")); 56 | mUtils = createUtils(); 57 | } else { 58 | mUtils = new IOSUtilsStub(); 59 | } 60 | } 61 | 62 | IOSUtils::~IOSUtils() { 63 | if (mIsApp) { 64 | using destroy_t = void (*)(IOSUtilsInterface *); 65 | auto destroyUtils = reinterpret_cast(loadSymbol("bctbx_destroy_ios_utils_app")); 66 | destroyUtils(mUtils); 67 | dlclose(mHandle); 68 | } else { 69 | delete mUtils; 70 | } 71 | } 72 | 73 | bool IOSUtils::isApp() { 74 | return mIsApp; 75 | } 76 | 77 | void IOSUtils::openDynamicLib() { 78 | NSString *frameworkPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingString: @"/Frameworks/bctoolbox-ios.framework/bctoolbox-ios"]; 79 | const char *frameworkChar = [frameworkPath cStringUsingEncoding:[NSString defaultCStringEncoding]]; 80 | 81 | mHandle = dlopen(frameworkChar, RTLD_LAZY); 82 | if (!mHandle) { 83 | throw BCTBX_EXCEPTION << "bctoolbox error dlopen : " << dlerror(); 84 | } 85 | 86 | // reset errors 87 | dlerror(); 88 | } 89 | 90 | void *IOSUtils::loadSymbol(const char *symbol) { 91 | void *loadedSymbol = dlsym(mHandle, symbol); 92 | const char *dlsym_error = dlerror(); 93 | 94 | if (dlsym_error) { 95 | std::string error = dlsym_error; 96 | dlclose(mHandle); 97 | throw BCTBX_EXCEPTION << "bctoolbox error dlsym : " << error; 98 | } 99 | 100 | return loadedSymbol; 101 | } 102 | 103 | unsigned long IOSUtils::beginBackgroundTask(const char *name, std::function cb) { 104 | return mUtils->beginBackgroundTask(name, cb); 105 | } 106 | 107 | void IOSUtils::endBackgroundTask(unsigned long id) { 108 | return mUtils->endBackgroundTask(id); 109 | } 110 | 111 | bool IOSUtils::isApplicationStateActive() { 112 | return mUtils->isApplicationStateActive(); 113 | } 114 | 115 | int IOSUtils::getOSMajorVersion() const{ 116 | #if TARGET_OS_IPHONE 117 | NSArray *versionCompatibility = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."]; 118 | return [[versionCompatibility objectAtIndex:0] intValue]; 119 | #else 120 | bctbx_error("IOSUtils::getOSMajorVersion() not running on iOS"); 121 | return 0; 122 | #endif 123 | } 124 | 125 | 126 | unsigned long IOSUtilsStub::beginBackgroundTask(BCTBX_UNUSED(const char *name), BCTBX_UNUSED(std::function cb)) { 127 | return 0; 128 | } 129 | 130 | void IOSUtilsStub::endBackgroundTask(BCTBX_UNUSED(unsigned long id)) {} 131 | 132 | bool IOSUtilsStub::isApplicationStateActive() { 133 | return false; 134 | } 135 | 136 | } //namespace bctoolbox 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /include/bctoolbox/parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_PARSER_H_ 21 | #define BCTBX_PARSER_H_ 22 | 23 | #include "bctoolbox/port.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | /** 29 | * A 256 entries table where each entries defines if character corresponding to its index is allowed or not (value = 0) 30 | * for instance noescape_rules[':'] = 1 means that ':' should not be escaped 31 | */ 32 | typedef unsigned char 33 | bctbx_noescape_rules_t[256 + 1]; /*last entry (BCTBX_NOESCAPE_RULES_USER_INDEX) is reserved for user purpose. Might 34 | be usefull to set if array was initialed of not */ 35 | 36 | #define BCTBX_NOESCAPE_RULES_USER_INDEX (sizeof(bctbx_noescape_rules_t) - 1) 37 | /** 38 | * Allocate a new string with unauthorized characters escaped (I.E replaced by % HEX HEX) if any. 39 | * sample: 40 | * bctbx_noescape_rules_t my_rules = {0}; nothing allowed 41 | * bctbx_noescape_rules_add_alfanums(my_rules); 42 | * char * my_escaped_string = bctbx_escape("François",my_rules); 43 | * expeted result my_escaped_string == Fran%c3%a7ois 44 | * @param buff NULL terminated input buffer. 45 | * @param noescape_rules bctbx_noescape_rules_t to apply for this input buff 46 | 47 | * @return a newly allocated null terminated string 48 | */ 49 | BCTBX_PUBLIC char *bctbx_escape(const char *buff, const bctbx_noescape_rules_t noescape_rules); 50 | 51 | /** 52 | * Add a list of allowed charaters to a noescape rule. 53 | * @param noescape_rules rule to be modified. 54 | * @param allowed string representing allowed char. Sample: ";-/" 55 | */ 56 | BCTBX_PUBLIC void bctbx_noescape_rules_add_list(bctbx_noescape_rules_t noescape_rules, const char *allowed); 57 | 58 | /** 59 | * Add a range of allowed charaters to noescape rule. bctbx_noescape_rules_add_range(noescape_rules, '0','9') is the 60 | * same as bctbx_noescape_rules_add_list(noescape_rules,"0123456789") 61 | * @param noescape_rules rule to be modified. 62 | * @param first allowed char. 63 | * @param last allowed char. 64 | */ 65 | BCTBX_PUBLIC void bctbx_noescape_rules_add_range(bctbx_noescape_rules_t noescape_rules, char first, char last); 66 | /** 67 | * Add ['0'..'9'], ['a'..'z'] ['A'..'z'] to no escape rule. 68 | */ 69 | BCTBX_PUBLIC void bctbx_noescape_rules_add_alfanums(bctbx_noescape_rules_t noescape_rules); 70 | 71 | /** 72 | * Allocate a new string with escaped character (I.E % HEX HEX) replaced by unicode char. 73 | * @param buff NULL terminated input buffer. 74 | * @return a newly allocated null terminated string with unescated values. 75 | */ 76 | BCTBX_PUBLIC char *bctbx_unescaped_string(const char *buff); 77 | 78 | /** 79 | * Does the same as bctbx_unescaped_string() except it does it only for characters in unescape_rules 80 | * @param buff NULL terminated input buffer. 81 | * @param unescape_rules bctbx_noescape_rules_t characters to unescape, other will be kept escaped 82 | * @return a newly allocated null terminated string with unescated values. 83 | */ 84 | BCTBX_PUBLIC char *bctbx_unescaped_string_only_chars_in_rules(const char *buff, 85 | const bctbx_noescape_rules_t unescape_rules); 86 | 87 | /** 88 | *Convert a single input "a" into unscaped output if need. 89 | * a = "%c3%a7" into "ç" with return value = 3 90 | * a = "A" into "A" with return value = 1 91 | * @param a input value 92 | * @param out outbut buffer for conversion 93 | * @return number of byte wrote into out 94 | */ 95 | BCTBX_PUBLIC size_t bctbx_get_char(const char *a, char *out); 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | #endif /*BCTBX_PARSER_H_*/ 102 | -------------------------------------------------------------------------------- /include/bctoolbox/ownership.hh: -------------------------------------------------------------------------------- 1 | /** SPDX-License-Identifier: GPL-3.0-or-later 2 | * 3 | * Pointer wrappers for explicit ownership semantics. 4 | * Those are NOT smart pointers (they do not manage memory) 5 | * 6 | * They can all be constructed from raw pointers to interop with existing code, but the conversion is explicit to make 7 | * sure the intent is clear. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | namespace ownership { 16 | 17 | /* A pointer that is NOT responsible for the destruction of its pointee. 18 | * 19 | * Same as `Borrowed` but mutable (non-const) 20 | */ 21 | template 22 | class BorrowedMut { 23 | T *mPointer; 24 | 25 | public: 26 | /* State explicitly that this pointer represents a mutable borrow */ 27 | explicit BorrowedMut(T *pointer) : mPointer(pointer) { 28 | } 29 | 30 | /* Downcasts from smart pointers */ 31 | BorrowedMut(const std::shared_ptr &shared) : mPointer(shared.get()) { 32 | } 33 | template 34 | BorrowedMut(const std::unique_ptr &unique) : mPointer(unique.get()) { 35 | } 36 | 37 | /* Cast wrapped type */ 38 | template 39 | BorrowedMut(BorrowedMut other) : mPointer(other) { 40 | } 41 | 42 | T *operator->() { 43 | return mPointer; 44 | }; 45 | 46 | operator T *() { 47 | return mPointer; 48 | }; 49 | 50 | const T *operator->() const { 51 | return mPointer; 52 | }; 53 | 54 | operator const T *() const { 55 | return mPointer; 56 | }; 57 | }; 58 | 59 | /* A pointer that IS responsible for the destruction of its pointee. 60 | * 61 | * When reference counting, having an Owned means the reference count has been incremented. 62 | * 63 | * Use .take() to move the pointer out of the wrapper (typically before deleting the pointee). 64 | * Use .borrow() to use mutating operations without incrementing the reference count. 65 | */ 66 | template 67 | class Owned { 68 | T *mPointer; 69 | 70 | void assertFreed() { 71 | if (mPointer != nullptr) { 72 | throw std::logic_error("Owned pointer lost. If you did free it, maybe you forgot to call .take() before"); 73 | } 74 | } 75 | 76 | public: 77 | Owned(std::nullptr_t null) : mPointer(null) { 78 | } 79 | /* State explicitly that this pointer owns its pointee */ 80 | explicit Owned(T *pointer) : mPointer(pointer) { 81 | } 82 | /* Avoid inadvertently creating an owned pointer from a borrowed pointer */ 83 | Owned(BorrowedMut borrowed) = delete; 84 | ~Owned() { 85 | assertFreed(); 86 | } 87 | 88 | // Move only semantics to ensure ownership is always transferred 89 | Owned(Owned &&other) : mPointer(other.take()) { 90 | } 91 | Owned &operator=(Owned &&other) { 92 | assertFreed(); 93 | mPointer = other.take(); 94 | return *this; 95 | } 96 | Owned(const Owned &other) = delete; 97 | Owned &operator=(const Owned &other) = delete; 98 | 99 | /* Move the raw pointer out of the wrapper (leaving nullptr in its place). 100 | * Use it to pass ownership to the appropriate destructor 101 | */ 102 | T *take() { 103 | auto moved = mPointer; 104 | mPointer = nullptr; 105 | return moved; 106 | } 107 | 108 | /* Take a mutable borrow. 109 | * Use it to call mutating operations that don't need ownership 110 | */ 111 | BorrowedMut borrow() { 112 | return BorrowedMut(mPointer); 113 | } 114 | 115 | /* Automatically degrade into const pointer because that is always safe */ 116 | operator const T *() const { 117 | return mPointer; 118 | }; 119 | }; 120 | 121 | /* A const pointer that is NOT responsible for the destruction of its pointee. 122 | * 123 | * Care must be taken to ensure appropiate lifetimes: Since the borrow is not responsible for the lifetime of the 124 | * pointee, the latter might be destroyed before the borrow is used, leaving it dangling. 125 | */ 126 | template 127 | class Borrowed { 128 | const T *mPointer; 129 | 130 | public: 131 | /* State explicitly that this pointer represents an immutable borrow */ 132 | explicit Borrowed(const T *pointer) : mPointer(pointer) { 133 | } 134 | Borrowed(const Owned &owned) : Borrowed(static_cast(owned)) { 135 | } 136 | Borrowed(const BorrowedMut &mutBorrow) : Borrowed(static_cast(mutBorrow)) { 137 | } 138 | 139 | operator const T *() const { 140 | return mPointer; 141 | }; 142 | }; 143 | 144 | template 145 | auto owned(T *pointer) { 146 | return Owned(pointer); 147 | } 148 | 149 | template 150 | auto borrowed(const T *pointer) { 151 | return Borrowed(pointer); 152 | } 153 | 154 | template 155 | auto borrowed_mut(T *pointer) { 156 | return BorrowedMut(pointer); 157 | } 158 | 159 | } // namespace ownership 160 | -------------------------------------------------------------------------------- /src/logging/log-tags.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2023 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include "bctoolbox/defs.h" 25 | #include "bctoolbox/logging.h" 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | using namespace std; 33 | 34 | namespace bctoolbox { 35 | 36 | class LogTags { 37 | public: 38 | static LogTags &get() { 39 | return sThreadLocalInstance; 40 | } 41 | void pushTag(const string &tagType, const string &tagValue) { 42 | auto &tagStack = mTags[tagType]; 43 | if (tagStack.empty() || tagStack.top().mValue != tagValue) { 44 | tagStack.push({tagValue, 1}); 45 | } else { 46 | tagStack.top().mCount++; 47 | } 48 | mTagsModfied = true; 49 | } 50 | void popTag(const string &tagType) { 51 | auto &tagStack = mTags[tagType]; 52 | if (tagStack.empty()) { 53 | bctbx_error("logging: no tag type '%s' pushed previously. Check your code.", tagType.c_str()); 54 | return; 55 | } else { 56 | if (--tagStack.top().mCount == 0) { 57 | tagStack.pop(); 58 | mTagsModfied = true; 59 | } 60 | } 61 | } 62 | const list &getTags() { 63 | if (mTagsModfied) { 64 | mCurrentTags.clear(); 65 | bctbx_list_free(mCurrentTagsCList); 66 | mCurrentTagsCList = nullptr; 67 | for (auto it = mTags.rbegin(); it != mTags.rend(); ++it) { 68 | auto &tagStack = (*it).second; 69 | if (!tagStack.empty()) { 70 | const string &value = tagStack.top().mValue; 71 | mCurrentTags.emplace_front(value); 72 | mCurrentTagsCList = bctbx_list_prepend(mCurrentTagsCList, const_cast(value.c_str())); 73 | } 74 | } 75 | mTagsModfied = false; 76 | } 77 | return mCurrentTags; 78 | } 79 | const bctbx_list_t *getTagsAsCList() { 80 | getTags(); 81 | return mCurrentTagsCList; 82 | } 83 | /* bctbx_log_tags_t is the C opaque typedef for the ContextCopy */ 84 | typedef map ContextCopy; 85 | ContextCopy createCopy() { 86 | ContextCopy ret; 87 | for (auto &tag : mTags) { 88 | auto &tagStack = tag.second; 89 | if (!tagStack.empty()) { 90 | ret[tag.first] = tagStack.top().mValue; 91 | } 92 | } 93 | return ret; 94 | } 95 | void paste(const ContextCopy &ctx) { 96 | if (!mTags.empty()) { 97 | bctbx_error("logging: assigning log tags to an non-empty context - not recommended, pre-existing tags will " 98 | "be lost."); 99 | } 100 | for (auto &p : ctx) { 101 | pushTag(p.first, p.second); 102 | } 103 | } 104 | ~LogTags() { 105 | bctbx_list_free(mCurrentTagsCList); 106 | } 107 | 108 | private: 109 | LogTags() = default; 110 | struct TagValue { 111 | string mValue; 112 | int mCount = 0; 113 | }; 114 | map> mTags; 115 | list mCurrentTags; 116 | bctbx_list_t *mCurrentTagsCList = nullptr; 117 | bool mTagsModfied = false; 118 | thread_local static LogTags sThreadLocalInstance; 119 | }; 120 | 121 | thread_local LogTags LogTags::sThreadLocalInstance; 122 | 123 | } // namespace bctoolbox 124 | 125 | void bctbx_push_log_tag(const char *tag_identifier, const char *tag_value) { 126 | bctoolbox::LogTags::get().pushTag(tag_identifier, tag_value); 127 | } 128 | 129 | void bctbx_pop_log_tag(const char *tag_identifier) { 130 | bctoolbox::LogTags::get().popTag(tag_identifier); 131 | } 132 | 133 | const bctbx_list_t *bctbx_get_log_tags(void) { 134 | return bctoolbox::LogTags::get().getTagsAsCList(); 135 | } 136 | 137 | bctbx_log_tags_t *bctbx_create_log_tags_copy(void) { 138 | return (bctbx_log_tags_t *)new bctoolbox::LogTags::ContextCopy(bctoolbox::LogTags::get().createCopy()); 139 | } 140 | 141 | BCTBX_PUBLIC void bctbx_paste_log_tags(const bctbx_log_tags_t *log_tags) { 142 | bctoolbox::LogTags::get().paste(*(const bctoolbox::LogTags::ContextCopy *)log_tags); 143 | } 144 | 145 | BCTBX_PUBLIC void bctbx_log_tags_destroy(bctbx_log_tags_t *log_tags) { 146 | delete (bctoolbox::LogTags::ContextCopy *)log_tags; 147 | } 148 | -------------------------------------------------------------------------------- /src/utils/utils.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2021 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "bctoolbox/utils.hh" 21 | #include 22 | 23 | using namespace std; 24 | 25 | #ifdef BCTBX_WINDOWS_UWP 26 | using namespace Windows::System; 27 | using namespace Windows::Foundation; 28 | #endif 29 | 30 | vector bctoolbox::Utils::split(const string &str, const string &delimiter) { 31 | vector out; 32 | 33 | size_t pos = 0, oldPos = 0; 34 | for (; (pos = str.find(delimiter, pos)) != string::npos; oldPos = pos + delimiter.length(), pos = oldPos) 35 | out.push_back(str.substr(oldPos, pos - oldPos)); 36 | out.push_back(str.substr(oldPos)); 37 | 38 | return out; 39 | } 40 | 41 | string bctoolbox::Utils::fold(const string &str) { 42 | string output = str; 43 | size_t crlf = 0; 44 | size_t next_crlf = 0; 45 | const char *endline = "\r\n"; 46 | 47 | while (next_crlf != string::npos) { 48 | next_crlf = output.find(endline, crlf); 49 | if (next_crlf != string::npos) { 50 | if (next_crlf - crlf > 75) { 51 | output.insert(crlf + 74, "\r\n "); 52 | crlf += 76; 53 | } else { 54 | crlf = next_crlf + 2; 55 | } 56 | } 57 | } 58 | 59 | return output; 60 | } 61 | 62 | string bctoolbox::Utils::unfold(const string &str) { 63 | string output = str; 64 | const char *endline = "\r\n"; 65 | size_t crlf = output.find(endline); 66 | 67 | if (crlf == string::npos) { 68 | endline = "\n"; 69 | crlf = output.find(endline); 70 | } 71 | 72 | while (crlf != string::npos) { 73 | if (isspace(output[crlf + strlen(endline)])) { 74 | output.erase(crlf, strlen(endline) + 1); 75 | } else { 76 | crlf += strlen(endline); 77 | } 78 | 79 | crlf = output.find(endline, crlf); 80 | } 81 | 82 | return output; 83 | } 84 | 85 | void bctoolbox::Utils::replace(string &source, const string &from, const string &to, const bool recursive) { 86 | size_t start_pos = 0; 87 | while ((start_pos = source.find(from, start_pos)) != string::npos) { 88 | source.replace(start_pos, from.length(), to); 89 | if (recursive) start_pos += to.length(); 90 | } 91 | } 92 | 93 | std::string bctoolbox::Utils::getMemoryReportAsString() { 94 | std::ostringstream ossReport; 95 | #ifdef WIN32 96 | // Use to convert bytes to MB 97 | const int division = 1048576; 98 | MEMORYSTATUSEX memoryStatus; 99 | memoryStatus.dwLength = sizeof(memoryStatus); 100 | GlobalMemoryStatusEx(&memoryStatus); 101 | ossReport << "Memory stats (MB): Usage=" << memoryStatus.dwMemoryLoad 102 | << ", Total physical=" << memoryStatus.ullTotalPhys / division 103 | << ", Free physical=" << memoryStatus.ullAvailPhys / division 104 | << ", Total paging file=" << memoryStatus.ullTotalPageFile / division 105 | << ", Free paging file=" << memoryStatus.ullAvailPageFile / division 106 | << ", Total virtual=" << memoryStatus.ullTotalVirtual / division 107 | << ", Free virtual=" << memoryStatus.ullAvailVirtual / division 108 | << ", Free extended=" << memoryStatus.ullAvailExtendedVirtual / division; 109 | #ifdef BCTBX_WINDOWS_UWP 110 | ossReport << " | UWP App Memory (MB): Usage=" << MemoryManager::AppMemoryUsage / division 111 | << ", Usage limit=" << MemoryManager::AppMemoryUsageLimit / division 112 | << ", Usage level=" << (int)MemoryManager::AppMemoryUsageLevel 113 | << ", Expected usage limit=" << MemoryManager::ExpectedAppMemoryUsageLimit / division 114 | << ", Free=" << (long)(MemoryManager::AppMemoryUsageLimit - MemoryManager::AppMemoryUsage) / division; 115 | #endif 116 | #endif 117 | return ossReport.str(); 118 | } 119 | 120 | bool bctoolbox::Utils::isExecutableInstalled(const std::string &executable, const std::string &resource) { 121 | auto pos = executable.find_last_of('/'); 122 | if (pos == std::string::npos) { 123 | pos = executable.find_last_of('\\'); 124 | } 125 | 126 | std::string path = executable.substr(0, pos + 1).append("../share/"); 127 | std::string name = executable.substr(pos + 1); 128 | 129 | std::string check = path + name + "/" + resource; 130 | 131 | return bctbx_file_exist(check.c_str()) == 0; 132 | } 133 | -------------------------------------------------------------------------------- /src/crypto/crypto.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | #ifdef HAVE_CONFIG_H 20 | #include "config.h" 21 | #endif 22 | 23 | #include 24 | 25 | /** 26 | * List of available key agreement algorithm 27 | */ 28 | uint32_t bctbx_key_agreement_algo_list(void) { 29 | uint32_t ret = BCTBX_DHM_2048 | BCTBX_DHM_3072; /* provided by mbedtls */ 30 | #ifdef HAVE_DECAF 31 | /* decaf always provide X448 and X25519 */ 32 | ret |= BCTBX_ECDH_X25519 | BCTBX_ECDH_X448; 33 | #endif /* HAVE_DECAF */ 34 | return ret; 35 | } 36 | 37 | /*****************************************************************************/ 38 | /***** AES GCM encrypt/decrypt chunk by chunk, needed for file encryption ****/ 39 | /*****************************************************************************/ 40 | /** 41 | * @brief encrypt the file in input buffer for linphone encrypted file transfer 42 | * 43 | * @param[in/out] cryptoContext a context already initialized using bctbx_aes_gcm_context_new 44 | * @param[in] key encryption key 45 | * @param[in] length buffer size 46 | * @param[in] plain buffer holding the input data 47 | * @param[out] cipher buffer to store the output data 48 | */ 49 | int bctbx_aes_gcm_encryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) { 50 | bctbx_aes_gcm_context_t *gcmContext; 51 | 52 | if (*cryptoContext == NULL && key == NULL) return -1; // we need the key, at least at first call 53 | 54 | if (*cryptoContext == NULL) { /* first call to the function, allocate a crypto context and initialise it */ 55 | /* key contains 192bits of key || 64 bits of Initialisation Vector, no additional data */ 56 | gcmContext = bctbx_aes_gcm_context_new(key, 24, NULL, 0, key + 24, 8, BCTBX_GCM_ENCRYPT); 57 | if (gcmContext == NULL) { 58 | return -1; 59 | } 60 | *cryptoContext = gcmContext; 61 | } else { /* this is not the first call, get the context */ 62 | gcmContext = (bctbx_aes_gcm_context_t *)*cryptoContext; 63 | } 64 | 65 | if (plain != NULL) { 66 | bctbx_aes_gcm_process_chunk(gcmContext, (const uint8_t *)plain, length, (uint8_t *)cipher); 67 | } else { /* plain is NULL, finish the stream, if cipher is not null, generate a tag in it */ 68 | if (cipher != NULL && length > 0) { 69 | bctbx_aes_gcm_finish(gcmContext, (uint8_t *)cipher, length); 70 | } else { 71 | bctbx_aes_gcm_finish(gcmContext, NULL, 0); 72 | } 73 | *cryptoContext = NULL; 74 | } 75 | 76 | return 0; 77 | } 78 | 79 | /** 80 | * @brief decrypt the file in input buffer for linphone encrypted file transfer 81 | * 82 | * @param[in/out] cryptoContext a context already initialized using bctbx_aes_gcm_context_new 83 | * @param[in] key encryption key 84 | * @param[in] length buffer size 85 | * @param[out] plain buffer holding the output data 86 | * @param[int] cipher buffer to store the input data 87 | */ 88 | int bctbx_aes_gcm_decryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) { 89 | bctbx_aes_gcm_context_t *gcmContext; 90 | int ret = -1; 91 | 92 | if (*cryptoContext == NULL && key == NULL) return ret; // we need the key, at least at first call 93 | 94 | if (*cryptoContext == NULL) { /* first call to the function, allocate a crypto context and initialise it */ 95 | 96 | /* key contains 192bits of key || 64 bits of Initialisation Vector, no additional data */ 97 | gcmContext = bctbx_aes_gcm_context_new(key, 24, NULL, 0, key + 24, 8, BCTBX_GCM_DECRYPT); 98 | if (gcmContext == NULL) { 99 | return ret; 100 | } 101 | *cryptoContext = gcmContext; 102 | } else { /* this is not the first call, get the context */ 103 | gcmContext = (bctbx_aes_gcm_context_t *)*cryptoContext; 104 | } 105 | 106 | if (cipher != NULL) { 107 | ret = bctbx_aes_gcm_process_chunk(gcmContext, (const uint8_t *)cipher, length, (uint8_t *)plain); 108 | } else { /* cipher is NULL, finish the stream, if plain is not null and we have a length, compute the authentication 109 | tag*/ 110 | if (plain != NULL && length > 0) { 111 | ret = bctbx_aes_gcm_finish(gcmContext, (uint8_t *)plain, length); 112 | } else { 113 | ret = bctbx_aes_gcm_finish(gcmContext, NULL, 0); 114 | } 115 | *cryptoContext = NULL; 116 | } 117 | 118 | return ret; 119 | } 120 | -------------------------------------------------------------------------------- /src/vfs/vfs_encryption_module_aes256gcm_sha256.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_VFS_ENCRYPTION_MODULE_AES256GCM_SHA256_HH 21 | #define BCTBX_VFS_ENCRYPTION_MODULE_AES256GCM_SHA256_HH 22 | #include "bctoolbox/crypto.hh" 23 | #include "bctoolbox/vfs_encrypted.hh" 24 | #include "vfs_encryption_module.hh" 25 | #include 26 | 27 | /*********** The AES256-GCM SHA256 module ************************ 28 | * Key derivations: 29 | * - file Header HMAC key = HKDF(Mk, fileHeaderSalt, "EVFS file header") 30 | * - chunk encryption key = HKDF(Mk, fileHeaderSalt || Chunk Index, "EVFS chunk") 31 | * File Header: 32 | * - 32 bytes auth tag: HMAC-sha256 on the file header 33 | * - 16 bytes salt: random generated at file creation : input of the HKDF keyed by the master key. 34 | * Chunk Header: 35 | * - Authentication tag : 16 bytes 36 | * - IV: 12 bytes. A random updated at each encryption 37 | * Chunk encryption: 38 | * - AES256-GCM with 128 bit auth tag. No associated Data. 39 | * - IV is 12 bytes random : MUST use a random for IV as attacker having access to file system could restore an old 40 | * version of the file and monitor further writing. So deterministic IV could lead to key/IV reuse. 41 | */ 42 | namespace bctoolbox { 43 | class VfsEM_AES256GCM_SHA256 : public VfsEncryptionModule { 44 | private: 45 | /** 46 | * The local RNG 47 | */ 48 | std::shared_ptr mRNG; // list it first so it is available in the constructor's init list 49 | 50 | /** 51 | * File header 52 | */ 53 | std::vector mFileSalt; 54 | std::array mFileHeaderIntegrity; 55 | 56 | /** keys 57 | */ 58 | std::vector sMasterKey; // used to derive all keys 59 | std::vector sFileHeaderHMACKey; // used to feed HMAC integrity check on file header 60 | 61 | /** 62 | * Derive the key from master key for the given chunkIndex: 63 | * HKDF(fileSalt || ChunkIndex, master Key, "EVFS chunk") 64 | * 65 | * @param[in] chunkIndex the chunk index used in key derivation 66 | * 67 | * @return the AES256-GCM128 key 68 | */ 69 | std::vector deriveChunkKey(uint32_t chunkIndex); 70 | 71 | public: 72 | /** 73 | * This function exists as static and non static 74 | */ 75 | static size_t moduleFileHeaderSize() noexcept; 76 | 77 | /** 78 | * @return the size in bytes of the chunk header 79 | */ 80 | size_t getChunkHeaderSize() const noexcept override; 81 | 82 | /** 83 | * @return the size in bytes of file header module data 84 | */ 85 | size_t getModuleFileHeaderSize() const noexcept override; 86 | 87 | /** 88 | * @return the EncryptionSuite provided by this module 89 | */ 90 | EncryptionSuite getEncryptionSuite() const noexcept override { 91 | return EncryptionSuite::aes256gcm128_sha256; 92 | } 93 | 94 | /** 95 | * @return the secret material size 96 | */ 97 | size_t getSecretMaterialSize() const noexcept override; 98 | 99 | /** 100 | * Decrypt a chunk of data 101 | * @param[in] a vector which size shall be chunkHeaderSize + chunkSize holding the raw data read from disk 102 | * @return the decrypted data chunk 103 | */ 104 | std::vector decryptChunk(const uint32_t chunkIndex, const std::vector &rawChunk) override; 105 | 106 | void encryptChunk(const uint32_t chunkIndex, 107 | std::vector &rawChunk, 108 | const std::vector &plainData) override; 109 | std::vector encryptChunk(const uint32_t chunkIndex, const std::vector &plainData) override; 110 | 111 | const std::vector getModuleFileHeader(const VfsEncryption &fileContext) const override; 112 | 113 | void setModuleSecretMaterial(const std::vector &secret) override; 114 | 115 | /** 116 | * Check the integrity over the whole file 117 | * @param[in] fileContext a way to access the file content 118 | * 119 | * @return true if the integrity check successfully passed, false otherwise 120 | */ 121 | bool checkIntegrity(const VfsEncryption &fileContext) override; 122 | 123 | /** 124 | * constructors 125 | */ 126 | // At file creation 127 | VfsEM_AES256GCM_SHA256(); 128 | // Opening an existing file 129 | VfsEM_AES256GCM_SHA256(const std::vector &fileHeader); 130 | 131 | ~VfsEM_AES256GCM_SHA256(); 132 | }; 133 | 134 | } // namespace bctoolbox 135 | #endif // BCTBX_VFS_ENCRYPTION_MODULE_AES256GCM_SHA256_HH 136 | -------------------------------------------------------------------------------- /include/bctoolbox/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_LIST_H_ 21 | #define BCTBX_LIST_H_ 22 | 23 | #include "bctoolbox/port.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | typedef struct _bctbx_list { 30 | struct _bctbx_list *next; 31 | struct _bctbx_list *prev; 32 | void *data; 33 | } bctbx_list_t; 34 | 35 | typedef int (*bctbx_compare_func)(const void *, const void *); 36 | typedef void (*bctbx_list_iterate_func)(void *); 37 | typedef void (*bctbx_list_iterate2_func)(void *, void *); 38 | typedef void (*bctbx_list_free_func)(void *); 39 | typedef void *(*bctbx_list_copy_func)(void *); 40 | 41 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_new(void *data); 42 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_append(bctbx_list_t *elem, void *data); 43 | BCTBX_PUBLIC BCTBX_DEPRECATED bctbx_list_t *bctbx_list_append_link(bctbx_list_t *elem, bctbx_list_t *new_elem); 44 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_prepend(bctbx_list_t *elem, void *data); 45 | BCTBX_PUBLIC BCTBX_DEPRECATED bctbx_list_t *bctbx_list_prepend_link(bctbx_list_t *elem, bctbx_list_t *new_elem); 46 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_last_elem(const bctbx_list_t *l); 47 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_first_elem(const bctbx_list_t *l); 48 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_free(bctbx_list_t *elem); 49 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_concat(bctbx_list_t *first, bctbx_list_t *second); 50 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_remove(bctbx_list_t *first, void *data); 51 | bctbx_list_t *bctbx_list_remove_with_data(bctbx_list_t *first, void *data, bctbx_list_free_func free_func); 52 | BCTBX_PUBLIC bctbx_list_t * 53 | bctbx_list_remove_custom(bctbx_list_t *first, bctbx_compare_func compare_func, const void *user_data); 54 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_remove_custom_with_data(bctbx_list_t *first, 55 | bctbx_compare_func compare_func, 56 | bctbx_list_free_func free_func, 57 | const void *user_data); 58 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_pop_front(bctbx_list_t *list, void **front_data); 59 | BCTBX_PUBLIC size_t bctbx_list_size(const bctbx_list_t *first); 60 | BCTBX_PUBLIC void bctbx_list_for_each(const bctbx_list_t *list, bctbx_list_iterate_func func); 61 | BCTBX_PUBLIC void bctbx_list_for_each2(const bctbx_list_t *list, bctbx_list_iterate2_func func, void *user_data); 62 | 63 | /** 64 | * Removes the element pointed by elem from the list. The element itself is not freed, allowing 65 | * to be chained in another list for example. 66 | * Use bctbx_list_erase_link() if you simply want to delete an element of a list. 67 | **/ 68 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_unlink(bctbx_list_t *list, bctbx_list_t *elem); 69 | /** 70 | * Delete the element pointed by 'elem' from the list. 71 | **/ 72 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_erase_link(bctbx_list_t *list, bctbx_list_t *elem); 73 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_find(bctbx_list_t *list, const void *data); 74 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_free(bctbx_list_t *list); 75 | /*frees list elements and associated data, using the supplied function pointer*/ 76 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_free_with_data(bctbx_list_t *list, bctbx_list_free_func freefunc); 77 | 78 | BCTBX_PUBLIC bctbx_list_t * 79 | bctbx_list_find_custom(const bctbx_list_t *list, bctbx_compare_func cmp, const void *user_data); 80 | BCTBX_PUBLIC void *bctbx_list_nth_data(const bctbx_list_t *list, int index); 81 | BCTBX_PUBLIC int bctbx_list_position(const bctbx_list_t *list, bctbx_list_t *elem); 82 | BCTBX_PUBLIC int bctbx_list_index(const bctbx_list_t *list, void *data); 83 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_insert_sorted(bctbx_list_t *list, void *data, bctbx_compare_func cmp); 84 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_insert(bctbx_list_t *list, bctbx_list_t *before, void *data); 85 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_copy(const bctbx_list_t *list); 86 | /*copy list elements and associated data, using the supplied function pointer*/ 87 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_copy_with_data(const bctbx_list_t *list, bctbx_list_copy_func copyfunc); 88 | /*Same as bctbx_list_copy_with_data but in reverse order*/ 89 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_copy_reverse_with_data(const bctbx_list_t *list, bctbx_list_copy_func copyfunc); 90 | 91 | BCTBX_PUBLIC bctbx_list_t *bctbx_list_next(const bctbx_list_t *elem); 92 | BCTBX_PUBLIC void *bctbx_list_get_data(const bctbx_list_t *elem); 93 | 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | 98 | #endif /* BCTLBX_LIST_H_ */ 99 | -------------------------------------------------------------------------------- /cmake/FindMbedTLS.cmake: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # FindMbedTLS.cmake 3 | # Copyright (C) 2015-2023 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | # 23 | # Find the mbedtls library. 24 | # 25 | # Targets 26 | # ^^^^^^^ 27 | # 28 | # The following targets may be defined: 29 | # 30 | # mbedtls - If the mbedtls library has been found 31 | # 32 | # 33 | # Result variables 34 | # ^^^^^^^^^^^^^^^^ 35 | # 36 | # This module will set the following variables in your project: 37 | # 38 | # MbedTLS_FOUND - The mbedtls library has been found 39 | # MbedTLS_TARGET - The name of the CMake target for the mbedtls library 40 | # MbedX509_TARGET - The name of the CMake target for the mbedx509 library 41 | # MbedCrypto_TARGET - The name of the CMake target for the mbedcrypto library 42 | # MbedTLS_VERSION - The version of the medtls library 43 | # DTLS_SRTP_AVAILABLE - If the mbedtls library has DTLS-SRTP support 44 | 45 | 46 | include(FindPackageHandleStandardArgs) 47 | 48 | set(_MbedTLS_REQUIRED_VARS MbedTLS_TARGET MbedX509_TARGET MbedCrypto_TARGET MbedTLS_VERSION) 49 | set(_MbedTLS_CACHE_VARS 50 | ${_MbedTLS_REQUIRED_VARS} DTLS_SRTP_AVAILABLE 51 | ) 52 | 53 | if(TARGET mbedtls) 54 | 55 | set(MbedTLS_TARGET mbedtls) 56 | set(MbedX509_TARGET mbedx509) 57 | set(MbedCrypto_TARGET mbedcrypto) 58 | 59 | get_target_property(MbedTLS_VERSION mbedtls VERSION) 60 | if (MbedTLS_VERSION EQUAL "MbedTLS_VERSION-NOTFOUND") 61 | set(MbedTLS_VERSION 3) 62 | else() 63 | string(REPLACE "." ";" MbedTLS_VERSION "${MbedTLS_VERSION}") 64 | list(GET MbedTLS_VERSION 0 MbedTLS_VERSION) 65 | # We are building mbedTLS, we have DTLS-SRTP support 66 | set(DTLS_SRTP_AVAILABLE ON) 67 | endif() 68 | 69 | else() 70 | 71 | include(CMakePushCheckState) 72 | include(CheckSymbolExists) 73 | 74 | find_path(_MbedTLS_INCLUDE_DIRS 75 | NAMES mbedtls/ssl.h 76 | PATH_SUFFIXES include 77 | ) 78 | 79 | # Find the three mbedtls libraries 80 | find_library(_MbedTLS_LIBRARY 81 | NAMES mbedtls 82 | ) 83 | 84 | find_library(_MbedX509_LIBRARY 85 | NAMES mbedx509 86 | ) 87 | 88 | find_library(_MbedCrypto_LIBRARY 89 | NAMES mbedcrypto 90 | ) 91 | 92 | cmake_push_check_state(RESET) 93 | set(CMAKE_REQUIRED_INCLUDES ${_MbedTLS_INCLUDE_DIRS} ${CMAKE_REQUIRED_INCLUDES_${BUILD_TYPE}}) 94 | list(APPEND CMAKE_REQUIRED_LIBRARIES ${_MbedTLS_LIBRARY} ${_MbedX509_LIBRARY} ${_MbedCrypto_LIBRARY}) 95 | 96 | # Check that we have a mbedTLS version 2 or above (all functions are prefixed mbedtls_) 97 | if(_MbedTLS_LIBRARY AND _MbedX509_LIBRARY AND _MbedCrypto_LIBRARY) 98 | check_symbol_exists(mbedtls_ssl_init "mbedtls/ssl.h" _MbedTLS_V2) 99 | if(NOT _MbedTLS_V2) 100 | message("MESSAGE: NO MbedTLS_V2") 101 | message("MESSAGE: MbedTLS_LIBRARY=" ${_MbedTLS_LIBRARY}) 102 | message("MESSAGE: MbedX509_LIBRARY=" ${MbedX509_LIBRARY}) 103 | message("MESSAGE: MbedCrypto_LIBRARY=" ${MbedCrypto_LIBRARY}) 104 | set(MbedTLS_VERSION 1) 105 | else() 106 | # Are we mbdetls 2 or 3? 107 | # From version 3 and on, version number is given in include/mbedtls/build_info.h. 108 | # This file does not exist before version 3 109 | if(EXISTS "${_MbedTLS_INCLUDE_DIRS}/mbedtls/build_info.h") 110 | set(MbedTLS_VERSION 3) 111 | else() 112 | set(MbedTLS_VERSION 2) 113 | endif() 114 | endif() 115 | endif() 116 | 117 | check_symbol_exists(mbedtls_ssl_conf_dtls_srtp_protection_profiles "mbedtls/ssl.h" DTLS_SRTP_AVAILABLE) 118 | 119 | cmake_pop_check_state() 120 | 121 | # Define the imported target for the three mbedtls libraries 122 | foreach(_VARPREFIX "MbedTLS" "MbedX509" "MbedCrypto") 123 | string(TOLOWER ${_VARPREFIX} _TARGET) 124 | add_library(${_TARGET} UNKNOWN IMPORTED) 125 | if(WIN32) 126 | set_target_properties(${_TARGET} PROPERTIES 127 | INTERFACE_INCLUDE_DIRECTORIES "${_MbedTLS_INCLUDE_DIRS}" 128 | IMPORTED_IMPLIB "${_${_VARPREFIX}_LIBRARY}" 129 | ) 130 | else() 131 | set_target_properties(${_TARGET} PROPERTIES 132 | INTERFACE_INCLUDE_DIRECTORIES "${_MbedTLS_INCLUDE_DIRS}" 133 | IMPORTED_LOCATION "${_${_VARPREFIX}_LIBRARY}" 134 | ) 135 | endif() 136 | endforeach() 137 | 138 | set(MbedTLS_TARGET mbedtls) 139 | set(MbedX509_TARGET mbedx509) 140 | set(MbedCrypto_TARGET mbedcrypto) 141 | 142 | endif() 143 | 144 | find_package_handle_standard_args(MbedTLS 145 | REQUIRED_VARS ${_MbedTLS_REQUIRED_VARS} 146 | ) 147 | mark_as_advanced(${_MbedTLS_CACHE_VARS}) 148 | -------------------------------------------------------------------------------- /include/bctoolbox/charconv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_CHARCONV_H 21 | #define BCTBX_CHARCONV_H 22 | 23 | #include "bctoolbox/port.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /** 30 | * @brief Set the default encoding for the application. 31 | * 32 | * @deprecated 2024/07/09: use setLocale() from to set the locale. On Windows, CP_APC will be used as 33 | * default. 34 | * @param[in] encoding default encoding, "locale" to set it to the system's locale 35 | */ 36 | BCTBX_DEPRECATED BCTBX_PUBLIC void bctbx_set_default_encoding(const char *encoding); 37 | 38 | /** 39 | * @brief Return the default encoding for the application. 40 | * 41 | * @return a pointer to a null-terminated string containing the default encoding. 42 | */ 43 | BCTBX_PUBLIC const char *bctbx_get_default_encoding(void); 44 | 45 | /** 46 | * @brief Convert the given string from system locale to UTF8. 47 | * 48 | * @param[in] str string to convert 49 | * 50 | * @return a pointer to a null-terminated string containing the converted string. This buffer must then be freed 51 | * by caller. NULL on failure. 52 | */ 53 | BCTBX_PUBLIC char *bctbx_locale_to_utf8(const char *str); 54 | 55 | /** 56 | * @brief Convert the given string from UTF8 to system locale. 57 | * 58 | * @param[in] str string to convert 59 | * 60 | * @return a pointer to a null-terminated string containing the converted string. This buffer must then be freed 61 | * by caller. NULL on failure. 62 | */ 63 | BCTBX_PUBLIC char *bctbx_utf8_to_locale(const char *str); 64 | 65 | /** 66 | * @brief Convert the given string. 67 | * 68 | * @param[in] str string to convert 69 | * @param[in] encoding charset of the string 70 | * 71 | * @return a pointer to a null-terminated string containing the converted string. This buffer must then be freed 72 | * by caller. NULL on failure. 73 | * 74 | * @note If encoding is equal to "locale" or NULL then it will use the system's locale 75 | * @note If encoding is UTF-8 then it returns a copy of str 76 | */ 77 | BCTBX_PUBLIC char *bctbx_convert_any_to_utf8(const char *str, const char *encoding); 78 | 79 | /** 80 | * @brief Convert the given string. 81 | * 82 | * @param[in] str string to convert 83 | * @param[in] encoding charset of the string 84 | * 85 | * @return a pointer to a null-terminated string containing the converted string. This buffer must then be freed 86 | * by caller. NULL on failure. 87 | * 88 | * @note If encoding is equal to "locale" or NULL then it will use the system's locale 89 | * @note If encoding is UTF-8 then it returns a copy of str 90 | */ 91 | BCTBX_PUBLIC char *bctbx_convert_utf8_to_any(const char *str, const char *encoding); 92 | 93 | /** 94 | * @brief Convert the given string. 95 | * 96 | * @param[in] str string to convert 97 | * @param[in] encoding charset of the string 98 | * @param[in] encoding charset of the string 99 | * 100 | * @return a pointer to a null-terminated string containing the converted string. This buffer must then be freed 101 | * by caller. NULL on failure. 102 | * 103 | * @note If from_encoding or to_encoding is equal to "locale" or NULL then it will use the system's locale. Use 104 | * bctbx_get_default_encoding() to get the application locale. 105 | * @note If encodings are the same then it returns a copy of str 106 | */ 107 | BCTBX_PUBLIC char *bctbx_convert_string(const char *str, const char *from_encoding, const char *to_encoding); 108 | 109 | /** 110 | * @brief Convert the char string to wide char string using current locale. 111 | * 112 | * @param[in] str string to convert 113 | * 114 | * @return a pointer to a null-terminated string containing the converted string. This buffer must then be freed 115 | * by caller. NULL on failure. 116 | */ 117 | BCTBX_PUBLIC wchar_t *bctbx_string_to_wide_string(const char *s); 118 | 119 | /** 120 | * @brief Convert the wide char string to char string using current locale. 121 | * 122 | * @param[in] wstr wide string to convert 123 | * 124 | * @return a pointer to a null-terminated string containing the converted string. This buffer must then be freed 125 | * by caller. NULL on failure. 126 | */ 127 | BCTBX_PUBLIC char *bctbx_wide_string_to_string(const wchar_t *wstr); 128 | 129 | /** 130 | * @brief Return the code page from the encoding. Only available for Windows platform 131 | * 132 | * @param[in] encoding string to convert. If NULL or "", return the code page defined by bctbx_get_default_encoding(). 133 | * @maybenil 134 | * 135 | * @return The code page associated to the encoding. Return system's locale if not found. 136 | */ 137 | BCTBX_PUBLIC unsigned int bctbx_get_code_page(const char *encoding); 138 | 139 | #ifdef __cplusplus 140 | } 141 | #endif 142 | 143 | #endif /* BCTBX_CHARCONV_H */ 144 | -------------------------------------------------------------------------------- /src/vconnect.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include "bctoolbox/logging.h" 25 | #include "bctoolbox/port.h" 26 | #include "bctoolbox/vconnect.h" 27 | #include 28 | #include 29 | #include 30 | 31 | /**============================================================ 32 | * Wrappers around default libc calls used to handle windows 33 | * differences in function prototypes. 34 | *=============================================================*/ 35 | 36 | static bctbx_socket_t vsocket_socket(int socket_family, int socket_type, int protocol) { 37 | return socket(socket_family, socket_type, protocol); 38 | } 39 | 40 | static int vsocket_connect(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len) { 41 | #ifdef _WIN32 42 | return connect(sock, address, (int)address_len); 43 | #else 44 | return connect(sock, address, address_len); 45 | #endif 46 | } 47 | 48 | static int vsocket_bind(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len) { 49 | #ifdef _WIN32 50 | return bind(sock, address, (int)address_len); 51 | #else 52 | return bind(sock, address, address_len); 53 | #endif 54 | } 55 | 56 | static int vsocket_getsockname(bctbx_socket_t sockfd, struct sockaddr *addr, socklen_t *addrlen) { 57 | #ifdef _WIN32 58 | return getsockname(sockfd, addr, (int *)addrlen); 59 | #else 60 | return getsockname(sockfd, addr, addrlen); 61 | #endif 62 | } 63 | 64 | static int vsocket_getsockopt(bctbx_socket_t sockfd, int level, int optname, void *optval, socklen_t *optlen) { 65 | #ifdef _WIN32 66 | return getsockopt(sockfd, level, optname, (char *)optval, (int *)optlen); 67 | #else 68 | return getsockopt(sockfd, level, optname, optval, optlen); 69 | #endif 70 | } 71 | 72 | static int vsocket_setsockopt(bctbx_socket_t sockfd, int level, int optname, const void *optval, socklen_t optlen) { 73 | #ifdef _WIN32 74 | return setsockopt(sockfd, level, optname, (char *)optval, (int)optlen); 75 | #else 76 | return setsockopt(sockfd, level, optname, optval, optlen); 77 | #endif 78 | } 79 | 80 | static int vsocket_close(bctbx_socket_t sock) { 81 | #ifdef _WIN32 82 | return closesocket(sock); 83 | #else 84 | return close(sock); 85 | #endif 86 | } 87 | 88 | static int vsocket_shutdown(bctbx_socket_t sock, int how) { 89 | return shutdown(sock, how); 90 | } 91 | 92 | #if !defined(_WIN32) && !defined(_WIN32_WCE) 93 | static char *vsocket_error(int err) { 94 | return strerror(err); 95 | } 96 | 97 | #else 98 | 99 | static char *vsocket_error(int err) { 100 | return (char *)__bctbx_getWinSocketError(err); 101 | } 102 | #endif 103 | 104 | /**=================================================== 105 | * Socket API default methods pointer definition. 106 | * ===================================================*/ 107 | 108 | static const bctbx_vsocket_methods_t bcSocketAPI = { 109 | vsocket_socket, vsocket_connect, vsocket_bind, vsocket_getsockname, vsocket_getsockopt, 110 | vsocket_setsockopt, vsocket_close, vsocket_error, vsocket_shutdown, 111 | }; 112 | 113 | static bctbx_vsocket_api_t bcvSocket = { 114 | "bctbx_socket", /* vSockName */ 115 | &bcSocketAPI, /*pSocketMethods */ 116 | }; 117 | 118 | /* Pointer to default socket methods initialized to standard libc implementation here.*/ 119 | static bctbx_vsocket_api_t *pDefaultvSocket = &bcvSocket; 120 | 121 | bctbx_socket_t bctbx_socket(int socket_family, int socket_type, int protocol) { 122 | return pDefaultvSocket->pSocketMethods->pFuncSocket(socket_family, socket_type, protocol); 123 | } 124 | 125 | int bctbx_socket_close(bctbx_socket_t sock) { 126 | return pDefaultvSocket->pSocketMethods->pFuncClose(sock); 127 | } 128 | 129 | int bctbx_bind(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len) { 130 | return pDefaultvSocket->pSocketMethods->pFuncBind(sock, address, address_len); 131 | } 132 | 133 | int bctbx_connect(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len) { 134 | return pDefaultvSocket->pSocketMethods->pFuncConnect(sock, address, address_len); 135 | } 136 | 137 | int bctbx_getsockname(bctbx_socket_t sockfd, struct sockaddr *addr, socklen_t *addrlen) { 138 | return pDefaultvSocket->pSocketMethods->pFuncGetSockName(sockfd, addr, addrlen); 139 | } 140 | 141 | int bctbx_getsockopt(bctbx_socket_t sockfd, int level, int optname, void *optval, socklen_t *optlen) { 142 | return pDefaultvSocket->pSocketMethods->pFuncGetSockOpt(sockfd, level, optname, optval, optlen); 143 | } 144 | 145 | int bctbx_setsockopt(bctbx_socket_t sockfd, int level, int optname, const void *optval, socklen_t optlen) { 146 | return pDefaultvSocket->pSocketMethods->pFuncSetSockOpt(sockfd, level, optname, optval, optlen); 147 | } 148 | 149 | int bctbx_shutdown(bctbx_socket_t sock, int how) { 150 | return pDefaultvSocket->pSocketMethods->pFuncShutdown(sock, how); 151 | } 152 | 153 | char *bctbx_socket_error(int err) { 154 | return pDefaultvSocket->pSocketMethods->pFuncGetError(err); 155 | } 156 | 157 | void bctbx_vsocket_api_set_default(bctbx_vsocket_api_t *my_vsocket_api) { 158 | 159 | if (my_vsocket_api == NULL) { 160 | pDefaultvSocket = &bcvSocket; 161 | } else { 162 | pDefaultvSocket = my_vsocket_api; 163 | } 164 | } 165 | 166 | bctbx_vsocket_api_t *bctbx_vsocket_api_get_default(void) { 167 | return pDefaultvSocket; 168 | } 169 | 170 | bctbx_vsocket_api_t *bctbx_vsocket_api_get_standard(void) { 171 | return &bcvSocket; 172 | } 173 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | description: File a bug/issue 4 | title: "[Bug]: " 5 | labels: ["bug"] 6 | 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: '# Reminder' 11 | - type: markdown 12 | attributes: 13 | value: | 14 | The responses are provided by the **community** and, on a **best effort** basis, by some Belledonne Communications SARL engineers working on Linphone and its related projects. 15 | The community means any people all around the world simply willing to participate to the discussions. 16 | 17 | Belledonne Communications SARL **disclaims any WARRANTY** that the content posted on github issues or mailing lists is technically correct. 18 | Responses from Belledonne Communications SARL engineers shall be considered as individual contributions and shall not be seen as Belledonne Communications's official point of view or commitment. 19 | 20 | The Github issue tracker must be seen as a place for **collaboration**. Issues submitted should be of general interest, in the goal of improving the software. Consider that a **well documented** issue (with precise reproduction procedure, logs, stack trace if relevant, possibly a corrective patch) has a higher chance to receive interest and feedback from community members and Belledonne Communications' engineers. 21 | 22 | __Issues poorly documented, with no facts, or asking for debugging assistance for a custom app using Linphone's libraries, or for a modified version of Linphone are unlikely to receive any kind of response.__ 23 | 24 | People using Linphone or its related projects within the scope of their company job are invited to contact [Belledonne Communications](https://linphone.org/contact#content-bottom3) in order to obtain commercial support. 25 | 26 | - type: markdown 27 | attributes: 28 | value: | 29 | # Well ordered issues are treated issues 30 | **In our apps, the [Linphone-SDK](https://github.com/BelledonneCommunications/linphone-sdk) is used.** 31 | Please report your issue here **ONLY** if you are sure that the origin of the error is in this module. 32 | Otherwise, open an issue in the repository of the app you are using or in the Linphone-SDK, and we will move it to the related module. 33 | 34 | - type: markdown 35 | attributes: 36 | value: | 37 | # Useful links 38 | [Linphone.org](https://linphone.org) 39 | [Linphone commercial contact](https://linphone.org/contact#content-bottom3) 40 | Linphone Vulnerability/Security contact: vulnerabilities@linphone.org 41 | [Contributor agreement (to sign and to return to sales@belledonne-communications.com for a pull request)](https://linphone.org/sites/default/files/bc-contributor-agreement_0.pdf) 42 | 43 | - type: textarea 44 | attributes: 45 | label: | 46 | Context 47 | description: | 48 | - For which purpose do you use the project ? 49 | - With which software/hardware it is integrated ? 50 | - Did you use sip.linphone.org or a different SIP service (in this case specify which one and which version) ? 51 | value: | 52 | I use this project in a custom app running on Linux with the sip.linphone.org service for my company. I want to do a simple call between an Android phone and a Linux client. There is an error with a method of this project and I'm sure that I followed the documentation and double checked before posting. 53 | validations: 54 | required: true 55 | 56 | - type: textarea 57 | attributes: 58 | label: General information 59 | description: | 60 | Complete it multiple time if there are multiple devices involved. 61 | Please note that the issue has more chances to be read if you report a bug seen in the latest version of the module. 62 | 63 | Ex: 64 | - Device: [e.g. Samsung Note 20 Ultra] 65 | - OS: [e.g. Android 11] 66 | - Version of the App [e.g. 4.3.1] 67 | - Version of the SDK [e.g 4.4.16] 68 | value: | 69 | - Device: 70 | - OS: 71 | - Version of the App: 72 | - Version of the SDK: 73 | validations: 74 | required: true 75 | 76 | - type: textarea 77 | attributes: 78 | label: Expected behaviour 79 | description: "A clear and concise description of what you expected to happen." 80 | value: | 81 | I wanted to do a simple call with the Linux client calling the Android phone. However, the phone doesn't ring when it is asleep. 82 | validations: 83 | required: true 84 | 85 | - type: textarea 86 | attributes: 87 | label: To Reproduce 88 | description: "Steps to reproduce the behavior:" 89 | value: | 90 | 1. Go to '...' 91 | 2. Click on '....' 92 | 3. Scroll down to '....' 93 | 4. See error 94 | validations: 95 | required: true 96 | 97 | - type: textarea 98 | attributes: 99 | label: 'Additional context' 100 | value: Add any other context about the problem here. 101 | 102 | - type: markdown 103 | attributes: 104 | value: | 105 | # Logs 106 | ## Module logs 107 | Enable debug logs in advanced section of the settings, restart the app, reproduce the issue and then go to About page, click on "Send logs" and copy/paste the link here. 108 | If you doesn't have such an option, just provide the logs in attachments. 109 | 110 | - type: input 111 | attributes: 112 | label: 'SDK logs URL' 113 | 114 | - type: markdown 115 | attributes: 116 | value: | 117 | ## Module crash logs 118 | In case of a crash related to this module, please also provide the backtrace of the crash in attachments using adb logcat (Android) or the device console (iOS). 119 | For desktop versions, you can get the backtrace from a core dump. 120 | 121 | - type: markdown 122 | attributes: 123 | value: | 124 | # Screenshots 125 | Please add screenshots in attachments to help us to understand your problem. 126 | 127 | - type: markdown 128 | attributes: 129 | value: | 130 | # Pcap file 131 | If this is a network issue, join a pcap file of your attempt in attachments (done with Wireshark or TCPDump, for example) 132 | -------------------------------------------------------------------------------- /include/bctoolbox/map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_MMAP_H_ 21 | #define BCTBX_MMAP_H_ 22 | #include "bctoolbox/list.h" 23 | #include "bctoolbox/port.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | typedef struct _bctbx_map_t bctbx_map_t; 30 | typedef struct _bctbx_pair_t bctbx_pair_t; 31 | typedef struct _bctbx_iterator_t bctbx_iterator_t; 32 | 33 | typedef struct _bctbx_mmap_ullong_t bctbx_mmap_ullong_t; 34 | typedef struct _bctbx_mmap_cchar_t bctbx_mmap_cchar_t; 35 | 36 | typedef void (*bctbx_map_free_func)(void *); 37 | /*map*/ 38 | BCTBX_PUBLIC bctbx_map_t *bctbx_mmap_ullong_new(void); 39 | BCTBX_PUBLIC bctbx_map_t *bctbx_mmap_cchar_new(void); 40 | BCTBX_PUBLIC void bctbx_mmap_ullong_delete(bctbx_map_t *mmap); 41 | BCTBX_PUBLIC void bctbx_mmap_cchar_delete(bctbx_map_t *mmap); 42 | BCTBX_PUBLIC void bctbx_mmap_ullong_delete_with_data(bctbx_map_t *mmap, bctbx_map_free_func freefunc); 43 | BCTBX_PUBLIC void bctbx_mmap_cchar_delete_with_data(bctbx_map_t *mmap, bctbx_map_free_func freefunc); 44 | #define bctbx_map_insert bctbx_map_ullong_insert 45 | BCTBX_PUBLIC void bctbx_map_ullong_insert(bctbx_map_t *map, const bctbx_pair_t *pair); 46 | BCTBX_PUBLIC void bctbx_map_cchar_insert(bctbx_map_t *map, const bctbx_pair_t *pair); 47 | /*same as insert, but also deleting pair*/ 48 | #define bctbx_map_insert_and_delete bctbx_map_ullong_insert_and_delete 49 | BCTBX_PUBLIC void bctbx_map_ullong_insert_and_delete(bctbx_map_t *map, bctbx_pair_t *pair); 50 | BCTBX_PUBLIC void bctbx_map_cchar_insert_and_delete(bctbx_map_t *map, bctbx_pair_t *pair); 51 | /*same as insert and deleting pair with a newly allocated it returned */ 52 | #define bctbx_map_insert_and_delete_with_returned_it bctbx_map_ullong_insert_and_delete_with_returned_it 53 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_ullong_insert_and_delete_with_returned_it(bctbx_map_t *map, 54 | bctbx_pair_t *pair); 55 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_cchar_insert_and_delete_with_returned_it(bctbx_map_t *map, bctbx_pair_t *pair); 56 | /*at return, it point to the next element*/ 57 | #define bctbx_map_erase bctbx_map_ullong_erase 58 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_ullong_erase(bctbx_map_t *map, bctbx_iterator_t *it); 59 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_cchar_erase(bctbx_map_t *map, bctbx_iterator_t *it); 60 | /*return a new allocated iterator*/ 61 | #define bctbx_map_begin bctbx_map_ullong_begin 62 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_ullong_begin(const bctbx_map_t *map); 63 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_cchar_begin(const bctbx_map_t *map); 64 | /*return a new allocated iterator*/ 65 | #define bctbx_map_end bctbx_map_ullong_end 66 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_ullong_end(const bctbx_map_t *map); 67 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_cchar_end(const bctbx_map_t *map); 68 | /*return a new allocated iterator or null*/ 69 | #define bctbx_map_find_custom bctbx_map_ullong_find_custom 70 | BCTBX_PUBLIC bctbx_iterator_t * 71 | bctbx_map_ullong_find_custom(const bctbx_map_t *map, bctbx_compare_func compare_func, const void *user_data); 72 | BCTBX_PUBLIC bctbx_iterator_t * 73 | bctbx_map_cchar_find_custom(const bctbx_map_t *map, bctbx_compare_func compare_func, const void *user_data); 74 | /*return the iterator associated to the key in the map or Null*/ 75 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_ullong_find_key(const bctbx_map_t *map, unsigned long long key); 76 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_map_cchar_find_key(const bctbx_map_t *map, const char *key); 77 | /* return the size of the map*/ 78 | #define bctbx_map_size bctbx_map_ullong_size 79 | BCTBX_PUBLIC size_t bctbx_map_ullong_size(const bctbx_map_t *map); 80 | BCTBX_PUBLIC size_t bctbx_map_cchar_size(const bctbx_map_t *map); 81 | 82 | /*iterator*/ 83 | #define bctbx_iterator_get_pair bctbx_iterator_ullong_get_pair 84 | BCTBX_PUBLIC bctbx_pair_t *bctbx_iterator_ullong_get_pair(const bctbx_iterator_t *it); 85 | BCTBX_PUBLIC bctbx_pair_t *bctbx_iterator_cchar_get_pair(const bctbx_iterator_t *it); 86 | /*return same pointer but pointing to next*/ 87 | #define bctbx_iterator_get_next bctbx_iterator_ullong_get_next 88 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_iterator_ullong_get_next(bctbx_iterator_t *it); 89 | BCTBX_PUBLIC bctbx_iterator_t *bctbx_iterator_cchar_get_next(bctbx_iterator_t *it); 90 | #define bctbx_iterator_equals bctbx_iterator_ullong_equals 91 | BCTBX_PUBLIC bool_t bctbx_iterator_ullong_equals(const bctbx_iterator_t *a, const bctbx_iterator_t *b); 92 | BCTBX_PUBLIC bool_t bctbx_iterator_cchar_equals(const bctbx_iterator_t *a, const bctbx_iterator_t *b); 93 | #define bctbx_iterator_delete bctbx_iterator_ullong_delete 94 | BCTBX_PUBLIC void bctbx_iterator_ullong_delete(bctbx_iterator_t *it); 95 | BCTBX_PUBLIC void bctbx_iterator_cchar_delete(bctbx_iterator_t *it); 96 | 97 | /*pair*/ 98 | typedef struct _bctbx_pair_ullong_t bctbx_pair_ullong_t; /*inherit from bctbx_pair_t*/ 99 | BCTBX_PUBLIC bctbx_pair_ullong_t *bctbx_pair_ullong_new(unsigned long long key, void *value); 100 | typedef struct _bctbx_pair_cchar_t bctbx_pair_cchar_t; /*inherit from bctbx_pair_t*/ 101 | BCTBX_PUBLIC bctbx_pair_cchar_t *bctbx_pair_cchar_new(const char *key, void *value); 102 | 103 | #define bctbx_pair_get_second bctbx_pair_ullong_get_second 104 | BCTBX_PUBLIC void *bctbx_pair_ullong_get_second(const bctbx_pair_t *pair); 105 | BCTBX_PUBLIC void *bctbx_pair_cchar_get_second(const bctbx_pair_t *pair); 106 | BCTBX_PUBLIC unsigned long long bctbx_pair_ullong_get_first(const bctbx_pair_ullong_t *pair); 107 | BCTBX_PUBLIC const char *bctbx_pair_cchar_get_first(const bctbx_pair_cchar_t *pair); 108 | #define bctbx_pair_delete bctbx_pair_ullong_delete 109 | BCTBX_PUBLIC void bctbx_pair_ullong_delete(bctbx_pair_t *pair); 110 | BCTBX_PUBLIC void bctbx_pair_cchar_delete(bctbx_pair_t *pair); 111 | 112 | #ifdef __cplusplus 113 | } 114 | #endif 115 | 116 | #endif /* BCTBX_LIST_H_ */ 117 | -------------------------------------------------------------------------------- /src/conversion/charconv_windows.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include 25 | #include 26 | 27 | #include "bctoolbox/charconv.h" 28 | #include "bctoolbox/logging.h" 29 | #include "bctoolbox/port.h" 30 | 31 | static std::unordered_map windowsCharset{ 32 | {"LOCALE", CP_ACP}, {"IBM037", 037}, {"IBM437", 437}, {"IBM500", 500}, 33 | {"ASMO-708", 708}, {"IBM775", 775}, {"IBM850", 850}, {"IBM852", 852}, 34 | {"IBM855", 855}, {"IBM857", 857}, {"IBM860", 860}, {"IBM861", 861}, 35 | {"IBM863", 863}, {"IBM864", 864}, {"IBM865", 865}, {"CP866", 866}, 36 | {"IBM869", 869}, {"IBM870", 870}, {"WINDOWS-874", 874}, {"CP875", 875}, 37 | {"SHIFT_JIS", 932}, {"GB2312", 936}, {"BIG5", 950}, {"IBM1026", 1026}, 38 | {"UTF-16", 1200}, {"WINDOWS-1250", 1250}, {"WINDOWS-1251", 1251}, {"WINDOWS-1252", 1252}, 39 | {"WINDOWS-1253", 1253}, {"WINDOWS-1254", 1254}, {"WINDOWS-1255", 1255}, {"WINDOWS-1256", 1256}, 40 | {"WINDOWS-1257", 1257}, {"WINDOWS-1258", 1258}, {"JOHAB", 1361}, {"MACINTOSH", 10000}, 41 | {"UTF-32", 12000}, {"UTF-32BE", 12001}, {"US-ASCII", 20127}, {"IBM273", 20273}, 42 | {"IBM277", 20277}, {"IBM278", 20278}, {"IBM280", 20280}, {"IBM284", 20284}, 43 | {"IBM285", 20285}, {"IBM290", 20290}, {"IBM297", 20297}, {"IBM420", 20420}, 44 | {"IBM423", 20423}, {"IBM424", 20424}, {"KOI8-R", 20866}, {"IBM871", 20871}, 45 | {"IBM880", 20880}, {"IBM905", 20905}, {"EUC-JP", 20932}, {"CP1025", 21025}, 46 | {"KOI8-U", 21866}, {"ISO-8859-1", 28591}, {"ISO-8859-2", 28592}, {"ISO-8859-3", 28593}, 47 | {"ISO-8859-4", 28594}, {"ISO-8859-5", 28595}, {"ISO-8859-6", 28596}, {"ISO-8859-7", 28597}, 48 | {"ISO-8859-8", 28598}, {"ISO-8859-9", 28599}, {"ISO-8859-13", 28603}, {"ISO-8859-15", 28605}, 49 | {"ISO-2022-JP", 50222}, {"CSISO2022JP", 50221}, {"ISO-2022-KR", 50225}, {"EUC-JP", 51932}, 50 | {"EUC-CN", 51936}, {"EUC-KR", 51949}, {"GB18030", 54936}, {"UTF-7", 65000}, 51 | {"UTF-8", 65001}, {"UTF7", 65000}, {"UTF8", 65001}, {"UTF16", 1200}, 52 | {"UTF32", 12000}, {"UTF32BE", 12001}}; 53 | 54 | static std::string stringToUpper(const std::string &str) { 55 | std::string result(str.size(), ' '); 56 | std::transform(str.cbegin(), str.cend(), result.begin(), ::toupper); 57 | return result; 58 | } 59 | 60 | static char *convertFromTo(const char *str, const char *from, const char *to) { 61 | if (!from || !to) return NULL; 62 | 63 | if (strcasecmp(from, to) == 0) return bctbx_strdup(str); 64 | 65 | char *convertedStr; 66 | int nChar, nbByte; 67 | LPWSTR wideStr; 68 | UINT rFrom, rTo; 69 | 70 | try { 71 | rFrom = bctbx_get_code_page(from); 72 | rTo = bctbx_get_code_page(to); 73 | } catch (const std::out_of_range &) { 74 | bctbx_error("Error while converting a string from '%s' to '%s': unknown charset", from, to); 75 | return NULL; 76 | } 77 | if (rFrom == rTo) return bctbx_strdup(str); 78 | 79 | nChar = MultiByteToWideChar(rFrom, 0, str, -1, NULL, 0); 80 | if (nChar == 0) return NULL; 81 | wideStr = (LPWSTR)bctbx_malloc(nChar * sizeof(wideStr[0])); 82 | if (wideStr == NULL) return NULL; 83 | nChar = MultiByteToWideChar(rFrom, 0, str, -1, wideStr, nChar); 84 | if (nChar == 0) { 85 | bctbx_free(wideStr); 86 | wideStr = 0; 87 | return NULL; 88 | } 89 | 90 | nbByte = WideCharToMultiByte(rTo, 0, wideStr, -1, 0, 0, 0, 0); 91 | if (nbByte == 0) return NULL; 92 | convertedStr = (char *)bctbx_malloc(nbByte); 93 | if (convertedStr == NULL) return NULL; 94 | nbByte = WideCharToMultiByte(rTo, 0, wideStr, -1, convertedStr, nbByte, 0, 0); 95 | if (nbByte == 0) { 96 | bctbx_free(convertedStr); 97 | convertedStr = 0; 98 | } 99 | bctbx_free(wideStr); 100 | return convertedStr; 101 | } 102 | 103 | char *bctbx_locale_to_utf8(const char *str) { 104 | const char *defaultEncoding = bctbx_get_default_encoding(); 105 | 106 | if (!strcmp(defaultEncoding, "UTF-8")) return bctbx_strdup(str); 107 | 108 | return convertFromTo(str, defaultEncoding, "UTF-8"); 109 | } 110 | 111 | char *bctbx_utf8_to_locale(const char *str) { 112 | const char *defaultEncoding = bctbx_get_default_encoding(); 113 | 114 | if (!strcmp(defaultEncoding, "UTF-8")) return bctbx_strdup(str); 115 | 116 | return convertFromTo(str, "UTF-8", defaultEncoding); 117 | } 118 | 119 | char *bctbx_convert_any_to_utf8(const char *str, const char *encoding) { 120 | return convertFromTo(str, (encoding ? encoding : "LOCALE"), "UTF-8"); 121 | } 122 | 123 | char *bctbx_convert_utf8_to_any(const char *str, const char *encoding) { 124 | return convertFromTo(str, "UTF-8", (encoding ? encoding : "LOCALE")); 125 | } 126 | 127 | char *bctbx_convert_string(const char *str, const char *from_encoding, const char *to_encoding) { 128 | if ((from_encoding && to_encoding && !strcmp(from_encoding, to_encoding)) || (!from_encoding && !to_encoding)) 129 | return bctbx_strdup(str); 130 | return convertFromTo(str, (from_encoding ? from_encoding : "LOCALE"), (to_encoding ? to_encoding : "LOCALE")); 131 | } 132 | 133 | unsigned int bctbx_get_code_page(const char *encoding) { 134 | unsigned int codePage = CP_ACP; 135 | std::string encodingStr; 136 | if (!encoding || encoding[0] == '\0') encodingStr = stringToUpper(bctbx_get_default_encoding()); 137 | else encodingStr = stringToUpper(encoding); 138 | if (encodingStr == "LOCALE") { 139 | char *locale = setlocale(LC_CTYPE, NULL); 140 | if (strstr(locale, ".") != NULL) { 141 | // return codeset (last block of chars preceeded by a dot) 142 | encodingStr = stringToUpper(strrchr(locale, '.') + 1); 143 | } 144 | } 145 | try { 146 | codePage = windowsCharset.at(encodingStr); 147 | } catch (const std::out_of_range &) { 148 | bctbx_error("No code page found for '%s'. Using Locale.", encodingStr.c_str()); 149 | return CP_ACP; 150 | } 151 | return codePage; 152 | } 153 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # CMakeLists.txt 3 | # Copyright (C) 2010-2021 Belledonne Communications, Grenoble France 4 | # 5 | ############################################################################ 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU General Public License 9 | # as published by the Free Software Foundation; either version 2 10 | # of the License, or (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | # 21 | ############################################################################ 22 | 23 | cmake_minimum_required(VERSION 3.22) 24 | 25 | project(BCToolbox VERSION 5.5.0) 26 | 27 | set(BCTOOLBOX_VERSION "${PROJECT_VERSION}") 28 | set(BCTOOLBOX_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) 29 | set(BCTOOLBOX_VERSION_MINOR ${PROJECT_VERSION_MINOR}) 30 | set(BCTOOLBOX_VERSION_PATCH ${PROJECT_VERSION_PATCH}) 31 | set(BCTOOLBOX_SO_VERSION 1) 32 | set(BCTOOLBOXTESTER_SO_VERSION 1) 33 | 34 | 35 | option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO) 36 | option(ENABLE_MBEDTLS "Enable mbedtls support" ON) 37 | option(ENABLE_OPENSSL "Enable openssl support" OFF) 38 | option(ENABLE_DECAF "Enable Elliptic Curve Cryptography support" ON) 39 | option(ENABLE_STRICT "Pass strict flags to the compiler" ON) 40 | option(ENABLE_TESTS_COMPONENT "Enable compilation of tests helper library" ON) 41 | option(ENABLE_UNIT_TESTS "Enable compilation of tests" ON) 42 | option(ENABLE_PACKAGE_SOURCE "Create 'package_source' target for source archive making" OFF) 43 | option(ENABLE_DEFAULT_LOG_HANDLER "A default log handler will be initialized, if OFF no logging will be done before you initialize one." ON) 44 | 45 | 46 | set(CMAKE_CXX_STANDARD 17) 47 | set(CMAKE_CXX_EXTENSIONS NO) 48 | 49 | include(CheckLibraryExists) 50 | include(CheckSymbolExists) 51 | include(CheckCSourceCompiles) 52 | include(CMakePushCheckState) 53 | include(GNUInstallDirs) 54 | include("cmake/BCToolboxCMakeUtils.cmake") 55 | 56 | list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") 57 | 58 | if(ENABLE_MBEDTLS AND ENABLE_OPENSSL) 59 | message(FATAL_ERROR "Cannot build bctoolbox with both openssl and mbedtls enabled") 60 | endif() 61 | 62 | if(NOT CPACK_GENERATOR AND NOT CMAKE_INSTALL_RPATH AND CMAKE_INSTALL_PREFIX) 63 | set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}) 64 | message(STATUS "Setting install rpath to ${CMAKE_INSTALL_RPATH}") 65 | endif() 66 | 67 | if(APPLE) 68 | find_package(Iconv REQUIRED) 69 | endif() 70 | 71 | if(ENABLE_MBEDTLS) 72 | message(STATUS "MBEDTLS Enabled") 73 | find_package(MbedTLS) 74 | if(MbedTLS_FOUND) 75 | message(STATUS "Found mbedTLS v${MbedTLS_VERSION}") 76 | if(MbedTLS_VERSION LESS 3) 77 | message(FATAL_ERROR "Mbedtls version incompatible (requires v3)") 78 | endif() 79 | set(HAVE_MBEDTLS 1) 80 | endif() 81 | endif() 82 | 83 | if(ENABLE_OPENSSL) 84 | message(STATUS "OPENSSL Enabled") 85 | find_package(OpenSSL) 86 | if(OPENSSL_FOUND) 87 | message(STATUS "Using OPENSSL v. ${OPENSSL_VERSION}") 88 | set(HAVE_OPENSSL 1) 89 | set(DTLS_SRTP_AVAILABLE TRUE) 90 | endif() 91 | endif() 92 | 93 | if(ENABLE_DECAF) 94 | find_package(Decaf) 95 | if(Decaf_FOUND) 96 | message(STATUS "Using Decaf") 97 | set(HAVE_DECAF 1) 98 | endif() 99 | endif() 100 | 101 | if(DTLS_SRTP_AVAILABLE) 102 | message(STATUS "DTLS SRTP available") 103 | set(HAVE_DTLS_SRTP 1) 104 | else() 105 | message(STATUS "DTLS SRTP not available") 106 | endif() 107 | 108 | if(ENABLE_TESTS_COMPONENT) 109 | find_package(BCUnit 3.0.2 REQUIRED) 110 | set(TESTER_REQUIRES_PRIVATE "${BCUnit_TARGET}") 111 | endif() 112 | 113 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/bctoolbox.pc.in ${CMAKE_CURRENT_BINARY_DIR}/bctoolbox.pc) 114 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bctoolbox.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) 115 | 116 | if(ENABLE_TESTS_COMPONENT) 117 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/bctoolbox-tester.pc.in ${CMAKE_CURRENT_BINARY_DIR}/bctoolbox-tester.pc) 118 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bctoolbox-tester.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) 119 | endif() 120 | 121 | find_package(Threads REQUIRED) 122 | 123 | include_directories( 124 | include 125 | src 126 | ${CMAKE_CURRENT_BINARY_DIR} 127 | ) 128 | 129 | if(ENABLE_DEBUG_LOGS) 130 | add_definitions("-DBCTBX_DEBUG_MODE") 131 | endif() 132 | 133 | bc_init_compilation_flags(STRICT_OPTIONS_CPP STRICT_OPTIONS_C STRICT_OPTIONS_CXX ENABLE_STRICT) 134 | 135 | check_library_exists("rt" "clock_gettime" "" HAVE_LIBRT) 136 | check_library_exists("dl" "dladdr" "" HAVE_LIBDL) 137 | 138 | if(ANDROID) 139 | set(HAVE_EXECINFO 0) 140 | else() 141 | check_include_file("execinfo.h" HAVE_EXECINFO) 142 | endif() 143 | 144 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/config.h") 145 | set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/config.h" PROPERTIES GENERATED ON) 146 | add_definitions("-DHAVE_CONFIG_H") 147 | 148 | add_subdirectory(include) 149 | add_subdirectory(src) 150 | if(ENABLE_UNIT_TESTS AND ENABLE_TESTS_COMPONENT) 151 | add_subdirectory(tester) 152 | endif() 153 | if(ENABLE_PACKAGE_SOURCE) 154 | add_subdirectory(build) 155 | endif() 156 | 157 | include(CMakePackageConfigHelpers) 158 | set(CMAKE_MODULES_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake") 159 | configure_package_config_file("cmake/${PROJECT_NAME}Config.cmake.in" "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 160 | INSTALL_DESTINATION "${CMAKE_MODULES_INSTALL_DIR}" 161 | PATH_VARS CMAKE_MODULES_INSTALL_DIR 162 | ) 163 | write_basic_package_version_file("${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 164 | VERSION ${PROJECT_VERSION} 165 | COMPATIBILITY AnyNewerVersion 166 | ) 167 | 168 | configure_file("cmake/BCToolboxCMakeUtils.cmake" "${CMAKE_CURRENT_BINARY_DIR}/BCToolboxCMakeUtils.cmake" COPYONLY) 169 | configure_file("cmake/BCGitVersion.cmake" "${CMAKE_CURRENT_BINARY_DIR}/BCGitVersion.cmake" COPYONLY) 170 | configure_file("cmake/gitversion.h.in" "${CMAKE_CURRENT_BINARY_DIR}/gitversion.h.in" COPYONLY) 171 | 172 | install(EXPORT ${PROJECT_NAME}Targets 173 | FILE "${PROJECT_NAME}Targets.cmake" 174 | DESTINATION ${CMAKE_MODULES_INSTALL_DIR} 175 | ) 176 | 177 | install(FILES 178 | "cmake/MakeArchive.cmake" 179 | "cmake/ConfigureSpecfile.cmake" 180 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 181 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 182 | "${CMAKE_CURRENT_BINARY_DIR}/BCToolboxCMakeUtils.cmake" 183 | "${CMAKE_CURRENT_BINARY_DIR}/BCGitVersion.cmake" 184 | "${CMAKE_CURRENT_BINARY_DIR}/gitversion.h.in" 185 | DESTINATION ${CMAKE_MODULES_INSTALL_DIR} 186 | ) 187 | 188 | if(MbedTLS_FOUND) 189 | install(FILES "cmake/FindMbedTLS.cmake" DESTINATION ${CMAKE_MODULES_INSTALL_DIR}) 190 | endif() 191 | if(Decaf_FOUND) 192 | install(FILES "cmake/FindDecaf.cmake" DESTINATION ${CMAKE_MODULES_INSTALL_DIR}) 193 | endif() 194 | -------------------------------------------------------------------------------- /include/bctoolbox/vconnect.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_VCONNECT 21 | #define BCTBX_VCONNECT 22 | 23 | #include 24 | 25 | #include 26 | 27 | #if !defined(_WIN32_WCE) 28 | #include 29 | #include 30 | #if _MSC_VER 31 | #include 32 | #endif 33 | #endif /*_WIN32_WCE*/ 34 | 35 | #ifndef _WIN32 36 | #include 37 | #endif 38 | 39 | #define BCTBX_VCONNECT_OK 0 /* Successful result */ 40 | 41 | #define BCTBX_VCONNECT_ERROR -255 /* Some kind of socket error occurred */ 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | /** 48 | * Methods associated with the bctbx_vsocket_api_t. 49 | */ 50 | typedef struct bctbx_vsocket_methods_t bctbx_vsocket_methods_t; 51 | 52 | /** 53 | * Methods pointer prototypes for the socket functions. 54 | */ 55 | struct bctbx_vsocket_methods_t { 56 | 57 | bctbx_socket_t (*pFuncSocket)(int socket_family, int socket_type, int protocol); 58 | int (*pFuncConnect)(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len); 59 | int (*pFuncBind)(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len); 60 | 61 | int (*pFuncGetSockName)(bctbx_socket_t sockfd, struct sockaddr *addr, socklen_t *addrlen); 62 | int (*pFuncGetSockOpt)(bctbx_socket_t sockfd, int level, int optname, void *optval, socklen_t *optlen); 63 | int (*pFuncSetSockOpt)(bctbx_socket_t sockfd, int level, int optname, const void *optval, socklen_t optlen); 64 | int (*pFuncClose)(bctbx_socket_t sock); 65 | char *(*pFuncGetError)(int err); 66 | int (*pFuncShutdown)(bctbx_socket_t sock, int how); 67 | }; 68 | 69 | /** 70 | * Socket API structure definition 71 | */ 72 | typedef struct bctbx_vsocket_api_t bctbx_vsocket_api_t; 73 | struct bctbx_vsocket_api_t { 74 | const char *vSockName; /* Socket API name */ 75 | const bctbx_vsocket_methods_t *pSocketMethods; /* Pointer to the socket methods structure */ 76 | }; 77 | 78 | /**=================================================== 79 | * Socket API methods prototypes. 80 | * The default implementation relies on libc methods. 81 | *====================================================*/ 82 | 83 | /** 84 | * Creates a socket. 85 | * @param socket_family type of address structure 86 | * @param socket_type socket type i.e SOCK_STREAM 87 | * @param protocol protocol family i.e AF_INET 88 | * @return Returns a socket file descriptor. 89 | */ 90 | BCTBX_PUBLIC bctbx_socket_t bctbx_socket(int socket_family, int socket_type, int protocol); 91 | 92 | /** 93 | * Get the local socket address. 94 | * Calls the function pointer pFuncGetSockName. The default method associated with this pointer 95 | * is getsockname. 96 | * @param sockfd socket descriptor 97 | * @param addr buffer holding the current address to which the socket sockfd is bound 98 | * @param addrlen amount of space (in bytes) pointed to by addr 99 | * @return On success, zero is returned. On error, -1 is returned, and errno is 100 | * set appropriately. 101 | */ 102 | BCTBX_PUBLIC int bctbx_getsockname(bctbx_socket_t sockfd, struct sockaddr *addr, socklen_t *addrlen); 103 | /** 104 | * Get socket options. 105 | * @param sockfd socket file descriptor 106 | * @param level level of the socket option 107 | * @param optname name of the option 108 | * @param optval buffer in which the value for the requested option(s) are to be returned 109 | * @param optlen contains the size of the buffer pointed to by optval, and on return 110 | * contains the actual size of the value returned. 111 | * @return On success, zero is returned. On error, -1 is returned, and errno is 112 | * set appropriately. 113 | */ 114 | BCTBX_PUBLIC int bctbx_getsockopt(bctbx_socket_t sockfd, int level, int optname, void *optval, socklen_t *optlen); 115 | /** 116 | * Set socket options. 117 | * @param sockfd socket file descriptor 118 | * @param level level of the socket option 119 | * @param optname name of the option 120 | * @param optval buffer holding the value for the requested option 121 | * @param optlen contains the size of the buffer pointed to by optval 122 | * @return On success, zero is returned. On error, -1 is returned, and errno is 123 | * set appropriately. 124 | */ 125 | BCTBX_PUBLIC int bctbx_setsockopt(bctbx_socket_t sockfd, int level, int optname, const void *optval, socklen_t optlen); 126 | 127 | /** 128 | * Shut down part of a full duplex connection. 129 | * @param sockfd socket file descriptor 130 | * @param how specifies what is shut down in the connection. 131 | * @return On success, zero is returned. On error, -1 is returned, and errno is 132 | * set appropriately. 133 | */ 134 | BCTBX_PUBLIC int bctbx_shutdown(bctbx_socket_t sockfd, int how); 135 | 136 | /** 137 | * Close a socket file descriptor. 138 | * @param sockfd socket file descriptor 139 | * @return 0 on success , -1 on error and errno is set. 140 | */ 141 | BCTBX_PUBLIC int bctbx_socket_close(bctbx_socket_t sockfd); 142 | 143 | /** 144 | * Assign a name to a socket. 145 | * @param sockfd socket file descriptor to assign the name to. 146 | * @param address address of the socket 147 | * @param address_len size of the address structure pointed to by address (bytes) 148 | * @return On success, zero is returned. On error, -1 is returned, and errno is 149 | * set appropriately. 150 | */ 151 | BCTBX_PUBLIC int bctbx_bind(bctbx_socket_t sockfd, const struct sockaddr *address, socklen_t address_len); 152 | 153 | /** 154 | * Initialize a connection to a socket. 155 | * @param sockfd socket file descriptor 156 | * @param address address of the socket 157 | * @param address_len size of the address structure pointed to by address (bytes) 158 | * @return On success, zero is returned. On error, -1 is returned, and errno is 159 | * set appropriately. 160 | */ 161 | BCTBX_PUBLIC int bctbx_connect(bctbx_socket_t sockfd, const struct sockaddr *address, socklen_t address_len); 162 | 163 | /** 164 | * strerror equivalent. 165 | * When an error is returned on a socket operations, returns 166 | * the error description based on err (errno) value. 167 | * @param err should be set to errno 168 | * @return Error description 169 | */ 170 | BCTBX_PUBLIC char *bctbx_socket_error(int err); 171 | 172 | /** 173 | * Set default bctbx_vsocket_api_t pointer pDefaultvSocket to my_vsocket_api 174 | * if it is not NULL, sets it to the standard API implementation otherwise. 175 | * By default, the global pointer is set to use bcvSocket implemented in vconnect.c 176 | * @param my_vsocket_api Pointer to a bctbx_vsocket_api_t structure. 177 | */ 178 | BCTBX_PUBLIC void bctbx_vsocket_api_set_default(bctbx_vsocket_api_t *my_vsocket_api); 179 | 180 | /** 181 | * Returns the value of the global variable pDefaultvSocket, 182 | * pointing to the default bctbx_vsocket_api_t used. 183 | * @return Pointer to bctbx_vsocket_api_t set to operate as default. 184 | */ 185 | BCTBX_PUBLIC bctbx_vsocket_api_t *bctbx_vsocket_api_get_default(void); 186 | 187 | /** 188 | * Return pointer to standard bctbx_vsocket_api_t implementation based on libc 189 | * functions. 190 | * @return pointer to bcSocketAPI 191 | */ 192 | BCTBX_PUBLIC bctbx_vsocket_api_t *bctbx_vsocket_api_get_standard(void); 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | #endif /* BCTBX_VCONNECT */ 199 | -------------------------------------------------------------------------------- /src/vfs/vfs_standard.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include "bctoolbox/defs.h" 25 | #include "bctoolbox/logging.h" 26 | #include "bctoolbox/port.h" 27 | #include "bctoolbox/vfs.h" 28 | #include 29 | #include 30 | #include 31 | 32 | /** 33 | * Opens the file with filename fName, associate it to the file handle pointed 34 | * by pFile, sets the methods bctbx_io_methods_t to the bcio structure 35 | * and initializes the file size. 36 | * Sets the error in pErrSvd if an error occurred while opening the file fName. 37 | * @param pVfs Pointer to bctx_vfs VFS. 38 | * @param fName Absolute path filename. 39 | * @param openFlags Flags to use when opening the file. 40 | * @return BCTBX_VFS_ERROR if an error occurs, BCTBX_VFS_OK otherwise. 41 | */ 42 | static int bcOpen(bctbx_vfs_t *pVfs, bctbx_vfs_file_t *pFile, const char *fName, int openFlags); 43 | 44 | /* User data for the standard vfs */ 45 | typedef struct bctbx_vfs_standard_t bctbx_vfs_standard_t; 46 | struct bctbx_vfs_standard_t { 47 | int fd; /* File descriptor */ 48 | }; 49 | 50 | bctbx_vfs_t bcStandardVfs = { 51 | "bctbx_vfs", /* vfsName */ 52 | bcOpen, /*xOpen */ 53 | }; 54 | 55 | /** 56 | * Closes file by closing the associated file descriptor. 57 | * Sets the error errno in the argument pErrSrvd after allocating it 58 | * if an error occurrred. 59 | * @param pFile bctbx_vfs_file_t File handle pointer. 60 | * @return BCTBX_VFS_OK if successful, BCTBX_VFS_ERROR otherwise. 61 | */ 62 | static int bcClose(bctbx_vfs_file_t *pFile) { 63 | int ret; 64 | if (pFile == NULL || pFile->pUserData == NULL) return BCTBX_VFS_ERROR; 65 | bctbx_vfs_standard_t *ctx = (bctbx_vfs_standard_t *)pFile->pUserData; 66 | ret = close(ctx->fd); 67 | if (!ret) { 68 | ret = BCTBX_VFS_OK; 69 | } else { 70 | ret = -errno; 71 | } 72 | bctbx_free(pFile->pUserData); 73 | return ret; 74 | } 75 | 76 | /** 77 | * Simply sync the file contents given through the file handle 78 | * to the persistent media. 79 | * @param pFile File handle pointer. 80 | * @return BCTBX_VFS_OK on success, BCTBX_VFS_ERROR otherwise 81 | */ 82 | static int bcSync(bctbx_vfs_file_t *pFile) { 83 | if (pFile == NULL || pFile->pUserData == NULL) return BCTBX_VFS_ERROR; 84 | bctbx_vfs_standard_t *ctx = (bctbx_vfs_standard_t *)pFile->pUserData; 85 | #if _WIN32 86 | int ret; 87 | ret = FlushFileBuffers((HANDLE)_get_osfhandle(ctx->fd)); 88 | return (ret != 0 ? BCTBX_VFS_OK : BCTBX_VFS_ERROR); 89 | #else 90 | int rc = fsync(ctx->fd); 91 | return (rc == 0 ? BCTBX_VFS_OK : BCTBX_VFS_ERROR); 92 | #endif 93 | } 94 | 95 | /** 96 | * Read count bytes from the open file given by pFile, starting at offset. 97 | * Sets the error errno in the argument pErrSrvd after allocating it 98 | * if an error occurrred. 99 | * @param pFile File handle pointer. 100 | * @param buf buffer to write the read bytes to. 101 | * @param count number of bytes to read 102 | * @param offset file offset where to start reading 103 | * @return -errno if erroneous read, number of bytes read (count) on success, 104 | * if the error was something else BCTBX_VFS_ERROR otherwise 105 | */ 106 | static ssize_t bcRead(bctbx_vfs_file_t *pFile, void *buf, size_t count, off_t offset) { 107 | ssize_t nRead; /* Return value from read() */ 108 | if (pFile == NULL || pFile->pUserData == NULL) return BCTBX_VFS_ERROR; 109 | bctbx_vfs_standard_t *ctx = (bctbx_vfs_standard_t *)pFile->pUserData; 110 | 111 | if (lseek(ctx->fd, offset, SEEK_SET) < 0) { 112 | if (errno) return -errno; 113 | } else { 114 | nRead = bctbx_read(ctx->fd, buf, count); 115 | /* Error while reading */ 116 | if (nRead < 0) { 117 | if (errno) return -errno; 118 | } 119 | return nRead; 120 | } 121 | return BCTBX_VFS_ERROR; 122 | } 123 | 124 | /** 125 | * Writes directly to the open file given through the pFile argument. 126 | * Sets the error errno in the argument pErrSrvd after allocating it 127 | * if an error occurrred. 128 | * @param pFile bctbx_vfs_file_t File handle pointer. 129 | * @param buf Buffer containing data to write 130 | * @param count Size of data to write in bytes 131 | * @param offset File offset where to write to 132 | * @return number of bytes written (can be 0), negative value errno if an error occurred. 133 | */ 134 | static ssize_t bcWrite(bctbx_vfs_file_t *pFile, const void *buf, size_t count, off_t offset) { 135 | ssize_t nWrite = 0; /* Return value from write() */ 136 | 137 | if (pFile == NULL || pFile->pUserData == NULL) return BCTBX_VFS_ERROR; 138 | bctbx_vfs_standard_t *ctx = (bctbx_vfs_standard_t *)pFile->pUserData; 139 | 140 | if ((lseek(ctx->fd, offset, SEEK_SET)) < 0) { 141 | if (errno) return -errno; 142 | } else { 143 | nWrite = bctbx_write(ctx->fd, buf, count); 144 | if (nWrite >= 0) return nWrite; 145 | else if (nWrite == (ssize_t)-1) { 146 | if (errno) return -errno; 147 | return 0; 148 | } 149 | } 150 | return BCTBX_VFS_ERROR; 151 | } 152 | 153 | /** 154 | * Returns the file size associated with the file handle pFile. 155 | * @param pFile File handle pointer. 156 | * @return -errno if an error occurred, file size otherwise (can be 0). 157 | */ 158 | static ssize_t bcFileSize(bctbx_vfs_file_t *pFile) { 159 | int rc; /* Return code from fstat() call */ 160 | struct stat sStat; /* Output of fstat() call */ 161 | if (pFile == NULL || pFile->pUserData == NULL) return BCTBX_VFS_ERROR; 162 | bctbx_vfs_standard_t *ctx = (bctbx_vfs_standard_t *)pFile->pUserData; 163 | 164 | rc = fstat(ctx->fd, &sStat); 165 | if (rc != 0) { 166 | return -errno; 167 | } 168 | return (ssize_t)sStat.st_size; 169 | } 170 | 171 | /* 172 | ** Truncate a file 173 | * @param pFile File handle pointer. 174 | * @param new_size Extends the file with null bytes if it is superiori to the file's size 175 | * truncates the file otherwise. 176 | * @return -errno if an error occurred, 0 otherwise. 177 | */ 178 | static int bcTruncate(bctbx_vfs_file_t *pFile, int64_t new_size) { 179 | 180 | int ret; 181 | if (pFile == NULL || pFile->pUserData == NULL) return BCTBX_VFS_ERROR; 182 | bctbx_vfs_standard_t *ctx = (bctbx_vfs_standard_t *)pFile->pUserData; 183 | 184 | #if _WIN32 185 | ret = _chsize(ctx->fd, (long)new_size); 186 | #else 187 | ret = ftruncate(ctx->fd, new_size); 188 | #endif 189 | 190 | if (ret < 0) { 191 | return -errno; 192 | } 193 | return 0; 194 | } 195 | 196 | static const bctbx_io_methods_t bcio = { 197 | bcClose, /* pFuncClose */ 198 | bcRead, /* pFuncRead */ 199 | bcWrite, /* pFuncWrite */ 200 | bcTruncate, /* pFuncTruncate */ 201 | bcFileSize, /* pFuncFileSize */ 202 | bcSync, NULL, /* use the generic implementation of getnxt line */ 203 | NULL /* pFuncIsEncrypted -> no function so we will return false */ 204 | }; 205 | 206 | static int bcOpen(BCTBX_UNUSED(bctbx_vfs_t *pVfs), bctbx_vfs_file_t *pFile, const char *fName, int openFlags) { 207 | if (pFile == NULL || fName == NULL) { 208 | return BCTBX_VFS_ERROR; 209 | } 210 | #ifdef _WIN32 211 | openFlags |= O_BINARY; 212 | #endif 213 | 214 | /* Create the userData structure */ 215 | bctbx_vfs_standard_t *userData = (bctbx_vfs_standard_t *)bctbx_malloc(sizeof(bctbx_vfs_standard_t)); 216 | userData->fd = open(fName, openFlags, S_IRUSR | S_IWUSR); 217 | if (userData->fd == -1) { 218 | bctbx_free(userData); 219 | return -errno; 220 | } 221 | 222 | pFile->pMethods = &bcio; 223 | pFile->pUserData = (void *)userData; 224 | return BCTBX_VFS_OK; 225 | } 226 | -------------------------------------------------------------------------------- /tester/containers.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "bctoolbox/list.h" 21 | #include "bctoolbox/map.h" 22 | #include "bctoolbox_tester.h" 23 | #include 24 | 25 | static void multimap_insert(void) { 26 | bctbx_map_t *mmap = bctbx_mmap_ullong_new(); 27 | bctbx_list_t *head = NULL, *ref = NULL; 28 | bctbx_iterator_t *it, *end; 29 | long i = 0; 30 | int N = 100; 31 | 32 | for (i = 0; i < N; i++) { 33 | bctbx_pair_t *pair = (bctbx_pair_t *)bctbx_pair_ullong_new(N - i - 1, (void *)((long)N - i - 1)); 34 | ref = bctbx_list_append(ref, (void *)i); 35 | bctbx_map_ullong_insert(mmap, pair); 36 | bctbx_pair_ullong_delete(pair); 37 | } 38 | BC_ASSERT_EQUAL(bctbx_map_ullong_size(mmap), N, int, "%i"); 39 | 40 | it = bctbx_map_ullong_begin(mmap); 41 | head = bctbx_list_first_elem(ref); 42 | for (ref = bctbx_list_first_elem(ref); ref != NULL; ref = bctbx_list_next(ref)) { 43 | BC_ASSERT_EQUAL((long)bctbx_pair_ullong_get_second(bctbx_iterator_ullong_get_pair(it)), 44 | (long)bctbx_list_get_data(ref), long, "%lu"); 45 | it = bctbx_iterator_ullong_get_next(it); 46 | } 47 | bctbx_iterator_ullong_delete(it); 48 | 49 | ref = head; 50 | end = bctbx_map_ullong_end(mmap); 51 | 52 | for (it = bctbx_map_ullong_begin(mmap); !bctbx_iterator_ullong_equals(it, end); 53 | it = bctbx_iterator_ullong_get_next(it)) { 54 | BC_ASSERT_PTR_NOT_NULL(ref); 55 | BC_ASSERT_EQUAL((long)bctbx_pair_ullong_get_second(bctbx_iterator_ullong_get_pair(it)), 56 | (long)bctbx_list_get_data(ref), long, "%lu"); 57 | ref = bctbx_list_next(ref); 58 | } 59 | bctbx_iterator_ullong_delete(it); 60 | bctbx_iterator_ullong_delete(end); 61 | bctbx_list_free(head); 62 | bctbx_mmap_ullong_delete(mmap); 63 | } 64 | 65 | static void multimap_erase(void) { 66 | bctbx_map_t *mmap = bctbx_mmap_ullong_new(); 67 | bctbx_iterator_t *it; 68 | bctbx_iterator_t *end; 69 | long i = 0; 70 | int N = 100; 71 | 72 | for (i = 0; i < N; i++) { 73 | bctbx_map_ullong_insert_and_delete(mmap, (bctbx_pair_t *)bctbx_pair_ullong_new(i, (void *)((long)i))); 74 | } 75 | 76 | end = bctbx_map_ullong_end(mmap); 77 | 78 | for (it = bctbx_map_ullong_begin(mmap); !bctbx_iterator_ullong_equals(it, end);) { 79 | long value = (long)bctbx_pair_ullong_get_second(bctbx_iterator_ullong_get_pair(it)); 80 | if (value < N / 2) { 81 | it = bctbx_map_ullong_erase(mmap, it); 82 | } else { 83 | break; 84 | } 85 | } 86 | bctbx_iterator_ullong_delete(it); 87 | it = bctbx_map_ullong_begin(mmap); 88 | BC_ASSERT_EQUAL((long)bctbx_pair_ullong_get_second(bctbx_iterator_ullong_get_pair(it)), N / 2, long, "%lu"); 89 | 90 | bctbx_mmap_ullong_delete(mmap); 91 | bctbx_iterator_ullong_delete(it); 92 | bctbx_iterator_ullong_delete(end); 93 | } 94 | static int compare_func(const void *a, const void *b) { 95 | return (long)a == (long)b; 96 | } 97 | static void multimap_find_custom(void) { 98 | bctbx_map_t *mmap = bctbx_mmap_ullong_new(); 99 | long i = 0; 100 | int N = 100; 101 | 102 | for (i = 0; i < N; i++) { 103 | bctbx_pair_t *pair = (bctbx_pair_t *)bctbx_pair_ullong_new(i, (void *)((long)i)); 104 | bctbx_map_ullong_insert_and_delete(mmap, pair); 105 | } 106 | bctbx_iterator_t *it = bctbx_map_ullong_find_custom(mmap, compare_func, (void *)10l); 107 | BC_ASSERT_EQUAL((long)bctbx_pair_ullong_get_second(bctbx_iterator_ullong_get_pair(it)), 0, long, "%lu"); 108 | bctbx_mmap_ullong_delete(mmap); 109 | bctbx_iterator_ullong_delete(it); 110 | } 111 | 112 | static void multimap_insert_cchar(void) { 113 | bctbx_map_t *mmap = bctbx_mmap_cchar_new(); 114 | bctbx_iterator_t *it, *end; 115 | long i = 0; 116 | int N = 100; 117 | 118 | for (i = 0; i < N; i++) { 119 | char str[32]; 120 | snprintf(str, sizeof(str), "%ld", N - i - 1); 121 | bctbx_pair_t *pair = (bctbx_pair_t *)bctbx_pair_cchar_new((const char *)str, (void *)((long)N - i - 1)); 122 | bctbx_map_cchar_insert(mmap, pair); 123 | bctbx_pair_cchar_delete(pair); 124 | } 125 | BC_ASSERT_EQUAL(bctbx_map_cchar_size(mmap), N, int, "%i"); 126 | 127 | for (i = 0; i < N; i++) { 128 | char str[32]; 129 | snprintf(str, sizeof(str), "%ld", i); 130 | it = bctbx_map_cchar_find_key(mmap, (const char *)str); 131 | BC_ASSERT_EQUAL((long)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)), (long)i, long, "%lu"); 132 | bctbx_iterator_cchar_delete(it); 133 | } 134 | 135 | end = bctbx_map_cchar_end(mmap); 136 | 137 | bctbx_iterator_cchar_delete(end); 138 | bctbx_mmap_cchar_delete(mmap); 139 | } 140 | 141 | static void multimap_erase_cchar(void) { 142 | bctbx_map_t *mmap = bctbx_mmap_cchar_new(); 143 | bctbx_iterator_t *it; 144 | bctbx_iterator_t *end; 145 | long i = 0; 146 | int N = 100; 147 | 148 | for (i = 0; i < N; i++) { 149 | char str[32]; 150 | snprintf(str, sizeof(str), "%ld", i); 151 | bctbx_map_cchar_insert_and_delete(mmap, 152 | (bctbx_pair_t *)bctbx_pair_cchar_new((const char *)str, (void *)((long)i))); 153 | } 154 | 155 | end = bctbx_map_cchar_end(mmap); 156 | 157 | for (it = bctbx_map_cchar_begin(mmap); !bctbx_iterator_cchar_equals(it, end);) { 158 | long value = (long)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)); 159 | if (value < N / 2) { 160 | it = bctbx_map_cchar_erase(mmap, it); 161 | } else { 162 | break; 163 | } 164 | } 165 | bctbx_iterator_cchar_delete(it); 166 | it = bctbx_map_cchar_begin(mmap); 167 | BC_ASSERT_EQUAL((long)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)), N / 2, long, "%lu"); 168 | bctbx_iterator_cchar_delete(it); 169 | 170 | bctbx_mmap_cchar_delete(mmap); 171 | bctbx_iterator_cchar_delete(end); 172 | } 173 | static int compare_func_cchar(const void *a, const void *b) { 174 | return (long)a == (long)b; 175 | } 176 | static void multimap_find_custom_cchar(void) { 177 | bctbx_map_t *mmap = bctbx_mmap_cchar_new(); 178 | long i = 0; 179 | int N = 100; 180 | 181 | for (i = 0; i < N; i++) { 182 | char str[32]; 183 | snprintf(str, sizeof(str), "%ld", i); 184 | bctbx_pair_t *pair = (bctbx_pair_t *)bctbx_pair_cchar_new((const char *)str, (void *)((long)i)); 185 | bctbx_map_cchar_insert_and_delete(mmap, pair); 186 | } 187 | bctbx_iterator_t *it = bctbx_map_cchar_find_custom(mmap, compare_func, (void *)10l); 188 | BC_ASSERT_EQUAL((long)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)), 0, long, "%lu"); 189 | bctbx_mmap_cchar_delete(mmap); 190 | bctbx_iterator_cchar_delete(it); 191 | } 192 | 193 | static void list_updates(void) { 194 | bctbx_list_t *list = NULL; 195 | bctbx_list_t *prep_list = NULL; 196 | bctbx_list_t *add_list = NULL; 197 | int sequence[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; 198 | // For testing added elements 199 | list = bctbx_list_append(list, &sequence[4]); 200 | list = bctbx_list_append(list, &sequence[5]); 201 | 202 | // For testing prepended elements 203 | list = bctbx_list_prepend(list, &sequence[3]); 204 | 205 | prep_list = bctbx_list_append(prep_list, &sequence[0]); 206 | prep_list = bctbx_list_append(prep_list, &sequence[1]); 207 | prep_list = bctbx_list_append(prep_list, &sequence[2]); 208 | 209 | add_list = bctbx_list_prepend(add_list, &sequence[6]); 210 | add_list = bctbx_list_append(add_list, &sequence[7]); 211 | add_list = bctbx_list_append(add_list, &sequence[8]); 212 | 213 | // For testing prepended list 214 | prep_list = bctbx_list_concat(prep_list, list); 215 | 216 | // For testing added list 217 | list = bctbx_list_concat(prep_list, add_list); 218 | 219 | // Check sequence: order and count must be correct. 220 | bctbx_list_t *list_it = list; 221 | int count = 0; 222 | while (list_it != NULL) { 223 | BC_ASSERT_EQUAL(*(int *)bctbx_list_get_data(list_it), count++, int, "%d"); 224 | list_it = bctbx_list_next(list_it); 225 | } 226 | BC_ASSERT_EQUAL(count, 9, int, "%d"); 227 | bctbx_list_free(list); 228 | } 229 | 230 | static test_t container_tests[] = { 231 | TEST_NO_TAG("mmap insert", multimap_insert), 232 | TEST_NO_TAG("mmap erase", multimap_erase), 233 | TEST_NO_TAG("mmap find custom", multimap_find_custom), 234 | TEST_NO_TAG("mmap insert cchar", multimap_insert_cchar), 235 | TEST_NO_TAG("mmap erase cchar", multimap_erase_cchar), 236 | TEST_NO_TAG("mmap find custom cchar", multimap_find_custom_cchar), 237 | TEST_NO_TAG("list updates", list_updates), 238 | }; 239 | 240 | test_suite_t containers_test_suite = { 241 | "Containers", NULL, NULL, NULL, NULL, sizeof(container_tests) / sizeof(container_tests[0]), container_tests, 0}; 242 | -------------------------------------------------------------------------------- /include/bctoolbox/vfs_encrypted.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef BCTBX_VFS_ENCRYPTED_HH 21 | #define BCTBX_VFS_ENCRYPTED_HH 22 | 23 | #include "bctoolbox/exception.hh" 24 | #include "bctoolbox/port.h" 25 | #include "bctoolbox/vfs.h" 26 | #include 27 | #include 28 | #include 29 | 30 | namespace bctoolbox { 31 | 32 | /** 33 | * @brief This dedicated exception inherits \ref BctoolboxException. 34 | * 35 | */ 36 | class EvfsException : public BctbxException { 37 | public: 38 | EvfsException() = default; 39 | EvfsException(const std::string &message) : BctbxException(message) { 40 | } 41 | EvfsException(const char *message) : BctbxException(message) { 42 | } 43 | virtual ~EvfsException() throw() { 44 | } 45 | EvfsException(const EvfsException &other) : BctbxException(other) { 46 | } 47 | 48 | template 49 | EvfsException &operator<<(const T &val) { 50 | BctbxException::operator<<(val); 51 | return *this; 52 | } 53 | }; 54 | 55 | #define EVFS_EXCEPTION EvfsException() << " " << __FILE__ << ":" << __LINE__ << " " 56 | 57 | /** 58 | * Virtual File sytem provided 59 | */ 60 | extern BCTBX_PUBLIC bctbx_vfs_t bcEncryptedVfs; 61 | 62 | /** 63 | * Provided encryption suites 64 | */ 65 | enum class EncryptionSuite : uint16_t { 66 | unset = 0, /**< no encryption suite selected */ 67 | dummy = 1, /**< a test suite, do not use other than for test */ 68 | aes256gcm128_sha256 = 69 | 2, /**< This module encrypts blocks with AES256GCM and authenticate header using HMAC-sha256 */ 70 | plain = 0xFFFF /**< no encryption activated, direct use of standard file system API */ 71 | }; 72 | 73 | /** 74 | * Helper function returning a string holding the suite name 75 | * @param[in] suite the encryption suite as a c++ enum 76 | * @return the suite name in a readable string 77 | */ 78 | const std::string encryptionSuiteString(const EncryptionSuite suite) noexcept; 79 | 80 | /* complete declaration follows, we need this one to define the callback type */ 81 | class VfsEncryption; 82 | 83 | /** 84 | * Define a function prototype to be called at each file opening. 85 | * This function is a static class property, used to retrieve secretMaterial to encrypt/decrypt the file 86 | */ 87 | using EncryptedVfsOpenCb = std::function; 88 | 89 | // forward declare this type, store all the encryption data and functions 90 | class VfsEncryptionModule; 91 | 92 | /** Store in the bctbx_vfs_file_t userData field an object specific to encryption */ 93 | class VfsEncryption { 94 | /* Class properties and method */ 95 | private: 96 | static EncryptedVfsOpenCb s_openCallback; /**< a class callback to get secret material at file opening. Implemented 97 | as static as it is called by constructor */ 98 | public: 99 | /** 100 | * at file opening a callback ask for crypto material, it is class property, set it using this class method 101 | */ 102 | static void openCallbackSet(const EncryptedVfsOpenCb &cb) noexcept; 103 | static EncryptedVfsOpenCb openCallbackGet() noexcept; 104 | 105 | /* Object properties and methods */ 106 | private: 107 | uint16_t mVersionNumber; /**< version number of the encryption vfs */ 108 | size_t mChunkSize; /**< size of the file chunks payload in bytes : default is 4kB */ 109 | size_t rawChunkSizeGet() 110 | const noexcept; /** return the size of a chunk including its encryption header, as stored in the raw file */ 111 | std::shared_ptr 112 | m_module; /**< one of the available encryption module : if nullptr, assume we deal with regular plain file */ 113 | size_t mHeaderExtensionSize; /**< header extension size */ 114 | const std::string mFilename; /**< the filename as given to the open function */ 115 | uint64_t mFileSize; /**< size of the plaintext file */ 116 | 117 | uint64_t rawFileSizeGet() const noexcept; /**< return the size of the raw file */ 118 | uint32_t 119 | getChunkIndex(uint64_t offset) const noexcept; /**< return the chunk index where to find the given offset */ 120 | size_t getChunkOffset( 121 | uint32_t index) const noexcept; /**< return the offset in the actual file of the begining of the chunk */ 122 | std::vector r_header; /**< a cache of the header - without the encryption module data */ 123 | /** flags use to communicate during differents functions involved at file opening **/ 124 | bool mEncryptExistingPlainFile; /**< when opening a plain file, if the callback set an encryption suite and key 125 | material : migrate the file */ 126 | bool mIntegrityFullCheck; /**< if the file size given in the header metadata is incorrect, full check the file 127 | integrity and revrite header */ 128 | int mAccessMode; /**< the flags used to open the file, filtered on the access mode */ 129 | 130 | /** 131 | * Parse the header of an encrypted file, check everything seems correct 132 | * may perform integrity checking if the encryption module provides it 133 | * 134 | * @throw a EvfsException if something goes wrong 135 | */ 136 | void parseHeader(); 137 | /** 138 | * Write the encrypted file header to the actual file 139 | * Create the needed structures if the file is actually empty 140 | * @param[in] fp if a file pointer is given write to this one, otherwise use the pFileStp property 141 | * 142 | * @throw a EvfsException if something goes wrong 143 | **/ 144 | void writeHeader(bctbx_vfs_file_t *fp = nullptr); 145 | 146 | public: 147 | bctbx_vfs_file_t *pFileStd; /**< The encrypted vfs encapsulate a standard one */ 148 | 149 | VfsEncryption(bctbx_vfs_file_t *stdFp, const std::string &filename, int openFlags, int accessMode); 150 | ~VfsEncryption(); 151 | 152 | /*** 153 | * Plain version of the file related accessors 154 | ***/ 155 | /** 156 | * @return the size of the plain text file 157 | */ 158 | int64_t fileSizeGet() const noexcept; 159 | 160 | /* Read from file at given offset the requested size */ 161 | std::vector read(size_t offset, size_t count) const; 162 | 163 | /* write to file at given offset the requested size */ 164 | size_t write(const std::vector &plainData, size_t offset); 165 | 166 | /* Truncate the file to the given size, if given size is greater than current, pad with 0 */ 167 | void truncate(const uint64_t size); 168 | 169 | /** 170 | * Get the filename 171 | * @return a string with the filename as given to the open function 172 | */ 173 | std::string filenameGet() const noexcept; 174 | 175 | /*** 176 | * Encryption related API 177 | ***/ 178 | /** 179 | * Set an encryption suite. 180 | * When called at file creation, select the module to use for this file 181 | * When called at the opening of an existing file, check it is the suite used at file creation, throw an exception 182 | * if they differs 183 | */ 184 | void encryptionSuiteSet(const EncryptionSuite); 185 | 186 | /** 187 | * Set the secret Material in the encryption module 188 | * This function cannot be called if a encryption suite was not set. 189 | */ 190 | void secretMaterialSet(const std::vector &secretMaterial); 191 | 192 | /** 193 | * Returns the encryption suite used for this file 194 | * Can be return unset if the file is being created 195 | */ 196 | EncryptionSuite encryptionSuiteGet() const noexcept; 197 | 198 | /** 199 | * Returns the size of chunks in which the file is divided for encryption 200 | */ 201 | size_t chunkSizeGet() const noexcept; 202 | /** 203 | * Set the size, in bytes, of chunks in which the file is divided for encryption 204 | * This size must be a multiple of 16, accepted values in range [16, (2^16-1)*16]. 205 | * If the size is set on an existing file and differs from previous setting, an exception is generated 206 | * Default chunk size at file creation is 4kB. 207 | * A file holds a maximum of 2^32-1 chunks. 16 bytes chunks - not recommended smallest admissible value - limit the 208 | * file size to 64GB 209 | */ 210 | void chunkSizeSet(const size_t size); 211 | 212 | /** 213 | * Get raw header: encryption module might check integrity on header 214 | * This function returns the raw header, without the encryption module part 215 | */ 216 | const std::vector &rawHeaderGet() const noexcept; 217 | }; 218 | 219 | } // namespace bctoolbox 220 | #endif /* BCTBX_VFS_STANDARD_HH */ 221 | -------------------------------------------------------------------------------- /src/vfs/vfs_encryption_module_aes256gcm_sha256.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Belledonne Communications SARL. 3 | * 4 | * This file is part of bctoolbox. 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "vfs_encryption_module_aes256gcm_sha256.hh" 21 | #include "bctoolbox/crypto.h" // bctbx_clean 22 | #include "bctoolbox/crypto.hh" 23 | #include 24 | #include 25 | 26 | #include "bctoolbox/logging.h" 27 | using namespace bctoolbox; 28 | /** 29 | * Constants associated to this encryption module 30 | */ 31 | 32 | /** Chunk Header in this module holds: Auth tag(16 bytes), IV : 12 bytes, Encryption Counter 4 bytes 33 | */ 34 | static constexpr size_t chunkAuthTagSize = AES256GCM128::tagSize(); 35 | static constexpr size_t chunkIVSize = 12; 36 | static constexpr size_t chunkHeaderSize = chunkAuthTagSize + chunkIVSize; 37 | /** 38 | * File header holds: fileSalt (16 bytes), file header auth tag(32 bytes) 39 | */ 40 | static constexpr size_t fileSaltSize = 16; 41 | static constexpr size_t fileAuthTagSize = 32; 42 | static constexpr size_t fileHeaderSize = fileSaltSize + fileAuthTagSize; 43 | 44 | /** 45 | * The master Key is expected to be 32 bytes 46 | */ 47 | static constexpr size_t masterKeySize = 32; 48 | 49 | /** constructor called at file creation */ 50 | VfsEM_AES256GCM_SHA256::VfsEM_AES256GCM_SHA256() 51 | : mRNG(std::make_shared()), // start the local RNG 52 | mFileSalt(mRNG->randomize(fileSaltSize)) // generate a random file Salt 53 | { 54 | } 55 | 56 | /** constructor called when opening an existing file */ 57 | VfsEM_AES256GCM_SHA256::VfsEM_AES256GCM_SHA256(const std::vector &fileHeader) 58 | : mRNG(std::make_shared()), // start the local RNG 59 | mFileSalt(std::vector(fileSaltSize)) { 60 | if (fileHeader.size() != fileHeaderSize) { 61 | throw EVFS_EXCEPTION << "The AES256GCM128-SHA256 encryption module expect a fileHeader of size " 62 | << fileHeaderSize << " bytes but " << fileHeader.size() << " are provided"; 63 | } 64 | // File header Data is 32 bytes of integrity data, 16 bytes of global salt 65 | std::copy(fileHeader.cbegin(), fileHeader.cbegin() + fileAuthTagSize, mFileHeaderIntegrity.begin()); 66 | std::copy(fileHeader.cbegin() + fileAuthTagSize, fileHeader.cend(), mFileSalt.begin()); 67 | } 68 | 69 | /** destructor ensure proper cleaning of any key material **/ 70 | VfsEM_AES256GCM_SHA256::~VfsEM_AES256GCM_SHA256() { 71 | bctbx_clean(sMasterKey.data(), sMasterKey.size()); 72 | bctbx_clean(sFileHeaderHMACKey.data(), sFileHeaderHMACKey.size()); 73 | } 74 | 75 | const std::vector VfsEM_AES256GCM_SHA256::getModuleFileHeader(const VfsEncryption &fileContext) const { 76 | if (sFileHeaderHMACKey.empty()) { 77 | throw EVFS_EXCEPTION 78 | << "The AES256GCM128-SHA256 encryption module cannot generate its file header without master key"; 79 | } 80 | // Only the actual file header is to authenticate, the module file header holds the global salt used to derive the 81 | // key feed to HMAC authenticating the file header so it is useless to authenticate it 82 | auto tag = HMAC(sFileHeaderHMACKey, fileContext.rawHeaderGet()); 83 | 84 | // Append the actual file salt value to the tag 85 | auto ret = mFileSalt; 86 | ret.insert(ret.begin(), tag.cbegin(), tag.cend()); 87 | return ret; 88 | } 89 | 90 | void VfsEM_AES256GCM_SHA256::setModuleSecretMaterial(const std::vector &secret) { 91 | if (secret.size() != masterKeySize) { 92 | throw EVFS_EXCEPTION << "The AES256GCM128 SHA256 encryption module expect a secret material of size " 93 | << masterKeySize << " bytes but " << secret.size() << " are provided"; 94 | } 95 | sMasterKey = secret; 96 | 97 | // Now that we have a master key, we can derive the header authentication one 98 | sFileHeaderHMACKey = bctoolbox::HKDF(mFileSalt, sMasterKey, "EVFS file Header", masterKeySize); 99 | } 100 | 101 | /** 102 | * Derive the key from master key for the given chunkIndex: 103 | * HKDF(fileSalt || ChunkIndex, master Key, "EVFS chunk") 104 | * 105 | * @param[in] chunkIndex the chunk index used in key derivation 106 | * 107 | * @return the AES256-GCM128 key 108 | */ 109 | std::vector VfsEM_AES256GCM_SHA256::deriveChunkKey(uint32_t chunkIndex) { 110 | std::vector chunkSalt{mFileSalt}; 111 | chunkSalt.push_back((chunkIndex >> 24) & 0xFF); 112 | chunkSalt.push_back((chunkIndex >> 16) & 0xFF); 113 | chunkSalt.push_back((chunkIndex >> 8) & 0xFF); 114 | chunkSalt.push_back(chunkIndex & 0xFF); 115 | return bctoolbox::HKDF(chunkSalt, sMasterKey, "EVFS chunk", AES256GCM128::keySize()); 116 | } 117 | 118 | std::vector VfsEM_AES256GCM_SHA256::decryptChunk(const uint32_t chunkIndex, 119 | const std::vector &rawChunk) { 120 | if (sMasterKey.empty()) { 121 | throw EVFS_EXCEPTION << "No encryption Master key set, cannot decrypt"; 122 | } 123 | 124 | // derive the key : HKDF (fileHeaderSalt || Chunk Index, Master key, "EVFS chunk") 125 | std::vector key{deriveChunkKey(chunkIndex)}; 126 | 127 | // parse the header: tag, IV, encryption Counter 128 | std::vector tag(AES256GCM128::tagSize()); 129 | std::copy(rawChunk.cbegin(), rawChunk.cbegin() + chunkAuthTagSize, tag.begin()); 130 | std::vector IV(rawChunk.cbegin() + chunkAuthTagSize, rawChunk.cbegin() + chunkAuthTagSize + chunkIVSize); 131 | std::vector AD{}; // No associated data 132 | 133 | // extract cipher 134 | std::vector cipher(rawChunk.cbegin() + chunkHeaderSize, rawChunk.cend()); 135 | 136 | // decrypt and auth 137 | std::vector plain; 138 | if (AEADDecrypt(key, IV, cipher, AD, tag, plain) == false) { 139 | throw EVFS_EXCEPTION << "Authentication failure during chunk decryption"; 140 | } 141 | 142 | // cleaning 143 | bctbx_clean(key.data(), key.size()); 144 | 145 | return plain; 146 | } 147 | 148 | // This module does not reuse any part of its chunk header during encryption 149 | // So re-encryption is the same than initial encryption 150 | void VfsEM_AES256GCM_SHA256::encryptChunk(const uint32_t chunkIndex, 151 | std::vector &rawChunk, 152 | const std::vector &plainData) { 153 | 154 | rawChunk = encryptChunk(chunkIndex, plainData); 155 | } 156 | 157 | std::vector VfsEM_AES256GCM_SHA256::encryptChunk(const uint32_t chunkIndex, 158 | const std::vector &plainData) { 159 | if (sMasterKey.empty()) { 160 | throw EVFS_EXCEPTION << "No encryption Master key set, cannot encrypt"; 161 | } 162 | // generate a random IV 163 | auto IV = mRNG->randomize(chunkIVSize); 164 | 165 | // derive the key : HKDF (fileHeaderSalt || Chunk Index, Master key, "EVFS chunk") 166 | std::vector key{deriveChunkKey(chunkIndex)}; 167 | 168 | std::vector AD{}; 169 | std::vector tag(AES256GCM128::tagSize()); 170 | std::vector rawChunk = AEADEncrypt(key, IV, plainData, AD, tag); 171 | 172 | // insert header: 173 | std::vector chunkHeader(chunkHeaderSize, 0); 174 | std::copy(tag.cbegin(), tag.cend(), chunkHeader.begin()); 175 | std::copy(IV.cbegin(), IV.cend(), chunkHeader.begin() + tag.size()); 176 | rawChunk.insert(rawChunk.begin(), chunkHeader.cbegin(), chunkHeader.cend()); 177 | 178 | // cleaning 179 | bctbx_clean(key.data(), key.size()); 180 | 181 | return rawChunk; 182 | } 183 | 184 | /** 185 | * When this function is called, m_fileHeader holds the integrity tag read from file 186 | * and sFileHeaderHMACKey holds the derived key for header authentication 187 | * Compute the HMAC on the whole rawfileHeader + the module header 188 | * Check it match what we have in the m_fileHeader 189 | */ 190 | bool VfsEM_AES256GCM_SHA256::checkIntegrity(const VfsEncryption &fileContext) { 191 | if (sFileHeaderHMACKey.empty()) { 192 | throw EVFS_EXCEPTION 193 | << "The AES256GCM128-SHA256 encryption module cannot generate its file header without master key"; 194 | } 195 | // Only the actual file header is to authenticate, the module file header holds the global salt used to derive the 196 | // key feed to HMAC authenticating the file header so it is useless to authenticate it 197 | auto tag = HMAC(sFileHeaderHMACKey, fileContext.rawHeaderGet()); 198 | 199 | return (std::equal(tag.cbegin(), tag.cend(), mFileHeaderIntegrity.cbegin())); 200 | } 201 | /** 202 | * This function exists as static and non static 203 | */ 204 | size_t VfsEM_AES256GCM_SHA256::moduleFileHeaderSize() noexcept { 205 | return fileHeaderSize; 206 | } 207 | 208 | /** 209 | * @return the size in bytes of the chunk header 210 | */ 211 | size_t VfsEM_AES256GCM_SHA256::getChunkHeaderSize() const noexcept { 212 | return chunkHeaderSize; 213 | } 214 | /** 215 | * @return the size in bytes of file header module data 216 | */ 217 | size_t VfsEM_AES256GCM_SHA256::getModuleFileHeaderSize() const noexcept { 218 | return fileHeaderSize; 219 | } 220 | 221 | /** 222 | * @return the secret material size 223 | */ 224 | size_t VfsEM_AES256GCM_SHA256::getSecretMaterialSize() const noexcept { 225 | return masterKeySize; 226 | } 227 | --------------------------------------------------------------------------------