diff --git a/.gitattribute b/.gitattribute deleted file mode 100644 index bc501446c4..0000000000 --- a/.gitattribute +++ /dev/null @@ -1,2 +0,0 @@ -win32/msvcproj.head -crlf -win32/msvcproj.foot -crlf diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index f883236e6b..c9d505eca5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -19,8 +19,9 @@ A recipe or example code that reproduces the problem? A stack trace from a crash A clear and concise description of what you expected to happen. **Version (please complete the following information):** - - OS: [e.g. iOS] - - libssh2 version [e.g. 1.8.0] + - OS and version: [e.g. iOS, macOS, Windows, Linux (distro)] + - libssh2 version: [e.g. 1.10.0] + - crypto backend and version: [OpenSSL, mbedTLS, Libgcrypt, LibreSSL, WinCNG, OS400, wolfSSL, None] **Additional context** Add any other context about the problem here. diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000000..bc8dcc480a --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +See [SECURITY.md](https://github.com/libssh2/libssh2/blob/master/docs/SECURITY.md) for full details. + +## Reporting a Vulnerability + +If you have found or just suspect a security problem somewhere in libssh2, +email `libssh2-security@haxx.se` about it. + +**Do not submit suspected security issues in the public bug tracker!** + +We treat security issues with confidentiality until controlled and disclosed +responsibly. diff --git a/.github/workflows/appveyor.yml b/.github/workflows/appveyor_docker.yml similarity index 99% rename from .github/workflows/appveyor.yml rename to .github/workflows/appveyor_docker.yml index f0fa0eaf9e..ab53e65ad5 100644 --- a/.github/workflows/appveyor.yml +++ b/.github/workflows/appveyor_docker.yml @@ -40,6 +40,8 @@ on: ssh_privkey: required: true +permissions: {} + jobs: daemon: runs-on: ubuntu-latest diff --git a/.github/workflows/appveyor_status.yml b/.github/workflows/appveyor_status.yml new file mode 100644 index 0000000000..62f0d7e75d --- /dev/null +++ b/.github/workflows/appveyor_status.yml @@ -0,0 +1,60 @@ +# Copyright (c) 2022 Marc Hoersken +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +name: AppVeyor Status Report + +on: + status + +concurrency: + group: ${{ github.workflow }}-${{ github.event.sha }}-${{ github.event.target_url }} + cancel-in-progress: true + +permissions: + statuses: write + +jobs: + split: + runs-on: ubuntu-latest + if: ${{ github.event.sender.login == 'appveyor[bot]' }} + steps: + - name: Create individual AppVeyor build statuses + if: ${{ github.event.sha && github.event.target_url }} + env: + APPVEYOR_COMMIT_SHA: ${{ github.event.sha }} + APPVEYOR_TARGET_URL: ${{ github.event.target_url }} + APPVEYOR_REPOSITORY: ${{ github.event.repository.full_name }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo ${APPVEYOR_TARGET_URL} | sed 's/\/project\//\/api\/projects\//' | xargs -t -n1 curl -s | \ + jq -c '.build.jobs[] | {target_url: ($target_url + "/job/" + .jobId), + context: (.name | sub("^(Environment: )?"; "AppVeyor / ")), + state: (.status | sub("queued"; "pending") + | sub("starting"; "pending") + | sub("running"; "pending") + | sub("failed"; "failure") + | sub("cancelled"; "error")), + description: .status}' \ + --arg target_url ${APPVEYOR_TARGET_URL} | tee /dev/stderr | parallel --pipe -j 1 -N 1 \ + gh api --silent --input - repos/${APPVEYOR_REPOSITORY}/statuses/${APPVEYOR_COMMIT_SHA} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3333d9c006..c85eb1a4d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,104 +2,318 @@ name: CI on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] + +permissions: {} jobs: - style-check: - runs-on: ubuntu-16.04 + check_style: + name: 'style-check' + runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - uses: actions/checkout@v2 - - name: Check Style + - uses: actions/checkout@v3 + - name: 'checksrc' run: ./ci/checksrc.sh - build: - runs-on: ubuntu-16.04 + + build_linux: + name: 'linux' + runs-on: ubuntu-latest + timeout-minutes: 60 strategy: fail-fast: false matrix: compiler: [gcc, clang] - address_size: [32, 64] - crypto_backend: [OpenSSL, Libgcrypt, mbedTLS] - build_shared_libs: [OFF, ON] - enable_zlib_compression: [OFF, ON] - b: [cmake] + crypto_backend: [OpenSSL, wolfSSL, Libgcrypt, mbedTLS] + enable_zlib_compression: ['OFF', 'ON'] + build: [cmake] include: - compiler: gcc - address_size: 64 crypto_backend: OpenSSL - build_shared_libs: OFF - enable_zlib_compression: OFF - b: configure + enable_zlib_compression: 'OFF' + build: autotools - compiler: clang - address_size: 64 crypto_backend: OpenSSL - build_shared_libs: OFF - enable_zlib_compression: OFF - b: configure + enable_zlib_compression: 'OFF' + build: autotools + - compiler: clang + crypto_backend: OpenSSL + enable_zlib_compression: 'ON' + build: autotools + target: 'distcheck' env: CC: ${{ matrix.compiler }} CC_FOR_BUILD: ${{ matrix.compiler }} CRYPTO_BACKEND: ${{ matrix.crypto_backend }} - BUILD_SHARED_LIBS: ${{ matrix.build_shared_libs }} ENABLE_ZLIB_COMPRESSION: ${{ matrix.enable_zlib_compression }} steps: - - uses: actions/checkout@v2 - - name: Install 32 Bit Dependencies - if: ${{ matrix.address_size == 32 }} - run: | - sudo dpkg --add-architecture i386 - sudo apt-get update -qq - sudo apt-get install -y gcc-multilib - sudo apt-get install -y libssl-dev:i386 libgcrypt20-dev:i386 zlib1g-dev:i386 build-essential gcc-multilib - sudo dpkg --purge --force-depends gcc-multilib - sudo dpkg --purge --force-depends libssl-dev - echo "TOOLCHAIN_OPTION=-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-Linux-32.cmake" >> $GITHUB_ENV - - name: Install 64 Bit Dependencies - if: ${{ matrix.address_size == 64 }} + - uses: actions/checkout@v3 + - name: 'install packages' + if: ${{ matrix.crypto_backend != 'mbedTLS' }} run: | - sudo apt-get install -y libssl-dev - sudo apt-get install -y libgcrypt11-dev - - name: Install mbedTLS Dependencies + [ "${{ matrix.crypto_backend }}" == 'OpenSSL' ] && pkg='libssl-dev' + [ "${{ matrix.crypto_backend }}" == 'wolfSSL' ] && pkg='libwolfssl-dev' + [ "${{ matrix.crypto_backend }}" == 'Libgcrypt' ] && pkg='libgcrypt-dev' + sudo apt-get install -y "${pkg}" + + - name: 'install mbedTLS from source' if: ${{ matrix.crypto_backend == 'mbedTLS' }} run: | - MBEDTLSVER=mbedtls-2.7.0 - curl -L https://github.com/ARMmbed/mbedtls/archive/$MBEDTLSVER.tar.gz | tar -xzf - + MBEDTLSVER=mbedtls-3.4.0 + curl -L https://github.com/Mbed-TLS/mbedtls/archive/$MBEDTLSVER.tar.gz | tar -xzf - cd mbedtls-$MBEDTLSVER - cmake $TOOLCHAIN_OPTION -DUSE_SHARED_MBEDTLS_LIBRARY=ON -DCMAKE_INSTALL_PREFIX:PATH=../usr . + cmake . \ + -DUSE_SHARED_MBEDTLS_LIBRARY=ON \ + -DCMAKE_INSTALL_PREFIX:PATH=../usr make -j3 install cd .. echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/usr/lib" >> $GITHUB_ENV echo "TOOLCHAIN_OPTION=$TOOLCHAIN_OPTION -DCMAKE_PREFIX_PATH=$PWD/usr" >> $GITHUB_ENV - - name: Build with Configure - if: ${{ matrix.b == 'configure' }} + + - name: 'autotools autoreconf' + if: ${{ matrix.build == 'autotools' }} + run: autoreconf -fi + - name: 'autotools configure' + if: ${{ matrix.build == 'autotools' }} + run: mkdir bld && cd bld && ../configure --enable-werror --enable-debug + - name: 'autotools build' + if: ${{ matrix.build == 'autotools' && !matrix.target }} + run: make -C bld -j3 + - name: 'autotools tests' + if: ${{ matrix.build == 'autotools' && !matrix.target }} + timeout-minutes: 10 + run: make -C bld check VERBOSE=1 + - name: 'autotools distcheck' + if: ${{ matrix.target == 'distcheck' }} + run: make -C bld -j3 distcheck + - name: 'cmake configure' + if: ${{ matrix.build == 'cmake' }} + run: | + cmake . -B bld $TOOLCHAIN_OPTION \ + -DENABLE_WERROR=ON \ + -DCRYPTO_BACKEND=$CRYPTO_BACKEND \ + -DENABLE_ZLIB_COMPRESSION=$ENABLE_ZLIB_COMPRESSION + + - name: 'cmake build' + if: ${{ matrix.build == 'cmake' }} + run: cmake --build bld --parallel 3 --target package + - name: 'cmake tests' + if: ${{ matrix.build == 'cmake' && matrix.crypto_backend != 'wolfSSL' }} + timeout-minutes: 10 + run: | + export OPENSSH_SERVER_IMAGE=ghcr.io/libssh2/ci_tests_openssh_server:$(git rev-parse --short=20 HEAD:tests/openssh_server) + cd bld && ctest -VV --output-on-failure + + build_msys2: + name: 'msys2' + runs-on: windows-latest + timeout-minutes: 30 + strategy: + matrix: + include: + - { build: 'autotools', sys: mingw64, env: x86_64 } + - { build: 'autotools', sys: mingw32, env: i686 } + - { build: 'autotools', sys: ucrt64, env: ucrt-x86_64 } + - { build: 'autotools', sys: clang64, env: clang-x86_64 } + - { build: 'cmake' , sys: ucrt64, env: ucrt-x86_64 } + - { build: 'cmake' , sys: clang64, env: clang-x86_64 } + - { build: 'make' , sys: mingw64, env: x86_64 } + fail-fast: false + steps: + - uses: actions/checkout@v3 + - uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.sys }} + install: >- + mingw-w64-${{ matrix.env }}-cc + mingw-w64-${{ matrix.env }}-${{ matrix.build }} make + mingw-w64-${{ matrix.env }}-openssl + + - name: 'autotools autoreconf' + if: ${{ matrix.build == 'autotools' }} + shell: msys2 {0} + run: autoreconf -fi + - name: 'autotools configure' + if: ${{ matrix.build == 'autotools' }} + env: + SSHD: 'C:/Program Files/Git/usr/bin/sshd.exe' + shell: msys2 {0} + run: | + # sshd tests sometimes hang + mkdir bld && cd bld && ../configure --enable-werror --enable-debug \ + --with-crypto=openssl \ + --disable-docker-tests \ + --disable-sshd-tests + + - name: 'autotools build' + if: ${{ matrix.build == 'autotools' }} + shell: msys2 {0} + run: make -C bld -j3 + - name: 'autotools tests' + if: ${{ matrix.build == 'autotools' }} + timeout-minutes: 10 + shell: msys2 {0} + run: make -C bld check VERBOSE=1 + - name: 'cmake configure' + if: ${{ matrix.build == 'cmake' }} + env: + CMAKE_GENERATOR: 'MSYS Makefiles' + shell: msys2 {0} run: | - autoreconf -fi - ./configure --enable-debug --enable-werror - make - make check - - name: Build with CMake - if: ${{ matrix.b == 'cmake' }} + if [[ "${{ matrix.env }}" = 'clang'* ]]; then + options='-DCMAKE_C_COMPILER=clang -DCMAKE_UNITY_BUILD=ON' + else + options='-DCMAKE_C_COMPILER=gcc' + fi + cmake . -B bld ${options} \ + -DENABLE_WERROR=ON \ + -DENABLE_DEBUG_LOGGING=ON \ + -DCRYPTO_BACKEND=OpenSSL \ + -DENABLE_ZLIB_COMPRESSION=ON \ + -DRUN_DOCKER_TESTS=OFF \ + -DRUN_SSHD_TESTS=OFF + + - name: 'cmake build' + if: ${{ matrix.build == 'cmake' }} + shell: msys2 {0} + run: cmake --build bld --parallel 3 + - name: 'cmake tests' + if: ${{ matrix.build == 'cmake' }} + timeout-minutes: 10 + shell: msys2 {0} + run: cd bld && ctest -VV --output-on-failure + - name: 'make build' + if: ${{ matrix.build == 'make' }} + env: + CPPFLAGS: -DLIBSSH2_NO_MD5 -DLIBSSH2_NO_HMAC_RIPEMD -DLIBSSH2_NO_DSA -DLIBSSH2_NO_AES_CBC -DLIBSSH2_NO_AES_CTR -DLIBSSH2_NO_BLOWFISH -DLIBSSH2_NO_RC4 -DLIBSSH2_NO_CAST -DLIBSSH2_NO_3DES + LIBSSH2_CPPFLAGS_LIB: -DLIBSSH2_EXPORTS + ZLIB_PATH: /${{ matrix.sys }} + OPENSSL_PATH: /${{ matrix.sys }} + shell: msys2 {0} + run: mkdir bld && cd bld && BLD_DIR=bld make -C .. -j3 -f Makefile.mk dyn example test + + build_msvc: + name: 'msvc' + runs-on: windows-latest + timeout-minutes: 30 + strategy: + matrix: + include: + - { arch: x64 , plat: windows, crypto: WinCNG , log: 'OFF', shared: 'OFF', zlib: 'OFF', unity: 'OFF' } + - { arch: x64 , plat: windows, crypto: WinCNG , log: 'ON' , shared: 'ON' , zlib: 'OFF', unity: 'OFF' } + - { arch: x64 , plat: windows, crypto: OpenSSL, log: 'OFF', shared: 'ON' , zlib: 'OFF', unity: 'OFF' } + - { arch: x64 , plat: uwp , crypto: WinCNG , log: 'OFF', shared: 'ON' , zlib: 'OFF', unity: 'OFF' } + - { arch: arm64, plat: windows, crypto: WinCNG , log: 'OFF', shared: 'ON' , zlib: 'OFF', unity: 'OFF' } + - { arch: arm64, plat: uwp , crypto: WinCNG , log: 'OFF', shared: 'ON' , zlib: 'OFF', unity: 'ON' } + - { arch: x86 , plat: windows, crypto: WinCNG , log: 'OFF', shared: 'ON' , zlib: 'OFF', unity: 'OFF' } + fail-fast: false + steps: + - uses: actions/checkout@v3 + - name: 'cmake configure' + shell: bash run: | - mkdir bin - cd bin - cmake $TOOLCHAIN_OPTION -DCRYPTO_BACKEND=$CRYPTO_BACKEND -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS -DENABLE_ZLIB_COMPRESSION=$ENABLE_ZLIB_COMPRESSION .. - cmake --build . - pushd ../tests - docker build -t libssh2/openssh_server openssh_server - popd - CTEST_OUTPUT_ON_FAILURE=1 cmake --build . --target test - cmake --build . --target package - fuzzer: - runs-on: ubuntu-16.04 + archgen=${{ matrix.arch }}; [ "${archgen}" = 'x86' ] && archgen='Win32' + if [ "${{ matrix.plat }}" = 'uwp' ]; then + system='WindowsStore' + options='-DCMAKE_SYSTEM_VERSION=10.0' + else + system='Windows' + fi + cmake . -B bld ${options} \ + -DCMAKE_SYSTEM_NAME=${system} \ + -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DCMAKE_GENERATOR_PLATFORM=${archgen} \ + -DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-${{ matrix.plat }} \ + -DCMAKE_VS_GLOBALS=TrackFileAccess=false \ + -DCMAKE_UNITY_BUILD=${{ matrix.unity }} \ + -DENABLE_WERROR=ON \ + -DENABLE_DEBUG_LOGGING=${{ matrix.log }} \ + -DBUILD_SHARED_LIBS=${{ matrix.shared }} \ + -DCRYPTO_BACKEND=${{ matrix.crypto }} \ + -DENABLE_ZLIB_COMPRESSION=${{ matrix.zlib }} \ + -DRUN_DOCKER_TESTS=OFF \ + -DRUN_SSHD_TESTS=OFF + + - name: 'cmake build' + run: cmake --build bld --parallel 3 --target package --config Release + - name: 'cmake tests' + # UWP binaries require a CRT DLL that is not found. Static CRT not supported. + if: ${{ matrix.arch != 'arm64' && matrix.plat != 'uwp' }} + timeout-minutes: 10 + run: cd bld && ctest -VV -C Release --output-on-failure + + build_macos: + name: 'macOS (${{ matrix.build }}, ${{ matrix.crypto.name }})' + runs-on: macos-latest + timeout-minutes: 30 strategy: fail-fast: false matrix: - compiler: [gcc, clang] - env: - CC: ${{ matrix.compiler }} - CC_FOR_BUILD: ${{ matrix.compiler }} + build: [autotools, cmake] + crypto: + - name: 'OpenSSL 3' + install: openssl + configure: --with-crypto=openssl --with-libssl-prefix=/usr/local/opt/openssl + cmake: -DCRYPTO_BACKEND=OpenSSL -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl + - name: 'OpenSSL 1.1' + install: openssl@1.1 + configure: --with-crypto=openssl --with-libssl-prefix=/usr/local/opt/openssl@1.1 + cmake: -DCRYPTO_BACKEND=OpenSSL -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 + - name: 'LibreSSL' + install: libressl + configure: --with-crypto=openssl --with-libssl-prefix=/usr/local/opt/libressl + cmake: -DCRYPTO_BACKEND=OpenSSL -DOPENSSL_ROOT_DIR=/usr/local/opt/libressl + - name: 'wolfSSL' + install: wolfssl + configure: --with-crypto=wolfssl --with-libwolfssl-prefix=/usr/local/opt/wolfssl + cmake: -DCRYPTO_BACKEND=wolfSSL + - name: 'libgcrypt' + install: libgcrypt + configure: --with-crypto=libgcrypt --with-libgcrypt-prefix=/usr/local/opt/libgcrypt + cmake: -DCRYPTO_BACKEND=Libgcrypt + - name: 'mbedTLS' + install: mbedtls + configure: --with-crypto=mbedtls --with-libmbedcrypto-prefix=/usr/local/opt/mbedtls + cmake: -DCRYPTO_BACKEND=mbedTLS -DMBEDCRYPTO_LIBRARY=/usr/local/opt/mbedtls/lib/libmbedcrypto.a -DMBEDTLS_LIBRARY=/usr/local/opt/mbedtls/lib/libmbedtls.a -DMBEDX509_LIBRARY=/usr/local/opt/mbedtls/lib/libmbedx509.a -DMBEDTLS_INCLUDE_DIR=/usr/local/opt/mbedtls/include steps: - - uses: actions/checkout@v2 - - name: Run Fuzzer - run: GIT_REF=$GITHUB_REF ./ci/ossfuzz.sh + - name: 'install packages' + run: brew install automake ${{ matrix.crypto.install }} + - uses: actions/checkout@v3 + - name: 'autotools autoreconf' + if: ${{ matrix.build == 'autotools' }} + run: autoreconf -fi + - name: 'autotools configure' + if: ${{ matrix.build == 'autotools' }} + run: | + mkdir bld && cd bld && ../configure --enable-werror --enable-debug \ + --with-libz ${{ matrix.crypto.configure }} \ + --disable-docker-tests \ + --disable-sshd-tests + + - name: 'autotools build' + if: ${{ matrix.build == 'autotools' }} + run: make -C bld -j3 + - name: 'autotools tests' + if: ${{ matrix.build == 'autotools' }} + timeout-minutes: 10 + run: make -C bld check VERBOSE=1 + - name: 'cmake configure' + if: ${{ matrix.build == 'cmake' }} + run: | + cmake . -B bld ${{ matrix.crypto.cmake }} \ + -DCMAKE_UNITY_BUILD=ON \ + -DENABLE_WERROR=ON \ + -DENABLE_DEBUG_LOGGING=ON \ + -DENABLE_ZLIB_COMPRESSION=ON \ + -DRUN_DOCKER_TESTS=OFF \ + -DRUN_SSHD_TESTS=OFF + + - name: 'cmake build' + if: ${{ matrix.build == 'cmake' }} + run: cmake --build bld --parallel 3 + - name: 'cmake tests' + if: ${{ matrix.build == 'cmake' }} + timeout-minutes: 10 + run: cd bld && ctest -VV --output-on-failure diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 0000000000..4c570270c0 --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,30 @@ +name: CIFuzz +on: [pull_request] + +permissions: {} + +jobs: + Fuzzing: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'libssh2' + dry-run: false + language: c + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'libssh2' + fuzz-seconds: 600 + dry-run: false + language: c + - name: Upload Crash + uses: actions/upload-artifact@v3 + if: failure() && steps.build.outcome == 'success' + with: + name: artifacts + path: ./out/artifacts diff --git a/.github/workflows/openssh_server.yml b/.github/workflows/openssh_server.yml new file mode 100644 index 0000000000..026f333f0d --- /dev/null +++ b/.github/workflows/openssh_server.yml @@ -0,0 +1,66 @@ +# Copyright (c) 2022 Marc Hoersken +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +name: OpenSSH Server Docker Image + +on: + push: + branches: [ master ] + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/checkout@v3 + + - shell: bash + id: hash + run: echo "::set-output name=hash::$(git rev-parse --short=20 HEAD:tests/openssh_server)" + + - shell: bash + id: poll + run: docker manifest inspect ghcr.io/${{ github.repository_owner }}/ci_tests_openssh_server:${{ steps.hash.outputs.hash }} + continue-on-error: true + + - uses: docker/metadata-action@v4 + id: meta + with: + images: ghcr.io/${{ github.repository_owner }}/ci_tests_openssh_server + tags: | + type=raw,value=${{ steps.hash.outputs.hash }} + if: ${{ steps.poll.outcome == 'failure' }} + + - uses: docker/build-push-action@v3 + with: + context: ./tests/openssh_server + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + if: ${{ steps.poll.outcome == 'failure' }} diff --git a/.gitignore b/.gitignore index 09f037d855..ae793d80e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,14 @@ .deps .libs +*.a *.lib *.pdb *.dll +*.def *.exe *.obj .*.swp +*-*-* Debug Release *.exp @@ -24,8 +27,12 @@ depcomp libtool ltmain.sh missing -ssh2_sample +tap-driver.sh +test-driver +libssh2-*.tar.bz2 libssh2-*.tar.gz +libssh2-*.tar.xz +libssh2-*.zip install-sh *.o *.lo @@ -36,4 +43,4 @@ libssh2.pc TAGS *~ .DS_Store -build/ \ No newline at end of file +build diff --git a/.tipi/deps b/.tipi/deps index 2d2d22c681..c628a49192 100644 --- a/.tipi/deps +++ b/.tipi/deps @@ -1,6 +1,6 @@ { "u" : true, - "nxxm/boringssl" : { "@" : ":358175c062c3a3964d4734df4b122e6af851def0", + "google/boringssl" : { "@" : ":f896fbd7a94daf801446ae997d288e7f03a5d9a2", "u": true , "packages" : ["OpenSSL"] , "targets" : ["OpenSSL::SSL", "OpenSSL::Crypto"] diff --git a/.tipi/opts b/.tipi/opts index 9b3b81107d..9ffff82ea3 100644 --- a/.tipi/opts +++ b/.tipi/opts @@ -5,4 +5,6 @@ set(ENABLE_ZLIB_COMPRESSION ON CACHE BOOL "Enable zlib compression" FORCE) set(BUILD_EXAMPLES OFF CACHE BOOL "no example" FORCE) # Tests -set(BUILD_TESTING OFF CACHE BOOL "no test" FORCE) \ No newline at end of file +set(BUILD_TESTING OFF CACHE BOOL "no test" FORCE) + +set(BUILD_SHARED_LIBS OFF CACHE BOOL "no shared lib" FORCE) \ No newline at end of file diff --git a/.tipi/opts.vs-16-2019-win64-cxx17 b/.tipi/opts.vs-16-2019-win64-cxx17 deleted file mode 100644 index befa4b4a21..0000000000 --- a/.tipi/opts.vs-16-2019-win64-cxx17 +++ /dev/null @@ -1,10 +0,0 @@ -add_compile_definitions( - NOMINMAX - WIN32_LEAN_AND_MEAN - _WIN32_WINNT=0x0A00 # We have to set the windows version targeted - WINVER=0x0A00 # We have to set the windows version targeted -) - -add_compile_options( - /bigobj -) \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ec290126ea..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright (c) 2014 Alexander Lamaison -# -# Redistribution and use in source and binary forms, -# with or without modification, are permitted provided -# that the following conditions are met: -# -# Redistributions of source code must retain the above -# copyright notice, this list of conditions and the -# following disclaimer. -# -# Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# Neither the name of the copyright holder nor the names -# of any other contributors may be used to endorse or -# promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -# OF SUCH DAMAGE. - -sudo: required - -services: - - docker - -language: c - -compiler: - - gcc - - clang - -addons: - chrome: stable -matrix: - include: - - name: "Check style" - script: ./ci/checksrc.sh - -env: - - ADDRESS_SIZE=64 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF B=configure - - ADDRESS_SIZE=64 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=mbedTLS BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=mbedTLS BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=mbedTLS BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=64 CRYPTO_BACKEND=mbedTLS BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=OpenSSL BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=Libgcrypt BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=mbedTLS BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=mbedTLS BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=OFF B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=mbedTLS BUILD_SHARED_LIBS=OFF ENABLE_ZLIB_COMPRESSION=ON B=cmake - - ADDRESS_SIZE=32 CRYPTO_BACKEND=mbedTLS BUILD_SHARED_LIBS=ON ENABLE_ZLIB_COMPRESSION=ON B=cmake - - B=fuzzer - -before_install: - - if [ $ADDRESS_SIZE = '32' ]; then sudo dpkg --add-architecture i386; fi - - if [ $ADDRESS_SIZE = '32' ]; then sudo apt-get update -qq; fi - - if [ $ADDRESS_SIZE = '32' ]; then sudo apt-get install -y gcc-multilib; fi - - if [ $ADDRESS_SIZE = '32' ]; then sudo apt-get install -y libssl-dev:i386 libgcrypt20-dev:i386 build-essential gcc-multilib; fi - - if [ $ADDRESS_SIZE = '32' ]; then sudo dpkg --purge --force-depends gcc-multilib && sudo dpkg --purge --force-depends libssl-dev; fi - - if [ $ADDRESS_SIZE = '64' ]; then sudo apt-get install -y libssl-dev; fi - - if [ $ADDRESS_SIZE = '64' ]; then sudo apt-get install -y libgcrypt11-dev; fi - - if [ $ADDRESS_SIZE = '32' ]; then export TOOLCHAIN_OPTION="-DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-Linux-32.cmake"; fi - - if [ $CRYPTO_BACKEND = 'mbedTLS' ]; then - MBEDTLSVER=mbedtls-2.7.0; - curl -L https://github.com/ARMmbed/mbedtls/archive/$MBEDTLSVER.tar.gz | tar -xzf -; - cd mbedtls-$MBEDTLSVER; - cmake $TOOLCHAIN_OPTION -DUSE_SHARED_MBEDTLS_LIBRARY=ON -DCMAKE_INSTALL_PREFIX:PATH=../usr .; - make -j3 install; - cd ..; - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/usr/lib; - export TOOLCHAIN_OPTION="$TOOLCHAIN_OPTION -DCMAKE_PREFIX_PATH=$PWD/usr"; - fi - -install: - -script: - - | - if [ "$B" = "configure" ]; then - autoreconf -fi - ./configure --enable-debug --enable-werror - make - make check - fi - - | - if [ "$B" = "cmake" ]; then - mkdir bin - cd tests - docker build -t libssh2/openssh_server openssh_server - cd ../bin - cmake $TOOLCHAIN_OPTION -DCRYPTO_BACKEND=$CRYPTO_BACKEND -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS -DENABLE_ZLIB_COMPRESSION=$ENABLE_ZLIB_COMPRESSION .. && cmake --build . && CTEST_OUTPUT_ON_FAILURE=1 cmake --build . --target test && cmake --build . --target package - fi - - | - if [ "$B" = "fuzzer" ]; then - GIT_REF=$TRAVIS_COMMIT ./ci/ossfuzz.sh - fi - -# whitelist branches to avoid testing feature branches twice (as branch and as pull request) -branches: - only: - - master diff --git a/CMakeLists.txt b/CMakeLists.txt index e6c95c888c..1cdc524f46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ -# Copyright (c) 2014, 2015 Alexander Lamaison +# Copyright (c) 2014, 2015 Alexander Lamaison +# Copyright (c) 2023 Viktor Szakats # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided @@ -33,23 +34,32 @@ # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. -cmake_minimum_required(VERSION 2.8.11) +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckIncludeFiles) +include(CheckSymbolExists) +include(CMakePushCheckState) +include(FeatureSummary) + +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") +include(CheckFunctionExistsMayNeedLibrary) +include(CheckNonblockingSocketSupport) + +cmake_minimum_required(VERSION 3.1) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) project(libssh2 C) -set(PROJECT_URL "https://www.libssh2.org/") -set(PROJECT_DESCRIPTION "The SSH library") -if (CMAKE_VERSION VERSION_LESS "3.1") - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - set (CMAKE_C_FLAGS "--std=gnu90 ${CMAKE_C_FLAGS}") - endif() -else() - set (CMAKE_C_STANDARD 90) -endif() +set(CMAKE_UNITY_BUILD_BATCH_SIZE 32) + +option(BUILD_STATIC_LIBS "Build Static Libraries" ON) +add_feature_info("Static library" BUILD_STATIC_LIBS + "creating libssh2 static library") -option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF) +option(BUILD_SHARED_LIBS "Build Shared Libraries" ON) +add_feature_info("Shared library" BUILD_SHARED_LIBS + "creating libssh2 shared library (.so/.dll)") # Parse version @@ -79,20 +89,359 @@ endif() include(GNUInstallDirs) install( - FILES docs/AUTHORS COPYING docs/HACKING README RELEASE-NOTES NEWS + FILES + COPYING NEWS README RELEASE-NOTES + docs/AUTHORS docs/BINDINGS.md docs/HACKING.md DESTINATION ${CMAKE_INSTALL_DOCDIR}) include(max_warnings) -include(FeatureSummary) -add_subdirectory(src) +# Add socket libraries +if(WIN32) + list(APPEND SOCKET_LIBRARIES ws2_32) +else() + check_function_exists_may_need_library(socket HAVE_SOCKET socket) + if(NEED_LIB_SOCKET) + list(APPEND SOCKET_LIBRARIES socket) + endif() + check_function_exists_may_need_library(inet_addr HAVE_INET_ADDR nsl) + if(NEED_LIB_NSL) + list(APPEND SOCKET_LIBRARIES nsl) + endif() +endif() option(BUILD_EXAMPLES "Build libssh2 examples" ON) +option(BUILD_TESTING "Build libssh2 test suite" ON) + +if(NOT BUILD_STATIC_LIBS AND NOT BUILD_SHARED_LIBS) + set(BUILD_STATIC_LIBS ON) +endif() + +set(LIB_STATIC "libssh2_static") +set(LIB_SHARED "libssh2_shared") + +# lib flavour selected for example and test programs. +if(BUILD_SHARED_LIBS) + set(LIB_SELECTED ${LIB_SHARED}) +else() + set(LIB_SELECTED ${LIB_STATIC}) +endif() + +# Symbol hiding + +option(HIDE_SYMBOLS "Set to ON to hide all libssh2 symbols that are not officially external" ON) +mark_as_advanced(HIDE_SYMBOLS) +if(HIDE_SYMBOLS) + set(LIB_SHARED_DEFINITIONS LIBSSH2_EXPORTS) + if(WIN32) + elseif((CMAKE_C_COMPILER_ID MATCHES "Clang") OR + (CMAKE_COMPILER_IS_GNUCC AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0) OR + (CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)) + set(LIB_SHARED_C_FLAGS -fvisibility=hidden) + set(LIBSSH2_API "__attribute__ ((__visibility__ (\"default\")))") + elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0) + set(LIB_SHARED_C_FLAGS -xldscope=hidden) + set(LIBSSH2_API "__global") + endif() +endif() + +# Options + +# Enable debugging logging by default if the user configured a debug build +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(DEBUG_LOGGING_DEFAULT ON) +else() + set(DEBUG_LOGGING_DEFAULT OFF) +endif() +option(ENABLE_DEBUG_LOGGING "log execution with debug trace" + ${DEBUG_LOGGING_DEFAULT}) +add_feature_info(Logging ENABLE_DEBUG_LOGGING + "Logging of execution with debug trace") +if(ENABLE_DEBUG_LOGGING) + # Must be visible to the library and tests using internals + add_definitions(-DLIBSSH2DEBUG) +endif() + +# Auto-detection + +# Prefill values with known detection results +# Keep this synced with src/libssh2_setup.h +if(WIN32) + if(MINGW) + set(HAVE_SNPRINTF 1) + set(HAVE_UNISTD_H 1) + set(HAVE_INTTYPES_H 1) + set(HAVE_SYS_TIME_H 1) + set(HAVE_SYS_PARAM_H 1) + set(HAVE_GETTIMEOFDAY 1) + set(HAVE_STRTOLL 1) + elseif(MSVC) + set(HAVE_GETTIMEOFDAY 0) + if(NOT MSVC_VERSION LESS 1800) + set(HAVE_INTTYPES_H 1) + set(HAVE_STRTOLL 1) + else() + set(HAVE_INTTYPES_H 0) + set(HAVE_STRTOI64 1) + endif() + if(NOT MSVC_VERSION LESS 1900) + set(HAVE_SNPRINTF 1) + endif() + endif() +endif() + +## Platform checks +check_include_files(inttypes.h HAVE_INTTYPES_H) +if(NOT MSVC) + check_include_files(unistd.h HAVE_UNISTD_H) + check_include_files(sys/time.h HAVE_SYS_TIME_H) + check_include_files(sys/param.h HAVE_SYS_PARAM_H) # tests +endif() +if(NOT WIN32) + check_include_files(sys/select.h HAVE_SYS_SELECT_H) + check_include_files(sys/uio.h HAVE_SYS_UIO_H) + check_include_files(sys/socket.h HAVE_SYS_SOCKET_H) + check_include_files(sys/ioctl.h HAVE_SYS_IOCTL_H) + check_include_files(sys/un.h HAVE_SYS_UN_H) + check_include_files(arpa/inet.h HAVE_ARPA_INET_H) # example and tests + check_include_files(netinet/in.h HAVE_NETINET_IN_H) # example and tests +endif() + +# CMake uses C syntax in check_symbol_exists() that generates a warning with +# MSVC. To not break detection with ENABLE_WERRROR, we disable it for the +# duration of these tests. +if(MSVC AND ENABLE_WERROR) + cmake_push_check_state() + set(CMAKE_REQUIRED_FLAGS "/WX-") +endif() + +if(HAVE_SYS_TIME_H) + check_symbol_exists(gettimeofday sys/time.h HAVE_GETTIMEOFDAY) +else() + check_function_exists(gettimeofday HAVE_GETTIMEOFDAY) +endif() +check_symbol_exists(strtoll stdlib.h HAVE_STRTOLL) +if(NOT HAVE_STRTOLL) + # Try _strtoi64() if strtoll() is not available + check_symbol_exists(_strtoi64 stdlib.h HAVE_STRTOI64) +endif() +check_symbol_exists(snprintf stdio.h HAVE_SNPRINTF) +if(NOT WIN32) + check_symbol_exists(explicit_bzero string.h HAVE_EXPLICIT_BZERO) + check_symbol_exists(explicit_memset string.h HAVE_EXPLICIT_MEMSET) + check_symbol_exists(memset_s string.h HAVE_MEMSET_S) +endif() + +if(MSVC AND ENABLE_WERROR) + cmake_pop_check_state() +endif() + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "Interix") + # poll() does not work on these platforms + # + # Interix: "does provide poll(), but the implementing developer must + # have been in a bad mood, because poll() only works on the /proc + # filesystem here" + # + # macOS poll() has funny behaviors, like: + # not being able to do poll on no filedescriptors (10.3?) + # not being able to poll on some files (like anything in /dev) + # not having reliable timeout support + # inconsistent return of POLLHUP where other implementations give POLLIN + message("poll use is disabled on this platform") +elseif(NOT WIN32) + check_function_exists(poll HAVE_POLL) +endif() +if(WIN32) + set(HAVE_SELECT 1) +else() + check_function_exists(select HAVE_SELECT) +endif() + +# Non-blocking socket support tests. Use a separate, yet unset variable +# for the socket libraries to not link against the other configured +# dependencies which might not have been built yet. +if(NOT WIN32) + cmake_push_check_state() + set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES}) + check_nonblocking_socket_support() + cmake_pop_check_state() +endif() + +# Config file + +add_definitions(-DHAVE_CONFIG_H) + +configure_file(src/libssh2_config_cmake.h.in + ${CMAKE_CURRENT_BINARY_DIR}/src/libssh2_config.h) + +## Cryptography backend choice + +set(CRYPTO_BACKEND + "" + CACHE + STRING + "The backend to use for cryptography: OpenSSL, wolfSSL, Libgcrypt, +WinCNG, mbedTLS, or empty to try any available") + +# If the crypto backend was given, rather than searching for the first +# we are able to find, the find_package commands must abort configuration +# and report to the user. +if(CRYPTO_BACKEND) + set(SPECIFIC_CRYPTO_REQUIREMENT REQUIRED) +endif() + +if(CRYPTO_BACKEND STREQUAL "OpenSSL" OR NOT CRYPTO_BACKEND) + + find_package(OpenSSL ${SPECIFIC_CRYPTO_REQUIREMENT}) + + if(OPENSSL_FOUND) + set(CRYPTO_BACKEND "OpenSSL") + set(CRYPTO_BACKEND_DEFINE "LIBSSH2_OPENSSL") + set(CRYPTO_BACKEND_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR}) + list(APPEND LIBRARIES ${OPENSSL_LIBRARIES}) + list(APPEND PC_REQUIRES_PRIVATE libssl libcrypto) + + if(WIN32) + # Statically linking to OpenSSL requires crypt32 for some Windows APIs. + # This should really be handled by FindOpenSSL.cmake. + list(APPEND LIBRARIES crypt32 bcrypt) + list(APPEND PC_LIBS -lcrypt32 -lbcrypt) + + #set(CMAKE_FIND_DEBUG_MODE TRUE) + + find_file(DLL_LIBCRYPTO + NAMES crypto.dll + libcrypto-1_1.dll libcrypto-1_1-x64.dll + libcrypto-3.dll libcrypto-3-x64.dll + HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS} + PATH_SUFFIXES bin NO_DEFAULT_PATH) + if(DLL_LIBCRYPTO) + message(STATUS "Found libcrypto DLL: ${DLL_LIBCRYPTO}") + else() + message(WARNING + "Unable to find OpenSSL libcrypto DLL, executables may not run") + endif() + + find_file(DLL_LIBSSL + NAMES ssl.dll + libssl-1_1.dll libssl-1_1-x64.dll + libssl-3.dll libssl-3-x64.dll + HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS} + PATH_SUFFIXES bin NO_DEFAULT_PATH) + if(DLL_LIBSSL) + message(STATUS "Found libssl DLL: ${DLL_LIBSSL}") + else() + message(WARNING + "Unable to find OpenSSL libssl DLL, executables may not run") + endif() + + #set(CMAKE_FIND_DEBUG_MODE FALSE) + + if(DLL_LIBCRYPTO AND DLL_LIBSSL) + list(APPEND _RUNTIME_DEPENDENCIES ${DLL_LIBCRYPTO} ${DLL_LIBSSL}) + endif() + endif() + + find_package(ZLIB) + + if(ZLIB_FOUND) + list(APPEND LIBRARIES ${ZLIB_LIBRARIES}) + list(APPEND PC_REQUIRES_PRIVATE zlib) + endif() + endif() +endif() + +if(CRYPTO_BACKEND STREQUAL "wolfSSL" OR NOT CRYPTO_BACKEND) + + find_package(wolfssl ${SPECIFIC_CRYPTO_REQUIREMENT}) + + if(WOLFSSL_FOUND) + set(CRYPTO_BACKEND "wolfSSL") + set(CRYPTO_BACKEND_DEFINE "LIBSSH2_WOLFSSL") + set(CRYPTO_BACKEND_INCLUDE_DIR ${WOLFSSL_INCLUDE_DIR} ${WOLFSSL_INCLUDE_DIR}/wolfssl) + list(APPEND LIBRARIES ${WOLFSSL_LIBRARIES}) + list(APPEND PC_LIBS -lwolfssl) + + if(WIN32) + list(APPEND LIBRARIES crypt32) + list(APPEND PC_LIBS -lcrypt32) + endif() + + find_package(ZLIB) + + if(ZLIB_FOUND) + list(APPEND CRYPTO_BACKEND_INCLUDE_DIR ${ZLIB_INCLUDE_DIR}) # Public wolfSSL headers require zlib headers + list(APPEND LIBRARIES ${ZLIB_LIBRARIES}) + list(APPEND PC_REQUIRES_PRIVATE zlib) + endif() + endif() +endif() + +if(CRYPTO_BACKEND STREQUAL "Libgcrypt" OR NOT CRYPTO_BACKEND) + + find_package(Libgcrypt ${SPECIFIC_CRYPTO_REQUIREMENT}) + + if(LIBGCRYPT_FOUND) + set(CRYPTO_BACKEND "Libgcrypt") + set(CRYPTO_BACKEND_DEFINE "LIBSSH2_LIBGCRYPT") + set(CRYPTO_BACKEND_INCLUDE_DIR ${LIBGCRYPT_INCLUDE_DIRS}) + list(APPEND LIBRARIES ${LIBGCRYPT_LIBRARIES}) + list(APPEND PC_LIBS -lgcrypt) + endif() +endif() + +if(CRYPTO_BACKEND STREQUAL "mbedTLS" OR NOT CRYPTO_BACKEND) + + find_package(mbedTLS ${SPECIFIC_CRYPTO_REQUIREMENT}) + + if(MBEDTLS_FOUND) + set(CRYPTO_BACKEND "mbedTLS") + set(CRYPTO_BACKEND_DEFINE "LIBSSH2_MBEDTLS") + set(CRYPTO_BACKEND_INCLUDE_DIR ${MBEDTLS_INCLUDE_DIR}) + list(APPEND LIBRARIES ${MBEDTLS_LIBRARIES}) + list(APPEND PC_LIBS -lmbedcrypto) + link_directories(${MBEDTLS_LIBRARY_DIR}) + endif() +endif() + +# Detect platform-specific crypto-backends last: + +if(CRYPTO_BACKEND STREQUAL "WinCNG" OR NOT CRYPTO_BACKEND) + if(WIN32) + set(CRYPTO_BACKEND "WinCNG") + set(CRYPTO_BACKEND_DEFINE "LIBSSH2_WINCNG") + set(CRYPTO_BACKEND_INCLUDE_DIR "") + + list(APPEND LIBRARIES crypt32 bcrypt) + list(APPEND PC_LIBS -lcrypt32 -lbcrypt) + elseif(${SPECIFIC_CRYPTO_REQUIREMENT} STREQUAL ${REQUIRED}) + message(FATAL_ERROR "WinCNG not available") + endif() +endif() + +# Global functions + +# Convert GNU Make assignments into CMake ones. +function(transform_makefile_inc INPUT_FILE OUTPUT_FILE) + file(READ ${INPUT_FILE} MAKEFILE_INC_CMAKE) + + string(REGEX REPLACE "\\\\\n" "" MAKEFILE_INC_CMAKE ${MAKEFILE_INC_CMAKE}) + string(REGEX REPLACE "([A-Za-z_]+) *= *([^\n]*)" "set(\\1 \\2)" MAKEFILE_INC_CMAKE ${MAKEFILE_INC_CMAKE}) + + file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_CMAKE}) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${INPUT_FILE}") +endfunction() + +# + +add_subdirectory(src) + if(BUILD_EXAMPLES) add_subdirectory(example) endif() -option(BUILD_TESTING "Build libssh2 test suite" ON) if(BUILD_TESTING) enable_testing() add_subdirectory(tests) @@ -103,7 +452,11 @@ if(LINT) add_custom_target(lint ALL ./ci/checksrc.sh WORKING_DIRECTORY ${libssh2_SOURCE_DIR}) - add_dependencies(libssh2 lint) + if(BUILD_STATIC_LIBS) + add_dependencies(${LIB_STATIC} lint) + else() + add_dependencies(${LIB_SHARED} lint) + endif() endif() add_subdirectory(docs) diff --git a/COPYING b/COPYING index 937ed32e3a..af4d874cdb 100644 --- a/COPYING +++ b/COPYING @@ -2,7 +2,7 @@ * Copyright (c) 2005,2006 Mikhail Gusarov * Copyright (c) 2006-2007 The Written Word, Inc. * Copyright (c) 2007 Eli Fant - * Copyright (c) 2009-2021 Daniel Stenberg + * Copyright (c) 2009-2023 Daniel Stenberg * Copyright (C) 2008, 2009 Simon Josefsson * Copyright (c) 2000 Markus Friedl * Copyright (c) 2015 Microsoft Corp. @@ -41,4 +41,3 @@ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ - diff --git a/Makefile.OpenSSL.inc b/Makefile.OpenSSL.inc deleted file mode 100644 index 1e4e8f0bbb..0000000000 --- a/Makefile.OpenSSL.inc +++ /dev/null @@ -1,3 +0,0 @@ -CRYPTO_CSOURCES = openssl.c -CRYPTO_HHEADERS = openssl.h -CRYPTO_LTLIBS = $(LTLIBSSL) diff --git a/Makefile.WinCNG.inc b/Makefile.WinCNG.inc deleted file mode 100644 index bbcb82bfde..0000000000 --- a/Makefile.WinCNG.inc +++ /dev/null @@ -1,3 +0,0 @@ -CRYPTO_CSOURCES = wincng.c -CRYPTO_HHEADERS = wincng.h -CRYPTO_LTLIBS = $(LTLIBBCRYPT) $(LTLIBCRYPT32) diff --git a/Makefile.am b/Makefile.am index 986441bd68..677be76a23 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,9 @@ AUTOMAKE_OPTIONS = foreign nostdinc -SUBDIRS = src tests docs +SUBDIRS = src docs +if ENABLE_TESTS +SUBDIRS += tests +endif if BUILD_EXAMPLES SUBDIRS += example endif @@ -8,44 +11,34 @@ endif pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libssh2.pc -include_HEADERS = \ - include/libssh2.h \ - include/libssh2_publickey.h \ - include/libssh2_sftp.h - -NETWAREFILES = nw/keepscreen.c \ - nw/nwlib.c \ - nw/GNUmakefile \ - nw/test/GNUmakefile - -DSP = win32/libssh2.dsp -VCPROJ = win32/libssh2.vcproj - -DISTCLEANFILES = $(DSP) - -VMSFILES = vms/libssh2_make_example.dcl vms/libssh2_make_help.dcl \ -vms/libssh2_make_kit.dcl vms/libssh2_make_lib.dcl vms/man2help.c \ -vms/readme.vms vms/libssh2_config.h - -WIN32FILES = win32/GNUmakefile win32/test/GNUmakefile \ -win32/libssh2_config.h win32/config.mk win32/rules.mk \ -win32/Makefile.Watcom win32/libssh2.dsw win32/tests.dsp $(DSP) \ -win32/msvcproj.head win32/msvcproj.foot win32/libssh2.rc - -OS400FILES = os400/README400 os400/initscript.sh os400/make.sh \ -os400/make-src.sh os400/make-rpg.sh os400/make-include.sh \ -os400/os400sys.c os400/ccsid.c \ -os400/libssh2_config.h os400/macros.h os400/libssh2_ccsid.h \ -os400/include/alloca.h os400/include/sys/socket.h os400/include/stdio.h \ -os400/libssh2rpg/libssh2.rpgle.in \ -os400/libssh2rpg/libssh2_ccsid.rpgle.in \ -os400/libssh2rpg/libssh2_publickey.rpgle \ -os400/libssh2rpg/libssh2_sftp.rpgle \ -Makefile.os400qc3.inc - -EXTRA_DIST = $(WIN32FILES) $(NETWAREFILES) get_ver.awk \ - maketgz NMakefile RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath \ - CMakeLists.txt cmake $(OS400FILES) +include_HEADERS = \ + include/libssh2.h \ + include/libssh2_publickey.h \ + include/libssh2_sftp.h + +DISTCLEANFILES = + +VMSFILES = vms/libssh2_make_example.dcl vms/libssh2_make_help.dcl \ + vms/libssh2_make_kit.dcl vms/libssh2_make_lib.dcl vms/man2help.c \ + vms/readme.vms vms/libssh2_config.h + +WIN32FILES = src/libssh2.rc NMakefile + +OS400FILES = os400/README400 os400/initscript.sh os400/make.sh \ + os400/make-src.sh os400/make-rpg.sh os400/make-include.sh \ + os400/os400sys.c os400/ccsid.c \ + os400/libssh2_config.h os400/macros.h os400/libssh2_ccsid.h \ + os400/include/alloca.h os400/include/sys/socket.h os400/include/stdio.h \ + os400/include/assert.h \ + os400/libssh2rpg/libssh2.rpgle.in \ + os400/libssh2rpg/libssh2_ccsid.rpgle.in \ + os400/libssh2rpg/libssh2_publickey.rpgle \ + os400/libssh2rpg/libssh2_sftp.rpgle + +EXTRA_DIST = $(WIN32FILES) get_ver.awk \ + maketgz RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath \ + CMakeLists.txt cmake git2news.pl libssh2-style.el README.md $(OS400FILES) \ + buildconf Makefile.mk ACLOCAL_AMFLAGS = -I m4 @@ -76,79 +69,21 @@ build-coverage: make CFLAGS=$(COVERAGE_CCOPTS) check mkdir -p $(COVERAGE_OUT) lcov --directory . --output-file $(COVERAGE_OUT)/$(PACKAGE).info \ - --capture + --capture gen-coverage: genhtml --output-directory $(COVERAGE_OUT) \ - $(COVERAGE_OUT)/$(PACKAGE).info \ - --highlight --frames --legend \ - --title "$(PACKAGE_NAME)" + $(COVERAGE_OUT)/$(PACKAGE).info \ + --highlight --frames --legend \ + --title "$(PACKAGE_NAME)" coverage: init-coverage build-coverage gen-coverage -# DSP/VCPROJ generation adapted from libcurl -# only OpenSSL and WinCNG are supported with this build system -CRYPTO_CSOURCES = openssl.c wincng.c mbedtls.c -CRYPTO_HHEADERS = openssl.h wincng.h mbedtls.h -# Makefile.inc provides the CSOURCES and HHEADERS defines -include Makefile.inc - -WIN32SOURCES = $(CSOURCES) -WIN32HEADERS = $(HHEADERS) libssh2_config.h - -$(DSP): win32/msvcproj.head win32/msvcproj.foot Makefile.am - echo "creating $(DSP)" - @( (cat $(srcdir)/win32/msvcproj.head; \ - echo "# Begin Group \"Source Files\""; \ - echo ""; \ - echo "# PROP Default_Filter \"cpp;c;cxx\""; \ - win32_srcs='$(WIN32SOURCES)'; \ - sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \ - for file in $$sorted_srcs; do \ - echo "# Begin Source File"; \ - echo ""; \ - echo "SOURCE=..\\src\\"$$file; \ - echo "# End Source File"; \ - done; \ - echo "# End Group"; \ - echo "# Begin Group \"Header Files\""; \ - echo ""; \ - echo "# PROP Default_Filter \"h;hpp;hxx\""; \ - win32_hdrs='$(WIN32HEADERS)'; \ - sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \ - for file in $$sorted_hdrs; do \ - echo "# Begin Source File"; \ - echo ""; \ - if [ "$$file" = "libssh2_config.h" ]; \ - then \ - echo "SOURCE=.\\"$$file; \ - else \ - echo "SOURCE=..\\src\\"$$file; \ - fi; \ - echo "# End Source File"; \ - done; \ - echo "# End Group"; \ - cat $(srcdir)/win32/msvcproj.foot) | \ - awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ ) - -$(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am - echo "creating $(VCPROJ)" - @( (cat $(srcdir)/vc8proj.head; \ - win32_srcs='$(WIN32SOURCES)'; \ - sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \ - for file in $$sorted_srcs; do \ - echo ""; \ - done; \ - echo ""; \ - win32_hdrs='$(WIN32HEADERS)'; \ - sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \ - for file in $$sorted_hdrs; do \ - echo ""; \ - done; \ - cat $(srcdir)/vc8proj.foot) | \ - awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ ) - checksrc: - perl src/checksrc.pl -i4 -m79 -ASIZEOFNOPAREN -ASNPRINTF -ACOPYRIGHT \ - -AFOPENMODE -Wsrc/libssh2_config.h src/*.[ch] include/*.h example/*.c \ - tests/*.[ch] + perl ci/checksrc.pl -i4 -m79 \ + -ASNPRINTF \ + -ACOPYRIGHT \ + -AFOPENMODE \ + -ATYPEDEFSTRUCT \ + -Wsrc/libssh2_config.h src/*.[ch] include/*.h example/*.c \ + tests/*.[ch] diff --git a/Makefile.inc b/Makefile.inc deleted file mode 100644 index 20d2ebeeb2..0000000000 --- a/Makefile.inc +++ /dev/null @@ -1,7 +0,0 @@ -CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \ - packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \ - version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c \ - blowfish.c bcrypt_pbkdf.c agent_win.c - -HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \ - mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h blf.h agent.h diff --git a/Makefile.libgcrypt.inc b/Makefile.libgcrypt.inc deleted file mode 100644 index 0a3aae9aad..0000000000 --- a/Makefile.libgcrypt.inc +++ /dev/null @@ -1,3 +0,0 @@ -CRYPTO_CSOURCES = libgcrypt.c -CRYPTO_HHEADERS = libgcrypt.h -CRYPTO_LTLIBS = $(LTLIBGCRYPT) diff --git a/Makefile.mbedTLS.inc b/Makefile.mbedTLS.inc deleted file mode 100644 index b9f19fce1a..0000000000 --- a/Makefile.mbedTLS.inc +++ /dev/null @@ -1,3 +0,0 @@ -CRYPTO_CSOURCES = mbedtls.c -CRYPTO_HHEADERS = mbedtls.h -CRYPTO_LTLIBS = $(LTLIBMBEDCRYPTO) diff --git a/Makefile.mk b/Makefile.mk new file mode 100644 index 0000000000..b5c13d5680 --- /dev/null +++ b/Makefile.mk @@ -0,0 +1,326 @@ +######################################################################### +# +# Makefile for building libssh2 with GCC-like toolchains. +# Use: make -f Makefile.mk [help|all|clean|dist|distclean|dyn|objclean|example|exampleclean|test|testclean] +# +# Written by Guenter Knauf and Viktor Szakats +# +# Look for ' ?=' to find accepted customization variables. +# +######################################################################### + +### Common + +CFLAGS ?= +CPPFLAGS ?= +LIBSSH2_CPPFLAGS_LIB ?= +RCFLAGS ?= +LDFLAGS ?= +LIBSSH2_LDFLAGS_BIN ?= +LIBSSH2_LDFLAGS_DYN ?= +LIBS ?= + +CROSSPREFIX ?= + +ifeq ($(CC),cc) + CC := gcc +endif +CC := $(CROSSPREFIX)$(CC) +AR := $(CROSSPREFIX)$(AR) +RC ?= $(CROSSPREFIX)windres + +# For compatibility +ARCH ?= +ifeq ($(ARCH),w64) + TRIPLET := x86_64-w64-mingw32 + CFLAGS += -m64 + LDFLAGS += -m64 + RCFLAGS += --target=pe-x86-64 +else ifdef ARCH + TRIPLET := i686-w64-mingw32 + CFLAGS += -m32 + LDFLAGS += -m32 + RCFLAGS += --target=pe-i386 +else + TRIPLET ?= $(shell $(CC) -dumpmachine) +endif + +BLD_DIR ?= $(TRIPLET) + +ifneq ($(findstring -w,$(TRIPLET)),) + WIN32 := 1 + BIN_EXT := .exe + DYN_EXT := .dll +else + CPPFLAGS += -I$(BLD_DIR) -DHAVE_CONFIG_H +endif + +CPPFLAGS += -Isrc -Iinclude +RCFLAGS += -Iinclude + +# examples, tests + +LIBSSH2_LDFLAGS_BIN += -L$(BLD_DIR) +LIBS_BIN := -lssh2 +ifdef WIN32 + LIBS_BIN += -lws2_32 +endif + +ifdef DYN + ifdef WIN32 + libssh2_DEPENDENCIES := $(BLD_DIR)/libssh2.dll.a + else + libssh2_DEPENDENCIES := $(BLD_DIR)/libssh2$(DYN_EXT) + endif + LIBSSH2_LDFLAGS_BIN += -shared +else + libssh2_DEPENDENCIES := $(BLD_DIR)/libssh2.a + LIBSSH2_LDFLAGS_BIN += -static +endif + +### Optional features + +# must be equal to DEBUG or NDEBUG +DB ?= NDEBUG +CPPFLAGS += -D$(DB) +ifeq ($(DB),NDEBUG) + OBJ_DIR := release +else + OBJ_DIR := debug + CFLAGS += -g + CPPFLAGS += -DLIBSSH2DEBUG +endif + +OBJ_DIR := $(BLD_DIR)/$(OBJ_DIR) + +# Linker options to exclude for shared mode executables. +_LDFLAGS := +_LIBS := + +ifdef OPENSSL_PATH + CPPFLAGS += -DLIBSSH2_OPENSSL + OPENSSL_INCLUDE ?= $(OPENSSL_PATH)/include + OPENSSL_LIBPATH ?= $(OPENSSL_PATH)/lib + CPPFLAGS += -I"$(OPENSSL_INCLUDE)" + _LDFLAGS += -L"$(OPENSSL_LIBPATH)" + OPENSSL_LIBS ?= -lssl -lcrypto + _LIBS += $(OPENSSL_LIBS) +else ifdef WOLFSSL_PATH + CPPFLAGS += -DLIBSSH2_WOLFSSL + CPPFLAGS += -I"$(WOLFSSL_PATH)/include" + CPPFLAGS += -I"$(WOLFSSL_PATH)/include/wolfssl" + _LDFLAGS += -L"$(WOLFSSL_PATH)/lib" + _LIBS += -lwolfssl +else ifdef LIBGCRYPT_PATH + CPPFLAGS += -DLIBSSH2_LIBGCRYPT + CPPFLAGS += -I"$(LIBGCRYPT_PATH)/include" + _LDFLAGS += -L"$(LIBGCRYPT_PATH)/lib" + _LIBS += -lgcrypt +else ifdef MBEDTLS_PATH + CPPFLAGS += -DLIBSSH2_MBEDTLS + CPPFLAGS += -I"$(MBEDTLS_PATH)/include" + _LDFLAGS += -L"$(MBEDTLS_PATH)/lib" + _LIBS += -lmbedtls -lmbedx509 -lmbedcrypto +else ifdef WIN32 + CPPFLAGS += -DLIBSSH2_WINCNG +else + $(error No suitable cryptography backend found) +endif + +ifdef ZLIB_PATH + CPPFLAGS += -DLIBSSH2_HAVE_ZLIB + CPPFLAGS += -I"$(ZLIB_PATH)/include" + _LDFLAGS += -L"$(ZLIB_PATH)/lib" + _LIBS += -lz +endif + +ifdef WIN32 + _LIBS += -lws2_32 -lcrypt32 -lbcrypt +endif + +LIBSSH2_LDFLAGS_DYN += $(_LDFLAGS) +LIBS_DYN += $(_LIBS) + +ifndef DYN + LIBSSH2_LDFLAGS_BIN += $(_LDFLAGS) + LIBS_BIN += $(_LIBS) +endif + +### Rules + +# Platform-dependent helper tool macros +ifneq ($(findstring /sh,$(SHELL)),) +DEL = rm -f $1 +RMDIR = rm -fr $1 +MKDIR = mkdir -p $1 +COPY = -cp -afv $1 $2 +DL = ' +else +DEL = -del 2>NUL /q /f $(subst /,\,$1) +RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) +MKDIR = -md 2>NUL $(subst /,\,$1) +COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) +endif +AWK := awk +ZIP := zip -qzr9 + +# Include the version info retrieved from libssh2.h +-include $(OBJ_DIR)/version.inc + +vpath %.c src +ifdef WIN32 +vpath %.rc src +endif + +# Get CSOURCES define +include src/Makefile.inc + +OBJS := $(addprefix $(OBJ_DIR)/,$(patsubst %.c,%.o,$(CSOURCES))) + +TARGET := $(BLD_DIR)/libssh2 + +# Override the path below to point to your Distribution folder. +DISTNAM ?= libssh2-$(LIBSSH2_VERSION_STR)-bin-$(word 1,$(subst -, ,$(TRIPLET))) +DISTDIR := $(BLD_DIR)/$(DISTNAM) +DISTARC := $(DISTDIR).zip + +LIBSSH2_DYN_SUFFIX ?= +libssh2_dyn_LIBRARY := $(TARGET)$(LIBSSH2_DYN_SUFFIX)$(DYN_EXT) +OBJS_dyn := $(OBJS) +ifdef WIN32 + libssh2_def_LIBRARY := $(libssh2_dyn_LIBRARY:$(DYN_EXT)=.def) + libssh2_dyn_a_LIBRARY := $(TARGET).dll.a + OBJS_dyn += $(OBJ_DIR)/libssh2.res + LIBSSH2_LDFLAGS_DYN += -Wl,--output-def,$(libssh2_def_LIBRARY),--out-implib,$(libssh2_dyn_a_LIBRARY) +endif + +# Get noinst_PROGRAMS define +include example/Makefile.am +TARGETS_EXAMPLES := $(patsubst %.c,%$(BIN_EXT),$(strip $(wildcard example/*.c))) + +all: lib dyn + +# For compatibility +dll: dyn + +dyn: prebuild $(libssh2_dyn_LIBRARY) + +lib: prebuild $(TARGET).a + +prebuild: $(OBJ_DIR) $(OBJ_DIR)/version.inc + +example: $(TARGETS_EXAMPLES) + +# Get DOCKER_TESTS, STANDALONE_TESTS, SSHD_TESTS, TESTS_WITH_LIB_STATIC, +# librunner_la_SOURCES defines +include tests/Makefile.inc +TARGETS_RUNNER := $(TARGET)-runner.a +TARGETS_RUNNER_OBJS := $(addprefix $(OBJ_DIR)/,$(patsubst %.c,%.o,$(filter %.c,$(librunner_la_SOURCES)))) +TARGETS_TESTS := $(patsubst %.c,%$(BIN_EXT),$(addprefix tests/,$(addsuffix .c,$(DOCKER_TESTS) $(STANDALONE_TESTS) $(SSHD_TESTS)))) +ifdef DYN +TARGETS_TESTS := $(filter-out $(patsubst %.c,%$(BIN_EXT),$(addprefix tests/,$(addsuffix .c,$(TESTS_WITH_LIB_STATIC)))),$(TARGETS_TESTS)) +endif + +test: $(TARGETS_RUNNER) $(TARGETS_TESTS) + +$(TARGETS_RUNNER_OBJS): + $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) -c $(patsubst $(OBJ_DIR)/%.o,tests/%.c,$@) -o $@ + +$(TARGETS_RUNNER): $(TARGETS_RUNNER_OBJS) + @$(call DEL, $@) + $(AR) rcs $@ $^ + +test_%$(BIN_EXT): $(libssh2_DEPENDENCIES) $(TARGETS_RUNNER) + $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LIBSSH2_LDFLAGS_BIN) \ + $(patsubst %$(BIN_EXT),%.c,$@) -o $@ $(TARGETS_RUNNER) $(LIBS) $(LIBS_BIN) + +%$(BIN_EXT): %.c $(libssh2_DEPENDENCIES) + $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LIBSSH2_LDFLAGS_BIN) $< -o $@ $(LIBS) $(LIBS_BIN) + +$(OBJ_DIR)/%.o: %.c + $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) $(LIBSSH2_CPPFLAGS_LIB) -c $< -o $@ + +$(libssh2_dyn_LIBRARY) $(libssh2_dyn_a_LIBRARY): $(OBJS_dyn) + @$(call DEL, $@) + $(CC) $(LDFLAGS) -shared $(LIBSSH2_LDFLAGS_DYN) $^ -o $@ $(LIBS) $(LIBS_DYN) + +ifdef WIN32 +$(OBJ_DIR)/%.res: %.rc + $(RC) -O coff $(RCFLAGS) -i $< -o $@ +endif + +$(TARGET).a: $(OBJS) + @$(call DEL, $@) + $(AR) rcs $@ $^ + +$(OBJ_DIR)/version.inc: get_ver.awk include/libssh2.h $(OBJ_DIR) + $(AWK) -f $^ > $@ + +dist: all $(DISTDIR) $(DISTDIR)/readme.txt + @$(call MKDIR, $(DISTDIR)/bin) + @$(call MKDIR, $(DISTDIR)/include) + @$(call MKDIR, $(DISTDIR)/lib) + @$(call COPY, COPYING, $(DISTDIR)) + @$(call COPY, README, $(DISTDIR)) + @$(call COPY, RELEASE-NOTES, $(DISTDIR)) + @$(call COPY, include/*.h, $(DISTDIR)/include) + @$(call COPY, $(TARGET).a, $(DISTDIR)/lib) +ifdef WIN32 + @$(call COPY, $(libssh2_def_LIBRARY), $(DISTDIR)/bin) + @$(call COPY, $(libssh2_dyn_LIBRARY), $(DISTDIR)/bin) + @$(call COPY, $(libssh2_dyn_a_LIBRARY), $(DISTDIR)/lib) +else + @$(call COPY, $(libssh2_dyn_LIBRARY), $(DISTDIR)/lib) +endif + @echo Creating... $(DISTARC) + (cd $(DISTDIR)/.. && $(ZIP) $(abspath $(DISTARC)) $(DISTNAM)/* < $(abspath $(DISTDIR)/readme.txt)) + +distclean vclean: clean + $(call RMDIR, $(DISTDIR)) + $(call DEL, $(DISTARC)) + +objclean: all + $(call RMDIR, $(OBJ_DIR)) + +exampleclean: + $(call DEL, $(TARGETS_EXAMPLES)) + +testclean: + $(call DEL, $(TARGETS_RUNNER_OBJS) $(TARGETS_RUNNER) $(TARGETS_TESTS)) + +clean: + $(call DEL, $(TARGET).a $(libssh2_dyn_LIBRARY) $(libssh2_def_LIBRARY) $(libssh2_dyn_a_LIBRARY)) + $(call RMDIR, $(OBJ_DIR)) + +$(OBJ_DIR) $(DISTDIR): + @$(call MKDIR, $@) + +$(DISTDIR)/readme.txt: Makefile.mk + @echo Creating... $@ + @echo $(DL)This is a binary distribution for $(TRIPLET).$(DL) > $@ + @echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@ + @echo $(DL)Please download the complete libssh2 package for$(DL) >> $@ + @echo $(DL)any further documentation:$(DL) >> $@ + @echo $(DL)https://www.libssh2.org/$(DL) >> $@ + +help: $(OBJ_DIR)/version.inc + @echo $(DL)===========================================================$(DL) + @echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL) + @echo $(DL)wolfSSL path = $(WOLFSSL_PATH)$(DL) + @echo $(DL)libgcrypt path = $(LIBGCRYPT_PATH)$(DL) + @echo $(DL)mbedTLS path = $(MBEDTLS_PATH)$(DL) + @echo $(DL)zlib path = $(ZLIB_PATH)$(DL) + @echo $(DL)===========================================================$(DL) + @echo $(DL)libssh2 $(LIBSSH2_VERSION_STR) - available targets are:$(DL) + @echo $(DL)$(MAKE) all$(DL) + @echo $(DL)$(MAKE) dyn$(DL) + @echo $(DL)$(MAKE) lib$(DL) + @echo $(DL)$(MAKE) clean$(DL) + @echo $(DL)$(MAKE) dist$(DL) + @echo $(DL)$(MAKE) distclean$(DL) + @echo $(DL)$(MAKE) objclean$(DL) + @echo $(DL)$(MAKE) example$(DL) + @echo $(DL)$(MAKE) exampleclean$(DL) + @echo $(DL)$(MAKE) test$(DL) + @echo $(DL)$(MAKE) testclean$(DL) + @echo $(DL)===========================================================$(DL) diff --git a/Makefile.os400qc3.inc b/Makefile.os400qc3.inc deleted file mode 100644 index e55094d9bd..0000000000 --- a/Makefile.os400qc3.inc +++ /dev/null @@ -1,2 +0,0 @@ -CRYPTO_CSOURCES = os400qc3.c -CRYPTO_HHEADERS = os400qc3.h diff --git a/NMakefile b/NMakefile index 07bc2ddad1..9e3f36e378 100644 --- a/NMakefile +++ b/NMakefile @@ -1,23 +1,86 @@ -!include "win32/config.mk" +!if "$(TARGET)" == "" +TARGET=Release +!endif -!if "$(WITH_WINCNG)" == "1" -!include "Makefile.WinCNG.inc" +!if "$(TARGET)" == "Debug" +SUFFIX=_debug +CFLAGS=/Od /MDd +DLLFLAGS=/LDd /DEBUG !else -!include "Makefile.OpenSSL.inc" +CFLAGS=/Oi /O2 /Oy /GF /Y- /MD /DNDEBUG +DLLFLAGS=/LD +!endif + +CFLAGS=/nologo /GL /Zi /EHsc $(CFLAGS) /Iinclude + +!if "$(OPENSSL_PATH)" != "" +CFLAGS=$(CFLAGS) /DLIBSSH2_OPENSSL /I$(OPENSSL_PATH)\include +LIBS=$(LIBS) $(OPENSSL_PATH)\lib\crypto.lib $(OPENSSL_PATH)\lib\ssl.lib +!else +CFLAGS=$(CFLAGS) /DLIBSSH2_WINCNG +LIBS=crypt32.lib bcrypt.lib +!endif + +!if "$(ZLIB_PATH)" != "" +CFLAGS=$(CFLAGS) /DLIBSSH2_HAVE_ZLIB /I$(ZLIB_PATH)\include +LIBS=$(LIBS) $(ZLIB_PATH)\lib\zlib.lib !endif -!include "Makefile.inc" + +LIBS=$(LIBS) ws2_32.lib user32.lib advapi32.lib gdi32.lib + +INTDIR=$(TARGET) + +SUBDIR=src + +!include "src/Makefile.inc" OBJECTS=$(CSOURCES:.c=.obj) -# SUBDIRS=src example -SUBDIRS=src +!if "$(TARGET)" == "Debug" +OBJECTS=Debug/$(OBJECTS: = Debug/) +OBJECTS=$(OBJECTS: Debug/ = ) +!else +TARGET=Release +OBJECTS=Release/$(OBJECTS: = Release/) +OBJECTS=$(OBJECTS: Release/ = ) +!endif -all-sub: win32\objects.mk - -for %D in ($(SUBDIRS)) do $(MAKE) /nologo /f %D/NMakefile BUILD=$(BUILD) SUBDIR=%D all-sub +!if "$(AR)" == "" +AR=lib +ARFLAGS=-nologo /LTCG +!endif -clean: - -rmdir 2>NUL /s/q $(TARGET) - -del 2>NUL win32\objects.mk +RESOURCE=$(INTDIR)\libssh2.res +DLL=libssh2$(SUFFIX).dll +STATICLIB=$(INTDIR)\libssh2.lib + +!if "$(BUILD_STATIC_LIB)" == "" +all: $(INTDIR) $(DLL) +!else +all: $(INTDIR) $(STATICLIB) +!endif + +$(INTDIR): + @if not exist $(INTDIR) mkdir $(INTDIR) + +$(DLL): $(OBJECTS) $(RESOURCE) + $(CC) -o $(DLL) $(CFLAGS) $(DLLFLAGS) $(OBJECTS) $(RESOURCE) $(LIBS) + +$(STATICLIB): $(OBJECTS) + $(AR) $(ARFLAGS) -out:$@ $(OBJECTS) + +$(RESOURCE): src\libssh2.rc + $(RC) /Iinclude /Fo"$@" $? + +all-sub: $(INTDIR) all + +clean-sub: clean + +{$(SUBDIR)}.c{$(INTDIR)}.obj:: + $(CC) -c $(CFLAGS) /Fo"$(INTDIR)\\" $< + +clean: + -rd 2>NUL /q /s $(TARGET) real-clean vclean: clean -del 2>NUL libssh2.dll @@ -25,9 +88,3 @@ real-clean vclean: clean -del 2>NUL libssh2.ilk -del 2>NUL libssh2.lib -del 2>NUL *.pdb - -win32\objects.mk: Makefile.inc - @echo OBJECTS = \>$@ - @for %O in ($(OBJECTS)) do @echo $$(INTDIR)\%O \>>$@ - @echo $$(EOL)>>$@ - diff --git a/README b/README index 8a148568cf..89639ba7d2 100644 --- a/README +++ b/README @@ -6,7 +6,7 @@ the revised BSD license. Web site: https://www.libssh2.org/ -Mailing list: https://cool.haxx.se/mailman/listinfo/libssh2-devel +Mailing list: https://lists.haxx.se/listinfo/libssh2-devel License: see COPYING diff --git a/README.md b/README.md index a4c741f68c..caa0b6708a 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ the revised BSD license. [Web site](https://www.libssh2.org/) -[Mailing list](https://cool.haxx.se/mailman/listinfo/libssh2-devel) +[Mailing list](https://lists.haxx.se/listinfo/libssh2-devel) -[BSD Licensed](https://libssh2.org/license.html) +[BSD Licensed](https://www.libssh2.org/license.html) [Web site source code](https://github.com/libssh2/www) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 62064a9fe6..c1c73db968 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,62 +1,75 @@ -libssh2 1.10 +libssh2 1.11 This release includes the following enhancements and bugfixes: - o adds agent forwarding support - o adds OpenSSH Agent support on Windows - o adds ECDSA key support using the Mbed TLS backend - o adds ECDSA cert authentication - o adds diffie-hellman-group14-sha256, diffie-hellman-group16-sha512, - diffie-hellman-group18-sha512 key exchanges - o adds support for PKIX key reading when using ed25519 with OpenSSL - o adds support for EWOULDBLOCK on VMS systems - o adds support for building with OpenSSL 3 - o adds support for using FIPS mode in OpenSSL - o adds debug symbols when building with MSVC - o adds support for building on the 3DS - o adds unicode build support on Windows - o restores os400 building - o increases min, max and opt Diffie Hellman group values - o improves portiablity of the make file - o improves timeout behavior with 2FA keyboard auth - o various improvements to the Wincng backend - o fixes reading parital packet replies when using an agent - o fixes Diffie Hellman key exchange on Windows 1903+ builds - o fixes building tests with older versions of OpenSSL - o fixes possible multiple definition warnings - o fixes potential cast issues _libssh2_ecdsa_key_get_curve_type() - o fixes potential use after free if libssh2_init() is called twice - o improved linking when using Mbed TLS - o fixes call to libssh2_crypto_exit() if crypto hasn't been initialized - o fixes crash when loading public keys with no id - o fixes possible out of bounds read when exchanging keys - o fixes possible out of bounds read when reading packets - o fixes possible out of bounds read when opening an X11 connection - o fixes possible out of bounds read when ecdh host keys - o fixes possible hang when trying to read a disconnected socket - o fixes a crash when using the delayed compression option - o fixes read error with large known host entries - o fixes various warnings - o fixes various small memory leaks - o improved error handling, various detailed errors will now be reported - o builds are now using OSS-Fuzz - o builds now use autoreconf instead of a custom build script - o cmake now respects install directory - o improved CI backend - o updated HACKING-CRYPTO documentation - o use markdown file extensions - o improved unit tests + o Adds support for encrypt-then-mac (ETM) MACs + o Adds support for AES-GCM crypto protocols + o Adds support for sk-ecdsa-sha2-nistp256 and sk-ssh-ed25519 keys + o Adds support for RSA certificate authentication + o Adds FIDO support with *_sk() functions + o Adds RSA-SHA2 key upgrading to OpenSSL, WinCNG, mbedTLS, OS400 backends + o Adds Agent Forwarding and libssh2_agent_sign() + o Adds support for Channel Signal message libssh2_channel_signal_ex() + o Adds support to get the user auth banner message libssh2_userauth_banner() + o Adds LIBSSH2_NO_{MD5, HMAC_RIPEMD, DSA, RSA, RSA_SHA1, ECDSA, ED25519, + AES_CBC, AES_CTR, BLOWFISH, RC4, CAST, 3DES} options + o Adds direct stream UNIX sockets with libssh2_channel_direct_streamlocal_ex() + o Adds wolfSSL support to CMake file + o Adds mbedTLS 3.x support + o Adds LibreSSL 3.5 support + o Adds support for CMake "unity" builds + o Adds CMake support for building shared and static libs in a single pass + o Adds symbol hiding support to CMake + o Adds support for libssh2.rc for all build tools + o Adds .zip, .tar.xz and .tar.bz2 release tarballs + o Enables ed25519 key support for LibreSSL 3.7.0 or higher + o Improves OpenSSL 1.1 and 3 compatibility + o Now requires OpenSSL 1.0.2 or newer + o Now requires CMake 3.1 or newer + o SFTP: Adds libssh2_sftp_open_ex_r() and libssh2_sftp_open_r() extended APIs + o SFTP: No longer has a packet limit when reading a directory + o SFTP: now parses attribute extensions if they exist + o SFTP: no longer will busy loop if SFTP fails to initialize + o SFTP: now clear various errors as expected + o SFTP: no longer skips files if the line buffer is too small + o SCP: add option to not quote paths + o SCP: Enables 64-bit offset support unconditionally + o Now skips leading \r and \n characters in banner_receive() + o Enables secure memory zeroing with all build tools on all platforms + o No longer logs SSH_MSG_REQUEST_FAILURE packets from keepalive + o Speed up base64 encoding by 7x + o Assert if there is an attempt to write a value that is too large + o WinCNG: fix memory leak in _libssh2_dh_secret() + o Added protection against possible null pointer dereferences + o Agent now handles overly large comment lengths + o Now ensure KEX replies don't include extra bytes + o Fixed possible buffer overflow when receiving SSH_MSG_USERAUTH_BANNER + o Fixed possible buffer overflow in keyboard interactive code path + o Fixed overlapping memcpy() + o Fixed Windows UWP builds + o Fixed DLL import name + o Renamed local RANDOM_PADDING macro to avoid unexpected define on Windows + o Support for building with gcc versions older than 8 + o Improvements to CMake, Makefile, NMakefile, GNUmakefile, autoreconf files + o Restores ANSI C89 compliance + o Enabled new compiler warnings and fixed/silenced them + o Improved error messages + o Now uses CIFuzz + o Numerous minor code improvements + o Improvements to CI builds + o Improvements to unit tests + o Improvements to doc files + o Improvements to example files + o Removed "old gex" build option + o Removed no-encryption/no-mac builds + o Removed support for NetWare and Watcom wmake build files This release would not have looked like this without help, code, reports and advice from friends like these: - katzer, Orgad Shaneh, mark-i-m, Zenju, axjowa, Thilo Schulz, - Etienne Samson, hlefebvre, seba30, Panos, jethrogb, Fabrice Fontaine, - Will Cosgrove, Daniel Stenberg, Michael Buckley, Wallace Souza Silva, - Romain-Geissler-1A, meierha, Tseng Jun, Thomas Klausner, Brendan Shanks, - Harry Sintonen, monnerat, Koutheir Attouchi, Marc Hörsken, yann-morin-1998, - Wez Furlong, TDi-jonesds, David Benjamin, Max Dymond, Igor Klevanets, - Viktor Szakats, Laurent Stacul, Mstrodl, Gabriel Smith, MarcT512, - Paul Capron, teottin, Tor Erik Ottinsen, Brian Inglis - - (40 contributors) + Viktor Szakats, Dan Fandrich, Will Cosgrove, Daniel Stenberg, Michael Buckley, + Zenju, Miguel de Icaza, Nick Woodruff, Keith Dart, Anders Borum, + Jörgen Sigvardsson, vajdaakos, Gustavo Junior Alves, Marc Hörsken, iruis, + Nishit Majithia, Stefan Eissing, metab0t, Y. Yang, skundu07, Mike Harris, + Gabriel Smith, Leo Liu, Miguel de Icaza, Sandeep Bansal, Harry Sintonen, + xalopp, tihmstar, Sunil Nimmagadda diff --git a/acinclude.m4 b/acinclude.m4 index 2066f0ec9b..1d7121e71c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,3 +1,145 @@ +dnl CURL_CPP_P +dnl +dnl Check if $cpp -P should be used for extract define values due to gcc 5 +dnl splitting up strings and defines between line outputs. gcc by default +dnl (without -P) will show TEST EINVAL TEST as +dnl +dnl # 13 "conftest.c" +dnl TEST +dnl # 13 "conftest.c" 3 4 +dnl 22 +dnl # 13 "conftest.c" +dnl TEST + +AC_DEFUN([CURL_CPP_P], [ + AC_MSG_CHECKING([if cpp -P is needed]) + AC_EGREP_CPP([TEST.*TEST], [ + #include +TEST EINVAL TEST + ], [cpp=no], [cpp=yes]) + AC_MSG_RESULT([$cpp]) + + dnl we need cpp -P so check if it works then + if test "x$cpp" = "xyes"; then + AC_MSG_CHECKING([if cpp -P works]) + OLDCPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS -P" + AC_EGREP_CPP([TEST.*TEST], [ + #include +TEST EINVAL TEST + ], [cpp_p=yes], [cpp_p=no]) + AC_MSG_RESULT([$cpp_p]) + + if test "x$cpp_p" = "xno"; then + AC_MSG_WARN([failed to figure out cpp -P alternative]) + # without -P + CPPPFLAG="" + else + # with -P + CPPPFLAG="-P" + fi + dnl restore CPPFLAGS + CPPFLAGS=$OLDCPPFLAGS + else + # without -P + CPPPFLAG="" + fi +]) + +dnl CURL_CHECK_DEF (SYMBOL, [INCLUDES], [SILENT]) +dnl ------------------------------------------------- +dnl Use the C preprocessor to find out if the given object-style symbol +dnl is defined and get its expansion. This macro will not use default +dnl includes even if no INCLUDES argument is given. This macro will run +dnl silently when invoked with three arguments. If the expansion would +dnl result in a set of double-quoted strings the returned expansion will +dnl actually be a single double-quoted string concatenating all them. + +AC_DEFUN([CURL_CHECK_DEF], [ + AC_REQUIRE([CURL_CPP_P])dnl + OLDCPPFLAGS=$CPPFLAGS + # CPPPFLAG comes from CURL_CPP_P + CPPFLAGS="$CPPFLAGS $CPPPFLAG" + AS_VAR_PUSHDEF([ac_HaveDef], [curl_cv_have_def_$1])dnl + AS_VAR_PUSHDEF([ac_Def], [curl_cv_def_$1])dnl + if test -z "$SED"; then + AC_MSG_ERROR([SED not set. Cannot continue without SED being set.]) + fi + if test -z "$GREP"; then + AC_MSG_ERROR([GREP not set. Cannot continue without GREP being set.]) + fi + ifelse($3,,[AC_MSG_CHECKING([for preprocessor definition of $1])]) + tmp_exp="" + AC_PREPROC_IFELSE([ + AC_LANG_SOURCE( +ifelse($2,,,[$2])[[ +#ifdef $1 +CURL_DEF_TOKEN $1 +#endif + ]]) + ],[ + tmp_exp=`eval "$ac_cpp conftest.$ac_ext" 2>/dev/null | \ + "$GREP" CURL_DEF_TOKEN 2>/dev/null | \ + "$SED" 's/.*CURL_DEF_TOKEN[[ ]][[ ]]*//' 2>/dev/null | \ + "$SED" 's/[["]][[ ]]*[["]]//g' 2>/dev/null` + if test -z "$tmp_exp" || test "$tmp_exp" = "$1"; then + tmp_exp="" + fi + ]) + if test -z "$tmp_exp"; then + AS_VAR_SET(ac_HaveDef, no) + ifelse($3,,[AC_MSG_RESULT([no])]) + else + AS_VAR_SET(ac_HaveDef, yes) + AS_VAR_SET(ac_Def, $tmp_exp) + ifelse($3,,[AC_MSG_RESULT([$tmp_exp])]) + fi + AS_VAR_POPDEF([ac_Def])dnl + AS_VAR_POPDEF([ac_HaveDef])dnl + CPPFLAGS=$OLDCPPFLAGS +]) + +dnl CURL_CHECK_COMPILER_CLANG +dnl ------------------------------------------------- +dnl Verify if compiler being used is clang. + +AC_DEFUN([CURL_CHECK_COMPILER_CLANG], [ + AC_BEFORE([$0],[CURL_CHECK_COMPILER_GNU_C])dnl + AC_MSG_CHECKING([if compiler is clang]) + CURL_CHECK_DEF([__clang__], [], [silent]) + if test "$curl_cv_have_def___clang__" = "yes"; then + AC_MSG_RESULT([yes]) + AC_MSG_CHECKING([if compiler is xlclang]) + CURL_CHECK_DEF([__ibmxl__], [], [silent]) + if test "$curl_cv_have_def___ibmxl__" = "yes" ; then + dnl IBM's almost-compatible clang version + AC_MSG_RESULT([yes]) + compiler_id="XLCLANG" + else + AC_MSG_RESULT([no]) + compiler_id="CLANG" + fi + fullclangver=`$CC -v 2>&1 | grep version` + clangver=`echo $fullclangver | grep "based on LLVM " | "$SED" 's/.*(based on LLVM \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*)/\1/'` + if test -z "$clangver"; then + if echo $fullclangver | grep "Apple LLVM version " >/dev/null; then + dnl Starting with Xcode 7 / clang 3.7, Apple clang won't tell its upstream version + clangver="3.7" + else + clangver=`echo $fullclangver | "$SED" 's/.*version \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*/\1/'` + fi + fi + clangvhi=`echo $clangver | cut -d . -f1` + clangvlo=`echo $clangver | cut -d . -f2` + compiler_num=`(expr $clangvhi "*" 100 + $clangvlo) 2>/dev/null` + flags_dbg_yes="-g" + flags_opt_all="-O -O0 -O1 -O2 -Os -O3 -O4" + flags_opt_yes="-O2" + flags_opt_off="-O0" + else + AC_MSG_RESULT([no]) + fi +]) dnl ********************************************************************** dnl CURL_DETECT_ICC ([ACTION-IF-YES]) @@ -28,23 +170,136 @@ AC_DEFUN([CURL_DETECT_ICC], ]) dnl We create a function for detecting which compiler we use and then set as -dnl pendantic compiler options as possible for that particular compiler. The +dnl pedantic compiler options as possible for that particular compiler. The dnl options are only used for debug-builds. AC_DEFUN([CURL_CC_DEBUG_OPTS], [ + if test "z$CLANG" = "z"; then + CURL_CHECK_COMPILER_CLANG + if test "z$compiler_id" = "zCLANG"; then + CLANG="yes" + else + CLANG="no" + fi + fi if test "z$ICC" = "z"; then CURL_DETECT_ICC fi - if test "$GCC" = "yes"; then + if test "$CLANG" = "yes"; then + + dnl figure out clang version! + AC_MSG_CHECKING([clang version]) + fullclangver=`$CC -v 2>&1 | grep version` + clangver=`echo $fullclangver | grep "based on LLVM " | "$SED" 's/.*(based on LLVM \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*)/\1/'` + if test -z "$clangver"; then + if echo $fullclangver | grep "Apple LLVM version " >/dev/null; then + dnl Starting with Xcode 7 / clang 3.7, Apple clang won't tell its upstream version + clangver="3.7" + else + clangver=`echo $fullclangver | "$SED" 's/.*version \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*/\1/'` + fi + fi + clangvhi=`echo $clangver | cut -d . -f1` + clangvlo=`echo $clangver | cut -d . -f2` + compiler_num=`(expr $clangvhi "*" 100 + $clangvlo) 2>/dev/null` + AC_MSG_RESULT($compiler_num) + + WARN="-pedantic" + CURL_ADD_COMPILER_WARNINGS([WARN], [all extra]) + CURL_ADD_COMPILER_WARNINGS([WARN], [pointer-arith write-strings]) + CURL_ADD_COMPILER_WARNINGS([WARN], [shadow]) + CURL_ADD_COMPILER_WARNINGS([WARN], [inline nested-externs]) + CURL_ADD_COMPILER_WARNINGS([WARN], [missing-declarations]) + CURL_ADD_COMPILER_WARNINGS([WARN], [missing-prototypes]) + WARN="$WARN -Wno-long-long" + CURL_ADD_COMPILER_WARNINGS([WARN], [float-equal]) + CURL_ADD_COMPILER_WARNINGS([WARN], [no-multichar sign-compare]) + CURL_ADD_COMPILER_WARNINGS([WARN], [undef]) + WARN="$WARN -Wno-format-nonliteral" + CURL_ADD_COMPILER_WARNINGS([WARN], [endif-labels strict-prototypes]) + CURL_ADD_COMPILER_WARNINGS([WARN], [declaration-after-statement]) + CURL_ADD_COMPILER_WARNINGS([WARN], [cast-align]) + WARN="$WARN -Wno-system-headers" + CURL_ADD_COMPILER_WARNINGS([WARN], [shorten-64-to-32]) + # + dnl Only clang 1.1 or later + if test "$compiler_num" -ge "101"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [unused]) + fi + # + dnl Only clang 2.8 or later + if test "$compiler_num" -ge "208"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [vla]) + fi + # + dnl Only clang 2.9 or later + if test "$compiler_num" -ge "209"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [shift-sign-overflow]) + fi + # + dnl Only clang 3.0 or later (possibly earlier) + if test "$compiler_num" -ge "300"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [bad-function-cast]) + CURL_ADD_COMPILER_WARNINGS([WARN], [conversion]) + CURL_ADD_COMPILER_WARNINGS([WARN], [empty-body]) + CURL_ADD_COMPILER_WARNINGS([WARN], [ignored-qualifiers]) + CURL_ADD_COMPILER_WARNINGS([WARN], [type-limits]) + CURL_ADD_COMPILER_WARNINGS([WARN], [no-sign-conversion]) + fi + # + dnl Only clang 3.2 or later + if test "$compiler_num" -ge "302"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [enum-conversion]) + case $host_os in + cygwin* | mingw*) + dnl skip missing-variable-declarations warnings for cygwin and + dnl mingw because the libtool wrapper executable causes them + ;; + *) + CURL_ADD_COMPILER_WARNINGS([WARN], [missing-variable-declarations]) + ;; + esac + fi + # + dnl Only clang 3.4 or later + if test "$compiler_num" -ge "304"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [unused-const-variable]) + fi + # + dnl Only clang 3.6 or later + if test "$compiler_num" -ge "306"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [double-promotion]) + fi + # + dnl Only clang 3.9 or later + if test "$compiler_num" -ge "309"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [comma]) + # avoid the varargs warning, fixed in 4.0 + # https://bugs.llvm.org/show_bug.cgi?id=29140 + if test "$compiler_num" -lt "400"; then + WARN="$WARN -Wno-varargs" + fi + fi + dnl clang 7 or later + if test "$compiler_num" -ge "700"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [assign-enum]) + CURL_ADD_COMPILER_WARNINGS([WARN], [extra-semi-stmt]) + fi + + CFLAGS="$CFLAGS $WARN" + + AC_MSG_NOTICE([Added this set of compiler options: $WARN]) + + elif test "$GCC" = "yes"; then dnl figure out gcc version! AC_MSG_CHECKING([gcc version]) gccver=`$CC -dumpversion` num1=`echo $gccver | cut -d . -f1` num2=`echo $gccver | cut -d . -f2` - gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null` + compiler_num=`(expr $num1 "*" 100 + $num2) 2>/dev/null` AC_MSG_RESULT($gccver) if test "$ICC" = "yes"; then @@ -61,7 +316,7 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], WARN="-wd279,269,981,1418,1419" - if test "$gccnum" -gt "600"; then + if test "$compiler_num" -gt "600"; then dnl icc 6.0 and older doesn't have the -Wall flag WARN="-Wall $WARN" fi @@ -69,26 +324,24 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], dnl this is a set of options we believe *ALL* gcc versions support: WARN="-W -Wall -Wwrite-strings -pedantic -Wpointer-arith -Wnested-externs -Winline -Wmissing-prototypes" - dnl -Wcast-align is a bit too annoying on all gcc versions ;-) - - if test "$gccnum" -ge "207"; then + if test "$compiler_num" -ge "207"; then dnl gcc 2.7 or later WARN="$WARN -Wmissing-declarations" fi - if test "$gccnum" -gt "295"; then + if test "$compiler_num" -gt "295"; then dnl only if the compiler is newer than 2.95 since we got lots of dnl "`_POSIX_C_SOURCE' is not defined" in system headers with dnl gcc 2.95.4 on FreeBSD 4.9! - WARN="$WARN -Wundef -Wno-long-long -Wsign-compare" + WARN="$WARN -Wbad-function-cast -Wundef -Wno-long-long -Wno-multichar -Wshadow -Wsign-compare -Wunused" fi - if test "$gccnum" -ge "296"; then + if test "$compiler_num" -ge "296"; then dnl gcc 2.96 or later WARN="$WARN -Wfloat-equal" fi - if test "$gccnum" -gt "296"; then + if test "$compiler_num" -gt "296"; then dnl this option does not exist in 2.96 WARN="$WARN -Wno-format-nonliteral" fi @@ -98,16 +351,93 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], dnl Also, on gcc 4.0.X it is totally unbearable and complains all dnl over making it unusable for generic purposes. Let's not use it. - if test "$gccnum" -ge "303"; then + if test "$compiler_num" -ge "303"; then dnl gcc 3.3 and later WARN="$WARN -Wendif-labels -Wstrict-prototypes" fi - if test "$gccnum" -ge "304"; then + if test "$compiler_num" -ge "304"; then # try these on gcc 3.4 WARN="$WARN -Wdeclaration-after-statement" fi + dnl Only gcc 4.0 or later + if test "$compiler_num" -ge "400"; then + WARN="$WARN -Wstrict-aliasing=3" + fi + # + dnl Only gcc 4.1 or later (possibly earlier) + if test "$compiler_num" -ge "401"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [no-system-headers]) + fi + # + dnl Only gcc 4.2 or later + if test "$compiler_num" -ge "402"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [cast-align]) + fi + # + dnl Only gcc 4.3 or later + if test "$compiler_num" -ge "403"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [type-limits old-style-declaration]) + CURL_ADD_COMPILER_WARNINGS([WARN], [missing-parameter-type empty-body]) + CURL_ADD_COMPILER_WARNINGS([WARN], [ignored-qualifiers]) + CURL_ADD_COMPILER_WARNINGS([WARN], [conversion]) + WARN="$WARN -Wno-sign-conversion" + CURL_ADD_COMPILER_WARNINGS([WARN], [vla]) + dnl required for -Warray-bounds, included in -Wall + WARN="$WARN -ftree-vrp" + fi + # + dnl Only gcc 4.5 or later + if test "$compiler_num" -ge "405"; then + dnl Only windows targets + case $host_os in + mingw*) + WARN="$WARN -Wno-pedantic-ms-format" + ;; + esac + fi + # + dnl Only gcc 4.6 or later + if test "$compiler_num" -ge "406"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [double-promotion]) + fi + # + dnl only gcc 4.8 or later + if test "$compiler_num" -ge "408"; then + WARN="$WARN -Wformat=2" + fi + # + dnl Only gcc 5 or later + if test "$compiler_num" -ge "500"; then + WARN="$WARN -Warray-bounds=2" + fi + # + dnl Only gcc 6 or later + if test "$compiler_num" -ge "600"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [shift-negative-value]) + WARN="$WARN -Wshift-overflow=2" + CURL_ADD_COMPILER_WARNINGS([WARN], [null-dereference]) + WARN="$WARN -fdelete-null-pointer-checks" + CURL_ADD_COMPILER_WARNINGS([WARN], [duplicated-cond]) + CURL_ADD_COMPILER_WARNINGS([WARN], [unused-const-variable]) + fi + # + dnl Only gcc 7 or later + if test "$compiler_num" -ge "700"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [duplicated-branches]) + CURL_ADD_COMPILER_WARNINGS([WARN], [restrict]) + CURL_ADD_COMPILER_WARNINGS([WARN], [alloc-zero]) + WARN="$WARN -Wformat-overflow=2" + WARN="$WARN -Wformat-truncation=1" + fi + # + dnl Only gcc 10 or later + if test "$compiler_num" -ge "1000"; then + CURL_ADD_COMPILER_WARNINGS([WARN], [arith-conversion]) + CURL_ADD_COMPILER_WARNINGS([WARN], [enum-conversion]) + fi + for flag in $CPPFLAGS; do case "$flag" in -I*) @@ -148,6 +478,67 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], ]) dnl end of AC_DEFUN() +dnl CURL_ADD_COMPILER_WARNINGS (WARNING-LIST, NEW-WARNINGS) +dnl ------------------------------------------------------- +dnl Contents of variable WARNING-LIST and NEW-WARNINGS are +dnl handled as whitespace separated lists of words. +dnl Add each compiler warning from NEW-WARNINGS that has not +dnl been disabled via CFLAGS to WARNING-LIST. + +AC_DEFUN([CURL_ADD_COMPILER_WARNINGS], [ + AC_REQUIRE([CURL_SHFUNC_SQUEEZE])dnl + ac_var_added_warnings="" + for warning in [$2]; do + CURL_VAR_MATCH(CFLAGS, [-Wno-$warning -W$warning]) + if test "$ac_var_match_word" = "no"; then + ac_var_added_warnings="$ac_var_added_warnings -W$warning" + fi + done + dnl squeeze whitespace out of result + [$1]="$[$1] $ac_var_added_warnings" + squeeze [$1] +]) + +dnl CURL_SHFUNC_SQUEEZE +dnl ------------------------------------------------- +dnl Declares a shell function squeeze() which removes +dnl redundant whitespace out of a shell variable. + +AC_DEFUN([CURL_SHFUNC_SQUEEZE], [ +squeeze() { + _sqz_result="" + eval _sqz_input=\[$][$]1 + for _sqz_token in $_sqz_input; do + if test -z "$_sqz_result"; then + _sqz_result="$_sqz_token" + else + _sqz_result="$_sqz_result $_sqz_token" + fi + done + eval [$]1=\$_sqz_result + return 0 +} +]) + +dnl CURL_VAR_MATCH (VARNAME, VALUE) +dnl ------------------------------------------------- +dnl Verifies if shell variable VARNAME contains VALUE. +dnl Contents of variable VARNAME and VALUE are handled +dnl as whitespace separated lists of words. If at least +dnl one word of VALUE is present in VARNAME the match +dnl is considered positive, otherwise false. + +AC_DEFUN([CURL_VAR_MATCH], [ + ac_var_match_word="no" + for word1 in $[$1]; do + for word2 in [$2]; do + if test "$word1" = "$word2"; then + ac_var_match_word="yes" + fi + done + done +]) + dnl CURL_CHECK_NONBLOCKING_SOCKET dnl ------------------------------------------------- dnl Check for how to set a socket to non-blocking state. There seems to exist @@ -163,12 +554,12 @@ AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET], [ AC_MSG_CHECKING([non-blocking sockets style]) - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ /* headers for O_NONBLOCK test */ #include #include #include -],[ +]], [[ /* try to compile O_NONBLOCK */ #if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) @@ -187,22 +578,22 @@ AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET], #endif int socket; int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK); -],[ +]])],[ dnl the O_NONBLOCK test was fine nonblock="O_NONBLOCK" AC_DEFINE(HAVE_O_NONBLOCK, 1, [use O_NONBLOCK for non-blocking sockets]) ],[ dnl the code was bad, try a different program now, test 2 - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ /* headers for FIONBIO test */ #include #include -],[ +]], [[ /* FIONBIO source test (old-style unix) */ int socket; int flags = ioctl(socket, FIONBIO, &flags); -],[ +]])],[ dnl FIONBIO test was good nonblock="FIONBIO" AC_DEFINE(HAVE_FIONBIO, 1, [use FIONBIO for non-blocking sockets]) @@ -210,67 +601,34 @@ AC_DEFINE(HAVE_FIONBIO, 1, [use FIONBIO for non-blocking sockets]) dnl FIONBIO test was also bad dnl the code was bad, try a different program now, test 3 - AC_TRY_COMPILE([ -/* headers for ioctlsocket test (Windows) */ -#undef inline -#ifdef HAVE_WINDOWS_H -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#ifdef HAVE_WINSOCK2_H -#include -#else -#ifdef HAVE_WINSOCK_H -#include -#endif -#endif -#endif -],[ -/* ioctlsocket source code */ - SOCKET sd; - unsigned long flags = 0; - sd = socket(0, 0, 0); - ioctlsocket(sd, FIONBIO, &flags); -],[ -dnl ioctlsocket test was good -nonblock="ioctlsocket" -AC_DEFINE(HAVE_IOCTLSOCKET, 1, [use ioctlsocket() for non-blocking sockets]) -],[ -dnl ioctlsocket didnt compile!, go to test 4 - - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ /* headers for IoctlSocket test (Amiga?) */ #include -],[ +]], [[ /* IoctlSocket source code */ int socket; int flags = IoctlSocket(socket, FIONBIO, (long)1); -],[ +]])],[ dnl ioctlsocket test was good nonblock="IoctlSocket" AC_DEFINE(HAVE_IOCTLSOCKET_CASE, 1, [use Ioctlsocket() for non-blocking sockets]) ],[ -dnl Ioctlsocket didnt compile, do test 5! - AC_TRY_COMPILE([ +dnl Ioctlsocket did not compile, do test 4! + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ /* headers for SO_NONBLOCK test (BeOS) */ #include -],[ +]], [[ /* SO_NONBLOCK source code */ long b = 1; int socket; int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); -],[ +]])],[ dnl the SO_NONBLOCK test was good nonblock="SO_NONBLOCK" AC_DEFINE(HAVE_SO_NONBLOCK, 1, [use SO_NONBLOCK for non-blocking sockets]) ],[ -dnl test 5 didnt compile! +dnl test 4 did not compile! nonblock="nada" -AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1, [disabled non-blocking sockets]) -]) -dnl end of fifth test - ]) dnl end of forth test @@ -419,15 +777,21 @@ m4_case([$1], LIBSSH2_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include ], [ AC_DEFINE(LIBSSH2_OPENSSL, 1, [Use $1]) LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libssl libcrypto" + found_crypto="$1" + found_crypto_str="OpenSSL" + ]) +], - # Not all OpenSSL have AES-CTR functions. - libssh2_save_LIBS="$LIBS" - LIBS="$LIBS $LIBSSL" - AC_CHECK_FUNCS(EVP_aes_128_ctr) - LIBS="$libssh2_save_LIBS" - +[wolfssl], [ + if test "${with_libwolfssl_prefix+set}" = set; then + CPPFLAGS="$CPPFLAGS${CPPFLAGS:+ }-I${with_libwolfssl_prefix}/include/wolfssl" + else + AC_MSG_ERROR([When using wolfSSL, must specify prefix with --with-libwolfssl-prefix in order to find OpenSSL compatibility headers.]) + fi + LIBSSH2_LIB_HAVE_LINKFLAGS([wolfssl], [], [#include ], [ + AC_DEFINE(LIBSSH2_WOLFSSL, 1, [Use $1]) + LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libwolfssl" found_crypto="$1" - found_crypto_str="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})" ]) ], @@ -443,20 +807,15 @@ m4_case([$1], AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use $1]) LIBS="$LIBS -lmbedcrypto" found_crypto="$1" - support_clear_memory=yes ]) ], [wincng], [ # Look for Windows Cryptography API: Next Generation - AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [#include ]) - AC_CHECK_DECLS([SecureZeroMemory], [], [], [#include ]) + LIBS="$LIBS -lcrypt32" - LIBSSH2_LIB_HAVE_LINKFLAGS([crypt32], [], [ - #include - #include - ]) + # Check necessary for old-MinGW LIBSSH2_LIB_HAVE_LINKFLAGS([bcrypt], [], [ #include #include @@ -464,7 +823,6 @@ m4_case([$1], AC_DEFINE(LIBSSH2_WINCNG, 1, [Use $1]) found_crypto="$1" found_crypto_str="Windows Cryptography API: Next Generation" - support_clear_memory="$ac_cv_have_decl_SecureZeroMemory" ]) ], ) @@ -486,8 +844,8 @@ AC_DEFUN([LIBSSH2_CHECK_OPTION_WERROR], [ AC_MSG_CHECKING([whether to enable compiler warnings as errors]) OPT_COMPILER_WERROR="default" AC_ARG_ENABLE(werror, -AC_HELP_STRING([--enable-werror],[Enable compiler warnings as errors]) -AC_HELP_STRING([--disable-werror],[Disable compiler warnings as errors]), +AS_HELP_STRING([--enable-werror],[Enable compiler warnings as errors]) +AS_HELP_STRING([--disable-werror],[Disable compiler warnings as errors]), OPT_COMPILER_WERROR=$enableval) case "$OPT_COMPILER_WERROR" in no) @@ -509,4 +867,3 @@ AC_HELP_STRING([--disable-werror],[Disable compiler warnings as errors]), CFLAGS="$CFLAGS -Werror" fi ]) - diff --git a/appveyor.yml b/appveyor.yml index c2731ca2bd..69e58ff784 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,7 @@ # Copyright (c) 2014, Ruslan Baratov # Copyright (c) 2014, 2016 Alexander Lamaison # Copyright (c) 2020, 2021 Marc Hoersken +# Copyright (c) 2023 Viktor Szakats # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -24,55 +25,101 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -os: Visual Studio 2015 +# https://www.appveyor.com/docs/windows-images-software/ environment: + CONFIGURATION: "Release" + FIXTURE_XFER_COUNT: 35020 matrix: - - GENERATOR: "Visual Studio 14 2015" - BUILD_SHARED_LIBS: ON + - job_name: "VS2022, OpenSSL 3, x64, Server 2019" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2022" + GENERATOR: "Visual Studio 17 2022" + PLATFORM: "x64" CRYPTO_BACKEND: "OpenSSL" - - GENERATOR: "Visual Studio 14 2015" - BUILD_SHARED_LIBS: OFF + - job_name: "VS2022, OpenSSL 3, x64, UWP, Build-only" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2022" + GENERATOR: "Visual Studio 17 2022" + PLATFORM: "x64" CRYPTO_BACKEND: "OpenSSL" + UWP: "ON" - - GENERATOR: "Visual Studio 12 2013" - BUILD_SHARED_LIBS: ON + - job_name: "VS2015, OpenSSL 1.1, x86, Server 2016" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017" + GENERATOR: "Visual Studio 14 2015" + PLATFORM: "x86" CRYPTO_BACKEND: "OpenSSL" - - GENERATOR: "Visual Studio 12 2013" - BUILD_SHARED_LIBS: OFF + - job_name: "VS2015, OpenSSL 1.1, x64, Server 2012 R2, Logging" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + GENERATOR: "Visual Studio 14 2015" + PLATFORM: "x64" CRYPTO_BACKEND: "OpenSSL" + ENABLE_DEBUG_LOGGING: "ON" - - GENERATOR: "Visual Studio 14 2015" - BUILD_SHARED_LIBS: ON + - job_name: "VS2013, OpenSSL 1.1, x64, Server 2012 R2" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + GENERATOR: "Visual Studio 12 2013" + PLATFORM: "x64" + CRYPTO_BACKEND: "OpenSSL" + + - job_name: "VS2013, OpenSSL 1.1, x86, Server 2012 R2, Shared-only" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + GENERATOR: "Visual Studio 12 2013" + PLATFORM: "x86" + BUILD_STATIC_LIBS: "OFF" + CRYPTO_BACKEND: "OpenSSL" + + - job_name: "VS2013, OpenSSL 1.0.2, x64, Build-only, Static-only" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + GENERATOR: "Visual Studio 12 2013" + PLATFORM: "x64" + BUILD_SHARED_LIBS: "OFF" + CRYPTO_BACKEND: "OpenSSL" + SKIP_CTEST: "yes" + + - job_name: "VS2008, WinCNG, x86, Build-only" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + GENERATOR: "Visual Studio 9 2008" + PLATFORM: "x86" CRYPTO_BACKEND: "WinCNG" + SKIP_CTEST: "yes" - - GENERATOR: "Visual Studio 14 2015" - BUILD_SHARED_LIBS: OFF + - job_name: "VS2010, WinCNG, x64, Build-only" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + GENERATOR: "Visual Studio 10 2010" + PLATFORM: "x64" CRYPTO_BACKEND: "WinCNG" + UNITY: "ON" + SKIP_CTEST: "yes" - - GENERATOR: "Visual Studio 12 2013" - BUILD_SHARED_LIBS: ON + - job_name: "VS2022, WinCNG, x64, Server 2019, Logging" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2022" + GENERATOR: "Visual Studio 17 2022" + PLATFORM: "x64" CRYPTO_BACKEND: "WinCNG" + ENABLE_DEBUG_LOGGING: "ON" - - GENERATOR: "Visual Studio 12 2013" - BUILD_SHARED_LIBS: OFF + - job_name: "VS2022, WinCNG, ARM64, Build-only" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2022" + GENERATOR: "Visual Studio 17 2022" + PLATFORM: "ARM64" CRYPTO_BACKEND: "WinCNG" -platform: - - x86 - - x64 + - job_name: "VS2015, WinCNG, x86, Server 2016" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017" + GENERATOR: "Visual Studio 14 2015" + PLATFORM: "x86" + CRYPTO_BACKEND: "WinCNG" -configuration: -# - Debug - - Release + - job_name: "VS2015, WinCNG, x64, Server 2012 R2" + APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015" + GENERATOR: "Visual Studio 14 2015" + PLATFORM: "x64" + CRYPTO_BACKEND: "WinCNG" matrix: fast_finish: true - allow_failures: - - GENERATOR: "Visual Studio 9 2008" - platform: x64 install: # prepare local SSH server for reverse tunneling from GitHub Actions hosting our docker container @@ -80,33 +127,79 @@ install: $env:OPENSSH_SERVER_PORT = Get-Random -Minimum 2000 -Maximum 2300 [System.Environment]::SetEnvironmentVariable("OPENSSH_SERVER_PORT", $env:OPENSSH_SERVER_PORT) - ps: .\ci\appveyor\docker-bridge.ps1 - - choco install -y docker-cli build_script: - - ps: if($env:PLATFORM -eq "x64") { $env:CMAKE_GEN_SUFFIX=" Win64" } - - cmake "-G%GENERATOR%%CMAKE_GEN_SUFFIX%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% -DCRYPTO_BACKEND=%CRYPTO_BACKEND% -H. -B_builds - - cmake --build _builds --config "%CONFIGURATION%" - -before_test: - ps: | - Write-Host "Waiting for SSH connection from GitHub Actions" -NoNewline - while((Get-Process -Name "sshd" -ErrorAction SilentlyContinue).Count -eq 1) { - Write-Host "." -NoNewline - Start-Sleep -Seconds 1 + if($env:GENERATOR -eq "Visual Studio 17 2022") { + if($env:PLATFORM -eq "x86") { + $env:CMAKE_ARG = "-A Win32" + } else { + $env:CMAKE_ARG = "-A $env:PLATFORM" + } + } elseif($env:PLATFORM -eq "x64") { + $env:GENERATOR += " Win64" + } + if($env:SKIP_CTEST -ne "yes" -and $env:CRYPTO_BACKEND -eq "OpenSSL") { + if($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2022") { + if($env:PLATFORM -eq "x64") { + $env:CMAKE_ARG += " -DOPENSSL_ROOT_DIR=C:/OpenSSL-v30-Win64" + } + } else { + if($env:PLATFORM -eq "x64") { + $env:CMAKE_ARG += " -DOPENSSL_ROOT_DIR=C:/OpenSSL-v111-Win64" + } elseif($env:PLATFORM -eq "x86") { + $env:CMAKE_ARG += " -DOPENSSL_ROOT_DIR=C:/OpenSSL-v111-Win32" + } + } + } + if($env:ENABLE_DEBUG_LOGGING -eq "ON") { + $env:CMAKE_ARG += " -DENABLE_DEBUG_LOGGING=ON" + } + if($env:UWP -eq "ON") { + $env:CMAKE_ARG += " -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0" + } + if($env:UNITY -eq "ON") { + $env:CMAKE_ARG += " -DCMAKE_UNITY_BUILD=ON" } - if((Get-Process -Name "sshd" -ErrorAction SilentlyContinue).Count -gt 1) { - $env:DOCKER_HOST = "tcp://127.0.0.1:2375" - [System.Environment]::SetEnvironmentVariable("DOCKER_HOST", $env:DOCKER_HOST) - Write-Host "... ready!" - } else { - Write-Host "... failed!" + if($env:BUILD_STATIC_LIBS -eq "OFF") { + $env:CMAKE_ARG += " -DBUILD_STATIC_LIBS=OFF" } + if($env:BUILD_SHARED_LIBS -eq "OFF") { + $env:CMAKE_ARG += " -DBUILD_SHARED_LIBS=OFF" + } + $env:CMAKE_ARG += " -DCMAKE_VS_GLOBALS=TrackFileAccess=false" + # FIXME: First sshd test sometimes timeouts, subsequent ones almost always fail: + # 'libssh2_session_handshake failed (-43): Failed getting banner' + - echo cmake "-G%GENERATOR%" %CMAKE_ARG% -DENABLE_WERROR=ON -DCRYPTO_BACKEND=%CRYPTO_BACKEND% -DRUN_SSHD_TESTS=OFF + - cmake . -B _builds "-G%GENERATOR%" %CMAKE_ARG% -DENABLE_WERROR=ON -DCRYPTO_BACKEND=%CRYPTO_BACKEND% -DRUN_SSHD_TESTS=OFF + - cmake --build _builds --config "%CONFIGURATION%" test_script: - - ps: cd _builds - - ps: ctest -VV -C $($env:CONFIGURATION) --output-on-failure + - ps: | + if($env:SKIP_CTEST -ne "yes" -and $env:PLATFORM -ne "ARM64" -and $env:UWP -ne "ON") { + appveyor-retry choco install -y --no-progress --limit-output --timeout 180 docker-cli + Write-Host "Waiting for SSH connection from GitHub Actions" -NoNewline + $endDate = (Get-Date).AddMinutes(3) + while((Get-Process -Name "sshd" -ErrorAction SilentlyContinue).Count -eq 1 -and (Get-Date) -lt $endDate) { + Write-Host "." -NoNewline + Start-Sleep -Seconds 1 + } + if((Get-Process -Name "sshd" -ErrorAction SilentlyContinue).Count -gt 1) { + $env:DOCKER_HOST = "tcp://127.0.0.1:2375" + [System.Environment]::SetEnvironmentVariable("DOCKER_HOST", $env:DOCKER_HOST) + Write-Host "... ready!" + } else { + Write-Host "... failed!" + } + if($env:CRYPTO_BACKEND -eq "WinCNG") { + $env:FIXTURE_TRACE_ALL_CONNECT = "1" + } + $env:OPENSSH_SERVER_IMAGE=[string] (& bash -c "echo ghcr.io/libssh2/ci_tests_openssh_server:$(git rev-parse --short=20 HEAD:tests/openssh_server)") + cd _builds; ctest -VV -C $($env:CONFIGURATION) --output-on-failure --timeout 900 + } on_failure: + - ps: if(Test-Path _builds/CMakeFiles/CMakeConfigureLog.yaml) { cat _builds/CMakeFiles/CMakeConfigureLog.yaml } - ps: if(Test-Path _builds/CMakeFiles/CMakeOutput.log) { cat _builds/CMakeFiles/CMakeOutput.log } - ps: if(Test-Path _builds/CMakeFiles/CMakeError.log) { cat _builds/CMakeFiles/CMakeError.log } @@ -116,7 +209,7 @@ on_finish: Start-Sleep -Seconds 3 Get-Process -Name "sshd" -ErrorAction SilentlyContinue | Stop-Process -# whitelist branches to avoid testing feature branches twice (as branch and as pull request) +# Limit branches to avoid testing feature branches twice (as branch and as pull request) branches: - only: - - master + only: + - master diff --git a/buildconf b/buildconf index 8097193097..1649f37bd2 100755 --- a/buildconf +++ b/buildconf @@ -1,8 +1,8 @@ #!/bin/sh echo "***" >&2 -echo "*** Do not use buildconf. Instead, just use: autoreconf -fi" >&2 -echo "*** Doing it for you now, but buildconf may disapear in the future." >&2 +echo "*** Do not use buildconf. Instead, use: autoreconf -fi" >&2 +echo "*** Doing it for you now, but buildconf may disappear in the future." >&2 echo "***" >&2 exec ${AUTORECONF:-autoreconf} -fi "${@}" diff --git a/ci/appveyor/docker-bridge.bat b/ci/appveyor/docker-bridge.bat deleted file mode 100644 index e83b285d82..0000000000 --- a/ci/appveyor/docker-bridge.bat +++ /dev/null @@ -1,10 +0,0 @@ -@echo off - -netsh interface portproxy add v4tov4 listenport=3389 listenaddress=%1 connectport=22 connectaddress=127.0.0.1 -netsh interface portproxy show all - -C:\msys64\usr\bin\sh -l -c "/usr/bin/ssh-keygen -b 2048 -t rsa -f auth -q -N '' && mkdir .ssh && mv auth.pub .ssh/authorized_keys" -C:\msys64\usr\bin\sh -l -c "/usr/bin/ssh-keygen -A" -C:\msys64\usr\bin\sh -l -c "/usr/bin/sshd" - -C:\msys64\usr\bin\sh -l -c '/usr/bin/curl -F "account=%APPVEYOR_ACCOUNT_NAME%" -F "project=%APPVEYOR_PROJECT_SLUG%" -F "buildid=%APPVEYOR_BUILD_VERSION%" -F "base=%APPVEYOR_REPO_BRANCH%" -F "hash=%APPVEYOR_REPO_COMMIT%" -F "repo=%APPVEYOR_REPO_NAME%" -F "ssh_host=%2" -F "ssh_port=%3" -F "ssh_user=`whoami`" -F "ssh_forward=127.0.0.1:%OPENSSH_SERVER_PORT% 127.0.0.1:%OPENSSH_SERVER_PORT%,127.0.0.1:2375 /var/run/docker.sock" -F "ssh_hostkey=`paste -d , /etc/ssh/ssh_host_*_key.pub`" -F "ssh_privkey=`paste -sd , auth`" -s "https://stuff.marc-hoersken.de/libssh2/dispatch.php"' diff --git a/ci/appveyor/docker-bridge.ps1 b/ci/appveyor/docker-bridge.ps1 old mode 100644 new mode 100755 index 03dbf7dd29..201ef1d44c --- a/ci/appveyor/docker-bridge.ps1 +++ b/ci/appveyor/docker-bridge.ps1 @@ -1,22 +1,25 @@ -# Partially copied from https://github.com/appveyor/ci/blob/master/scripts/enable-rdp.ps1 - -# get current IP -$ip = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.InterfaceAlias -like 'ethernet*'}).IPAddress -$port = 3389 -if($ip.StartsWith('172.24.')) { - $port = 33800 + ($ip.split('.')[2] - 16) * 256 + $ip.split('.')[3] -} elseif ($ip.StartsWith('192.168.') -or $ip.StartsWith('10.240.')) { - # new environment - behind NAT - $port = 33800 + ($ip.split('.')[2] - 0) * 256 + $ip.split('.')[3] -} elseif ($ip.StartsWith('10.0.')) { - $port = 33800 + ($ip.split('.')[2] - 0) * 256 + $ip.split('.')[3] -} - -# get external IP -$extip = (New-Object Net.WebClient).DownloadString('https://www.appveyor.com/tools/my-ip.aspx').Trim() - -# allow inbound traffic -New-NetFirewallRule -DisplayName "SSH via RDP port" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 22,3389 - -# launch remote docker daemon with reverse SSH tunnel -& .\ci\appveyor\docker-bridge.bat $ip $extip $port +#!/usr/bin/env pwsh + +# Partially copied from https://github.com/appveyor/ci/blob/master/scripts/enable-rdp.ps1 + +# get current IP +$ip = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.InterfaceAlias -like 'ethernet*'}).IPAddress +$port = 3389 +if($ip.StartsWith('172.24.')) { + $port = 33800 + ($ip.split('.')[2] - 16) * 256 + $ip.split('.')[3] +} elseif ($ip.StartsWith('192.168.') -or $ip.StartsWith('10.240.')) { + # new environment - behind NAT + $port = 33800 + ($ip.split('.')[2] - 0) * 256 + $ip.split('.')[3] +} elseif ($ip.StartsWith('10.0.')) { + $port = 33800 + ($ip.split('.')[2] - 0) * 256 + $ip.split('.')[3] +} + +# get external IP +$extip = (New-Object Net.WebClient).DownloadString('https://www.appveyor.com/tools/my-ip.aspx').Trim() + +# allow inbound traffic +New-NetFirewallRule -DisplayName "SSH via RDP port" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 22,3389 + +# launch remote docker daemon with reverse SSH tunnel +$scriptPath = (split-path -parent $MyInvocation.MyCommand.Definition) -replace '\\', '/' +& C:\msys64\usr\bin\sh -l -c "$scriptPath/docker-bridge.sh $ip $extip $port" diff --git a/ci/appveyor/docker-bridge.sh b/ci/appveyor/docker-bridge.sh new file mode 100755 index 0000000000..11488a0abc --- /dev/null +++ b/ci/appveyor/docker-bridge.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +set -e + +netsh interface portproxy add v4tov4 listenport=3389 listenaddress="$1" connectport=22 connectaddress=127.0.0.1 +netsh interface portproxy show all + +ssh-keygen -t ed25519 -f auth -q -N '' && mkdir .ssh && mv auth.pub .ssh/authorized_keys +ssh-keygen -A +"$(command -v sshd)" & + +curl \ + -F "account=${APPVEYOR_ACCOUNT_NAME}" \ + -F "project=${APPVEYOR_PROJECT_SLUG}" \ + -F "buildid=${APPVEYOR_BUILD_VERSION}" \ + -F "base=${APPVEYOR_REPO_BRANCH}" \ + -F "hash=${APPVEYOR_REPO_COMMIT}" \ + -F "repo=${APPVEYOR_REPO_NAME}" \ + -F "ssh_host=$2" \ + -F "ssh_port=$3" \ + -F "ssh_user=$(whoami)" \ + -F "ssh_forward=127.0.0.1:${OPENSSH_SERVER_PORT} 127.0.0.1:${OPENSSH_SERVER_PORT},127.0.0.1:2375 /var/run/docker.sock" \ + -F "ssh_hostkey=$(paste -d , /etc/ssh/ssh_host_*_key.pub)" \ + -F "ssh_privkey=$(paste -sd , auth)" \ + -s 'https://stuff.marc-hoersken.de/libssh2/dispatch.php' diff --git a/ci/checksrc.pl b/ci/checksrc.pl index 965f0bab1d..5c279db903 100755 --- a/ci/checksrc.pl +++ b/ci/checksrc.pl @@ -6,11 +6,11 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 2011 - 2018, Daniel Stenberg, , et al. +# Copyright (C) Daniel Stenberg, , et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms -# are also available at https://curl.haxx.se/docs/copyright.html. +# are also available at https://curl.se/docs/copyright.html. # # You may opt to use, copy, modify, merge, publish, distribute and/or sell # copies of the Software, and permit persons to whom the Software is @@ -19,6 +19,8 @@ # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY # KIND, either express or implied. # +# SPDX-License-Identifier: curl +# ########################################################################### use strict; @@ -31,14 +33,14 @@ my $swarnings = 0; my $errors = 0; my $serrors = 0; -my $suppressed; # whitelisted problems +my $suppressed; # skipped problems my $file; my $dir="."; my $wlist=""; my @alist; -my $windows_os = $^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'cygwin'; +my $windows_os = $^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys'; my $verbose; -my %whitelist; +my %skiplist; my %ignore; my %ignore_set; @@ -47,47 +49,61 @@ my %warnings_extended = ( 'COPYRIGHTYEAR' => 'copyright year incorrect', + 'STRERROR', => 'strerror() detected', ); my %warnings = ( - 'LONGLINE' => "Line longer than $max_column", - 'TABS' => 'TAB characters not allowed', - 'TRAILINGSPACE' => 'Trailing white space on the line', - 'CPPCOMMENTS' => '// comment detected', - 'SPACEBEFOREPAREN' => 'space before an open parenthesis', - 'SPACEAFTERPAREN' => 'space after open parenthesis', - 'SPACEBEFORECLOSE' => 'space before a close parenthesis', - 'SPACEBEFORECOMMA' => 'space before a comma', - 'RETURNNOSPACE' => 'return without space', - 'COMMANOSPACE' => 'comma without following space', - 'BRACEELSE' => '} else on the same line', - 'PARENBRACE' => '){ without sufficient space', - 'SPACESEMICOLON' => 'space before semicolon', + 'ASSIGNWITHINCONDITION' => 'assignment within conditional expression', + 'ASTERISKNOSPACE' => 'pointer declared without space before asterisk', + 'ASTERISKSPACE' => 'pointer declared with space after asterisk', + 'BADCOMMAND' => 'bad !checksrc! instruction', 'BANNEDFUNC' => 'a banned function was used', - 'FOPENMODE' => 'fopen needs a macro for the mode string', + 'BRACEELSE' => '} else on the same line', 'BRACEPOS' => 'wrong position for an open brace', - 'INDENTATION' => 'wrong start column for code', + 'BRACEWHILE' => 'A single space between open brace and while', + 'COMMANOSPACE' => 'comma without following space', + 'COMMENTNOSPACEEND' => 'no space before */', + 'COMMENTNOSPACESTART' => 'no space following /*', 'COPYRIGHT' => 'file missing a copyright statement', - 'BADCOMMAND' => 'bad !checksrc! instruction', - 'UNUSEDIGNORE' => 'a warning ignore was not used', - 'OPENCOMMENT' => 'file ended with a /* comment still "open"', - 'ASTERISKSPACE' => 'pointer declared with space after asterisk', - 'ASTERISKNOSPACE' => 'pointer declared without space before asterisk', - 'ASSIGNWITHINCONDITION' => 'assignment within conditional expression', + 'CPPCOMMENTS' => '// comment detected', + 'DOBRACE' => 'A single space between do and open brace', + 'EMPTYLINEBRACE' => 'Empty line before the open brace', 'EQUALSNOSPACE' => 'equals sign without following space', + 'EQUALSNULL' => 'if/while comparison with == NULL', + 'EXCLAMATIONSPACE' => 'Whitespace after exclamation mark in expression', + 'FOPENMODE' => 'fopen needs a macro for the mode string', + 'INCLUDEDUP', => 'same file is included again', + 'INDENTATION' => 'wrong start column for code', + 'LONGLINE' => "Line longer than $max_column", + 'SPACEBEFORELABEL' => 'labels not at the start of the line', + 'MULTISPACE' => 'multiple spaces used when not suitable', 'NOSPACEEQUALS' => 'equals sign without preceding space', + 'NOTEQUALSZERO', => 'if/while comparison with != 0', + 'ONELINECONDITION' => 'conditional block on the same line as the if()', + 'OPENCOMMENT' => 'file ended with a /* comment still "open"', + 'PARENBRACE' => '){ without sufficient space', + 'RETURNNOSPACE' => 'return without space', 'SEMINOSPACE' => 'semicolon without following space', - 'MULTISPACE' => 'multiple spaces used when not suitable', 'SIZEOFNOPAREN' => 'use of sizeof without parentheses', 'SNPRINTF' => 'use of snprintf', + 'SPACEAFTERPAREN' => 'space after open parenthesis', + 'SPACEBEFORECLOSE' => 'space before a close parenthesis', + 'SPACEBEFORECOMMA' => 'space before a comma', + 'SPACEBEFOREPAREN' => 'space before an open parenthesis', + 'SPACESEMICOLON' => 'space before semicolon', + 'SPACESWITCHCOLON' => 'space before colon of switch label', + 'TABS' => 'TAB characters not allowed', + 'TRAILINGSPACE' => 'Trailing whitespace on the line', + 'TYPEDEFSTRUCT' => 'typedefed struct', + 'UNUSEDIGNORE' => 'a warning ignore was not used', ); -sub readwhitelist { - open(W, "<$dir/checksrc.whitelist") or return; +sub readskiplist { + open(W, "<$dir/checksrc.skip") or return; my @all=; for(@all) { $windows_os ? $_ =~ s/\r?\n$// : chomp; - $whitelist{$_}=1; + $skiplist{$_}=1; } close(W); } @@ -115,10 +131,19 @@ sub readlocalfile { } $warnings{$1} = $warnings_extended{$1}; } + elsif (/^\s*disable ([A-Z]+)$/) { + if(!defined($warnings{$1})) { + print STDERR "invalid warning specified in .checksrc: \"$1\"\n"; + next; + } + # Accept-list + push @alist, $1; + } else { die "Invalid format in $dir/.checksrc on line $i\n"; } } + close($rcfile); } sub checkwarn { @@ -131,8 +156,8 @@ sub checkwarn { # print STDERR "Dev! there's no description for $name!\n"; #} - # checksrc.whitelist - if($whitelist{$line}) { + # checksrc.skip + if($skiplist{$line}) { $nowarn = 1; } # !checksrc! controlled @@ -176,7 +201,7 @@ sub checkwarn { $file = shift @ARGV; -while(1) { +while(defined $file) { if($file =~ /-D(.*)/) { $dir = $1; @@ -217,17 +242,25 @@ sub checkwarn { print " -A[rule] Accept this violation, can be used multiple times\n"; print " -D[DIR] Directory to prepend file names\n"; print " -h Show help output\n"; - print " -W[file] Whitelist the given file - ignore all its flaws\n"; + print " -W[file] Skip the given file - ignore all its flaws\n"; print " -i Indent spaces. Default: 2\n"; print " -m Maximum line length. Default: 79\n"; print "\nDetects and warns for these problems:\n"; - for(sort keys %warnings) { - printf (" %-18s: %s\n", $_, $warnings{$_}); + my @allw = keys %warnings; + push @allw, keys %warnings_extended; + for my $w (sort @allw) { + if($warnings{$w}) { + printf (" %-18s: %s\n", $w, $warnings{$w}); + } + else { + printf (" %-18s: %s[*]\n", $w, $warnings_extended{$w}); + } } + print " [*] = disabled by default\n"; exit; } -readwhitelist(); +readskiplist(); readlocalfile(); do { @@ -344,11 +377,15 @@ sub scanfile { my $line = 1; my $prevl=""; - my $l; + my $prevpl=""; + my $l = ""; + my $prep = 0; + my $prevp = 0; open(R, "<$file") || die "failed to open $file"; my $incomment=0; my @copyright=(); + my %includes; checksrc_clear(); # for file based ignores accept_violations(); @@ -365,7 +402,8 @@ sub scanfile { } # check for a copyright statement and save the years - if($l =~ /\* +copyright .* \d\d\d\d/i) { + if($l =~ /\* +copyright .* (\d\d\d\d|)/i) { + my $count = 0; while($l =~ /([\d]{4})/g) { push @copyright, { year => $1, @@ -373,6 +411,16 @@ sub scanfile { col => index($l, $1), code => $l }; + $count++; + } + if(!$count) { + # year-less + push @copyright, { + year => -1, + line => $line, + col => index($l, $1), + code => $l + }; } } @@ -386,12 +434,24 @@ sub scanfile { checkwarn("TABS", $line, length($1), $file, $l, "Contains TAB character", 1); } - # detect trailing white space + # detect trailing whitespace if($l =~ /^(.*)[ \t]+\z/) { checkwarn("TRAILINGSPACE", $line, length($1), $file, $l, "Trailing whitespace"); } + # no space after comment start + if($l =~ /^(.*)\/\*\w/) { + checkwarn("COMMENTNOSPACESTART", + $line, length($1) + 2, $file, $l, + "Missing space after comment start"); + } + # no space at comment end + if($l =~ /^(.*)\w\*\//) { + checkwarn("COMMENTNOSPACEEND", + $line, length($1) + 1, $file, $l, + "Missing space end comment end"); + } # ------------------------------------------------------------ # Above this marker, the checks were done on lines *including* # comments @@ -426,16 +486,41 @@ sub scanfile { # comments # ------------------------------------------------------------ + # prev line was a preprocessor **and** ended with a backslash + if($prep && ($prevpl =~ /\\ *\z/)) { + # this is still a preprocessor line + $prep = 1; + goto preproc; + } + $prep = 0; + # crude attempt to detect // comments without too many false # positives - if($l =~ /^([^"\*]*)[^:"]\/\//) { + if($l =~ /^(([^"\*]*)[^:"]|)\/\//) { checkwarn("CPPCOMMENTS", $line, length($1), $file, $l, "\/\/ comment"); } + if($l =~ /^(\#\s*include\s+)([\">].*[>}"])/) { + my ($pre, $path) = ($1, $2); + if($includes{$path}) { + checkwarn("INCLUDEDUP", + $line, length($1), $file, $l, "duplicated include"); + } + $includes{$path} = $l; + } + + # detect and strip preprocessor directives + if($l =~ /^[ \t]*\#/) { + # preprocessor line + $prep = 1; + goto preproc; + } + my $nostr = nostrings($l); # check spaces after for/if/while/function call - if($nostr =~ /^(.*)(for|if|while| ([a-zA-Z0-9_]+)) \((.)/) { + if($nostr =~ /^(.*)(for|if|while|switch| ([a-zA-Z0-9_]+)) \((.)/) { + my ($leading, $word, $extra, $first)=($1,$2,$3,$4); if($1 =~ / *\#/) { # this is a #if, treat it differently } @@ -445,25 +530,69 @@ sub scanfile { elsif(defined $3 && $3 eq "case") { # case must have a space } - elsif($4 eq "*") { - # (* beginning makes the space OK! + elsif(($first eq "*") && ($word !~ /(for|if|while|switch)/)) { + # A "(*" beginning makes the space OK because it wants to + # allow funcion pointer declared } elsif($1 =~ / *typedef/) { # typedefs can use space-paren } else { - checkwarn("SPACEBEFOREPAREN", $line, length($1)+length($2), $file, $l, - "$2 with space"); + checkwarn("SPACEBEFOREPAREN", $line, length($leading)+length($word), $file, $l, + "$word with space"); } } + # check for '== NULL' in if/while conditions but not if the thing on + # the left of it is a function call + if($nostr =~ /^(.*)(if|while)(\(.*?)([!=]= NULL|NULL [!=]=)/) { + checkwarn("EQUALSNULL", $line, + length($1) + length($2) + length($3), + $file, $l, "we prefer !variable instead of \"== NULL\" comparisons"); + } + + # check for '!= 0' in if/while conditions but not if the thing on + # the left of it is a function call + if($nostr =~ /^(.*)(if|while)(\(.*[^)]) != 0[^x]/) { + checkwarn("NOTEQUALSZERO", $line, + length($1) + length($2) + length($3), + $file, $l, "we prefer if(rc) instead of \"rc != 0\" comparisons"); + } - if($nostr =~ /^((.*)(if) *\()(.*)\)/) { + # check spaces in 'do {' + if($nostr =~ /^( *)do( *)\{/ && length($2) != 1) { + checkwarn("DOBRACE", $line, length($1) + 2, $file, $l, "one space after do before brace"); + } + # check spaces in 'do {' + elsif($nostr =~ /^( *)\}( *)while/ && length($2) != 1) { + checkwarn("BRACEWHILE", $line, length($1) + 2, $file, $l, "one space between brace and while"); + } + if($nostr =~ /^((.*\s)(if) *\()(.*)\)(.*)/) { my $pos = length($1); - if($4 =~ / = /) { + my $postparen = $5; + my $cond = $4; + if($cond =~ / = /) { checkwarn("ASSIGNWITHINCONDITION", $line, $pos+1, $file, $l, "assignment within conditional expression"); } + my $temp = $cond; + $temp =~ s/\(//g; # remove open parens + my $openc = length($cond) - length($temp); + + $temp = $cond; + $temp =~ s/\)//g; # remove close parens + my $closec = length($cond) - length($temp); + my $even = $openc == $closec; + + if($l =~ / *\#/) { + # this is a #if, treat it differently + } + elsif($even && $postparen && + ($postparen !~ /^ *$/) && ($postparen !~ /^ *[,{&|\\]+/)) { + checkwarn("ONELINECONDITION", + $line, length($l)-length($postparen), $file, $l, + "conditional block on the same line"); + } } # check spaces after open parentheses if($l =~ /^(.*[a-z])\( /i) { @@ -551,16 +680,33 @@ sub scanfile { checkwarn("PARENBRACE", $line, length($1)+1, $file, $l, "missing space after close paren"); } + # check for "^{" with an empty line before it + if(($l =~ /^\{/) && ($prevl =~ /^[ \t]*\z/)) { + checkwarn("EMPTYLINEBRACE", + $line, 0, $file, $l, "empty line before open brace"); + } # check for space before the semicolon last in a line if($l =~ /^(.*[^ ].*) ;$/) { checkwarn("SPACESEMICOLON", - $line, length($1), $file, $ol, "space before last semicolon"); + $line, length($1), $file, $ol, "no space before semicolon"); + } + + # check for space before the colon in a switch label + if($l =~ /^( *(case .+|default)) :/) { + checkwarn("SPACESWITCHCOLON", + $line, length($1), $file, $ol, "no space before colon of switch label"); + } + + if($prevl !~ /\?\z/ && $l =~ /^ +([A-Za-z_][A-Za-z0-9_]*):$/ && $1 ne 'default') { + checkwarn("SPACEBEFORELABEL", + $line, length($1), $file, $ol, "no space before label"); } # scan for use of banned functions if($l =~ /^(.*\W) - (gets| + (gmtime|localtime| + gets| strtok| v?sprintf| (str|_mbs|_tcs|_wcs)n?cat| @@ -571,7 +717,18 @@ sub scanfile { $line, length($1), $file, $ol, "use of $2 is banned"); } - + if($warnings{"STRERROR"}) { + # scan for use of banned strerror. This is not a BANNEDFUNC to + # allow for individual enable/disable of this warning. + if($l =~ /^(.*\W)(strerror)\s*\(/x) { + if($1 !~ /^ *\#/) { + # skip preprocessor lines + checkwarn("STRERROR", + $line, length($1), $file, $ol, + "use of $2 is banned"); + } + } + } # scan for use of snprintf for curl-internals reasons if($l =~ /^(.*\W)(v?snprintf)\s*\(/x) { checkwarn("SNPRINTF", @@ -589,10 +746,9 @@ sub scanfile { } } - # check for open brace first on line but not first column - # only alert if previous line ended with a close paren and wasn't a cpp - # line - if((($prevl =~ /\)\z/) && ($prevl !~ /^ *#/)) && ($l =~ /^( +)\{/)) { + # check for open brace first on line but not first column only alert + # if previous line ended with a close paren and it wasn't a cpp line + if(($prevl =~ /\)\z/) && ($l =~ /^( +)\{/) && !$prevp) { checkwarn("BRACEPOS", $line, length($1), $file, $ol, "badly placed open brace"); } @@ -600,11 +756,10 @@ sub scanfile { # if the previous line starts with if/while/for AND ends with an open # brace, or an else statement, check that this line is indented $indent # more steps, if not a cpp line - if($prevl =~ /^( *)((if|while|for)\(.*\{|else)\z/) { + if(!$prevp && ($prevl =~ /^( *)((if|while|for)\(.*\{|else)\z/)) { my $first = length($1); - # this line has some character besides spaces - if(($l !~ /^ *#/) && ($l =~ /^( *)[^ ]/)) { + if($l =~ /^( *)[^ ]/) { my $second = length($1); my $expect = $first+$indent; if($expect != $second) { @@ -616,11 +771,37 @@ sub scanfile { } } + # if the previous line starts with if/while/for AND ends with a closed + # parenthesis and there's an equal number of open and closed + # parentheses, check that this line is indented $indent more steps, if + # not a cpp line + elsif(!$prevp && ($prevl =~ /^( *)(if|while|for)(\(.*\))\z/)) { + my $first = length($1); + my $op = $3; + my $cl = $3; + + $op =~ s/[^(]//g; + $cl =~ s/[^)]//g; + + if(length($op) == length($cl)) { + # this line has some character besides spaces + if($l =~ /^( *)[^ ]/) { + my $second = length($1); + my $expect = $first+$indent; + if($expect != $second) { + my $diff = $second - $first; + checkwarn("INDENTATION", $line, length($1), $file, $ol, + "not indented $indent steps (uses $diff)"); + } + } + } + } + # check for 'char * name' - if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost) *(\*+)) (\w+)/) && ($4 ne "const")) { - checkwarn("ASTERISKNOSPACE", + if(($l =~ /(^.*(char|int|long|void|CURL|CURLM|CURLMsg|[cC]url_[A-Za-z_]+|struct [a-zA-Z_]+) *(\*+)) (\w+)/) && ($4 !~ /^(const|volatile)$/)) { + checkwarn("ASTERISKSPACE", $line, length($1), $file, $ol, - "no space after declarative asterisk"); + "space after declarative asterisk"); } # check for 'char*' if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost|sockaddr_in|FILE)\*)/)) { @@ -675,6 +856,19 @@ sub scanfile { "no space after semicolon"); } + # typedef struct ... { + if($nostr =~ /^(.*)typedef struct.*{/) { + checkwarn("TYPEDEFSTRUCT", + $line, length($1)+1, $file, $ol, + "typedef'ed struct"); + } + + if($nostr =~ /(.*)! +(\w|\()/) { + checkwarn("EXCLAMATIONSPACE", + $line, length($1)+1, $file, $ol, + "space after exclamation mark"); + } + # check for more than one consecutive space before open brace or # question mark. Skip lines containing strings since they make it hard # due to artificially getting multiple spaces @@ -682,13 +876,13 @@ sub scanfile { $nostr =~ /^(.*(\S)) + [{?]/i) { checkwarn("MULTISPACE", $line, length($1)+1, $file, $ol, - "multiple space"); - print STDERR "L: $l\n"; - print STDERR "nostr: $nostr\n"; + "multiple spaces"); } - + preproc: $line++; - $prevl = $ol; + $prevp = $prep; + $prevl = $ol if(!$prep); + $prevpl = $ol if($prep); } if(!scalar(@copyright)) { @@ -712,17 +906,22 @@ sub scanfile { # A rather more interesting, and correct, check would be to not test # only locally committed files but inspect all files wrt the year of # their last commit. Removing the `git rev-list origin/master..HEAD` - # condition below will enfore copyright year checks against the year + # condition below will enforce copyright year checks against the year # the file was last committed (and thus edited to some degree). my $commityear = undef; @copyright = sort {$$b{year} cmp $$a{year}} @copyright; + # if the file is modified, assume commit year this year if(`git status -s -- $file` =~ /^ [MARCU]/) { $commityear = (localtime(time))[5] + 1900; } - elsif (`git rev-list --count origin/master..HEAD -- $file` !~ /^0/) { - my $grl = `git rev-list --max-count=1 --timestamp HEAD -- $file`; - $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900; + else { + # min-parents=1 to ignore wrong initial commit in truncated repos + my $grl = `git rev-list --max-count=1 --min-parents=1 --timestamp HEAD -- $file`; + if($grl) { + chomp $grl; + $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900; + } } if(defined($commityear) && scalar(@copyright) && diff --git a/ci/checksrc.sh b/ci/checksrc.sh index 3890815b4d..80789f88ca 100755 --- a/ci/checksrc.sh +++ b/ci/checksrc.sh @@ -2,7 +2,16 @@ set -e +cd "$(dirname "$0")/.." + FILES="src/*.[ch] include/*.h example/*.c tests/*.[ch]" WHITELIST="-Wsrc/libssh2_config.h" -perl ./ci/checksrc.pl -i4 -m79 -ASIZEOFNOPAREN -ASNPRINTF -ACOPYRIGHT -AFOPENMODE $WHITELIST $FILES +# shellcheck disable=SC2086 +# shellcheck disable=SC2248 +perl ./ci/checksrc.pl -i4 -m79 \ + -ASNPRINTF \ + -ACOPYRIGHT \ + -AFOPENMODE \ + -ATYPEDEFSTRUCT \ + $WHITELIST $FILES diff --git a/ci/ossfuzz.sh b/ci/ossfuzz.sh deleted file mode 100755 index 9ca9c165d3..0000000000 --- a/ci/ossfuzz.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -set -ex - -PROJECT_NAME=libssh2 - -# Clone the oss-fuzz repository -git clone https://github.com/google/oss-fuzz.git /tmp/ossfuzz - -if [[ ! -d /tmp/ossfuzz/projects/${PROJECT_NAME} ]] -then - echo "Could not find the ${PROJECT_NAME} project in ossfuzz" - - # Exit with a success code while the libssh2 project is not expected to exist - # on oss-fuzz. - exit 0 -fi - -# Modify the oss-fuzz Dockerfile so that we're checking out the current branch in the CI system. -sed -i \ - -e "s@--depth 1@--no-checkout@" \ - -e "s@/src/libssh2@/src/libssh2 ; git -C /src/libssh2 fetch origin $GIT_REF:ci; git -C /src/libssh2 checkout ci@" \ - /tmp/ossfuzz/projects/${PROJECT_NAME}/Dockerfile - -# Try and build the fuzzers -pushd /tmp/ossfuzz -python infra/helper.py build_image --pull ${PROJECT_NAME} -python infra/helper.py build_fuzzers ${PROJECT_NAME} -popd diff --git a/cmake/CheckFunctionExistsMayNeedLibrary.cmake b/cmake/CheckFunctionExistsMayNeedLibrary.cmake index 8ac61abe5e..2de0a70e3c 100644 --- a/cmake/CheckFunctionExistsMayNeedLibrary.cmake +++ b/cmake/CheckFunctionExistsMayNeedLibrary.cmake @@ -69,13 +69,13 @@ function(check_function_exists_may_need_library function variable) # new test check_library_exists(${lib} ${function} "" HAVE_${function}_IN_${lib}) if(HAVE_${function}_IN_${lib}) - set(${variable} 1 CACHE INTERNAL - "Function ${function} found in library ${lib}") - set(NEED_LIB_${UP_LIB} 1 CACHE INTERNAL - "Need to link ${lib}") - break() + set(${variable} 1 CACHE INTERNAL + "Function ${function} found in library ${lib}") + set(NEED_LIB_${UP_LIB} 1 CACHE INTERNAL + "Need to link ${lib}") + break() endif() endforeach() endif() -endfunction() \ No newline at end of file +endfunction() diff --git a/cmake/CheckNonblockingSocketSupport.cmake b/cmake/CheckNonblockingSocketSupport.cmake index 74f4776a68..4af73a29a2 100644 --- a/cmake/CheckNonblockingSocketSupport.cmake +++ b/cmake/CheckNonblockingSocketSupport.cmake @@ -11,10 +11,8 @@ include(CheckCSourceCompiles) # method (if any): # HAVE_O_NONBLOCK # HAVE_FIONBIO -# HAVE_IOCTLSOCKET # HAVE_IOCTLSOCKET_CASE # HAVE_SO_NONBLOCK -# HAVE_DISABLED_NONBLOCKING # # The following variables may be set before calling this macro to # modify the way the check is run: @@ -47,73 +45,49 @@ macro(check_nonblocking_socket_support) #error \"O_NONBLOCK does not work on this platform\" #endif -int main() +int main(void) { - int socket; - int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK); + int socket = 0; + (void)fcntl(socket, F_SETFL, O_NONBLOCK); }" - HAVE_O_NONBLOCK) + HAVE_O_NONBLOCK) if(NOT HAVE_O_NONBLOCK) check_c_source_compiles("/* FIONBIO test (old-style unix) */ #include #include -int main() +int main(void) { - int socket; - int flags = ioctl(socket, FIONBIO, &flags); + int socket = 0; + int flags = 0; + (void)ioctl(socket, FIONBIO, &flags); }" - HAVE_FIONBIO) + HAVE_FIONBIO) if(NOT HAVE_FIONBIO) - check_c_source_compiles("/* ioctlsocket test (Windows) */ -#undef inline -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include -#include - -int main() -{ - SOCKET sd; - unsigned long flags = 0; - sd = socket(0, 0, 0); - ioctlsocket(sd, FIONBIO, &flags); -}" - HAVE_IOCTLSOCKET) - - if(NOT HAVE_IOCTLSOCKET) - check_c_source_compiles("/* IoctlSocket test (Amiga?) */ + check_c_source_compiles("/* IoctlSocket test (Amiga?) */ #include -int main() +int main(void) { - int socket; - int flags = IoctlSocket(socket, FIONBIO, (long)1); + int socket = 0; + (void)IoctlSocket(socket, FIONBIO, (long)1); }" HAVE_IOCTLSOCKET_CASE) - if(NOT HAVE_IOCTLSOCKET_CASE) - check_c_source_compiles("/* SO_NONBLOCK test (BeOS) */ + if(NOT HAVE_IOCTLSOCKET_CASE) + check_c_source_compiles("/* SO_NONBLOCK test (BeOS) */ #include -int main() +int main(void) { long b = 1; - int socket; - int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); + int socket = 0; + (void)setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); }" HAVE_SO_NONBLOCK) - - if(NOT HAVE_SO_NONBLOCK) - # No non-blocking socket method found - set(HAVE_DISABLED_NONBLOCKING 1) - endif() - endif() endif() endif() endif() -endmacro() \ No newline at end of file +endmacro() diff --git a/cmake/FindLibgcrypt.cmake b/cmake/FindLibgcrypt.cmake index 44a79873d6..4de3888d1e 100644 --- a/cmake/FindLibgcrypt.cmake +++ b/cmake/FindLibgcrypt.cmake @@ -50,4 +50,4 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Libgcrypt DEFAULT_MSG LIBGCRYPT_LIBRARY LIBGCRYPT_INCLUDE_DIR) -mark_as_advanced(LIBGCRYPT_INCLUDE_DIR LIBGCRYPT_LIBRARY) \ No newline at end of file +mark_as_advanced(LIBGCRYPT_INCLUDE_DIR LIBGCRYPT_LIBRARY) diff --git a/cmake/FindmbedTLS.cmake b/cmake/FindmbedTLS.cmake index 2f4adbc519..906dcccbff 100644 --- a/cmake/FindmbedTLS.cmake +++ b/cmake/FindmbedTLS.cmake @@ -10,55 +10,53 @@ # MBEDX509_LIBRARY - path to mbedTLS X.509 library # MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library -FIND_PATH(MBEDTLS_INCLUDE_DIR mbedtls/version.h) +find_path(MBEDTLS_INCLUDE_DIR mbedtls/version.h) -IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES) - # Already in cache, be silent - SET(MBEDTLS_FIND_QUIETLY TRUE) -ENDIF() +if(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES) + # Already in cache, be silent + set(MBEDTLS_FIND_QUIETLY TRUE) +endif() -FIND_LIBRARY(MBEDTLS_LIBRARY NAMES mbedtls libmbedtls libmbedx509) -FIND_LIBRARY(MBEDX509_LIBRARY NAMES mbedx509 libmbedx509) -FIND_LIBRARY(MBEDCRYPTO_LIBRARY NAMES mbedcrypto libmbedcrypto) +find_library(MBEDTLS_LIBRARY NAMES mbedtls libmbedtls libmbedx509) +find_library(MBEDX509_LIBRARY NAMES mbedx509 libmbedx509) +find_library(MBEDCRYPTO_LIBRARY NAMES mbedcrypto libmbedcrypto) -IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY) - SET(MBEDTLS_FOUND TRUE) -ENDIF() +if(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY) + set(MBEDTLS_FOUND TRUE) +endif() -IF(MBEDTLS_FOUND) - # split mbedTLS into -L and -l linker options, so we can set them for pkg-config - GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH) - GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE) - GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE) - GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE) - STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE}) - STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE}) - STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE}) - SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}") +if(MBEDTLS_FOUND) + # split mbedTLS into -L and -l linker options, so we can set them for pkg-config + get_filename_component(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH) + get_filename_component(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE) + get_filename_component(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE) + get_filename_component(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE) + string(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE}) + string(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE}) + string(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE}) + set(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}") - IF(NOT MBEDTLS_FIND_QUIETLY) - MESSAGE(STATUS "Found mbedTLS:") - FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT) - STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT}) - IF (MBEDTLSMATCH) - STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH}) - MESSAGE(STATUS " version ${MBEDTLS_VERSION}") - ENDIF(MBEDTLSMATCH) - MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}") - MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}") - MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}") - ENDIF(NOT MBEDTLS_FIND_QUIETLY) -ELSE(MBEDTLS_FOUND) - IF(MBEDTLS_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find mbedTLS") - ENDIF(MBEDTLS_FIND_REQUIRED) -ENDIF(MBEDTLS_FOUND) + if(NOT MBEDTLS_FIND_QUIETLY) + message(STATUS "Found mbedTLS:") + file(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT) + string(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT}) + if(MBEDTLSMATCH) + string(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH}) + message(STATUS " version ${MBEDTLS_VERSION}") + endif() + message(STATUS " TLS: ${MBEDTLS_LIBRARY}") + message(STATUS " X509: ${MBEDX509_LIBRARY}") + message(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}") + endif() +elseif(MBEDTLS_FIND_REQUIRED) + message(FATAL_ERROR "Could not find mbedTLS") +endif() -MARK_AS_ADVANCED( - MBEDTLS_INCLUDE_DIR - MBEDTLS_LIBRARY_DIR - MBEDTLS_LIBRARIES - MBEDTLS_LIBRARY - MBEDX509_LIBRARY - MBEDCRYPTO_LIBRARY +mark_as_advanced( + MBEDTLS_INCLUDE_DIR + MBEDTLS_LIBRARY_DIR + MBEDTLS_LIBRARIES + MBEDTLS_LIBRARY + MBEDX509_LIBRARY + MBEDCRYPTO_LIBRARY ) diff --git a/cmake/Findwolfssl.cmake b/cmake/Findwolfssl.cmake new file mode 100644 index 0000000000..47e1bbad3e --- /dev/null +++ b/cmake/Findwolfssl.cmake @@ -0,0 +1,41 @@ +# - Try to find wolfssl +# Once done this will define +# WOLFSSL_FOUND - System has wolfssl +# WOLFSSL_INCLUDE_DIR - The wolfssl include directories +# WOLFSSL_LIBRARIES - The libraries needed to use wolfssl + +find_package(PkgConfig QUIET) +pkg_check_modules(PC_WOLFSSL QUIET wolfssl) + +find_path(WOLFSSL_INCLUDE_DIR + NAMES wolfssl/ssl.h + HINTS ${PC_WOLFSSL_INCLUDE_DIRS} +) +find_library(WOLFSSL_LIBRARY + NAMES wolfssl + HINTS ${PC_WOLFSSL_LIBRARY_DIRS} +) + +if(WOLFSSL_INCLUDE_DIR) + set(_version_regex "^#define[ \t]+LIBWOLFSSL_VERSION_STRING[ \t]+\"([^\"]+)\".*") + file(STRINGS "${WOLFSSL_INCLUDE_DIR}/wolfssl/version.h" + WOLFSSL_VERSION REGEX "${_version_regex}") + string(REGEX REPLACE "${_version_regex}" "\\1" + WOLFSSL_VERSION "${WOLFSSL_VERSION}") + unset(_version_regex) +endif() + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set WOLFSSL_FOUND +# to TRUE if all listed variables are TRUE and the requested version +# matches. +find_package_handle_standard_args(wolfssl REQUIRED_VARS + WOLFSSL_LIBRARY WOLFSSL_INCLUDE_DIR + VERSION_VAR WOLFSSL_VERSION) + +if(WOLFSSL_FOUND) + set(WOLFSSL_LIBRARIES ${WOLFSSL_LIBRARY}) + set(WOLFSSL_INCLUDE_DIRS ${WOLFSSL_INCLUDE_DIR}) +endif() + +mark_as_advanced(WOLFSSL_INCLUDE_DIR WOLFSSL_LIBRARY) diff --git a/cmake/SocketLibraries.cmake b/cmake/SocketLibraries.cmake deleted file mode 100644 index bfbbd711e3..0000000000 --- a/cmake/SocketLibraries.cmake +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (c) 2014 Alexander Lamaison -# -# Redistribution and use in source and binary forms, -# with or without modification, are permitted provided -# that the following conditions are met: -# -# Redistributions of source code must retain the above -# copyright notice, this list of conditions and the -# following disclaimer. -# -# Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# Neither the name of the copyright holder nor the names -# of any other contributors may be used to endorse or -# promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -# OF SUCH DAMAGE. - -# Some systems have their socket functions in a library. -# (Solaris -lsocket/-lnsl, Windows -lws2_32). This macro appends those -# libraries to the given list -macro(append_needed_socket_libraries LIBRARIES_LIST) - if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 4) - # x86 Windows uses STDCALL for these functions, so their names are mangled, - # meaning the platform checks don't work. Hardcoding these until we get - # a better solution. - set(HAVE_SOCKET 1) - set(HAVE_SELECT 1) - set(HAVE_INET_ADDR 1) - set(NEED_LIB_WS2_32 1) - else() - check_function_exists_may_need_library(socket HAVE_SOCKET socket ws2_32) - check_function_exists_may_need_library(select HAVE_SELECT ws2_32) - check_function_exists_may_need_library(inet_addr HAVE_INET_ADDR nsl ws2_32) - endif() - - if(NEED_LIB_SOCKET) - list(APPEND ${LIBRARIES_LIST} socket) - endif() - if(NEED_LIB_NSL) - list(APPEND ${LIBRARIES_LIST} nsl) - endif() - if(NEED_LIB_WS2_32) - list(APPEND ${LIBRARIES_LIST} ws2_32) - endif() - -endmacro() \ No newline at end of file diff --git a/cmake/Toolchain-Linux-32.cmake b/cmake/Toolchain-Linux-32.cmake deleted file mode 100644 index 6aad9b1e2d..0000000000 --- a/cmake/Toolchain-Linux-32.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2014 Alexander Lamaison -# -# Redistribution and use in source and binary forms, -# with or without modification, are permitted provided -# that the following conditions are met: -# -# Redistributions of source code must retain the above -# copyright notice, this list of conditions and the -# following disclaimer. -# -# Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# Neither the name of the copyright holder nor the names -# of any other contributors may be used to endorse or -# promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -# OF SUCH DAMAGE. - -# Cross-compile 32-bit binary on 64-bit linux host -set(CMAKE_SYSTEM_NAME Linux) -set(CMAKE_SYSTEM_VERSION 1) -set(CMAKE_SYSTEM_PROCESSOR "i386") - -set(CMAKE_CXX_COMPILER_ARG1 "-m32") -set(CMAKE_C_COMPILER_ARG1 "-m32") \ No newline at end of file diff --git a/cmake/max_warnings.cmake b/cmake/max_warnings.cmake index b176d302d3..1d4fe34972 100644 --- a/cmake/max_warnings.cmake +++ b/cmake/max_warnings.cmake @@ -1,23 +1,211 @@ -if(MSVC) - # Use the highest warning level for visual studio. - if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") - string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") +# Copyright (c) 2023 Viktor Szakats + +include(CheckCCompilerFlag) + +option(ENABLE_WERROR "Turn compiler warnings into errors" OFF) +option(PICKY_COMPILER "Enable picky compiler options" ON) + +if(ENABLE_WERROR) + if(MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX") + else() # llvm/clang and gcc style options + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") endif() - if(CMAKE_C_FLAGS MATCHES "/W[0-4]") - string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") +endif() + +if(MSVC) + # Use the highest warning level for Visual Studio. + if(PICKY_COMPILER) + if(CMAKE_CXX_FLAGS MATCHES "[/-]W[0-4]") + string(REGEX REPLACE "[/-]W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + endif() + if(CMAKE_C_FLAGS MATCHES "[/-]W[0-4]") + string(REGEX REPLACE "[/-]W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") + endif() endif() +elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang") + + # https://clang.llvm.org/docs/DiagnosticsReference.html + # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html - # Disable broken warnings - add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) -elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) if(NOT CMAKE_CXX_FLAGS MATCHES "-Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") endif() if(NOT CMAKE_C_FLAGS MATCHES "-Wall") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") endif() + + if(PICKY_COMPILER) + + # WPICKY_ENABLE = Options we want to enable as-is. + # WPICKY_DETECT = Options we want to test first and enable if available. + + # Prefer the -Wextra alias with clang. + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(WPICKY_ENABLE "-Wextra") + else() + set(WPICKY_ENABLE "-W") + endif() + + list(APPEND WPICKY_ENABLE + -pedantic + ) + + # ---------------------------------- + # Add new options here, if in doubt: + # ---------------------------------- + set(WPICKY_DETECT + ) + + # Assume these options always exist with both clang and gcc. + # Require clang 3.0 / gcc 2.95 or later. + list(APPEND WPICKY_ENABLE + -Wbad-function-cast # clang 3.0 gcc 2.95 + -Wconversion # clang 3.0 gcc 2.95 + -Winline # clang 1.0 gcc 1.0 + -Wmissing-declarations # clang 1.0 gcc 2.7 + -Wmissing-prototypes # clang 1.0 gcc 1.0 + -Wnested-externs # clang 1.0 gcc 2.7 + -Wno-long-long # clang 1.0 gcc 2.95 + -Wno-multichar # clang 1.0 gcc 2.95 + -Wpointer-arith # clang 1.0 gcc 1.4 + -Wshadow # clang 1.0 gcc 2.95 + -Wsign-compare # clang 1.0 gcc 2.95 + -Wundef # clang 1.0 gcc 2.95 + -Wunused # clang 1.1 gcc 2.95 + -Wwrite-strings # clang 1.0 gcc 1.4 + ) + + # Always enable with clang, version dependent with gcc + set(WPICKY_COMMON_OLD + -Wcast-align # clang 1.0 gcc 4.2 + -Wdeclaration-after-statement # clang 1.0 gcc 3.4 + -Wempty-body # clang 3.0 gcc 4.3 + -Wendif-labels # clang 1.0 gcc 3.3 + -Wfloat-equal # clang 1.0 gcc 2.96 (3.0) + -Wignored-qualifiers # clang 3.0 gcc 4.3 + -Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0) + -Wno-sign-conversion # clang 3.0 gcc 4.3 + -Wno-system-headers # clang 1.0 gcc 3.0 + -Wstrict-prototypes # clang 1.0 gcc 3.3 + -Wtype-limits # clang 3.0 gcc 4.3 + -Wvla # clang 2.8 gcc 4.3 + ) + + set(WPICKY_COMMON + -Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3 + -Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0 + -Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1 + ) + + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + list(APPEND WPICKY_ENABLE + ${WPICKY_COMMON_OLD} + -Wshift-sign-overflow # clang 2.9 + -Wshorten-64-to-32 # clang 1.0 + ) + # Enable based on compiler version + if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR + (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3)) + list(APPEND WPICKY_ENABLE + ${WPICKY_COMMON} + ) + endif() + if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR + (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.3)) + list(APPEND WPICKY_ENABLE + -Wcomma # clang 3.9 appleclang 8.3 + -Wmissing-variable-declarations # clang 3.2 appleclang 4.6 + ) + endif() + if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) OR + (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.3)) + list(APPEND WPICKY_ENABLE + -Wassign-enum # clang 7.0 appleclang 10.3 + -Wextra-semi-stmt # clang 7.0 appleclang 10.3 + ) + endif() + else() # gcc + list(APPEND WPICKY_DETECT + ${WPICKY_COMMON} + ) + # Enable based on compiler version + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3) + list(APPEND WPICKY_ENABLE + ${WPICKY_COMMON_OLD} + -Wmissing-parameter-type # gcc 4.3 + -Wold-style-declaration # gcc 4.3 + -Wstrict-aliasing=3 # gcc 4.0 + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5 AND MINGW) + list(APPEND WPICKY_ENABLE + -Wno-pedantic-ms-format # gcc 4.5 (mingw-only) + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8) + list(APPEND WPICKY_ENABLE + -Wformat=2 # clang 3.0 gcc 4.8 (clang part-default, enabling it fully causes -Wformat-nonliteral warnings) + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) + list(APPEND WPICKY_ENABLE + -Warray-bounds=2 -ftree-vrp # clang 3.0 gcc 5.0 (clang default: -Warray-bounds) + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0) + list(APPEND WPICKY_ENABLE + -Wduplicated-cond # gcc 6.0 + -Wnull-dereference # clang 3.0 gcc 6.0 (clang default) + -fdelete-null-pointer-checks + -Wshift-negative-value # clang 3.7 gcc 6.0 (clang default) + -Wshift-overflow=2 # clang 3.0 gcc 6.0 (clang default: -Wshift-overflow) + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) + list(APPEND WPICKY_ENABLE + -Walloc-zero # gcc 7.0 + -Wduplicated-branches # gcc 7.0 + -Wformat-overflow=2 # gcc 7.0 + -Wformat-truncation=1 # gcc 7.0 + -Wrestrict # gcc 7.0 + ) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) + list(APPEND WPICKY_ENABLE + -Warith-conversion # gcc 10.0 + ) + endif() + endif() + + # + + unset(WPICKY) + + foreach(_CCOPT ${WPICKY_ENABLE}) + set(WPICKY "${WPICKY} ${_CCOPT}") + endforeach() + + foreach(_CCOPT ${WPICKY_DETECT}) + # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new + # test result in. + string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname) + # GCC only warns about unknown -Wno- options if there are also other diagnostic messages, + # so test for the positive form instead + string(REPLACE "-Wno-" "-W" _CCOPT_ON "${_CCOPT}") + check_c_compiler_flag(${_CCOPT_ON} ${_optvarname}) + if(${_optvarname}) + set(WPICKY "${WPICKY} ${_CCOPT}") + endif() + endforeach() + + message(STATUS "Picky compiler options:${WPICKY}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WPICKY}") + endif() endif() diff --git a/configure.ac b/configure.ac index c4fc3e4e30..a4d386b9cb 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,9 @@ -# AC_PREREQ(2.57) -AC_INIT(libssh2, [-], libssh2-devel@cool.haxx.se) +# AC_PREREQ(2.59) +AC_INIT([libssh2],[-],[libssh2-devel@lists.haxx.se]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_HEADERS([src/libssh2_config.h]) +AC_REQUIRE_AUX_FILE([tap-driver.sh]) AM_MAINTAINER_MODE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -33,11 +34,9 @@ AB_INIT AC_CANONICAL_HOST case "$host" in *-mingw*) - CFLAGS="$CFLAGS -DLIBSSH2_WIN32" LIBS="$LIBS -lws2_32" ;; *darwin*) - CFLAGS="$CFLAGS -DLIBSSH2_DARWIN" ;; *hpux*) ;; @@ -48,12 +47,6 @@ case "$host" in ;; esac -AC_CHECK_TYPE(long long, - [AC_DEFINE(HAVE_LONGLONG, 1, - [Define to 1 if the compiler supports the 'long long' data type.])] - longlong="yes" -) - dnl Our configure and build reentrant settings CURL_CONFIGURE_REENTRANT @@ -74,10 +67,17 @@ AC_PATH_PROGS(SSHD, [sshd], [], [$PATH$PATH_SEPARATOR/usr/libexec$PATH_SEPARATOR]dnl [/usr/sbin$PATH_SEPARATOR/usr/etc$PATH_SEPARATOR/etc]) AM_CONDITIONAL(SSHD, test -n "$SSHD") +m4_ifdef([LT_INIT], +[dnl +LT_INIT([win32-dll]) +],[dnl AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL +]) AC_C_BIGENDIAN +LT_LANG([Windows Resource]) + dnl check for how to do large files AC_SYS_LARGEFILE @@ -85,16 +85,16 @@ AC_SYS_LARGEFILE found_crypto=none found_crypto_str="" -support_clear_memory=no crypto_errors="" m4_set_add([crypto_backends], [openssl]) m4_set_add([crypto_backends], [libgcrypt]) m4_set_add([crypto_backends], [mbedtls]) m4_set_add([crypto_backends], [wincng]) +m4_set_add([crypto_backends], [wolfssl]) AC_ARG_WITH([crypto], - AC_HELP_STRING([--with-crypto=auto|]m4_set_contents([crypto_backends], [|]), + AS_HELP_STRING([--with-crypto=auto|]m4_set_contents([crypto_backends], [|]), [Select crypto backend (default: auto)]), use_crypto=$withval, use_crypto=auto @@ -114,7 +114,7 @@ esac if test "$found_crypto" = "none"; then crypto_errors="${crypto_errors} -Specify --with-crypto=\$backend and/or the neccessary library search prefix. +Specify --with-crypto=\$backend and/or the necessary library search prefix. Known crypto backends: auto, m4_set_contents([crypto_backends], [, ])" AS_MESSAGE([ERROR: ${crypto_errors}]) @@ -122,14 +122,10 @@ else test "$found_crypto_str" = "" && found_crypto_str="$found_crypto" fi -m4_set_foreach([crypto_backends], [backend], - [AM_CONDITIONAL(m4_toupper(backend), test "$found_crypto" = "backend")] -) - # libz AC_ARG_WITH([libz], - AC_HELP_STRING([--with-libz],[Use libz for compression]), + AS_HELP_STRING([--with-libz],[Use libz for compression]), use_libz=$withval, use_libz=auto) @@ -159,43 +155,14 @@ AC_SUBST(LIBSREQUIRED) # # Optional Settings # -AC_ARG_ENABLE(crypt-none, - AC_HELP_STRING([--enable-crypt-none],[Permit "none" cipher -- NOT RECOMMENDED]), - [AC_DEFINE(LIBSSH2_CRYPT_NONE, 1, [Enable "none" cipher -- NOT RECOMMENDED])]) - -AC_ARG_ENABLE(mac-none, - AC_HELP_STRING([--enable-mac-none],[Permit "none" MAC -- NOT RECOMMENDED]), - [AC_DEFINE(LIBSSH2_MAC_NONE, 1, [Enable "none" MAC -- NOT RECOMMENDED])]) - -AC_ARG_ENABLE(gex-new, - AC_HELP_STRING([--disable-gex-new],[Disable "new" diffie-hellman-group-exchange-sha1 method]), - [GEX_NEW=$enableval]) -if test "$GEX_NEW" != "no"; then - AC_DEFINE(LIBSSH2_DH_GEX_NEW, 1, [Enable newer diffie-hellman-group-exchange-sha1 syntax]) -fi - AC_ARG_ENABLE(clear-memory, - AC_HELP_STRING([--disable-clear-memory],[Disable clearing of memory before being freed]), + AS_HELP_STRING([--disable-clear-memory],[Disable clearing of memory before being freed]), [CLEAR_MEMORY=$enableval]) -if test "$CLEAR_MEMORY" != "no"; then - if test "$support_clear_memory" = "yes"; then - AC_DEFINE(LIBSSH2_CLEAR_MEMORY, 1, [Enable clearing of memory before being freed]) - enable_clear_memory=yes - else - if test "$CLEAR_MEMORY" = "yes"; then - AC_MSG_ERROR([secure clearing/zeroing of memory is not supported by the selected crypto backend]) - else - AC_MSG_WARN([secure clearing/zeroing of memory is not supported by the selected crypto backend]) - fi - enable_clear_memory=unsupported - fi +if test "$CLEAR_MEMORY" = "no"; then + AC_DEFINE(LIBSSH2_NO_CLEAR_MEMORY, 1, [Disable clearing of memory before being freed]) + enable_clear_memory=no else - if test "$support_clear_memory" = "yes"; then - enable_clear_memory=no - else - AC_MSG_WARN([secure clearing/zeroing of memory is not supported by the selected crypto backend]) - enable_clear_memory=unsupported - fi + enable_clear_memory=yes fi dnl ************************************************************ @@ -203,8 +170,8 @@ dnl option to switch on compiler debug options dnl AC_MSG_CHECKING([whether to enable pedantic and debug compiler options]) AC_ARG_ENABLE(debug, -AC_HELP_STRING([--enable-debug],[Enable pedantic and debug options]) -AC_HELP_STRING([--disable-debug],[Disable debug options]), +AS_HELP_STRING([--enable-debug],[Enable pedantic and debug options]) +AS_HELP_STRING([--disable-debug],[Disable debug options]), [ case "$enable_debug" in no) AC_MSG_RESULT(no) @@ -232,8 +199,8 @@ dnl on gcc >= 4.0 and SunPro C. dnl AC_MSG_CHECKING([whether to enable hidden symbols in the library]) AC_ARG_ENABLE(hidden-symbols, -AC_HELP_STRING([--enable-hidden-symbols],[Hide internal symbols in library]) -AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibility in library]), +AS_HELP_STRING([--enable-hidden-symbols],[Hide internal symbols in library]) +AS_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibility in library]), [ case "$enableval" in no) AC_MSG_RESULT(no) @@ -264,11 +231,36 @@ AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibi AC_MSG_RESULT(no) ) +# Build tests? +AC_ARG_ENABLE([tests], + [AS_HELP_STRING([--disable-tests], [Disable tests @<:@default=enabled@:>@])], + [ + if ! test "x${enable_tests}" = "xyes"; then + enable_tests="no" + fi + ], + [enable_tests="yes"]) +AM_CONDITIONAL([ENABLE_TESTS], [test "x$enable_tests" = xyes]) + +# Run Docker tests? +AC_ARG_ENABLE([docker-tests], + [AS_HELP_STRING([--disable-docker-tests], + [Do not run tests requiring Docker])], + [run_docker_tests=no], [run_docker_tests=yes]) +AM_CONDITIONAL([RUN_DOCKER_TESTS], [test "x$run_docker_tests" != "xno"]) + +# Run sshd tests? +AC_ARG_ENABLE([sshd-tests], + [AS_HELP_STRING([--disable-sshd-tests], + [Do not run tests requiring sshd])], + [run_sshd_tests=no], [run_sshd_tests=yes]) +AM_CONDITIONAL([RUN_SSHD_TESTS], [test "x$run_sshd_tests" != "xno"]) + # Build example applications? AC_MSG_CHECKING([whether to build example applications]) AC_ARG_ENABLE([examples-build], -AC_HELP_STRING([--enable-examples-build], [Build example applications (this is the default)]) -AC_HELP_STRING([--disable-examples-build], [Do not build example applications]), +AS_HELP_STRING([--enable-examples-build], [Build example applications (this is the default)]) +AS_HELP_STRING([--disable-examples-build], [Do not build example applications]), [case "$enableval" in no | false) build_examples='no' @@ -296,19 +288,17 @@ AM_CONDITIONAL([USE_OSSFUZZ_STATIC], [test -f "$LIB_FUZZING_ENGINE"]) # Checks for header files. -# AC_HEADER_STDC -AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h]) +AC_CHECK_HEADERS([errno.h fcntl.h stdio.h unistd.h sys/param.h sys/uio.h]) AC_CHECK_HEADERS([sys/select.h sys/socket.h sys/ioctl.h sys/time.h]) AC_CHECK_HEADERS([arpa/inet.h netinet/in.h]) -AC_CHECK_HEADERS([sys/un.h], [have_sys_un_h=yes], [have_sys_un_h=no]) -AM_CONDITIONAL([HAVE_SYS_UN_H], test "x$have_sys_un_h" = xyes) +AC_CHECK_HEADERS([sys/un.h]) case $host in *-*-cygwin* | *-*-cegcc*) # These are POSIX-like systems using BSD-like sockets API. ;; *) - AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h]) + AC_CHECK_HEADERS([windows.h], [have_windows_h=yes], [have_windows_h=no]) ;; esac @@ -318,7 +308,7 @@ case $host in dnl Interix: "does provide poll(), but the implementing developer must dnl have been in a bad mood, because poll() only works on the /proc dnl filesystem here" - dnl Mac OS X's poll has funny behaviors, like: + dnl macOS poll() has funny behaviors, like: dnl not being able to do poll on no fildescriptors (10.3?) dnl not being able to poll on some files (like anything in /dev) dnl not having reliable timeout support @@ -330,21 +320,21 @@ case $host in ;; esac -AC_CHECK_FUNCS(gettimeofday select strtoll memset_s) +AC_CHECK_FUNCS(gettimeofday select strtoll explicit_bzero explicit_memset memset_s snprintf) dnl Check for select() into ws2_32 for Msys/Mingw if test "$ac_cv_func_select" != "yes"; then AC_MSG_CHECKING([for select in ws2_32]) - AC_TRY_LINK([ -#ifdef HAVE_WINSOCK2_H + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_WINDOWS_H #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #endif - ],[ + ]], [[ select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL); - ],[ + ]])],[ AC_MSG_RESULT([yes]) HAVE_SELECT="1" AC_DEFINE_UNQUOTED(HAVE_SELECT, 1, @@ -378,9 +368,25 @@ if test $missing_required_deps = 1; then AC_MSG_ERROR([Required dependencies are missing!]) fi +AM_CONDITIONAL([HAVE_WINDRES], + [test "x$have_windows_h" = "xyes" && test "x${enable_shared}" = "xyes" && test -n "${RC}"]) + # Configure parameters LIBSSH2_CHECK_OPTION_WERROR +# Append crypto lib +if test "$found_crypto" = "openssl"; then + LIBS="${LIBS} ${LTLIBSSL}" +elif test "$found_crypto" = "wolfssl"; then + LIBS="${LIBS} ${LTLIBWOLFSSL}" +elif test "$found_crypto" = "libgcrypt"; then + LIBS="${LIBS} ${LTLIBGCRYPT}" +elif test "$found_crypto" = "wincng"; then + LIBS="${LIBS} ${LTLIBBCRYPT}" +elif test "$found_crypto" = "mbedtls"; then + LIBS="${LIBS} ${LTLIBMBEDCRYPTO}" +fi + AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile @@ -399,9 +405,11 @@ AC_MSG_NOTICE([summary of build options: Compiler flags: ${CFLAGS} Library types: Shared=${enable_shared}, Static=${enable_static} Crypto library: ${found_crypto_str} + zlib compression: ${found_libz} Clear memory: $enable_clear_memory Debug build: $enable_debug Build examples: $build_examples + Run Docker tests: $run_docker_tests + Run sshd tests: $run_sshd_tests Path to sshd: $ac_cv_path_SSHD (only for self-tests) - zlib compression: ${found_libz} ]) diff --git a/docs/.gitignore b/docs/.gitignore index 3aed763290..6fc54d7cf0 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,3 +1,4 @@ Makefile Makefile.in +Makefile.am.cmake coverage diff --git a/docs/AUTHORS b/docs/AUTHORS index 5c7445bf13..e94299fcf6 100644 --- a/docs/AUTHORS +++ b/docs/AUTHORS @@ -1,5 +1,5 @@ libssh2 is the result of many friendly people. This list is an attempt to - mention all contributors. If we've missed anyone, tell us! + mention all contributors. If we have missed anyone, tell us! This list of names is a-z sorted. @@ -71,6 +71,7 @@ Steven Van Ingelgem TJ Saunders Tommy Lindgren Tor Arntsen +Viktor Szakats Vincent Jaulin Vincent Torri Vlad Grachov diff --git a/docs/BINDINGS b/docs/BINDINGS deleted file mode 100644 index 471f9be8c9..0000000000 --- a/docs/BINDINGS +++ /dev/null @@ -1,29 +0,0 @@ - -Creative people have written bindings or interfaces for various environments -and programming languages. Using one of these bindings allows you to take -advantage of libssh2 directly from within your favourite language. - -The bindings listed below are not part of the libssh2 distribution archives, -but must be downloaded and installed separately. - -Cocoa/Objective-C - https://github.com/karelia/libssh2_sftp-Cocoa-wrapper - -Haskell - FFI bindings - https://hackage.haskell.org/package/libssh2 - -Perl - Net::SSH2 - https://metacpan.org/pod/Net::SSH2 - -PHP - ssh2 - https://pecl.php.net/package/ssh2 - -Python - pylibssh2 - https://pypi.python.org/pypi/pylibssh2 - -Python-ctypes - - PySsh2 - https://github.com/gellule/PySsh2 - -Ruby - libssh2-ruby - https://github.com/mitchellh/libssh2-ruby diff --git a/docs/BINDINGS.md b/docs/BINDINGS.md new file mode 100644 index 0000000000..63ad1b0d34 --- /dev/null +++ b/docs/BINDINGS.md @@ -0,0 +1,25 @@ +libssh2 bindings +================ + +Creative people have written bindings or interfaces for various environments +and programming languages. Using one of these bindings allows you to take +advantage of libssh2 directly from within your favourite language. + +The bindings listed below are not part of the libssh2 distribution archives, +but must be downloaded and installed separately. + + + +[Cocoa/Objective-C](https://github.com/karelia/libssh2_sftp-Cocoa-wrapper) + +[Haskell FFI bindings](https://hackage.haskell.org/package/libssh2) + +[Perl Net::SSH2](https://metacpan.org/pod/Net::SSH2) + +[PHP ssh2](https://pecl.php.net/package/ssh2) + +[Python pylibssh2](https://pypi.python.org/pypi/pylibssh2) + +[Python-ctypes PySsh2](https://github.com/gellule/PySsh2) + +[Ruby libssh2-ruby](https://github.com/mitchellh/libssh2-ruby) diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 6abf0e4989..fe5810e08c 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright (c) 2014 Alexander Lamaison +# Copyright (c) 2023 Viktor Szakats # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided @@ -33,178 +34,9 @@ # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. -set(MAN_PAGES - libssh2_agent_connect.3 - libssh2_agent_disconnect.3 - libssh2_agent_free.3 - libssh2_agent_get_identity.3 - libssh2_agent_get_identity_path.3 - libssh2_agent_init.3 - libssh2_agent_list_identities.3 - libssh2_agent_set_identity_path.3 - libssh2_agent_userauth.3 - libssh2_banner_set.3 - libssh2_base64_decode.3 - libssh2_channel_close.3 - libssh2_channel_direct_tcpip.3 - libssh2_channel_direct_tcpip_ex.3 - libssh2_channel_eof.3 - libssh2_channel_exec.3 - libssh2_channel_flush.3 - libssh2_channel_flush_ex.3 - libssh2_channel_flush_stderr.3 - libssh2_channel_forward_accept.3 - libssh2_channel_forward_cancel.3 - libssh2_channel_forward_listen.3 - libssh2_channel_forward_listen_ex.3 - libssh2_channel_free.3 - libssh2_channel_get_exit_signal.3 - libssh2_channel_get_exit_status.3 - libssh2_channel_handle_extended_data.3 - libssh2_channel_handle_extended_data2.3 - libssh2_channel_ignore_extended_data.3 - libssh2_channel_open_ex.3 - libssh2_channel_open_session.3 - libssh2_channel_process_startup.3 - libssh2_channel_read.3 - libssh2_channel_read_ex.3 - libssh2_channel_read_stderr.3 - libssh2_channel_receive_window_adjust.3 - libssh2_channel_receive_window_adjust2.3 - libssh2_channel_request_pty.3 - libssh2_channel_request_pty_ex.3 - libssh2_channel_request_pty_size.3 - libssh2_channel_request_pty_size_ex.3 - libssh2_channel_send_eof.3 - libssh2_channel_set_blocking.3 - libssh2_channel_setenv.3 - libssh2_channel_setenv_ex.3 - libssh2_channel_shell.3 - libssh2_channel_subsystem.3 - libssh2_channel_wait_closed.3 - libssh2_channel_wait_eof.3 - libssh2_channel_window_read.3 - libssh2_channel_window_read_ex.3 - libssh2_channel_window_write.3 - libssh2_channel_window_write_ex.3 - libssh2_channel_write.3 - libssh2_channel_write_ex.3 - libssh2_channel_write_stderr.3 - libssh2_channel_x11_req.3 - libssh2_channel_x11_req_ex.3 - libssh2_exit.3 - libssh2_free.3 - libssh2_hostkey_hash.3 - libssh2_init.3 - libssh2_keepalive_config.3 - libssh2_keepalive_send.3 - libssh2_knownhost_add.3 - libssh2_knownhost_addc.3 - libssh2_knownhost_check.3 - libssh2_knownhost_checkp.3 - libssh2_knownhost_del.3 - libssh2_knownhost_free.3 - libssh2_knownhost_get.3 - libssh2_knownhost_init.3 - libssh2_knownhost_readfile.3 - libssh2_knownhost_readline.3 - libssh2_knownhost_writefile.3 - libssh2_knownhost_writeline.3 - libssh2_poll.3 - libssh2_poll_channel_read.3 - libssh2_publickey_add.3 - libssh2_publickey_add_ex.3 - libssh2_publickey_init.3 - libssh2_publickey_list_fetch.3 - libssh2_publickey_list_free.3 - libssh2_publickey_remove.3 - libssh2_publickey_remove_ex.3 - libssh2_publickey_shutdown.3 - libssh2_scp_recv.3 - libssh2_scp_recv2.3 - libssh2_scp_send.3 - libssh2_scp_send64.3 - libssh2_scp_send_ex.3 - libssh2_session_abstract.3 - libssh2_session_banner_get.3 - libssh2_session_banner_set.3 - libssh2_session_block_directions.3 - libssh2_session_callback_set.3 - libssh2_session_disconnect.3 - libssh2_session_disconnect_ex.3 - libssh2_session_flag.3 - libssh2_session_free.3 - libssh2_session_get_blocking.3 - libssh2_session_get_timeout.3 - libssh2_session_handshake.3 - libssh2_session_hostkey.3 - libssh2_session_init.3 - libssh2_session_init_ex.3 - libssh2_session_last_errno.3 - libssh2_session_last_error.3 - libssh2_session_set_last_error.3 - libssh2_session_method_pref.3 - libssh2_session_methods.3 - libssh2_session_set_blocking.3 - libssh2_session_set_timeout.3 - libssh2_session_startup.3 - libssh2_session_supported_algs.3 - libssh2_sftp_close.3 - libssh2_sftp_close_handle.3 - libssh2_sftp_closedir.3 - libssh2_sftp_fsetstat.3 - libssh2_sftp_fstat.3 - libssh2_sftp_fstat_ex.3 - libssh2_sftp_fstatvfs.3 - libssh2_sftp_fsync.3 - libssh2_sftp_get_channel.3 - libssh2_sftp_init.3 - libssh2_sftp_last_error.3 - libssh2_sftp_lstat.3 - libssh2_sftp_mkdir.3 - libssh2_sftp_mkdir_ex.3 - libssh2_sftp_open.3 - libssh2_sftp_open_ex.3 - libssh2_sftp_opendir.3 - libssh2_sftp_read.3 - libssh2_sftp_readdir.3 - libssh2_sftp_readdir_ex.3 - libssh2_sftp_readlink.3 - libssh2_sftp_realpath.3 - libssh2_sftp_rename.3 - libssh2_sftp_rename_ex.3 - libssh2_sftp_rewind.3 - libssh2_sftp_rmdir.3 - libssh2_sftp_rmdir_ex.3 - libssh2_sftp_seek.3 - libssh2_sftp_seek64.3 - libssh2_sftp_setstat.3 - libssh2_sftp_shutdown.3 - libssh2_sftp_stat.3 - libssh2_sftp_stat_ex.3 - libssh2_sftp_statvfs.3 - libssh2_sftp_symlink.3 - libssh2_sftp_symlink_ex.3 - libssh2_sftp_tell.3 - libssh2_sftp_tell64.3 - libssh2_sftp_unlink.3 - libssh2_sftp_unlink_ex.3 - libssh2_sftp_write.3 - libssh2_trace.3 - libssh2_trace_sethandler.3 - libssh2_userauth_authenticated.3 - libssh2_userauth_hostbased_fromfile.3 - libssh2_userauth_hostbased_fromfile_ex.3 - libssh2_userauth_keyboard_interactive.3 - libssh2_userauth_keyboard_interactive_ex.3 - libssh2_userauth_list.3 - libssh2_userauth_password.3 - libssh2_userauth_password_ex.3 - libssh2_userauth_publickey.3 - libssh2_userauth_publickey_fromfile.3 - libssh2_userauth_publickey_fromfile_ex.3 - libssh2_userauth_publickey_frommemory.3 - libssh2_version.3) +transform_makefile_inc("Makefile.am" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.am.cmake") +# Get 'dist_man_MANS' variable +include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.am.cmake) include(GNUInstallDirs) -install(FILES ${MAN_PAGES} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) +install(FILES ${dist_man_MANS} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) diff --git a/docs/HACKING b/docs/HACKING deleted file mode 100644 index 5da8e66c23..0000000000 --- a/docs/HACKING +++ /dev/null @@ -1,13 +0,0 @@ - -libssh2 source code style guide: - - - 4 level indent - - spaces-only (no tabs) - - open braces on the if/for line: - - if (banana) { - go_nuts(); - } - - - keep source lines shorter than 80 columns - - See libssh2-style.el for how to achieve this within Emacs diff --git a/docs/HACKING-CRYPTO b/docs/HACKING-CRYPTO index ca94772861..f1c025bdc8 100644 --- a/docs/HACKING-CRYPTO +++ b/docs/HACKING-CRYPTO @@ -31,18 +31,20 @@ LIBSSH2_LIB_HAVE_LINKFLAGS from LIBSSH2_CRYPTO_CHECK, which automatically creates and handles a --with-$newname-prefix option and sets an LTLIBNEWNAME variable on success. -0.3) Create Makefile.newname.inc in the top-level directory +0.3) Add new header to src/Makefile.inc -This must set CRYPTO_CSOURCES, CRYPTO_HHEADERS and CRYPTO_LTLIBS. -Set CRYPTO_CSOURCES and CRYPTO_HHEADERS to the new backend source files -and set CRYPTO_LTLIBS to the required library linking parameters, e.g. -$(LTLIBNEWNAME) as generated by by LIBSSH2_LIB_HAVE_LINKFLAGS. +0.4) Include new source in src/crypto.c -0.4) Add a new block in src/Makefile.am +0.5) Add a new block in configure.ac -if NEWNAME -include ../Makefile.newname.inc -endif +``` +elif test "$found_crypto" = "newname"; then + LIBS="${LIBS} ${LTLIBNEWNAME}" +``` + +0.6) Add CMake detection logic to CMakeLists.txt + +0.7) Add manual config logic to Makefile.mk 1) Crypto library initialization/termination. @@ -53,6 +55,10 @@ Initializes the crypto library. May be an empty macro if not needed. void libssh2_crypto_exit(void); Terminates the crypto library use. May be an empty macro if not needed. +1.1) Crypto runtime detection + +The libssh2_crypto_engine_t enum must include the new engine, and +libssh2_crypto_engine() must return it when it is built in. 2) HMAC @@ -148,7 +154,7 @@ Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. int libssh2_sha256(const unsigned char *message, - unsigned long len, + size_t len, unsigned char output[SHA256_DIGEST_LENGTH]); Computes the SHA-256 signature over the given message of length len and store the result into the output buffer. @@ -193,7 +199,7 @@ Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. int libssh2_sha384(const unsigned char *message, - unsigned long len, + size_t len, unsigned char output[SHA384_DIGEST_LENGTH]); Computes the SHA-384 signature over the given message of length len and store the result into the output buffer. @@ -227,7 +233,7 @@ Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. int libssh2_sha512(const unsigned char *message, - unsigned long len, + size_t len, unsigned char output[SHA512_DIGEST_LENGTH]); Computes the SHA-512 signature over the given message of length len and store the result into the output buffer. @@ -317,7 +323,8 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, - size_t blocksize); + size_t blocksize, + int firstlast); Encrypt or decrypt in-place data at (block, blocksize) using the given context and/or algorithm. Return 0 if OK, else -1. @@ -388,7 +395,7 @@ _libssh2_cipher_cast5 CAST5-CBC algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). -4.5) Tripple DES in CBC block mode. +4.5) Triple DES in CBC block mode. LIBSSH2_3DES #define as 1 if the crypto library supports TripleDES in CBC mode, else 0. If defined as 0, the rest of this section can be omitted. @@ -400,6 +407,21 @@ TripleDES-CBC algorithm identifier initializer. 5) Diffie-Hellman support. +LIBSSH2_DH_GEX_MINGROUP +The minimum Diffie-Hellman group length in bits supported by the backend. +Usually defined as 2048. + +LIBSSH2_DH_GEX_OPTGROUP +The preferred Diffie-Hellman group length in bits. Usually defined as 4096. + +LIBSSH2_DH_GEX_MAXGROUP +The maximum Diffie-Hellman group length in bits supported by the backend. +Usually defined as 8192. + +LIBSSH2_DH_MAX_MODULUS_BITS +The maximum Diffie-Hellman modulus bit count accepted from the server. This +value must be supported by the backend. Usually 16384. + 5.1) Diffie-Hellman context. _libssh2_dh_ctx Type of a Diffie-Hellman computation context. @@ -595,7 +617,7 @@ This procedure is already prototyped in crypto.h. int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *data, - size_t data_len, + size_t data_len, unsigned const char *passphrase); Gets an RSA private key from data into a new RSA context. Must call _libssh2_init_if_needed(). @@ -604,8 +626,8 @@ This procedure is already prototyped in crypto.h. int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, const unsigned char *sig, - unsigned long sig_len, - const unsigned char *m, unsigned long m_len); + size_t sig_len, + const unsigned char *m, size_t m_len); Verify (sig, sig_len) signature of (m, m_len) using an SHA-1 hash and the RSA context. Return 0 if OK, else -1. @@ -637,6 +659,53 @@ Note: this procedure is not used if macro _libssh2_rsa_sha1_signv() is defined. void _libssh2_rsa_free(libssh2_rsa_ctx *rsactx); Releases the RSA computation context at rsactx. +LIBSSH2_RSA_SHA2 +#define as 1 if the crypto library supports RSA SHA2 256/512, else 0. +If defined as 0, the rest of this section can be omitted. + +int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len); +RSA signs the (hash, hashlen) SHA-2 hash bytes based on hash length and stores +the allocated signature at (signature, signature_len). +Signature buffer must be allocated from the given session. +Returns 0 if OK, else -1. +This procedure is already prototyped in crypto.h. +Note: this procedure is not used if both macros _libssh2_rsa_sha2_256_signv() +and _libssh2_rsa_sha2_512_signv are defined. + +int _libssh2_rsa_sha2_256_signv(LIBSSH2_SESSION *session, + unsigned char **sig, size_t *siglen, + int count, const struct iovec vector[], + libssh2_rsa_ctx *ctx); +RSA signs the SHA-256 hash computed over the count data chunks in vector. +Signature is stored at (sig, siglen). +Signature buffer must be allocated from the given session. +Returns 0 if OK, else -1. +Note: this procedure is optional: if provided, it MUST be defined as a macro. + +int _libssh2_rsa_sha2_512_signv(LIBSSH2_SESSION *session, + unsigned char **sig, size_t *siglen, + int count, const struct iovec vector[], + libssh2_rsa_ctx *ctx); +RSA signs the SHA-512 hash computed over the count data chunks in vector. +Signature is stored at (sig, siglen). +Signature buffer must be allocated from the given session. +Returns 0 if OK, else -1. +Note: this procedure is optional: if provided, it MUST be defined as a macro. + +int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsa, + size_t hash_len, + const unsigned char *sig, + size_t sig_len, + const unsigned char *m, size_t m_len); +Verify (sig, sig_len) signature of (m, m_len) using an SHA-2 hash based on +hash length and the RSA context. +Return 0 if OK, else -1. +This procedure is already prototyped in crypto.h. 7.2) DSA LIBSSH2_DSA @@ -687,7 +756,7 @@ This procedure is already prototyped in crypto.h. int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, const unsigned char *sig, - const unsigned char *m, unsigned long m_len); + const unsigned char *m, size_t m_len); Verify (sig, siglen) signature of (m, m_len) using an SHA-1 hash and the DSA context. Returns 0 if OK, else -1. @@ -695,7 +764,7 @@ This procedure is already prototyped in crypto.h. int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, const unsigned char *hash, - unsigned long hash_len, unsigned char *sig); + size_t hash_len, unsigned char *sig); DSA signs the (hash, hash_len) data using SHA-1 and store the signature at sig. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. @@ -844,7 +913,7 @@ This procedure is already prototyped in crypto.h. int _libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx, LIBSSH2_SESSION *session, const unsigned char *raw_pub_key, - const uint8_t key_len); + const size_t key_len); Stores at ed_ctx a new ED25519 key context for raw public key (raw_pub_key, key_len). Return 0 if OK, else -1. @@ -897,6 +966,17 @@ In example, this is needed to preset unused structure slacks on platforms requiring it. If this is not needed, it should be defined as an empty macro. -int _libssh2_random(unsigned char *buf, int len); +int _libssh2_random(unsigned char *buf, size_t len); Store len random bytes at buf. Returns 0 if OK, else -1. + +const char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session, + unsigned char *key_method, + size_t key_method_len); + +This function is for implementing key hash upgrading as defined in RFC 8332. + +Based on the incoming key_method value, this function will return a +list of supported algorithms that can upgrade the original key method algorithm +as a comma separated list, if there is no upgrade option this function should +return NULL. diff --git a/docs/HACKING.md b/docs/HACKING.md new file mode 100644 index 0000000000..11ddbd305d --- /dev/null +++ b/docs/HACKING.md @@ -0,0 +1,14 @@ +# libssh2 source code style guide + +- 4 level indent +- spaces-only (no tabs) +- open braces on the if/for line: + + ``` + if (banana) { + go_nuts(); + } + ``` + +- keep source lines shorter than 80 columns +- See `libssh2-style.el` for how to achieve this within Emacs diff --git a/docs/INSTALL_AUTOTOOLS b/docs/INSTALL_AUTOTOOLS index a75b51814d..ce1461a4bf 100644 --- a/docs/INSTALL_AUTOTOOLS +++ b/docs/INSTALL_AUTOTOOLS @@ -11,8 +11,7 @@ When Building directly from Master ================================== If you want to build directly from the git repository, you must first -generate the configure script and Makefile using autotools. There is -a convenience script that calls all tools in the correct order. Make +generate the configure script and Makefile using autotools. Make sure that autoconf, automake and libtool are installed on your system, then execute: @@ -38,7 +37,7 @@ file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves +and enabled with `--cache-file=config.cache' or shortly `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) @@ -47,7 +46,7 @@ cache files.) to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you +some point `config.cache' contains results you do not want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create @@ -58,7 +57,7 @@ a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're + `./configure' to configure the package for your system. If you are using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. @@ -149,7 +148,7 @@ is something like `gnu-as' or `x' (for the X Window System). The package recognizes. For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, +find the X include and library files automatically, but if it does not, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. @@ -171,7 +170,7 @@ where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't +`config.sub' is not included in this package, then this package does not need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should @@ -255,73 +254,33 @@ More configure options Some ./configure options deserve additional comments: - * --enable-crypt-none - - The SSH2 Transport allows for unencrypted data - transmission using the "none" cipher. Because this is - such a huge security hole, it is typically disabled on - SSH2 implementations and is disabled in libssh2 by - default as well. - - Enabling this option will allow for "none" as a - negotiable method, however it still requires that the - method be advertized by the remote end and that no - more-preferable methods are available. - - * --enable-mac-none - - The SSH2 Transport also allows implementations to - forego a message authentication code. While this is - less of a security risk than using a "none" cipher, it - is still not recommended as disabling MAC hashes - removes a layer of security. - - Enabling this option will allow for "none" as a - negotiable method, however it still requires that the - method be advertized by the remote end and that no - more-preferable methods are available. - - * --disable-gex-new - - The diffie-hellman-group-exchange-sha1 (dh-gex) key - exchange method originally defined an exchange - negotiation using packet type 30 to request a - generation pair based on a single target value. Later - refinement of dh-gex provided for range and target - values. By default libssh2 will use the newer range - method. - - If you experience trouble connecting to an old SSH - server using dh-gex, try this option to fallback on - the older more reliable method. - * --with-libgcrypt * --without-libgcrypt * --with-libgcrypt-prefix=DIR - libssh2 can use the Libgcrypt library - (https://www.gnupg.org/) for cryptographic operations. + libssh2 can use the Libgcrypt library + (https://www.gnupg.org/) for cryptographic operations. One of the cryptographic libraries is required. - Configure will attempt to locate Libgcrypt - automatically. + Configure will attempt to locate Libgcrypt + automatically. - If your installation of Libgcrypt is in another - location, specify it using --with-libgcrypt-prefix. + If your installation of Libgcrypt is in another + location, specify it using --with-libgcrypt-prefix. * --with-openssl * --without-openssl * --with-libssl-prefix=[DIR] - libssh2 can use the OpenSSL library - (https://www.openssl.org) for cryptographic operations. + libssh2 can use the OpenSSL library + (https://www.openssl.org) for cryptographic operations. One of the cryptographic libraries is required. - Configure will attempt to locate OpenSSL in the - default location. + Configure will attempt to locate OpenSSL in the + default location. - If your installation of OpenSSL is in another - location, specify it using --with-libssl-prefix. + If your installation of OpenSSL is in another + location, specify it using --with-libssl-prefix. * --with-mbedtls * --without-mbedtls @@ -341,15 +300,15 @@ Some ./configure options deserve additional comments: * --without-libz * --with-libz-prefix=[DIR] - If present, libssh2 will attempt to use the zlib - (http://www.zlib.org) for payload compression, however - zlib is not required. + If present, libssh2 will attempt to use the zlib + (https://zlib.net/) for payload compression, however + zlib is not required. - If your installation of Libz is in another location, - specify it using --with-libz-prefix. + If your installation of Libz is in another location, + specify it using --with-libz-prefix. * --enable-debug - Will make the build use more pedantic and strict compiler - options as well as enable the libssh2_trace() function (for - showing debug traces). + Will make the build use more pedantic and strict compiler + options as well as enable the libssh2_trace() function (for + showing debug traces). diff --git a/docs/INSTALL_CMAKE.md b/docs/INSTALL_CMAKE.md index c136fdcee8..d1a6cf77a3 100644 --- a/docs/INSTALL_CMAKE.md +++ b/docs/INSTALL_CMAKE.md @@ -6,10 +6,11 @@ Web site source code: https://github.com/libssh2/www Installation instructions are in docs/INSTALL ======= -To build libssh2 you will need CMake v2.8 or later [1] and one of the +To build libssh2 you will need CMake v3.1 or later [1] and one of the following cryptography libraries: * OpenSSL +* wolfSSL * Libgcrypt * WinCNG * mbedTLS @@ -35,8 +36,8 @@ cryptography library available. The library binary will be put in Customising the build --------------------- -Of course, you might want to customise the build options. You can -pass the options to CMake on the command line: +You might want to customise the build options. You can pass the options +to CMake on the command line: cmake -D