diff --git a/.checksrc b/.checksrc new file mode 100644 index 0000000000..e6e578fc89 --- /dev/null +++ b/.checksrc @@ -0,0 +1,3 @@ +disable FOPENMODE +disable SNPRINTF +disable TYPEDEFSTRUCT 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 72% rename from .github/workflows/appveyor.yml rename to .github/workflows/appveyor_docker.yml index f0fa0eaf9e..6729ce7b89 100644 --- a/.github/workflows/appveyor.yml +++ b/.github/workflows/appveyor_docker.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Marc Hoersken +# Copyright (C) Marc Hoersken # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -21,6 +21,8 @@ # 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. +# +# SPDX-License-Identifier: BSD-3-Clause name: AppVeyor Docker Bridge @@ -40,6 +42,8 @@ on: ssh_privkey: required: true +permissions: {} + jobs: daemon: runs-on: ubuntu-latest @@ -48,18 +52,17 @@ jobs: - name: Setup SSH client configuration run: | cd ~ - mkdir .ssh - chmod 0700 .ssh - echo "ServerAliveInterval 45" > .ssh/config - echo "Host ${{ github.event.inputs.ssh_host }}" >> .ssh/config - echo "${{ github.event.inputs.ssh_forward }}" | sed 's/,/\n/g' | sed 's/^/\tRemoteForward /g' >> .ssh/config - chmod 0600 .ssh/config - cat .ssh/config - echo "${{ github.event.inputs.ssh_host }} ${{ github.event.inputs.ssh_hostkey }}" | sed 's/,/\n${{ github.event.inputs.ssh_host }} /g' > .ssh/known_hosts - chmod 0600 .ssh/known_hosts - cat .ssh/known_hosts - echo "${{ github.event.inputs.ssh_privkey }}" | sed 's/,/\n/g' > .ssh/id_rsa - chmod 0600 .ssh/id_rsa + mkdir -m 0700 .ssh + install -m 0600 /dev/null .ssh/config + { + echo 'ServerAliveInterval 45' + echo 'Host ${{ github.event.inputs.ssh_host }}' + echo '${{ github.event.inputs.ssh_forward }}' | sed 's/,/\n/g' | sed 's/^/ RemoteForward /g' + } | tee -a .ssh/config + install -m 0600 /dev/null .ssh/known_hosts + echo '${{ github.event.inputs.ssh_host }} ${{ github.event.inputs.ssh_hostkey }}' | sed 's/,/\n${{ github.event.inputs.ssh_host }} /g' | tee -a .ssh/known_hosts + install -m 0600 /dev/null .ssh/id_rsa + echo '${{ github.event.inputs.ssh_privkey }}' | sed 's/,/\n/g' >> .ssh/id_rsa # we sleep explicitly to allow the remote system to kill the sleep process - name: Connect to AppVeyor and sleep diff --git a/.github/workflows/appveyor_status.yml b/.github/workflows/appveyor_status.yml new file mode 100644 index 0000000000..6718ba10a1 --- /dev/null +++ b/.github/workflows/appveyor_status.yml @@ -0,0 +1,62 @@ +# Copyright (C) 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. +# +# SPDX-License-Identifier: BSD-3-Clause + +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 00846b1bb4..692780fc29 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,105 +1,647 @@ +# Copyright (C) The libssh2 project and its contributors. +# +# SPDX-License-Identifier: BSD-3-Clause +# name: CI on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] + +permissions: {} jobs: - style-check: + check_style: + name: 'style-check' runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - uses: actions/checkout@v2 - - name: Check Style + - uses: actions/checkout@v4 + - name: 'checksrc' run: ./ci/checksrc.sh - build: + + spellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: 'install tools' + run: pip install -U codespell + - name: 'spellcheck' + run: ./ci/spellcheck.sh + + build_integration: + name: 'integration' + runs-on: ubuntu-latest + timeout-minutes: 60 + env: + CC: clang + steps: + - uses: actions/checkout@v4 + - name: 'cmake' + run: | + sudo apt-get --quiet 2 --option Dpkg::Use-Pty=0 install libssl-dev + ./tests/cmake/test.sh + + build_linux: + name: 'linux' runs-on: ubuntu-latest + timeout-minutes: 60 strategy: fail-fast: false matrix: compiler: [gcc, clang] - address_size: [64] - crypto_backend: [OpenSSL, Libgcrypt, mbedTLS] - build_shared_libs: [OFF, ON] - enable_zlib_compression: [OFF, ON] - b: [cmake] + arch: [amd64] + crypto: [OpenSSL, wolfSSL, Libgcrypt, mbedTLS] + build: [cmake] + zlib: ['OFF', 'ON'] include: - compiler: gcc - address_size: 64 - crypto_backend: OpenSSL - build_shared_libs: OFF - enable_zlib_compression: OFF - b: configure + arch: amd64 + crypto: OpenSSL + build: autotools + zlib: 'OFF' + - compiler: clang + arch: amd64 + crypto: OpenSSL + build: autotools + zlib: 'OFF' - compiler: clang - address_size: 64 - crypto_backend: OpenSSL - build_shared_libs: OFF - enable_zlib_compression: OFF - b: configure + arch: amd64 + crypto: OpenSSL + build: autotools + zlib: 'ON' + target: 'distcheck' + - compiler: gcc + arch: i386 + crypto: mbedTLS + build: cmake + zlib: 'ON' + - compiler: gcc + arch: amd64 + crypto: BoringSSL + build: cmake + zlib: 'ON' + - compiler: gcc + arch: amd64 + crypto: OpenSSL-3-no-deprecated + build: cmake + zlib: 'ON' + - compiler: clang + arch: i386 + crypto: Libgcrypt + build: autotools + zlib: 'ON' + options: --disable-static 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 }} - run: | - sudo apt-get install -y libssl-dev - sudo apt-get install -y libgcrypt-dev - - name: Install mbedTLS Dependencies - if: ${{ matrix.crypto_backend == 'mbedTLS' }} - run: | - MBEDTLSVER=mbedtls-2.7.0 - curl -L https://github.com/ARMmbed/mbedtls/archive/$MBEDTLSVER.tar.gz | tar -xzf - + - uses: actions/checkout@v4 + - name: 'install architecture' + if: ${{ matrix.arch != 'amd64' }} + run: | + sudo dpkg --add-architecture '${{ matrix.arch }}' + sudo apt-get --quiet 2 --option Dpkg::Use-Pty=0 update + # Workaround for https://github.com/actions/runner-images/issues/7589 + sudo apt-get --quiet 2 --option Dpkg::Use-Pty=0 install libgcc-s1:${{ matrix.arch }} + sudo apt-get --quiet 2 --option Dpkg::Use-Pty=0 install gcc-multilib build-essential zlib1g-dev:${{ matrix.arch }} + + - name: 'install packages' + run: | + [ '${{ matrix.crypto }}' = 'OpenSSL' ] && pkg='libssl-dev' + [ '${{ matrix.crypto }}' = 'wolfSSL' ] && pkg='libwolfssl-dev' + [ '${{ matrix.crypto }}' = 'Libgcrypt' ] && pkg='libgcrypt-dev' + if [ -n "${pkg}" ]; then + sudo apt-get --quiet 2 --option Dpkg::Use-Pty=0 install "${pkg}:${{ matrix.arch }}" + fi + + - name: 'install mbedTLS from source' + if: ${{ matrix.crypto == 'mbedTLS' }} + run: | + MBEDTLSVER=mbedtls-3.5.1 + 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 . + if [ '${{ matrix.arch }}' = 'i386' ]; then + crossoptions='-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_VERSION=1 -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.arch }}' + cflags='-m32 -mpclmul -msse2 -maes' + fi + cmake ${crossoptions} \ + "-DCMAKE_C_FLAGS=${cflags}" \ + -DENABLE_PROGRAMS=OFF \ + -DENABLE_TESTING=OFF \ + -DUSE_STATIC_MBEDTLS_LIBRARY=OFF \ + -DUSE_SHARED_MBEDTLS_LIBRARY=ON \ + -DCMAKE_INSTALL_PREFIX:PATH=$PWD/../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: 'install BoringSSL from source' + if: ${{ matrix.crypto == 'BoringSSL' }} run: | - autoreconf -fi - ./configure --enable-debug --enable-werror - make - make check - - name: Build with CMake - if: ${{ matrix.b == 'cmake' }} - 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: + BORINGSSLVER=1b7fdbd9101dedc3e0aa3fcf4ff74eacddb34ecc + mkdir boringssl + cd boringssl + curl "https://boringssl.googlesource.com/boringssl/+archive/$BORINGSSLVER.tar.gz" | tar -xzf - + cmake \ + -DOPENSSL_SMALL=ON \ + -DCMAKE_C_FLAGS=-fPIC \ + -DCMAKE_INSTALL_PREFIX:PATH=$PWD/../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: 'install OpenSSL from source' + if: ${{ matrix.crypto == 'OpenSSL-3-no-deprecated' }} + run: | + OPENSSLVER=openssl-3.2.0 + curl -L https://www.openssl.org/source/$OPENSSLVER.tar.gz | tar -xzf - + cd $OPENSSLVER + ./Configure no-deprecated \ + no-apps no-docs no-tests no-makedepend \ + no-comp no-quic no-legacy --prefix=/usr + make -j3 install DESTDIR=$PWD/.. + 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: 'autotools autoreconf' + if: ${{ matrix.build == 'autotools' }} + run: autoreconf -fi + - name: 'autotools configure' + if: ${{ matrix.build == 'autotools' }} + run: | + if [ '${{ matrix.arch }}' = 'i386' ]; then + crossoptions='--host=i686-pc-linux-gnu' + export CFLAGS=-m32 + fi + mkdir bld && cd bld && ../configure --enable-werror --enable-debug \ + ${crossoptions} ${{ matrix.options }} + + - 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' }} + timeout-minutes: 10 + run: make -C bld -j3 distcheck + - name: 'cmake configure' + if: ${{ matrix.build == 'cmake' }} + run: | + if [ '${{ matrix.crypto }}' = 'BoringSSL' ] || \ + [[ '${{ matrix.crypto }}' = 'OpenSSL-'* ]]; then + crypto='OpenSSL' + else + crypto='${{ matrix.crypto }}' + fi + [ '${{ matrix.arch }}' = 'i386' ] && crossoptions='-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_VERSION=1 -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.arch }} -DCMAKE_C_FLAGS=-m32' + cmake -B bld ${crossoptions} $TOOLCHAIN_OPTION \ + -DENABLE_WERROR=ON \ + -DCRYPTO_BACKEND=${crypto} \ + -DENABLE_ZLIB_COMPRESSION=${{ matrix.zlib }} + + - name: 'cmake build' + if: ${{ matrix.build == 'cmake' }} + run: cmake --build bld --parallel 3 --target package + - name: 'cmake tests' + if: ${{ matrix.build == 'cmake' && matrix.crypto != '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_linux_cross_mingw64: + name: 'linux -> mingw-w64' runs-on: ubuntu-latest + timeout-minutes: 30 strategy: fail-fast: false matrix: - compiler: [gcc, clang] + build: [autotools, cmake] + compiler: [gcc] env: - CC: ${{ matrix.compiler }} - CC_FOR_BUILD: ${{ matrix.compiler }} + TRIPLET: 'x86_64-w64-mingw32' + steps: + - uses: actions/checkout@v4 + - name: 'install packages' + run: sudo apt-get --quiet 2 --option Dpkg::Use-Pty=0 install mingw-w64 + - 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 --host=${TRIPLET} + - name: 'autotools build' + if: ${{ matrix.build == 'autotools' }} + run: make -C bld -j3 + - name: 'cmake configure' + if: ${{ matrix.build == 'cmake' }} + run: | + cmake -B bld \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_C_COMPILER_TARGET=${TRIPLET} \ + -DCMAKE_C_COMPILER=${TRIPLET}-gcc \ + -DENABLE_WERROR=ON + + - name: 'cmake build' + if: ${{ matrix.build == 'cmake' }} + run: cmake --build bld --parallel 3 + + build_cygwin: + name: 'cygwin' + runs-on: windows-latest + timeout-minutes: 30 + env: + SHELLOPTS: 'igncr' + strategy: + matrix: + include: + - { build: 'automake', platform: 'x86_64', compiler: 'gcc' } + - { build: 'cmake' , platform: 'x86_64', compiler: 'gcc' } + fail-fast: false + steps: + - run: git config --global core.autocrlf input + - uses: actions/checkout@v4 + - uses: cygwin/cygwin-install-action@v4 + with: + platform: ${{ matrix.platform }} + packages: autoconf libtool ${{ matrix.build }} gcc-core gcc-g++ binutils make libssl-devel zlib-devel + site: https://mirrors.kernel.org/sourceware/cygwin/ + + - name: 'autotools' + if: ${{ matrix.build == 'automake' }} + timeout-minutes: 10 + shell: C:\cygwin\bin\bash.exe '{0}' + run: | + export PATH="/usr/bin:$(cygpath ${SYSTEMROOT})/system32" + autoreconf -fi + mkdir bld && cd bld && ../configure --enable-werror --enable-debug \ + --with-crypto=openssl \ + --disable-docker-tests + make -j3 + make check VERBOSE=1 + + - name: 'cmake' + if: ${{ matrix.build == 'cmake' }} + timeout-minutes: 10 + shell: C:\cygwin\bin\bash.exe '{0}' + run: | + export PATH="/usr/bin:$(cygpath ${SYSTEMROOT})/system32" + cmake -B bld \ + -DENABLE_WERROR=ON \ + -DENABLE_DEBUG_LOGGING=ON \ + -DCRYPTO_BACKEND=OpenSSL \ + -DOPENSSL_ROOT_DIR=/usr/lib \ + -DENABLE_ZLIB_COMPRESSION=ON \ + -DRUN_DOCKER_TESTS=OFF \ + -DRUN_SSHD_TESTS=OFF + cmake --build bld --parallel 3 + cd bld && ctest -VV --output-on-failure + + build_msys2: + name: 'msys2' + runs-on: windows-latest + timeout-minutes: 30 + strategy: + matrix: + include: + - { build: 'autotools', sys: msys , env: x86_64 } + - { build: 'cmake' , sys: msys , env: x86_64 } + - { 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: 'cmake' , sys: mingw64, env: x86_64, test: 'uwp' } + - { build: 'cmake' , sys: mingw64, env: x86_64, test: 'no-options' } + fail-fast: false + steps: + - uses: actions/checkout@v4 + - uses: msys2/setup-msys2@v2 + if: ${{ matrix.sys == 'msys' }} + with: + msystem: ${{ matrix.sys }} + install: gcc ${{ matrix.build }} make openssl-devel zlib-devel + - uses: msys2/setup-msys2@v2 + if: ${{ matrix.sys != 'msys' }} + 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' }} + shell: msys2 {0} + run: | + if [[ '${{ matrix.env }}' = 'clang'* ]]; then + options='-DCMAKE_C_COMPILER=clang -DCMAKE_UNITY_BUILD=ON' + else + options='-DCMAKE_C_COMPILER=gcc' + fi + if [ '${{ matrix.test }}' = 'uwp' ]; then + options="${options} -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0" + pacman --noconfirm --ask 20 --noprogressbar --sync --needed 'mingw-w64-${{ matrix.env }}-winstorecompat-git' + specs="$(realpath gcc-specs-uwp)" + gcc -dumpspecs | sed -e 's/-lmingwex/-lwindowsapp -lmingwex -lwindowsapp -lwindowsappcompat/' -e 's/-lmsvcrt/-lmsvcr120_app/' > "${specs}" + cflags="-specs=${specs} -DWINSTORECOMPAT -DWINAPI_FAMILY=WINAPI_FAMILY_APP" + # CMake (as of v3.26.4) gets confused and applies the MSVC rc.exe command-line + # template to windres. Reset it to the windres template manually: + rcopts=' -O coff ' + elif [ '${{ matrix.test }}' = 'no-options' ]; then + options="${options} -DLIBSSH2_NO_DEPRECATED=ON" + cflags='-DLIBSSH2_NO_MD5 -DLIBSSH2_NO_MD5_PEM -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' + else + cflags='' + rcopts='' + fi + cmake -B bld ${options} \ + "-DCMAKE_C_FLAGS=${cflags}" \ + "-DCMAKE_RC_COMPILE_OBJECT=${rcopts}" \ + -DENABLE_WERROR=ON \ + -DENABLE_DEBUG_LOGGING=ON \ + -DCRYPTO_BACKEND=OpenSSL \ + -DENABLE_ZLIB_COMPRESSION=ON \ + -DRUN_DOCKER_TESTS=OFF \ + -DRUN_SSHD_TESTS=OFF \ + -DCMAKE_VERBOSE_MAKEFILE=ON + + - name: 'cmake build' + if: ${{ matrix.build == 'cmake' }} + shell: msys2 {0} + run: cmake --build bld --parallel 3 + - name: 'cmake tests' + # UWP missing 'msvcr120_app.dll', fails with exit code 0xc0000135 + if: ${{ matrix.build == 'cmake' && matrix.test != 'uwp' }} + timeout-minutes: 10 + shell: msys2 {0} + run: cd bld && ctest -VV --output-on-failure + + 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@v4 + - name: 'cmake configure' + shell: bash + run: | + 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: + 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 -DMBEDTLS_INCLUDE_DIR=/usr/local/opt/mbedtls/include -DMBEDCRYPTO_LIBRARY=/usr/local/opt/mbedtls/lib/libmbedcrypto.a + steps: + - name: 'install packages' + run: brew install automake ${{ matrix.crypto.install }} + - uses: actions/checkout@v4 + - 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 + + build_freebsd: + name: 'FreeBSD (autotools, openssl, clang, amd64)' + runs-on: macos-12 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: 'autotools' + uses: cross-platform-actions/action@v0.21.1 + with: + operating_system: "freebsd" + version: "13.2" + architecture: "x86_64" + run: | + # https://ports.freebsd.org/ + sudo pkg install -y autoconf automake libtool + setenv CC clang + autoreconf -fi + mkdir bld && cd bld && ../configure --enable-werror --enable-debug \ + --with-crypto=openssl \ + --disable-docker-tests + make -j3 + make check VERBOSE=1 + + build_freebsd_new: + name: 'FreeBSD 14 (autotools, openssl, clang, amd64)' + runs-on: ubuntu-22.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: 'autotools' + uses: vmactions/freebsd-vm@v1 + with: + # https://ports.freebsd.org/ + prepare: pkg install -y autoconf automake libtool bash + run: | + setenv CC clang + autoreconf -fi + mkdir bld && cd bld && ../configure --enable-werror --enable-debug \ + --with-crypto=openssl \ + --disable-docker-tests + make -j3 + make check VERBOSE=1 + + build_netbsd: + name: 'NetBSD (cmake, openssl, clang, amd64)' + runs-on: macos-12 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: 'cmake' + uses: cross-platform-actions/action@v0.21.1 + with: + operating_system: "netbsd" + version: "9.3" + architecture: "x86_64" + run: | + # https://pkgsrc.se/ + sudo pkgin -y install cmake + cmake -B bld \ + -DENABLE_WERROR=ON \ + -DENABLE_DEBUG_LOGGING=ON \ + -DCRYPTO_BACKEND=OpenSSL \ + -DBUILD_STATIC_LIBS=OFF \ + -DRUN_DOCKER_TESTS=OFF \ + -DRUN_SSHD_TESTS=OFF + cmake --build bld --parallel 3 + + build_openbsd: + name: 'OpenBSD (cmake, libressl, clang, amd64)' + runs-on: macos-12 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: 'cmake' + uses: cross-platform-actions/action@v0.21.1 + with: + operating_system: "openbsd" + version: "7.4" + architecture: "x86_64" + run: | + # https://openbsd.app/ + sudo pkg_add cmake + cmake -B bld \ + -DENABLE_WERROR=ON \ + -DENABLE_DEBUG_LOGGING=ON \ + -DCRYPTO_BACKEND=OpenSSL \ + -DBUILD_STATIC_LIBS=OFF \ + -DRUN_DOCKER_TESTS=OFF \ + -DRUN_SSHD_TESTS=OFF + cmake --build bld --parallel 3 + + build_omnios: + name: 'OmniOS (autotools, openssl, gcc, amd64)' + runs-on: ubuntu-22.04 + timeout-minutes: 30 steps: - - uses: actions/checkout@v2 - - name: Run Fuzzer - run: GIT_REF=$GITHUB_REF ./ci/ossfuzz.sh + - uses: actions/checkout@v4 + - name: 'autotools' + uses: vmactions/omnios-vm@v1 + with: + usesh: true + # https://pkg.omnios.org/r151048/core/en/index.shtml + prepare: pkg install build-essential libtool + run: | + autoreconf -fi + mkdir bld && cd bld && ../configure --enable-werror --enable-debug \ + --with-crypto=openssl \ + --disable-docker-tests + gmake -j3 + gmake check VERBOSE=1 diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 0000000000..5fd235236d --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,34 @@ +# Copyright (C) The libssh2 project and its contributors. +# +# SPDX-License-Identifier: BSD-3-Clause +# +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..69526b2c7c --- /dev/null +++ b/.github/workflows/openssh_server.yml @@ -0,0 +1,68 @@ +# Copyright (C) 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. +# +# SPDX-License-Identifier: BSD-3-Clause + +name: OpenSSH Server Docker Image + +on: + push: + branches: [ master ] + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/checkout@v4 + + - 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@v5 + 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@v5 + 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/.github/workflows/reuse.yml b/.github/workflows/reuse.yml new file mode 100644 index 0000000000..562911db46 --- /dev/null +++ b/.github/workflows/reuse.yml @@ -0,0 +1,29 @@ +# Copyright (C) Daniel Stenberg +# SPDX-FileCopyrightText: 2022 Free Software Foundation Europe e.V. +# +# SPDX-License-Identifier: BSD-3-Clause + +name: REUSE compliance + +on: + push: + branches: + - master + - '*/ci' + pull_request: + branches: + - master + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + +permissions: {} + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: REUSE Compliance Check + uses: fsfe/reuse-action@v2 diff --git a/.gitignore b/.gitignore index d256f68b74..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,3 +43,4 @@ libssh2.pc TAGS *~ .DS_Store +build diff --git a/.reuse/dep5 b/.reuse/dep5 new file mode 100644 index 0000000000..8e91ab515e --- /dev/null +++ b/.reuse/dep5 @@ -0,0 +1,34 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: libssh2 +Upstream-Contact: The libssh2 team +Source: https://libssh2.org/ + +# Test data +Files: tests/ossfuzz/* tests/key_* tests/test_read_algos.txt ci/spellcheck-words.txt +Copyright: The libssh2 project and its contributors. +License: BSD-3-Clause + +# Test server +Files: tests/openssh_server/.gitattributes tests/openssh_server/authorized_keys tests/openssh_server/ca_* tests/openssh_server/ssh_* tests/openssh_server/sshd_config +Copyright: The libssh2 project and its contributors. +License: BSD-3-Clause + +# Root files +Files: NEWS README README.md RELEASE-NOTES +Copyright: The libssh2 project and its contributors. +License: BSD-3-Clause + +# Docs +Files: docs/.gitignore docs/AUTHORS docs/BINDINGS.md docs/HACKING-CRYPTO docs/HACKING.md docs/INSTALL_CMAKE.md docs/Makefile.am docs/SECURITY.md docs/TODO docs/template.3 os400/README400 +Copyright: The libssh2 project and its contributors. +License: BSD-3-Clause + +# vms files +Files: vms/libssh2_config.h 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 +Copyright: The libssh2 project and its contributors. +License: BSD-3-Clause + +# dot files +Files: .checksrc .editorconfig .github/ISSUE_TEMPLATE/bug_report.md .github/SECURITY.md .github/stale.yml .gitignore example/.gitignore m4/.gitignore src/.gitignore tests/.gitignore +Copyright: The libssh2 project and its contributors. +License: BSD-3-Clause 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..4ac44a0a41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ -# Copyright (c) 2014, 2015 Alexander Lamaison +# Copyright (C) Alexander Lamaison +# Copyright (C) Viktor Szakats # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided @@ -32,28 +33,38 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. +# +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.7) +message(STATUS "Using CMake version ${CMAKE_VERSION}") -cmake_minimum_required(VERSION 2.8.11) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) + +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckIncludeFiles) +include(CMakePushCheckState) +include(FeatureSummary) -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) +include(CheckFunctionExistsMayNeedLibrary) +include(CheckNonblockingSocketSupport) 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_SHARED_LIBS "Build Shared Libraries" OFF) +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" ON) +add_feature_info("Shared library" BUILD_SHARED_LIBS + "creating libssh2 shared library (.so/.dll)") # Parse version -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/include/libssh2.h _HEADER_CONTENTS) +file(READ "${PROJECT_SOURCE_DIR}/include/libssh2.h" _HEADER_CONTENTS) string( REGEX REPLACE ".*#define LIBSSH2_VERSION[ \t]+\"([^\"]+)\".*" "\\1" LIBSSH2_VERSION "${_HEADER_CONTENTS}") @@ -71,28 +82,354 @@ if(NOT LIBSSH2_VERSION OR NOT LIBSSH2_VERSION_MAJOR MATCHES "^[0-9]+$" OR NOT LIBSSH2_VERSION_MINOR MATCHES "^[0-9]+$" OR NOT LIBSSH2_VERSION_PATCH MATCHES "^[0-9]+$") - message( - FATAL_ERROR - "Unable to parse version from" - "${CMAKE_CURRENT_SOURCE_DIR}/include/libssh2.h") + message(FATAL_ERROR "Unable to parse version from ${PROJECT_SOURCE_DIR}/include/libssh2.h") 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) +include(PickyWarnings) -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_NAME "libssh2") +set(LIB_STATIC "${LIB_NAME}_static") +set(LIB_SHARED "${LIB_NAME}_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() + +option(LIBSSH2_NO_DEPRECATED "Build without deprecated APIs" OFF) +add_feature_info("Without deprecated APIs" LIBSSH2_NO_DEPRECATED "") +if(LIBSSH2_NO_DEPRECATED) + add_definitions("-DLIBSSH2_NO_DEPRECATED") +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_STRTOLL 0) + set(HAVE_STRTOI64 1) + endif() + if(NOT MSVC_VERSION LESS 1900) + set(HAVE_SNPRINTF 1) + else() + set(HAVE_SNPRINTF 0) + 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(STATUS "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 LIBSSH2_PC_LIBS_PRIVATE "-lcrypto") + list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "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 LIBSSH2_PC_LIBS_PRIVATE "-lcrypt32" "-lbcrypt") + + #set(CMAKE_FIND_DEBUG_MODE ON) + + 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) + list(APPEND _RUNTIME_DEPENDENCIES ${DLL_LIBCRYPTO}) + message(STATUS "Found libcrypto DLL: ${DLL_LIBCRYPTO}") + else() + message(WARNING "Unable to find OpenSSL libcrypto DLL, executables may not run") + endif() + + #set(CMAKE_FIND_DEBUG_MODE OFF) + endif() + + find_package(ZLIB) + + if(ZLIB_FOUND) + list(APPEND LIBRARIES ${ZLIB_LIBRARIES}) + list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lz") + 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 LIBSSH2_PC_LIBS_PRIVATE "-lwolfssl") + list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "wolfssl") + + if(WIN32) + list(APPEND LIBRARIES "crypt32") + list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-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 LIBSSH2_PC_LIBS_PRIVATE "-lz") + 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 LIBSSH2_PC_LIBS_PRIVATE "-lgcrypt") + list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "libgcrypt") + 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 LIBSSH2_PC_LIBS_PRIVATE "-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 LIBSSH2_PC_LIBS_PRIVATE "-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) @@ -100,10 +437,12 @@ endif() option(LINT "Check style while building" OFF) if(LINT) - add_custom_target(lint ALL - ./ci/checksrc.sh - WORKING_DIRECTORY ${libssh2_SOURCE_DIR}) - add_dependencies(libssh2 lint) + add_custom_target(lint ALL "./ci/checksrc.sh" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) + 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..6eb5146840 100644 --- a/COPYING +++ b/COPYING @@ -1,11 +1,11 @@ -/* Copyright (c) 2004-2007 Sara Golemon - * 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) 2004-2007 Sara Golemon + * Copyright (C) 2005,2006 Mikhail Gusarov + * Copyright (C) 2006-2007 The Written Word, Inc. + * Copyright (C) 2007 Eli Fant + * Copyright (C) 2009-2023 Daniel Stenberg * Copyright (C) 2008, 2009 Simon Josefsson - * Copyright (c) 2000 Markus Friedl - * Copyright (c) 2015 Microsoft Corp. + * Copyright (C) 2000 Markus Friedl + * Copyright (C) 2015 Microsoft Corp. * All rights reserved. * * Redistribution and use in source and binary forms, @@ -41,4 +41,3 @@ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ - diff --git a/LICENSES/BSD-2-Clause.txt b/LICENSES/BSD-2-Clause.txt new file mode 100644 index 0000000000..b0bed5edf6 --- /dev/null +++ b/LICENSES/BSD-2-Clause.txt @@ -0,0 +1,9 @@ +Copyright + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. 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. diff --git a/LICENSES/BSD-3-Clause.txt b/LICENSES/BSD-3-Clause.txt new file mode 100644 index 0000000000..086d3992cb --- /dev/null +++ b/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,11 @@ +Copyright (c) . + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder nor the names of its 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 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. diff --git a/LICENSES/FSFULLR.txt b/LICENSES/FSFULLR.txt new file mode 100644 index 0000000000..2247a667f5 --- /dev/null +++ b/LICENSES/FSFULLR.txt @@ -0,0 +1,5 @@ +# Copyright Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 0000000000..8aa26455d2 --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LICENSES/curl.txt b/LICENSES/curl.txt new file mode 100644 index 0000000000..982fe1e869 --- /dev/null +++ b/LICENSES/curl.txt @@ -0,0 +1,21 @@ +COPYRIGHT AND PERMISSION NOTICE + +Copyright (C) Daniel Stenberg, , and many contributors. + +All rights reserved. + +Permission to use, copy, modify, and distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright +notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization of the copyright holder. 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..dda85965fd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,9 @@ +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause AUTOMAKE_OPTIONS = foreign nostdinc -SUBDIRS = src tests docs +SUBDIRS = src docs +SUBDIRS += tests 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 + +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 ACLOCAL_AMFLAGS = -I m4 @@ -60,7 +53,7 @@ dist-hook: (distit=`find $(srcdir) -name "*.dist"`; \ for file in $$distit; do \ strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \ - cp $$file $(distdir)$$strip; \ + cp -p $$file $(distdir)$$strip; \ done) # Code Coverage @@ -69,86 +62,24 @@ init-coverage: make clean lcov --directory . --zerocounters -COVERAGE_CCOPTS ?= "-g --coverage" -COVERAGE_OUT ?= docs/coverage +COVERAGE_CCOPTS := "-g --coverage" +COVERAGE_OUT := docs/coverage 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 \ + -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.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 deleted file mode 100644 index 07bc2ddad1..0000000000 --- a/NMakefile +++ /dev/null @@ -1,33 +0,0 @@ -!include "win32/config.mk" - -!if "$(WITH_WINCNG)" == "1" -!include "Makefile.WinCNG.inc" -!else -!include "Makefile.OpenSSL.inc" -!endif -!include "Makefile.inc" - -OBJECTS=$(CSOURCES:.c=.obj) - -# SUBDIRS=src example -SUBDIRS=src - -all-sub: win32\objects.mk - -for %D in ($(SUBDIRS)) do $(MAKE) /nologo /f %D/NMakefile BUILD=$(BUILD) SUBDIR=%D all-sub - -clean: - -rmdir 2>NUL /s/q $(TARGET) - -del 2>NUL win32\objects.mk - -real-clean vclean: clean - -del 2>NUL libssh2.dll - -del 2>NUL libssh2.exp - -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 89639ba7d2..fca539dbbc 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ libssh2 - SSH2 library libssh2 is a library implementing the SSH2 protocol, available under the revised BSD license. -Web site: https://www.libssh2.org/ +Web site: https://libssh2.org/ Mailing list: https://lists.haxx.se/listinfo/libssh2-devel diff --git a/README.md b/README.md index caa0b6708a..9d167c0705 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ libssh2 is a library implementing the SSH2 protocol, available under the revised BSD license. -[Web site](https://www.libssh2.org/) +[Web site](https://libssh2.org/) [Mailing list](https://lists.haxx.se/listinfo/libssh2-devel) -[BSD Licensed](https://www.libssh2.org/license.html) +[BSD Licensed](https://libssh2.org/license.html) [Web site source code](https://github.com/libssh2/www) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 62064a9fe6..2d0affc039 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,62 +1,174 @@ -libssh2 1.10 +libssh2 1.11.1_DEV 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 +- autotools: delete `--disable-tests` option, fix CI tests (e051ae34 #1271 revert: 7483edfa) +- autotools: show the default for `hidden-symbols` option (a3f5594a #1269) +- autotools: enable `-Wunused-macros` with gcc (ecdf5199 #1262 #1227 #1224) +- autotools: fix dotless gcc and Apple clang version detections (89ccc83c #1232 #1187) +- autotools: show more clang/gcc version details (fb580161 #1230) +- autotools: avoid warnings in libtool stub code (96682bd5 #1227 #1224) +- autotools: sync warning enabler code with curl (5996fefe #1223) +- autotools: rename variable (ce5f208a #1222) +- autotools: picky warning options tidy-up (cdca8cff #1221) +- autotools: fix selecting WinCNG in cross-builds (and more) (00a3b88c #1187 #1186) +- autotools: use comma separator in `Requires.private` of `libssh2.pc` (7f83de14 #1124) +- autotools: improve libz position (c89174a7 #1077 #1075 #1013 regr: 4f0f4bff) +- autotools: skip tests requiring static lib if `--disable-static` (572c57c9 #1072 #1056 regr: 83853f8a) +- build: enable `-pedantic-errors` (3ec53f3e #1286) +- build: add mingw-w64 support to `LIBSSH2_PRINTF()` attribute (f8c45794 #1287) +- build: add `LIBSSH2_NO_DEPRECATED` option (b1414503 #1267 #1266 #1260 #1259) +- build: enable missing OpenSSF-recommended warnings, with fixes (afa6b865 #1257) +- build: enable more compiler warnings and fix them (7ecc309c #1224) +- build: picky warning updates (328a96b3 #1219) +- build: revert: respect autotools `DLL_EXPORT` in `libssh2.h` (481be044 #1141 revert: fb1195cf) +- build: stop requiring libssl from openssl (c84745e3 #1128) +- build: tidy-up `libssh2.pc.in` variable names (5720dd9f #1125) +- build: add/fix `Requires.private` packages in `libssh2.pc` (ef538069 #1123) +- checksrc: sync with curl (8cd473c9 #1272) +- checksrc: fix spelling in comment (a95d401f) +- checksrc: modernise perl file open (3d309f9b) +- checksrc: switch to dot file (d67a91aa #1052) +- ci: add FreeBSD 14 job, fix issues (46333adf #1277) +- ci: add OmniOS job, fix issues (5e0ec991) +- ci: show compiler in cross/cygwin job names (c9124088) +- ci: add OpenBSD (v7.4) job + fix build error in example (0c9a8e35 #1250) +- ci: add NetBSD (v9.3) job (65c7a7a5) +- ci: update and speed up FreeBSD job (eee4e805) +- ci: use absolute path in `CMAKE_INSTALL_PREFIX` (74948816 #1247) +- ci: boost mbedTLS build speed (236e79a1 #1245) +- ci: add BoringSSL job (cmake, gcc, amd64) (c9dd3566 #1233) +- ci: fixup FreeBSD version, bump mbedTLS (fea6664e #1217) +- ci: add FreeBSD 13.2 job (a7d2a573 #1215) +- ci: mbedTLS 3.5.0 (5e190442 #1202) +- ci: update actions, use shallow clones with appveyor (d468a33f #1199) +- ci: replace `mv` + `chmod` with `install` in `Dockerfile` (5754fed6 #1175) +- ci: set file mode early in `appveyor_docker.yml` (633db55f) +- ci: add spellcheck (codespell) (a79218d3) +- ci: add MSYS builds (autotools and cmake) (d43b8d9b #1162) +- ci: add Cygwin builds (autotools and cmake) (f1e96e73 #1161) +- ci: add mingw-w64 UWP build (1215aa5f #1155 #1147) +- ci: add missing timeout to 'autotools distcheck' step (6265ffdb) +- ci: add non-static autotools i386 build, ignore GHA updates on AppVeyor (c6e137f7 #1074 #1072) +- ci: prefer `=` operator in shell snippets (e5c03043 #1073) +- ci: drop redundant/unused vars, sync var names (ab8e95bc #1059) +- ci: add i386 Linux build (with mbedTLS) (abdf40c7 #1057 #1053) +- ci/appveyor: delete UWP job broken since Visual Studio upgrade (d0a7f1da #1275) +- ci/appveyor: YAML/PowerShell formatting, shorten variable name (06fd721f #1200) +- ci/appveyor: move to pure PowerShell (8a081fd9 #1197) +- ci/GHA: restore curly braces in `if` (36748270 #1145) +- ci/GHA: simplify `if` strings (cab3db58 #1140) +- cmake: rename picky warnings script (64d6789f #1225) +- cmake: fix multiple include of libssh2 package (932d6a32 #1216) +- cmake: show crypto backend in feature summary (20387285 #1211) +- cmake: simplify showing CMake version (fc00bdd7 #1203) +- cmake: cleanup mbedTLS version detection more (4c241d5c #1196 #1192) +- cmake: delete duplicate `include()` (30eef0a6) +- cmake: improve/fix mbedTLS detection (41594675 #1192 #1191) +- cmake: tidy-up `foreach()` syntax (4a64ca14 #1180) +- cmake: verify `libssh2_VERSION` in integration tests (a20572e9) +- cmake: show cmake versions in ci (87f5769b) +- cmake: quote more strings (e9c7d3af #1173) +- cmake: add `ExternalProject` integration test (aeaefaf6 #1171) +- cmake: add integration tests (8715c3d5 #1170) +- cmake: (re-)add aliases for `add_subdirectory()` builds (4ff64ae3 #1169) +- cmake: style tidy-up (3fa5282d #1166) +- cmake: add `LIB_NAME` variable (5453fc80 #1159) +- cmake: tidy-up concatenation in `CMAKE_MODULE_PATH` (ae7d5108 #1157) +- cmake: replace `libssh2` literals with `PROJECT_NAME` variable (72fd2595 #1152) +- cmake: fix `STREQUAL` check in error branch (42d3bf13 #1151) +- cmake: cache more config values on Windows (11a03690 #1142) +- cmake: streamline invocation (f58f77b5 #1138) +- cmake: merge `set_target_properties()` calls (a9091007 #1132) +- cmake: (re-)add zlib to `Libs.private` in `libssh2.pc` (64643018 #1131) +- cmake: use `wolfssl/options.h` for detection, like autotools (c5ec6c49 #1130) +- cmake: add openssl libs to `Libs.private` in `libssh2.pc` (5cfa59d3 #1127) +- cmake: bump minimum CMake version to v3.7.0 (9cd18f45 #1126) +- cmake: CMAKE_SOURCE_DIR -> PROJECT_SOURCE_DIR (0f396aa9 #1121) +- cmake: tidy-ups (2fc36790 #1122) +- cmake: re-add `Libssh2:libssh2` for compatibility + lowercase namespace (2da13c13 #1104 #1103) +- configure.ac: remove AB_INIT (f4f52ccc) +- copyright: remove years from copyright headers (187d89bb #1082) +- docs: replace SHA1 with SHA256 in CMake example (766bde9f) +- drop `www.` from `www.libssh2.org` (6e3e8839 #1172) +- example: use `libssh2_socket_t` in X11 example (3f60ccb7) +- example: replace remaining libssh2_scp_recv with libssh2_scp_recv2 in output messages (8d69e63d #1258 follow: 6c84a426) +- example: fix regression in `ssh2_exec.c` (279a2e57 #1106 #1105 regr: b13936bd) +- example, tests: call `WSACleanup()` for each `WSAStartup()` (94b6bad3 #1283) +- example, tests: fix/silence `-Wformat-truncation=2` gcc warnings (744e059f) +- hostkey: do not advertise ssh-rsa when SHA1 is disabled (82d1b8ff #1093 #1092) +- libssh2.h: add deprecated function warnings (9839ebe5 #1289 #1260) +- libssh2.h: add portable `LIBSSH2_SOCKET_CLOSE()` macro (28dbf016 #1278) +- libssh2.h: use `_WIN32` for Windows detection instead of rolling our own (631e7734 #1238) +- libssh2.pc: re-add & extend support for static-only libssh2 builds (624abe27 #1119 #1114) +- libssh2.pc: don't put `@LIBS@` in pc file (1209c16d) +- Makefile.am: fix `cp` to preserve attributes and timestamp (f64e6318) +- Makefile.mk: delete Windows-focused raw GNU Make build (43485579 #1204) +- man: fix double spaces and dash escaping (a3ffc422 #1210) +- man: add description to `libssh2_session_get_blocking.3` (67e39091 #1185) +- mbedtls: improve disabling `-Wredundant-decls` (ecec68a2 #1226 #1224) +- mbedtls: include `version.h` for `MBEDTLS_VERSION_NUMBER` (9d7bc253 #1095 #1094) +- mbedtls: use more `size_t` to sync up with `crypto.h` (1153ebde #1054 #1053) +- md5: allow disabling old-style encrypted private keys at build-time (eb9f9de2 #1181) +- mingw: fix printf mask for 64-bit integers (36c1e1d1 #1091 #1090) +- misc: flatten `_libssh2_explicit_zero` if tree (74e74288 #1149) +- NMakefile: delete (c515eed3 #1134 #1129) +- openssl: use OpenSSL 3 HMAC API, add `no-deprecated` CI job (363dcbf4 #1243 #1235 #1207) +- openssl: make a function static, add `#ifdef` comments (efee9133 #1246 follow: 03092292) +- openssl: fix DSA code to use OpenSSL 3 API (82581941 #1244 #1207) +- openssl: fix `EC_KEY` reference with OpenSSL 3 `no-deprecated` build (487152f4 #1236 #1235 #1207) +- openssl: use non-deprecated APIs with OpenSSL 3.x (b0ab005f #1207) +- openssl: silence `-Wunused-value` warnings (bf285500 #1205) +- openssl: use automatic initialization with LibreSSL 2.7.0+ (d79047c9 #1146) +- openssl: add missing check for `LIBRESSL_VERSION_NUMBER` before use (4a42f42e #1117 #1115) +- packet: properly bounds check packet_authagent_open() (88a960a8 #1179) +- pem: fix private keys encrypted with AES-GCM methods (e87bdefa #1133) +- reuse: fix duplicate copyright warning (b9a4ed83) +- reuse: comply with 3.1 spec and 2.0.0 checker (fe6239a1 #1102 #1101 #1098) +- reuse: provide SPDX identifiers (f6aa31f4 #1084) +- scp: fix missing cast for targets without large file support (c317e06f #1060 #1057 #1002 regr: 5db836b2) +- session: add `libssh2_session_callback_set2()` (c0f69548 #1285) +- session: handle EINTR from send/recv/poll/select to try again as the error is not fatal (798ed4a7 #1058) +- src: add 'strict KEX' to fix CVE-2023-48795 "Terrapin Attack" (d34d9258 #1291 #1290) +- src: disable `-Wsign-conversion` warnings, add option to re-enable (6e451669 #1284 #1257) +- src: fix gcc 13 `-Wconversion` warning on Darwin (8cca7b77 #1209 follow: 08354e0a) +- src: drop a redundant `#include` (1f0174d0 #1153) +- src: improve MSVC C4701 warning fix (8b924999 #1086 #1083) +- src: bump `hash_len` to `size_t` in `LIBSSH2_HOSTKEY_METHOD` (8b917d76 #1076) +- src: bump DSA and ECDSA sign `hash_len` to `size_t` (7b8e0225 #1055) +- stop using leading underscores in macro names (c6589b88 #1248) +- tests: sync port number type with the rest of codebase (eb996af8) +- tests: fall back to `$LOGNAME` for username (5326a5ce #1241 #1240) +- tests: show cmake version used in integration tests (2cd2f40e #1201) +- tests: formatting and tidy-ups (e61987a3) +- tests: replace FIXME with comments (1a99a86a) +- tests: add aes256-gcm encrypted key test (802336cf #1135 #1133) +- tests: trap signals in scripts (b2916b28 #1098) +- tests: cast to avoid `-Wchar-subscripts` with Cygwin (43df6a46 #1081 #1080) +- test_read: make it run without Docker (57e9d18e #1139) +- test_sshd.test: show sshd and test connect logs on harness failure (299c2040 #1097) +- test_sshd.test: set a safe PID directory (e8cabdcf #1089) +- test_sshd.test: minor cleanups (d29eea1d) +- tidy-up: bump casts from int to long for large C99 types in printfs (2e5a8719 #1264 #1257) +- tidy-up: `unsigned` -> `unsigned int` (b136c379) +- tidy-up: around `stdint.h` (bfa00f1b #1212) +- tidy-up: fix typo in `readme.vms` (a9a79e7a) +- tidy-up: delete duplicate word from comment (76307435) +- tidy-up: avoid exclamations, prefer single quotes, in outputs (003fb454 #1079) +- TODO: disable or drop weak algos (0b4bdc85 #1261) +- transport: fix incorrect byte offset in debug message (2388a3aa #1096) +- userauth: add a new structure to separate memory read and file read (63b4c20e) +- userauth: check whether `*key_method` is a NULL pointer instead of `key_method` (bec57c40) +- wincng: prefer `ULONG`/`DWORD` over `unsigned long` (186c1d63 #1165) +- wincng: tidy-ups (7bb669b5 #1164) +- windows: use built-in `_WIN32` macro to detect Windows (6fbc9505 #1195) 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, Ren Mingshuai, Michael Buckley, Daniel Stenberg, Aaron Stone, + Brian Inglis, concussious on Github, Dan Fandrich, Haowei Hsu, + Harmen Stoppels, Harry Mallon, Jack L, Jakob Egger, João M. S. Silva, + Joel Depooter, Kai Pastor, Kenneth Davidson, mike-jumper, naddy, + Nicolas Mora, Nursan Valeyev, PewPewPew, Radek Brich, rahmanih on Github, + Steve McIntyre, Will Cosgrove, Xi Ruoyao diff --git a/acinclude.m4 b/acinclude.m4 index 2066f0ec9b..e4c25c306b 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,3 +1,134 @@ +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause +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 + 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]) @@ -7,146 +138,490 @@ dnl sets the $ICC variable to "yes" or "no" dnl ********************************************************************** AC_DEFUN([CURL_DETECT_ICC], [ - ICC="no" - AC_MSG_CHECKING([for icc in use]) - if test "$GCC" = "yes"; then - dnl check if this is icc acting as gcc in disguise - AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER], - dnl action if the text is found, this it has not been replaced by the - dnl cpp - ICC="no", - dnl the text was not found, it was replaced by the cpp - ICC="yes" - AC_MSG_RESULT([yes]) - [$1] - ) - fi - if test "$ICC" = "no"; then - # this is not ICC - AC_MSG_RESULT([no]) - fi + ICC="no" + AC_MSG_CHECKING([for icc in use]) + if test "$GCC" = "yes"; then + dnl check if this is icc acting as gcc in disguise + AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER], + dnl action if the text is found, this it has not been replaced by the + dnl cpp + ICC="no", + dnl the text was not found, it was replaced by the cpp + ICC="yes" + AC_MSG_RESULT([yes]) + [$1] + ) + fi + if test "$ICC" = "no"; then + # this is not ICC + AC_MSG_RESULT([no]) + fi ]) 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$ICC" = "z"; then - CURL_DETECT_ICC + 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 - - 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` - AC_MSG_RESULT($gccver) - - if test "$ICC" = "yes"; then - dnl this is icc, not gcc. - - dnl ICC warnings we ignore: - dnl * 269 warns on our "%Od" printf formatters for curl_off_t output: - dnl "invalid format string conversion" - dnl * 279 warns on static conditions in while expressions - dnl * 981 warns on "operands are evaluated in unspecified order" - dnl * 1418 "external definition with no prior declaration" - dnl * 1419 warns on "external declaration in primary source file" - dnl which we know and do on purpose. - - WARN="-wd279,269,981,1418,1419" - - if test "$gccnum" -gt "600"; then - dnl icc 6.0 and older doesn't have the -Wall flag - WARN="-Wall $WARN" - fi - else dnl $ICC = yes - 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 - dnl gcc 2.7 or later - WARN="$WARN -Wmissing-declarations" - fi - - if test "$gccnum" -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" - fi - - if test "$gccnum" -ge "296"; then - dnl gcc 2.96 or later - WARN="$WARN -Wfloat-equal" - fi - - if test "$gccnum" -gt "296"; then - dnl this option does not exist in 2.96 - WARN="$WARN -Wno-format-nonliteral" - fi - - dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on - dnl on i686-Linux as it gives us heaps with false positives. - 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 - dnl gcc 3.3 and later - WARN="$WARN -Wendif-labels -Wstrict-prototypes" - fi - - if test "$gccnum" -ge "304"; then - # try these on gcc 3.4 - WARN="$WARN -Wdeclaration-after-statement" - fi - - for flag in $CPPFLAGS; do - case "$flag" in - -I*) - dnl Include path, provide a -isystem option for the same dir - dnl to prevent warnings in those dirs. The -isystem was not very - dnl reliable on earlier gcc versions. - add=`echo $flag | sed 's/^-I/-isystem /g'` - WARN="$WARN $add" + if test "$CLANG" = "yes"; then + + # indentation to match curl's m4/curl-compilers.m4 + + dnl figure out clang version! + AC_MSG_CHECKING([compiler version]) + fullclangver=`$CC -v 2>&1 | grep version` + if echo $fullclangver | grep 'Apple' >/dev/null; then + appleclang=1 + else + appleclang=0 + fi + clangver=`echo $fullclangver | grep "based on LLVM " | "$SED" 's/.*(based on LLVM \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*)/\1/'` + if test -z "$clangver"; then + clangver=`echo $fullclangver | "$SED" 's/.*version \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*/\1/'` + oldapple=0 + else + oldapple=1 + fi + clangvhi=`echo $clangver | cut -d . -f1` + clangvlo=`echo $clangver | cut -d . -f2` + compiler_num=`(expr $clangvhi "*" 100 + $clangvlo) 2>/dev/null` + if test "$appleclang" = '1' && test "$oldapple" = '0'; then + dnl Starting with Xcode 7 / clang 3.7, Apple clang won't tell its upstream version + if test "$compiler_num" -ge '1300'; then compiler_num='1200' + elif test "$compiler_num" -ge '1205'; then compiler_num='1101' + elif test "$compiler_num" -ge '1204'; then compiler_num='1000' + elif test "$compiler_num" -ge '1107'; then compiler_num='900' + elif test "$compiler_num" -ge '1103'; then compiler_num='800' + elif test "$compiler_num" -ge '1003'; then compiler_num='700' + elif test "$compiler_num" -ge '1001'; then compiler_num='600' + elif test "$compiler_num" -ge '904'; then compiler_num='500' + elif test "$compiler_num" -ge '902'; then compiler_num='400' + elif test "$compiler_num" -ge '803'; then compiler_num='309' + elif test "$compiler_num" -ge '703'; then compiler_num='308' + else compiler_num='307' + fi + fi + AC_MSG_RESULT([clang '$compiler_num' (raw: '$fullclangver' / '$clangver')]) + + tmp_CFLAGS="-pedantic" + if test "$want_werror" = "yes"; then + LIBSSH2_CFLAG_EXTRAS="$LIBSSH2_CFLAG_EXTRAS -pedantic-errors" + fi + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [all extra]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [pointer-arith write-strings]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [shadow]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [inline nested-externs]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-declarations]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-prototypes]) + tmp_CFLAGS="$tmp_CFLAGS -Wno-long-long" + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [float-equal]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sign-compare]) + tmp_CFLAGS="$tmp_CFLAGS -Wno-multichar" + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [undef]) + tmp_CFLAGS="$tmp_CFLAGS -Wno-format-nonliteral" + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [endif-labels strict-prototypes]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [declaration-after-statement]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [cast-align]) + tmp_CFLAGS="$tmp_CFLAGS -Wno-system-headers" + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [shorten-64-to-32]) + # + dnl Only clang 1.1 or later + if test "$compiler_num" -ge "101"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused]) + fi + # + dnl Only clang 2.7 or later + if test "$compiler_num" -ge "207"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [address]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [attributes]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [bad-function-cast]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [conversion]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [div-by-zero format-security]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [empty-body]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-field-initializers]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-noreturn]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [old-style-definition]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [redundant-decls]) + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [switch-enum]) # Not used because this basically disallows default case + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [type-limits]) + if test "x$have_windows_h" != "xyes"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused-macros]) # Seen to clash with libtool-generated stub code + fi + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unreachable-code unused-parameter]) + fi + # + dnl Only clang 2.8 or later + if test "$compiler_num" -ge "208"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [ignored-qualifiers]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [vla]) + fi + # + dnl Only clang 2.9 or later + if test "$compiler_num" -ge "209"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sign-conversion]) + tmp_CFLAGS="$tmp_CFLAGS -Wno-error=sign-conversion" # FIXME + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [shift-sign-overflow]) + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [padded]) # Not used because we cannot change public structs + fi + # + dnl Only clang 3.0 or later + if test "$compiler_num" -ge "300"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [language-extension-token]) + tmp_CFLAGS="$tmp_CFLAGS -Wformat=2" + fi + # + dnl Only clang 3.2 or later + if test "$compiler_num" -ge "302"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [enum-conversion]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sometimes-uninitialized]) + case $host_os in + cygwin* | mingw*) + dnl skip missing-variable-declarations warnings for cygwin and + dnl mingw because the libtool wrapper executable causes them ;; - esac - done - - fi dnl $ICC = no - - CFLAGS="$CFLAGS $WARN" - - AC_MSG_NOTICE([Added this set of compiler options: $WARN]) + *) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-variable-declarations]) + ;; + esac + fi + # + dnl Only clang 3.4 or later + if test "$compiler_num" -ge "304"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [header-guard]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused-const-variable]) + fi + # + dnl Only clang 3.5 or later + if test "$compiler_num" -ge "305"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [pragmas]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unreachable-code-break]) + fi + # + dnl Only clang 3.6 or later + if test "$compiler_num" -ge "306"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [double-promotion]) + fi + # + dnl Only clang 3.9 or later + if test "$compiler_num" -ge "309"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [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 + tmp_CFLAGS="$tmp_CFLAGS -Wno-varargs" + fi + fi + dnl clang 7 or later + if test "$compiler_num" -ge "700"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [assign-enum]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [extra-semi-stmt]) + fi + dnl clang 10 or later + if test "$compiler_num" -ge "1000"; then + tmp_CFLAGS="$tmp_CFLAGS -Wimplicit-fallthrough" # we have silencing markup for clang 10.0 and above only + fi + + CFLAGS="$CFLAGS $tmp_CFLAGS" + + AC_MSG_NOTICE([Added this set of compiler options: $tmp_CFLAGS]) + + elif test "$GCC" = "yes"; then + + # indentation to match curl's m4/curl-compilers.m4 + + dnl figure out gcc version! + AC_MSG_CHECKING([compiler version]) + # strip '-suffix' parts, e.g. Ubuntu Windows cross-gcc returns '10-win32' + gccver=`$CC -dumpversion | sed -E 's/-.+$//'` + gccvhi=`echo $gccver | cut -d . -f1` + if echo $gccver | grep -F "." >/dev/null; then + gccvlo=`echo $gccver | cut -d . -f2` + else + gccvlo="0" + fi + compiler_num=`(expr $gccvhi "*" 100 + $gccvlo) 2>/dev/null` + AC_MSG_RESULT([gcc '$compiler_num' (raw: '$gccver')]) + + if test "$ICC" = "yes"; then + dnl this is icc, not gcc. + + dnl ICC warnings we ignore: + dnl * 269 warns on our "%Od" printf formatters for curl_off_t output: + dnl "invalid format string conversion" + dnl * 279 warns on static conditions in while expressions + dnl * 981 warns on "operands are evaluated in unspecified order" + dnl * 1418 "external definition with no prior declaration" + dnl * 1419 warns on "external declaration in primary source file" + dnl which we know and do on purpose. + + tmp_CFLAGS="-wd279,269,981,1418,1419" + + if test "$compiler_num" -gt "600"; then + dnl icc 6.0 and older doesn't have the -Wall flag + tmp_CFLAGS="-Wall $tmp_CFLAGS" + fi + else dnl $ICC = yes + dnl this is a set of options we believe *ALL* gcc versions support: + tmp_CFLAGS="-pedantic" + if test "$want_werror" = "yes"; then + LIBSSH2_CFLAG_EXTRAS="$LIBSSH2_CFLAG_EXTRAS -pedantic-errors" + fi + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [all]) + tmp_CFLAGS="$tmp_CFLAGS -W" + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [pointer-arith write-strings]) + # + dnl Only gcc 2.7 or later + if test "$compiler_num" -ge "207"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [inline nested-externs]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-declarations]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-prototypes]) + fi + # + dnl Only gcc 2.95 or later + if test "$compiler_num" -ge "295"; then + tmp_CFLAGS="$tmp_CFLAGS -Wno-long-long" + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [bad-function-cast]) + fi + # + dnl Only gcc 2.96 or later + if test "$compiler_num" -ge "296"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [float-equal]) + tmp_CFLAGS="$tmp_CFLAGS -Wno-multichar" + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sign-compare]) + dnl -Wundef used only if gcc is 2.96 or later since we get + dnl lots of "`_POSIX_C_SOURCE' is not defined" in system + dnl headers with gcc 2.95.4 on FreeBSD 4.9 + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [undef]) + fi + # + dnl Only gcc 2.97 or later + if test "$compiler_num" -ge "297"; then + tmp_CFLAGS="$tmp_CFLAGS -Wno-format-nonliteral" + fi + # + dnl Only gcc 3.0 or later + if test "$compiler_num" -ge "300"; then + tmp_CFLAGS="$tmp_CFLAGS -Wno-system-headers" + dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on + dnl on i686-Linux as it gives us heaps with false positives. + 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. + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused shadow]) + fi + # + dnl Only gcc 3.3 or later + if test "$compiler_num" -ge "303"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [endif-labels strict-prototypes]) + fi + # + dnl Only gcc 3.4 or later + if test "$compiler_num" -ge "304"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [declaration-after-statement]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [old-style-definition]) + fi + # + dnl Only gcc 4.0 or later + if test "$compiler_num" -ge "400"; then + tmp_CFLAGS="$tmp_CFLAGS -Wstrict-aliasing=3" + fi + # + dnl Only gcc 4.1 or later (possibly earlier) + if test "$compiler_num" -ge "401"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [attributes]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [div-by-zero format-security]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-field-initializers]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-noreturn]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unreachable-code unused-parameter]) + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [padded]) # Not used because we cannot change public structs + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [pragmas]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [redundant-decls]) + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [switch-enum]) # Not used because this basically disallows default case + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused-macros]) + fi + # + dnl Only gcc 4.2 or later + if test "$compiler_num" -ge "402"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [cast-align]) + fi + # + dnl Only gcc 4.3 or later + if test "$compiler_num" -ge "403"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [address]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [type-limits old-style-declaration]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-parameter-type empty-body]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [clobbered ignored-qualifiers]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [conversion trampolines]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sign-conversion]) + tmp_CFLAGS="$tmp_CFLAGS -Wno-error=sign-conversion" # FIXME + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [vla]) + dnl required for -Warray-bounds, included in -Wall + tmp_CFLAGS="$tmp_CFLAGS -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*) + tmp_CFLAGS="$tmp_CFLAGS -Wno-pedantic-ms-format" + ;; + esac + fi + # + dnl Only gcc 4.6 or later + if test "$compiler_num" -ge "406"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [double-promotion]) + fi + # + dnl only gcc 4.8 or later + if test "$compiler_num" -ge "408"; then + tmp_CFLAGS="$tmp_CFLAGS -Wformat=2" + fi + # + dnl Only gcc 5 or later + if test "$compiler_num" -ge "500"; then + tmp_CFLAGS="$tmp_CFLAGS -Warray-bounds=2" + fi + # + dnl Only gcc 6 or later + if test "$compiler_num" -ge "600"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [shift-negative-value]) + tmp_CFLAGS="$tmp_CFLAGS -Wshift-overflow=2" + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [null-dereference]) + tmp_CFLAGS="$tmp_CFLAGS -fdelete-null-pointer-checks" + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [duplicated-cond]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused-const-variable]) + fi + # + dnl Only gcc 7 or later + if test "$compiler_num" -ge "700"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [duplicated-branches]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [restrict]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [alloc-zero]) + tmp_CFLAGS="$tmp_CFLAGS -Wformat-overflow=2" + tmp_CFLAGS="$tmp_CFLAGS -Wformat-truncation=2" + tmp_CFLAGS="$tmp_CFLAGS -Wimplicit-fallthrough" + fi + # + dnl Only gcc 10 or later + if test "$compiler_num" -ge "1000"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [arith-conversion]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [enum-conversion]) + fi + + for flag in $CPPFLAGS; do + case "$flag" in + -I*) + dnl Include path, provide a -isystem option for the same dir + dnl to prevent warnings in those dirs. The -isystem was not very + dnl reliable on earlier gcc versions. + add=`echo $flag | sed 's/^-I/-isystem /g'` + tmp_CFLAGS="$tmp_CFLAGS $add" + ;; + esac + done + + fi dnl $ICC = no + + CFLAGS="$CFLAGS $tmp_CFLAGS" + + AC_MSG_NOTICE([Added this set of compiler options: $tmp_CFLAGS]) + + else dnl $GCC = yes + + AC_MSG_NOTICE([Added no extra compiler options]) + + fi dnl $GCC = yes + + dnl strip off optimizer flags + NEWFLAGS="" + for flag in $CFLAGS; do + case "$flag" in + -O*) + dnl echo "cut off $flag" + ;; + *) + NEWFLAGS="$NEWFLAGS $flag" + ;; + esac + done + CFLAGS=$NEWFLAGS - else dnl $GCC = yes +]) dnl end of AC_DEFUN() - AC_MSG_NOTICE([Added no extra compiler options]) +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] +]) - fi dnl $GCC = yes +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 strip off optimizer flags - NEWFLAGS="" - for flag in $CFLAGS; do - case "$flag" in - -O*) - dnl echo "cut off $flag" - ;; - *) - NEWFLAGS="$NEWFLAGS $flag" - ;; - esac +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 - CFLAGS=$NEWFLAGS - -]) dnl end of AC_DEFUN() + done +]) dnl CURL_CHECK_NONBLOCKING_SOCKET dnl ------------------------------------------------- @@ -163,12 +638,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 +662,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 +685,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 @@ -418,22 +860,29 @@ m4_case([$1], [openssl], [ LIBSSH2_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include ], [ AC_DEFINE(LIBSSH2_OPENSSL, 1, [Use $1]) - LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libssl libcrypto" - - # 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" + LIBSSH2_PC_REQUIRES_PRIVATE="$LIBSSH2_PC_REQUIRES_PRIVATE${LIBSSH2_PC_REQUIRES_PRIVATE:+,}libcrypto" + found_crypto="$1" + found_crypto_str="OpenSSL" + ]) +], +[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]) + LIBSSH2_PC_REQUIRES_PRIVATE="$LIBSSH2_PC_REQUIRES_PRIVATE${LIBSSH2_PC_REQUIRES_PRIVATE:+,}wolfssl" found_crypto="$1" - found_crypto_str="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})" ]) ], [libgcrypt], [ LIBSSH2_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include ], [ AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use $1]) + LIBSSH2_PC_REQUIRES_PRIVATE="$LIBSSH2_PC_REQUIRES_PRIVATE${LIBSSH2_PC_REQUIRES_PRIVATE:+,}libgcrypt" found_crypto="$1" ]) ], @@ -443,29 +892,25 @@ 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 ]) - - LIBSSH2_LIB_HAVE_LINKFLAGS([crypt32], [], [ - #include - #include - ]) - LIBSSH2_LIB_HAVE_LINKFLAGS([bcrypt], [], [ - #include - #include - ], [ - 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" - ]) + if test "x$have_windows_h" = "xyes"; then + # Look for Windows Cryptography API: Next Generation + + LIBS="$LIBS -lcrypt32" + + # Check necessary for old-MinGW + LIBSSH2_LIB_HAVE_LINKFLAGS([bcrypt], [], [ + #include + #include + ], [ + AC_DEFINE(LIBSSH2_WINCNG, 1, [Use $1]) + found_crypto="$1" + found_crypto_str="Windows Cryptography API: Next Generation" + ]) + fi ], ) test "$found_crypto" = "none" && @@ -486,8 +931,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) @@ -506,7 +951,6 @@ AC_HELP_STRING([--disable-werror],[Disable compiler warnings as errors]), AC_MSG_RESULT([$want_werror]) if test X"$want_werror" = Xyes; then - CFLAGS="$CFLAGS -Werror" + LIBSSH2_CFLAG_EXTRAS="$LIBSSH2_CFLAG_EXTRAS -Werror" fi ]) - diff --git a/appveyor.yml b/appveyor.yml index c2731ca2bd..2c91054f31 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) Ruslan Baratov +# Copyright (C) Alexander Lamaison +# Copyright (C) Marc Hoersken +# Copyright (C) Viktor Szakats # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -23,100 +24,204 @@ # 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. +# +# SPDX-License-Identifier: BSD-3-Clause -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 - CRYPTO_BACKEND: "OpenSSL" - - - GENERATOR: "Visual Studio 14 2015" - BUILD_SHARED_LIBS: OFF - CRYPTO_BACKEND: "OpenSSL" - - - GENERATOR: "Visual Studio 12 2013" - BUILD_SHARED_LIBS: ON - CRYPTO_BACKEND: "OpenSSL" - - - GENERATOR: "Visual Studio 12 2013" - BUILD_SHARED_LIBS: OFF - CRYPTO_BACKEND: "OpenSSL" - - - GENERATOR: "Visual Studio 14 2015" - BUILD_SHARED_LIBS: ON - CRYPTO_BACKEND: "WinCNG" - - - GENERATOR: "Visual Studio 14 2015" - BUILD_SHARED_LIBS: OFF - CRYPTO_BACKEND: "WinCNG" - - - GENERATOR: "Visual Studio 12 2013" - BUILD_SHARED_LIBS: ON - CRYPTO_BACKEND: "WinCNG" - - - GENERATOR: "Visual Studio 12 2013" - BUILD_SHARED_LIBS: OFF - CRYPTO_BACKEND: "WinCNG" - -platform: - - x86 - - x64 - -configuration: -# - Debug - - Release + - 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' + + - 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' + + - 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' + + - 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' + + - 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' + + - 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' + + - job_name: 'VS2022, WinCNG, ARM64, Build-only' + APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2022' + GENERATOR: 'Visual Studio 17 2022' + PLATFORM: 'ARM64' + CRYPTO_BACKEND: 'WinCNG' + + - job_name: 'VS2015, WinCNG, x86, Server 2016' + APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2017' + GENERATOR: 'Visual Studio 14 2015' + PLATFORM: 'x86' + CRYPTO_BACKEND: 'WinCNG' + + - 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 - ps: | $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 + [System.Environment]::SetEnvironmentVariable('OPENSSH_SERVER_PORT', $env:OPENSSH_SERVER_PORT) + .\ci\appveyor\docker-bridge.ps1 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 + $options = @('-DENABLE_WERROR=ON') + + if($env:GENERATOR -eq 'Visual Studio 17 2022') { + if($env:PLATFORM -eq 'x86') { + $options += '-A Win32' + } + else { + $options += "-A $env:PLATFORM" + } + } + elseif($env:PLATFORM -eq 'x64') { + $env:GENERATOR += ' Win64' } - 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!" + $options += "-G$env:GENERATOR" + + $options += "-DCRYPTO_BACKEND=$env:CRYPTO_BACKEND" + 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') { + $options += '-DOPENSSL_ROOT_DIR=C:/OpenSSL-v30-Win64' + } + } + else { + if($env:PLATFORM -eq 'x64') { + $options += '-DOPENSSL_ROOT_DIR=C:/OpenSSL-v111-Win64' + } + elseif($env:PLATFORM -eq 'x86') { + $options += '-DOPENSSL_ROOT_DIR=C:/OpenSSL-v111-Win32' + } + } } + if($env:ENABLE_DEBUG_LOGGING -eq 'ON') { + $options += '-DENABLE_DEBUG_LOGGING=ON' + } + if($env:UNITY -eq 'ON') { + $options += '-DCMAKE_UNITY_BUILD=ON' + } + if($env:BUILD_STATIC_LIBS -eq 'OFF') { + $options += '-DBUILD_STATIC_LIBS=OFF' + } + if($env:BUILD_SHARED_LIBS -eq 'OFF') { + $options += '-DBUILD_SHARED_LIBS=OFF' + } + $options += '-DCMAKE_VS_GLOBALS=TrackFileAccess=false' + # FIXME: First sshd test sometimes timeouts, subsequent ones almost always fail: + # 'libssh2_session_handshake failed (-43): Failed getting banner' + $options += '-DRUN_SSHD_TESTS=OFF' + + Write-Host 'CMake options:' $options + cmake -B _builds $options + cmake --build _builds --config "$env: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') { + appveyor-retry choco install --yes --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/CMakeOutput.log) { cat _builds/CMakeFiles/CMakeOutput.log } - - ps: if(Test-Path _builds/CMakeFiles/CMakeError.log) { cat _builds/CMakeFiles/CMakeError.log } + - ps: | + if(Test-Path _builds/CMakeFiles/CMakeConfigureLog.yaml) { cat _builds/CMakeFiles/CMakeConfigureLog.yaml } + if(Test-Path _builds/CMakeFiles/CMakeOutput.log) { cat _builds/CMakeFiles/CMakeOutput.log } + if(Test-Path _builds/CMakeFiles/CMakeError.log) { cat _builds/CMakeFiles/CMakeError.log } on_finish: - ps: | - Get-Process -Name "sleep" -ErrorAction SilentlyContinue | Stop-Process + Get-Process -Name 'sleep' -ErrorAction SilentlyContinue | Stop-Process Start-Sleep -Seconds 3 - Get-Process -Name "sshd" -ErrorAction SilentlyContinue | Stop-Process + Get-Process -Name 'sshd' -ErrorAction SilentlyContinue | Stop-Process + +skip_commits: + files: + - '.github/**/*' + +clone_depth: 10 -# 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..1072328b55 100755 --- a/buildconf +++ b/buildconf @@ -1,8 +1,10 @@ #!/bin/sh +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause 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..d7a07b5faa --- a/ci/appveyor/docker-bridge.ps1 +++ b/ci/appveyor/docker-bridge.ps1 @@ -1,22 +1,29 @@ -# 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 +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause + +# 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..5e0a69bdea --- /dev/null +++ b/ci/appveyor/docker-bridge.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause + +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..34664585c5 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,49 +49,65 @@ my %warnings_extended = ( 'COPYRIGHTYEAR' => 'copyright year incorrect', + 'STRERROR', => 'strerror() detected', + 'STDERR', => 'stderr 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', + 'BANNEDPREPROC' => 'a banned symbol was used on a preprocessor line', + '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; - my @all=; +sub readskiplist { + open(my $W, '<', "$dir/checksrc.skip") or return; + my @all=<$W>; for(@all) { $windows_os ? $_ =~ s/\r?\n$// : chomp; - $whitelist{$_}=1; + $skiplist{$_}=1; } - close(W); + close($W); } # Reads the .checksrc in $dir for any extended warnings to enable locally. @@ -115,10 +133,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 +158,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 +203,7 @@ sub checkwarn { $file = shift @ARGV; -while(1) { +while(defined $file) { if($file =~ /-D(.*)/) { $dir = $1; @@ -217,17 +244,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,15 +379,19 @@ sub scanfile { my $line = 1; my $prevl=""; - my $l; - open(R, "<$file") || die "failed to open $file"; + my $prevpl=""; + my $l = ""; + my $prep = 0; + my $prevp = 0; + open(my $R, '<', $file) || die "failed to open $file"; my $incomment=0; my @copyright=(); + my %includes; checksrc_clear(); # for file based ignores accept_violations(); - while() { + while(<$R>) { $windows_os ? $_ =~ s/\r?\n$// : chomp; my $l = $_; my $ol = $l; # keep the unmodified line for error reporting @@ -365,7 +404,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 +413,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 +436,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 +488,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 +532,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 function 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"); + } - if($nostr =~ /^((.*)(if) *\()(.*)\)/) { + # 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"); + } + + # 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 +682,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 +719,30 @@ 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"); + } + } + } + if($warnings{"STDERR"}) { + # scan for use of banned stderr. This is not a BANNEDFUNC to + # allow for individual enable/disable of this warning. + if($l =~ /^([^\"-]*\W)(stderr)[^\"_]/x) { + if($1 !~ /^ *\#/) { + # skip preprocessor lines + checkwarn("STDERR", + $line, length($1), $file, $ol, + "use of $2 is banned (use tool_stderr instead)"); + } + } + } # scan for use of snprintf for curl-internals reasons if($l =~ /^(.*\W)(v?snprintf)\s*\(/x) { checkwarn("SNPRINTF", @@ -589,10 +760,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 +770,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 +785,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 +870,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 +890,25 @@ 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: + if($prep) { + # scan for use of banned symbols on a preprocessor line + if($l =~ /^(^|.*\W) + (WIN32) + (\W|$) + /x) { + checkwarn("BANNEDPREPROC", + $line, length($1), $file, $ol, + "use of $2 is banned from preprocessor lines" . + (($2 eq "WIN32") ? ", use _WIN32 instead" : "")); + } } - $line++; - $prevl = $ol; + $prevp = $prep; + $prevl = $ol if(!$prep); + $prevpl = $ol if($prep); } if(!scalar(@copyright)) { @@ -712,17 +932,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(`git status -s -- $file` =~ /^ [MARCU]/) { + # 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) && @@ -740,7 +965,7 @@ sub scanfile { checksrc_endoffile($file); - close(R); + close($R); } diff --git a/ci/checksrc.sh b/ci/checksrc.sh index 3890815b4d..49967463cf 100755 --- a/ci/checksrc.sh +++ b/ci/checksrc.sh @@ -1,8 +1,11 @@ #!/usr/bin/env bash +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause set -e -FILES="src/*.[ch] include/*.h example/*.c tests/*.[ch]" -WHITELIST="-Wsrc/libssh2_config.h" +cd "$(dirname "$0")/.." -perl ./ci/checksrc.pl -i4 -m79 -ASIZEOFNOPAREN -ASNPRINTF -ACOPYRIGHT -AFOPENMODE $WHITELIST $FILES +perl ./ci/checksrc.pl -i4 -m79 \ + -Wsrc/libssh2_config.h \ + src/*.[ch] include/*.h example/*.c tests/*.[ch] 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/ci/spellcheck-words.txt b/ci/spellcheck-words.txt new file mode 100644 index 0000000000..2f39b28074 --- /dev/null +++ b/ci/spellcheck-words.txt @@ -0,0 +1,3 @@ +gord +pase +nam diff --git a/ci/spellcheck.sh b/ci/spellcheck.sh new file mode 100755 index 0000000000..e8352b0cc6 --- /dev/null +++ b/ci/spellcheck.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause + +set -e + +cd "$(dirname "$0")/.." + +# shellcheck disable=SC2046 +codespell --skip='docs/AUTHORS' \ + --ignore-words='ci/spellcheck-words.txt' \ + $(git ls-files) diff --git a/cmake/CheckFunctionExistsMayNeedLibrary.cmake b/cmake/CheckFunctionExistsMayNeedLibrary.cmake index 8ac61abe5e..36bcd072e9 100644 --- a/cmake/CheckFunctionExistsMayNeedLibrary.cmake +++ b/cmake/CheckFunctionExistsMayNeedLibrary.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014 Alexander Lamaison +# Copyright (C) Alexander Lamaison # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided @@ -32,6 +32,8 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. +# +# SPDX-License-Identifier: BSD-3-Clause # - check_function_exists_maybe_need_library( [lib1 ... libn]) @@ -63,19 +65,19 @@ function(check_function_exists_may_need_library function variable) check_function_exists(${function} ${variable}) if(NOT ${variable}) - foreach(lib ${ARGN}) + foreach(lib IN LISTS ARGN) string(TOUPPER ${lib} UP_LIB) # Use new variable to prevent cache from previous step shortcircuiting # 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..bb3229cf38 100644 --- a/cmake/CheckNonblockingSocketSupport.cmake +++ b/cmake/CheckNonblockingSocketSupport.cmake @@ -1,3 +1,5 @@ +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause include(CheckCSourceCompiles) # - check_nonblocking_socket_support() @@ -11,10 +13,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 +47,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/CopyRuntimeDependencies.cmake b/cmake/CopyRuntimeDependencies.cmake index 083f762686..f3a72343e4 100644 --- a/cmake/CopyRuntimeDependencies.cmake +++ b/cmake/CopyRuntimeDependencies.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014 Alexander Lamaison +# Copyright (C) Alexander Lamaison # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided @@ -32,6 +32,8 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. +# +# SPDX-License-Identifier: BSD-3-Clause include(CMakeParseArguments) @@ -50,12 +52,11 @@ function(ADD_TARGET_TO_COPY_DEPENDENCIES) # parallel builds trying to kick off the commands at the same time add_custom_target(${COPY_TARGET}) - foreach(target ${COPY_BEFORE_TARGETS}) + foreach(target IN LISTS COPY_BEFORE_TARGETS) add_dependencies(${target} ${COPY_TARGET}) endforeach() - foreach(dependency ${COPY_DEPENDENCIES}) - + foreach(dependency IN LISTS COPY_DEPENDENCIES) add_custom_command( TARGET ${COPY_TARGET} DEPENDS ${dependency} @@ -66,7 +67,5 @@ function(ADD_TARGET_TO_COPY_DEPENDENCIES) COMMAND ${CMAKE_COMMAND} ARGS -E copy ${dependency} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} VERBATIM) - endforeach() - endfunction() diff --git a/cmake/FindLibgcrypt.cmake b/cmake/FindLibgcrypt.cmake index 44a79873d6..8fbe6fff71 100644 --- a/cmake/FindLibgcrypt.cmake +++ b/cmake/FindLibgcrypt.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2014 Alexander Lamaison +# Copyright (C) Alexander Lamaison # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided @@ -32,6 +32,8 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. +# +# SPDX-License-Identifier: BSD-3-Clause # - Try to find Libgcrypt # This will define all or none of: @@ -50,4 +52,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..18c9739d78 100644 --- a/cmake/FindmbedTLS.cmake +++ b/cmake/FindmbedTLS.cmake @@ -1,64 +1,34 @@ +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause +# # - Try to find mbedTLS -# Once done this will define # -# Read-Only variables -# MBEDTLS_FOUND - system has mbedTLS +# Input variables: # MBEDTLS_INCLUDE_DIR - the mbedTLS include directory -# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory -# MBEDTLS_LIBRARIES - Link these to use mbedTLS -# MBEDTLS_LIBRARY - path to mbedTLS library -# MBEDX509_LIBRARY - path to mbedTLS X.509 library # MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library +# Output variables: +# MBEDTLS_FOUND - system has mbedTLS +# MBEDTLS_LIBRARIES - link these to use mbedTLS -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() - -FIND_LIBRARY(MBEDTLS_LIBRARY NAMES mbedtls libmbedtls libmbedx509) -FIND_LIBRARY(MBEDX509_LIBRARY NAMES mbedx509 libmbedx509) -FIND_LIBRARY(MBEDCRYPTO_LIBRARY NAMES mbedcrypto libmbedcrypto) +find_path(MBEDTLS_INCLUDE_DIR NAMES mbedtls/version.h) +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) + file(READ "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h" _mbedtls_header_1) + file(READ "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h" _mbedtls_header_2) + set(_mbedtls_regex "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"") + string(REGEX MATCH "${_mbedtls_regex}" _mbedtls_match "${_mbedtls_header_1} ${_mbedtls_header_2}") + string(REGEX REPLACE "${_mbedtls_regex}" "\\1" MBEDTLS_VERSION "${_mbedtls_match}") +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}") +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(mbedTLS + REQUIRED_VARS MBEDTLS_INCLUDE_DIR MBEDCRYPTO_LIBRARY + VERSION_VAR MBEDTLS_VERSION) - 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(MBEDTLS_FOUND) + set(MBEDTLS_LIBRARIES "${MBEDCRYPTO_LIBRARY}") + message(STATUS "Found mbedTLS libraries: ${MBEDTLS_LIBRARIES}") +endif() -MARK_AS_ADVANCED( - MBEDTLS_INCLUDE_DIR - MBEDTLS_LIBRARY_DIR - MBEDTLS_LIBRARIES - MBEDTLS_LIBRARY - MBEDX509_LIBRARY - MBEDCRYPTO_LIBRARY -) +mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDCRYPTO_LIBRARY MBEDTLS_LIBRARIES) diff --git a/cmake/Findwolfssl.cmake b/cmake/Findwolfssl.cmake new file mode 100644 index 0000000000..7418811c6d --- /dev/null +++ b/cmake/Findwolfssl.cmake @@ -0,0 +1,44 @@ +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause +# +# - 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/options.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/PickyWarnings.cmake b/cmake/PickyWarnings.cmake new file mode 100644 index 0000000000..94feee87dc --- /dev/null +++ b/cmake/PickyWarnings.cmake @@ -0,0 +1,247 @@ +# Copyright (C) Viktor Szakats +# SPDX-License-Identifier: BSD-3-Clause + +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() +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 + + 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 + ) + + if(ENABLE_WERROR) + list(APPEND WPICKY_ENABLE + -pedantic-errors + ) + endif() + + # ---------------------------------- + # 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 2.7 gcc 2.95 + -Wconversion # clang 2.7 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 + -Waddress # clang 2.7 gcc 4.3 + -Wattributes # clang 2.7 gcc 4.1 + -Wcast-align # clang 1.0 gcc 4.2 + -Wdeclaration-after-statement # clang 1.0 gcc 3.4 + -Wdiv-by-zero # clang 2.7 gcc 4.1 + -Wempty-body # clang 2.7 gcc 4.3 + -Wendif-labels # clang 1.0 gcc 3.3 + -Wfloat-equal # clang 1.0 gcc 2.96 (3.0) + -Wformat-security # clang 2.7 gcc 4.1 + -Wignored-qualifiers # clang 2.8 gcc 4.3 + -Wmissing-field-initializers # clang 2.7 gcc 4.1 + -Wmissing-noreturn # clang 2.7 gcc 4.1 + -Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0) + -Wno-system-headers # clang 1.0 gcc 3.0 + # -Wpadded # clang 2.9 gcc 4.1 # Not used because we cannot change public structs + -Wold-style-definition # clang 2.7 gcc 3.4 + -Wredundant-decls # clang 2.7 gcc 4.1 + -Wsign-conversion # clang 2.9 gcc 4.3 + -Wno-error=sign-conversion # FIXME + -Wstrict-prototypes # clang 1.0 gcc 3.3 + # -Wswitch-enum # clang 2.7 gcc 4.1 # Not used because this basically disallows default case + -Wtype-limits # clang 2.7 gcc 4.3 + -Wunreachable-code # clang 2.7 gcc 4.1 + -Wunused-macros # clang 2.7 gcc 4.1 + -Wunused-parameter # clang 2.7 gcc 4.1 + -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 + -Wpragmas # clang 3.5 gcc 4.1 appleclang 6.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 + -Wlanguage-extension-token # clang 3.0 + -Wformat=2 # clang 3.0 gcc 4.8 + ) + # 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} + -Wunreachable-code-break # clang 3.5 appleclang 6.0 + -Wheader-guard # clang 3.4 appleclang 5.1 + -Wsometimes-uninitialized # clang 3.2 appleclang 4.6 + ) + 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() + if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) OR + (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.4)) + list(APPEND WPICKY_ENABLE + -Wimplicit-fallthrough # clang 4.0 gcc 7.0 appleclang 12.4 # we have silencing markup for clang 10.0 and above only + ) + 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} + -Wclobbered # gcc 4.3 + -Wmissing-parameter-type # gcc 4.3 + -Wold-style-declaration # gcc 4.3 + -Wstrict-aliasing=3 # gcc 4.0 + -Wtrampolines # gcc 4.3 + ) + 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 + ) + 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=2 # gcc 7.0 + -Wimplicit-fallthrough # clang 4.0 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 IN LISTS WPICKY_ENABLE) + set(WPICKY "${WPICKY} ${_CCOPT}") + endforeach() + + foreach(_CCOPT IN LISTS 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/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/libssh2-config.cmake.in b/cmake/libssh2-config.cmake.in new file mode 100644 index 0000000000..27ef5ec3a4 --- /dev/null +++ b/cmake/libssh2-config.cmake.in @@ -0,0 +1,14 @@ +# Copyright (C) The libssh2 project and its contributors. +# SPDX-License-Identifier: BSD-3-Clause + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake") + +# Alias for either shared or static library +if(NOT TARGET @PROJECT_NAME@::@LIB_NAME@) + add_library(@PROJECT_NAME@::@LIB_NAME@ ALIAS @PROJECT_NAME@::@LIB_SELECTED@) +endif() + +# Compatibility alias +if(NOT TARGET Libssh2::@LIB_NAME@) + add_library(Libssh2::@LIB_NAME@ ALIAS @PROJECT_NAME@::@LIB_SELECTED@) +endif() diff --git a/cmake/max_warnings.cmake b/cmake/max_warnings.cmake deleted file mode 100644 index b176d302d3..0000000000 --- a/cmake/max_warnings.cmake +++ /dev/null @@ -1,23 +0,0 @@ -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") - 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() - - # 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() -endif() diff --git a/config.rpath b/config.rpath index e082db6bb5..5e39f28d82 100755 --- a/config.rpath +++ b/config.rpath @@ -24,6 +24,8 @@ # than 256 bytes, otherwise the compiler driver will dump core. The only # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. +# +# SPDX-License-Identifier: FSFULLR # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). diff --git a/configure.ac b/configure.ac index b51bb4b947..2572c2d4ba 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,14 @@ -# AC_PREREQ(2.57) -AC_INIT(libssh2, [-], libssh2-devel@lists.haxx.se) +# Copyright (C) The libssh2 project and its contributors. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# 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])]) @@ -16,16 +22,12 @@ if test "x$SED" = "xsed-was-not-found-by-configure"; then fi dnl figure out the libssh2 version -LIBSSH2VER=`$SED -ne 's/^#define LIBSSH2_VERSION *"\(.*\)"/\1/p' ${srcdir}/include/libssh2.h` +LIBSSH2_VERSION=`$SED -ne 's/^#define LIBSSH2_VERSION *"\(.*\)"/\1/p' ${srcdir}/include/libssh2.h` AM_INIT_AUTOMAKE AC_MSG_CHECKING([libssh2 version]) -AC_MSG_RESULT($LIBSSH2VER) - -AC_SUBST(LIBSSH2VER) +AC_MSG_RESULT($LIBSSH2_VERSION) -AB_VERSION=$LIBSSH2VER - -AB_INIT +AC_SUBST(LIBSSH2_VERSION) # Check for the OS. # Daniel's note: this should not be necessary and we need to work to @@ -33,11 +35,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 +48,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 +68,27 @@ 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 windows.h +case $host in + *-*-msys | *-*-cygwin* | *-*-cegcc*) + # These are POSIX-like systems using BSD-like sockets API. + ;; + *) + AC_CHECK_HEADERS([windows.h], [have_windows_h=yes], [have_windows_h=no]) + ;; +esac + dnl check for how to do large files AC_SYS_LARGEFILE @@ -85,16 +96,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 @@ -105,16 +116,16 @@ case "${use_crypto}" in m4_set_map([crypto_backends], [LIBSSH2_CHECK_CRYPTO]) ;; yes|"") - crypto_errors="No crypto backend specified!" + crypto_errors="No crypto backend specified." ;; *) - crypto_errors="Unknown crypto backend '${use_crypto}' specified!" + crypto_errors="Unknown crypto backend '${use_crypto}' specified." ;; 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 +133,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) @@ -143,68 +150,43 @@ if test "$use_libz" != no; then AC_MSG_NOTICE([Cannot find libz, disabling compression]) found_libz="disabled; no libz found" else - libz_errors="No libz found! + libz_errors="No libz found. Try --with-libz-prefix=PATH if you know that you have it." AS_MESSAGE([ERROR: $libz_errors]) fi else AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support]) - LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }zlib" + LIBSSH2_PC_REQUIRES_PRIVATE="$LIBSSH2_PC_REQUIRES_PRIVATE${LIBSSH2_PC_REQUIRES_PRIVATE:+,}zlib" found_libz="yes" fi fi -AC_SUBST(LIBSREQUIRED) +AC_SUBST(LIBSSH2_PC_REQUIRES_PRIVATE) # # 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 +LIBSSH2_CFLAG_EXTRAS="" + +LIBSSH2_CHECK_OPTION_WERROR + dnl ************************************************************ 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) @@ -225,6 +207,8 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]), AC_MSG_RESULT(no) ) +AC_SUBST(LIBSSH2_CFLAG_EXTRAS) + dnl ************************************************************ dnl Enable hiding of internal symbols in library to reduce its size and dnl speed dynamic linking of applications. This currently is only supported @@ -232,8 +216,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 (default)]), [ case "$enableval" in no) AC_MSG_RESULT(no) @@ -264,11 +248,36 @@ AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibi AC_MSG_RESULT(no) ) +dnl Build without deprecated APIs? +AC_ARG_ENABLE([deprecated], + [AS_HELP_STRING([--disable-deprecated], [Build without deprecated APIs @<:@default=no@:>@])], + [case "$enableval" in + *) + with_deprecated="no" + CPPFLAGS="$CPPFLAGS -DLIBSSH2_NO_DEPRECATED" + ;; + esac], + [with_deprecated="yes"]) + +# 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,21 +305,10 @@ 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) - -case $host in - *-*-cygwin* | *-*-cegcc*) - # These are POSIX-like systems using BSD-like sockets API. - ;; - *) - AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h]) - ;; -esac +AC_CHECK_HEADERS([sys/un.h]) case $host in *darwin*|*interix*) @@ -318,7 +316,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 +328,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, @@ -375,11 +373,44 @@ if test "$found_crypto" = "none"; then fi if test $missing_required_deps = 1; then - AC_MSG_ERROR([Required dependencies are missing!]) + 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}"]) + +AM_CONDITIONAL([HAVE_LIB_STATIC], [test "x$enable_static" != "xno"]) + # 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 + +LIBS="${LIBS} ${LTLIBZ}" + +LIBSSH2_PC_LIBS_PRIVATE=$LIBS +AC_SUBST(LIBSSH2_PC_LIBS_PRIVATE) + +dnl merge the pkg-config private fields into public ones when static-only +if test "x$enable_shared" = "xyes"; then + LIBSSH2_PC_REQUIRES= + LIBSSH2_PC_LIBS= +else + LIBSSH2_PC_REQUIRES=$LIBSSH2_PC_REQUIRES_PRIVATE + LIBSSH2_PC_LIBS=$LIBSSH2_PC_LIBS_PRIVATE +fi +AC_SUBST(LIBSSH2_PC_REQUIRES) +AC_SUBST(LIBSSH2_PC_LIBS) AC_CONFIG_FILES([Makefile src/Makefile @@ -392,16 +423,19 @@ AC_OUTPUT AC_MSG_NOTICE([summary of build options: - version: ${LIBSSH2VER} + version: ${LIBSSH2_VERSION} Host type: ${host} Install prefix: ${prefix} Compiler: ${CC} 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 + Deprecated APIs: $with_deprecated 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..a3af046154 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,4 +1,5 @@ -# Copyright (c) 2014 Alexander Lamaison +# Copyright (C) Alexander Lamaison +# Copyright (C) Viktor Szakats # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided @@ -32,179 +33,12 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. +# +# SPDX-License-Identifier: BSD-3-Clause -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 ca6316b086..bce5d215e2 100644 --- a/docs/HACKING-CRYPTO +++ b/docs/HACKING-CRYPTO @@ -31,19 +31,18 @@ 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 1) Crypto library initialization/termination. @@ -53,6 +52,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 +151,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 +196,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 +230,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. @@ -389,7 +392,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. @@ -401,6 +404,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. @@ -596,7 +614,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(). @@ -605,8 +623,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. @@ -653,13 +671,34 @@ 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 macro _libssh2_rsa_sha1_signv() is defined. +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, - 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-2 hash based on hash length and the RSA context. Return 0 if OK, else -1. @@ -714,7 +753,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. @@ -722,7 +761,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. @@ -871,7 +910,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. @@ -924,6 +963,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..3e42c697e5 100644 --- a/docs/INSTALL_AUTOTOOLS +++ b/docs/INSTALL_AUTOTOOLS @@ -7,12 +7,13 @@ Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. +SPDX-License-Identifier: FSFULLR + 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 +39,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 +48,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 +59,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 +150,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 +172,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 +256,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 +302,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..146e80d4b3 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.7 or later [1] and one of the following cryptography libraries: * OpenSSL +* wolfSSL * Libgcrypt * WinCNG * mbedTLS @@ -21,8 +22,14 @@ If you are happy with the default options, make a new build directory, change to it, configure the build environment and build the project: ``` - mkdir bin - cd bin + cmake -B bld + cmake --build bld +``` + +Use this with CMake 3.12.x or older: +``` + mkdir bld + cd bld cmake .. cmake --build . ``` @@ -35,8 +42,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