├── .clang-format ├── .gitattributes ├── .github ├── CODEOWNERS ├── actions │ └── build │ │ └── action.yml ├── release-drafter.yml └── workflows │ ├── build-release.yml │ ├── cmake.yml │ ├── draft-release.yml │ ├── linters.yml │ └── mattermost-ziti-webhook.yml ├── .gitignore ├── .idea └── fileTemplates │ └── includes │ └── C File Header.h ├── BUILD.md ├── CMakeLists.txt ├── CMakePresets.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CONTRIBUTORS ├── Doxyfile ├── LICENSE ├── README.md ├── SECURITY.md ├── cmake ├── variables.cmake └── version.cmake ├── deps └── CMakeLists.txt ├── inc_internal ├── auth_method.h ├── auth_queries.h ├── authenticators.h ├── buffer.h ├── connect.h ├── deadline.h ├── internal_model.h ├── jsmn.h ├── metrics.h ├── oidc.h ├── pool.h ├── posture.h ├── utils.h ├── ziti_ctrl.h └── zt_internal.h ├── includes └── ziti │ ├── enroll.h │ ├── enums.h │ ├── errors.h │ ├── externs.h │ ├── model_collections.h │ ├── model_support.h │ ├── types.h │ ├── ziti.h │ ├── ziti_buffer.h │ ├── ziti_events.h │ ├── ziti_log.h │ ├── ziti_model.h │ ├── ziti_src.h │ └── zitilib.h ├── library ├── CMakeLists.txt ├── auth_queries.c ├── authenticators.c ├── bind.c ├── buffer.c ├── channel.c ├── config.c ├── conn_bridge.c ├── connect.c ├── crypto.c ├── edge_protocol.c ├── edge_protocol.h ├── endian_internal.h ├── errors.c ├── external_auth.c ├── ha_auth.c ├── internal_model.c ├── legacy_auth.c ├── message.c ├── message.h ├── metrics.c ├── model_collections.c ├── model_support.c ├── oidc.c ├── pool.c ├── posture.c ├── proto │ ├── README.md │ ├── edge_client.pb-c.c │ ├── edge_client.pb-c.h │ └── google │ │ └── protobuf │ │ ├── timestamp.pb-c.c │ │ └── timestamp.pb-c.h ├── sdk_info.c ├── util │ ├── future.c │ └── future.h ├── utils.c ├── ziti.c ├── ziti_ctrl.c ├── ziti_enroll.c ├── ziti_src.c └── zitilib.c ├── programs ├── CMakeLists.txt ├── auth-samples │ ├── CMakeLists.txt │ ├── jwt_auth.cpp │ └── ziti_mfa.cpp ├── host-proxy │ ├── CMakeLists.txt │ └── host-proxy.c ├── sample-bridge │ ├── CMakeLists.txt │ ├── ziti-fd-client.c │ ├── ziti-http-get.c │ └── ziti-ncat.c ├── sample-host │ ├── CMakeLists.txt │ └── sample-host.c ├── sample_enroll │ ├── CMakeLists.txt │ └── sample_enroll.c ├── sample_http_link │ ├── CMakeLists.txt │ ├── README.md │ └── sample_http_link.c ├── sample_wttr │ ├── CMakeLists.txt │ └── sample_wttr.c ├── wzcat │ ├── CMakeLists.txt │ └── ziti_ws.c ├── ziti-prox-c │ ├── CMakeLists.txt │ ├── main.cpp │ ├── proxy.c │ └── proxy.h └── zitilib-samples │ ├── CMakeLists.txt │ └── server.c ├── tests ├── CMakeLists.txt ├── buffer_tests.cpp ├── catch2_includes.hpp ├── collections_tests.cpp ├── enum_tests.cpp ├── integ │ ├── CMakeLists.txt │ ├── bootstrap.exp │ ├── ctrl_tests.cpp │ ├── enroll_tests.cpp │ ├── fixtures.h │ ├── integ-test.exp │ ├── legacy-auth.cpp │ ├── main.cpp │ ├── oidc-tests.cpp │ └── test-data.h.in ├── message_tests.cpp ├── model_tests.cpp ├── pool_tests.cpp ├── test_jwt.cpp ├── test_metrics.cpp ├── test_ziti_model.cpp ├── util_tests.cpp ├── ziti_src_tests.cpp └── zitilib-tests.cpp ├── toolchains ├── Linux-arm.cmake ├── Linux-arm64.cmake ├── Windows-arm64-msvc.cmake ├── Windows-x86.cmake ├── Windows-x86_64.cmake ├── iOS-arm64.cmake ├── iOS-x86_64.cmake ├── linux-embedded.cmake ├── macOS-arm64.cmake └── macOS-x86_64.cmake ├── vcpkg.json ├── version.txt └── ziti.pc.in /.gitattributes: -------------------------------------------------------------------------------- 1 | *.txt eol=lf 2 | *.gitignore text eol=lf 3 | *.sh text eol=lf 4 | *.md text eol=lf 5 | *.mod text eol=lf 6 | *.sum text eol=lf 7 | *.go text eol=lf 8 | *.yml text eol=lf 9 | *.proto text eol=lf 10 | *.json text eol=lf 11 | *.html text eol=lf 12 | *.svg text eol=lf 13 | *.js text eol=lf 14 | *.css text eol=lf 15 | *.yaml text eol=lf 16 | *.http text eol=lf 17 | *.ps1 text eol=lf 18 | *.g4 text eol=lf 19 | *.interp text eol=lf 20 | *.pem text eol=lf 21 | *.cnf text eol=lf 22 | *.conf text eol=lf 23 | *.gitmodules text eol=lf 24 | *.variants text eol=lf 25 | *.cmake text eol=lf 26 | *.bat text eol=lf 27 | *.env text eol=lf 28 | *.service text eol=lf 29 | *.tmpl text eol=lf 30 | *.partial text eol=lf 31 | *.liquid text eol=lf 32 | *.tokens text eol=lf 33 | *.attr text eol=lf 34 | *.in text eol=lf 35 | *.h text eol=lf 36 | *.c text eol=lf 37 | *.kts text eol=lf 38 | *.properties text eol=lf 39 | *.rst text eol=lf 40 | *.gradle text eol=lf 41 | *.java text eol=lf 42 | *.kt text eol=lf -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # see: 2 | # https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-code-owners 3 | * @openziti/maintainers 4 | -------------------------------------------------------------------------------- /.github/actions/build/action.yml: -------------------------------------------------------------------------------- 1 | name: Reusable build 2 | description: Reusable CMake build 3 | 4 | inputs: 5 | target: 6 | required: true 7 | description: build target 8 | 9 | test: 10 | required: true 11 | description: run tests 12 | 13 | config: 14 | default: RelWithDebInfo 15 | description: build type 16 | 17 | test_id: 18 | description: Ziti Test Identity 19 | 20 | runs: 21 | using: "composite" 22 | steps: 23 | - name: macOS tools 24 | if: runner.os == 'macOS' 25 | uses: gerlero/brew-install@v1 26 | with: 27 | packages: autoconf autoconf-archive automake pkg-config libtool 28 | 29 | - name: windows tools 30 | if: runner.os == 'Windows' 31 | shell: bash 32 | run: choco install pkgconfiglite 33 | 34 | - name: setup build 35 | shell: bash 36 | run: | 37 | CI_CACHE="${GITHUB_WORKSPACE}/.ci.cache" 38 | VCPKG_BINARY_SOURCES="clear;files,${GITHUB_WORKSPACE}/.ci.cache,readwrite" 39 | mkdir -p ${CI_CACHE} 40 | echo "CI_CACHE=${CI_CACHE}" >> $GITHUB_ENV 41 | echo "VCPKG_BINARY_SOURCES=${VCPKG_BINARY_SOURCES}" >> $GITHUB_ENV 42 | 43 | - uses: actions/setup-go@v5 44 | with: 45 | go-version: '1.23.x' 46 | cache-dependency-path: "**/*.sum" 47 | 48 | - uses: lukka/get-cmake@v3.30.1 49 | 50 | - uses: lukka/run-vcpkg@v11 51 | 52 | - uses: actions/cache@v4 53 | with: 54 | key: vbc-${{ inputs.target }}-${{ hashFiles('./vcpkg.json') }} 55 | path: ${{ env.CI_CACHE }} 56 | 57 | - name: Configure CMake 58 | shell: bash 59 | run: | 60 | cmake --preset ci-${{ inputs.target }} -B ./build 61 | 62 | - name: build CMake 63 | run: | 64 | cmake --build ./build --config ${{ inputs.config }} 65 | ls -lR ${CI_CACHE} 66 | shell: bash 67 | 68 | - name: bundle artifacts 69 | run: cmake --build ./build --config ${{ inputs.config }} --target ziti-prox-c-pack --target package 70 | shell: bash 71 | 72 | - name: test 73 | if: inputs.test == 'true' 74 | working-directory: ./build 75 | shell: bash 76 | run: ctest -VV --no-compress-output -R quick_tests 77 | 78 | - name: integration tests 79 | env: 80 | TEST_ID: ${{ inputs.test_id }} 81 | ZITI_TEST_IDENTITY: ${{ runner.workspace }}/test_id.json 82 | ZITI_LOG: "4" 83 | if: inputs.test == 'true' 84 | working-directory: ./build 85 | continue-on-error: true 86 | shell: bash 87 | run: | 88 | ctest -VV --no-compress-output -C ${{ inputs.config }} -R quickstart-test 89 | 90 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'v$RESOLVED_VERSION' 2 | tag-template: '$RESOLVED_VERSION' 3 | categories: 4 | - title: 'Features' 5 | labels: 6 | - 'feature' 7 | - 'enhancement' 8 | - title: 'Bug Fixes' 9 | labels: 10 | - 'fix' 11 | - 'bugfix' 12 | - 'bug' 13 | - title: 'Maintenance' 14 | label: 'chore' 15 | - title: 'Dependencies' 16 | label: 'dependencies' 17 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)' 18 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. 19 | version-resolver: 20 | major: 21 | labels: 22 | - 'major' 23 | minor: 24 | labels: 25 | - 'minor' 26 | patch: 27 | labels: 28 | - 'patch' 29 | default: patch 30 | template: | 31 | ## Changes 32 | 33 | $CHANGES 34 | -------------------------------------------------------------------------------- /.github/workflows/build-release.yml: -------------------------------------------------------------------------------- 1 | name: Publish Release 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [ published ] 7 | permissions: 8 | contents: write 9 | jobs: 10 | build: 11 | name: ${{ matrix.spec.name }} 12 | runs-on: ${{ matrix.spec.runner }} 13 | container: 14 | image: ${{ matrix.spec.builder }} 15 | env: 16 | BUILD_NUMBER: ${{ github.run_number }} 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | spec: 21 | - { name: 'Linux x86_64', runner: 'ubuntu-latest', target: 'linux-x64', builder: 'openziti/ziti-builder:v2' } 22 | - { name: 'Linux ARM', runner: 'ubuntu-latest', target: 'linux-arm', builder: 'openziti/ziti-builder:v2' } 23 | - { name: 'Linux ARM64', runner: 'ubuntu-latest', target: 'linux-arm64', builder: 'openziti/ziti-builder:v2' } 24 | - { name: 'MacOS x86_64', runner: 'macOS-13', target: 'macOS-x64' } 25 | - { name: 'MacOS arm64', runner: 'macOS-14', target: 'macOS-arm64' } 26 | - { name: 'Windows x86_64', runner: 'windows-2022', target: 'windows-x64' } 27 | - { name: 'Windows ARM64', runner: 'windows-2022', target: 'windows-arm64' } 28 | 29 | steps: 30 | - name: Add msbuild to PATH 31 | if: startsWith(matrix.spec.runner, 'windows') 32 | uses: microsoft/setup-msbuild@v2 33 | 34 | - uses: actions/checkout@v4 35 | with: 36 | fetch-depth: 0 37 | 38 | - name: run build for ${{ matrix.spec.target }} 39 | uses: ./.github/actions/build 40 | with: 41 | target: ${{ matrix.spec.target }} 42 | test: false 43 | config: RelWithDebInfo 44 | 45 | - name: upload SDK release bundle 46 | uses: softprops/action-gh-release@v0.1.13 47 | if: startsWith(github.ref, 'refs/tags/') 48 | with: 49 | files: | 50 | ./build/package/ziti-sdk* 51 | ./build/programs/ziti-prox-c/ziti-prox-c-*.zip 52 | 53 | - name: "upload pre-release artifacts: ziti-prox-c" 54 | uses: actions/upload-artifact@v4 55 | with: 56 | name: ziti-prox-c-${{ matrix.spec.target }} 57 | path: ./build/programs/ziti-prox-c/**/ziti-prox-c*.zip 58 | 59 | - name: upload SDK pre-release artifacts 60 | uses: actions/upload-artifact@v4 61 | with: 62 | name: ziti-sdk-${{ matrix.spec.target }} 63 | path: ./build/package/ziti-sdk-* 64 | -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: C/C++ CI 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | branches: 10 | - main 11 | - release-* 12 | 13 | permissions: 14 | contents: read 15 | 16 | jobs: 17 | build: 18 | name: ${{ matrix.spec.name }} 19 | runs-on: ${{ matrix.spec.runner }} 20 | container: 21 | image: ${{ matrix.spec.builder }} 22 | env: 23 | BUILD_NUMBER: ${{ github.run_number }} 24 | strategy: 25 | fail-fast: false 26 | matrix: 27 | spec: 28 | - { name: 'Linux x86_64', runner: 'ubuntu-latest', target: 'linux-x64', builder: 'openziti/ziti-builder:v2', test: 'true' } 29 | - { name: 'Linux ARM', runner: 'ubuntu-latest', target: 'linux-arm', builder: 'openziti/ziti-builder:v2' } 30 | - { name: 'Linux ARM64', runner: 'ubuntu-latest', target: 'linux-arm64', builder: 'openziti/ziti-builder:v2' } 31 | - { name: 'MacOS x86_64', runner: 'macOS-13', target: 'macOS-x64', test: 'true' } 32 | - { name: 'MacOS arm64', runner: 'macOS-14', target: 'macOS-arm64', test: 'true' } 33 | - { name: 'Windows x86_64', runner: 'windows-2022', target: 'windows-x64', test: 'true' } 34 | - { name: 'Windows ARM64', runner: 'windows-2022', target: 'windows-arm64' } 35 | steps: 36 | - name: Add msbuild to PATH 37 | if: startsWith(matrix.spec.runner, 'windows') 38 | uses: microsoft/setup-msbuild@v2 39 | 40 | - uses: actions/checkout@v4 41 | with: 42 | fetch-depth: 0 43 | 44 | - name: run build for ${{ matrix.spec.target }} 45 | uses: ./.github/actions/build 46 | with: 47 | target: ${{ matrix.spec.target }} 48 | test: ${{ matrix.spec.test }} 49 | test_id: ${{ secrets.ZITI_TEST_IDENTITY }} 50 | 51 | - name: upload artifacts 52 | uses: actions/upload-artifact@v4 53 | with: 54 | name: ziti-prox-c-${{ matrix.spec.target }} 55 | path: ./build/programs/ziti-prox-c/**/ziti-prox-c*.zip 56 | 57 | - name: upload SDK artifacts 58 | uses: actions/upload-artifact@v4 59 | with: 60 | name: ziti-sdk-${{ matrix.spec.target }} 61 | path: ./build/package/ziti-sdk-* 62 | -------------------------------------------------------------------------------- /.github/workflows/draft-release.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - release-1.x 8 | 9 | permissions: 10 | contents: write 11 | 12 | jobs: 13 | update_release_draft: 14 | runs-on: ubuntu-latest 15 | steps: 16 | # Drafts your next Release notes as Pull Requests are merged into "master" 17 | - uses: release-drafter/release-drafter@v5 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | -------------------------------------------------------------------------------- /.github/workflows/linters.yml: -------------------------------------------------------------------------------- 1 | name: Linters 2 | 3 | on: pull_request 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | codespell: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout Code 13 | uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | 17 | - name: Run code spelling check 18 | uses: codespell-project/actions-codespell@v2 19 | with: 20 | ignore_words_list: controll,mapp,precendence,tolen,uknown,ununsed,unstalled 21 | -------------------------------------------------------------------------------- /.github/workflows/mattermost-ziti-webhook.yml: -------------------------------------------------------------------------------- 1 | name: ziti-mattermost-action-py 2 | on: 3 | issues: 4 | issue_comment: 5 | pull_request_review: 6 | types: [submitted] 7 | pull_request_review_comment: 8 | pull_request: 9 | types: [opened, reopened] 10 | push: 11 | fork: 12 | release: 13 | types: [released] 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | ziti-webhook: 20 | runs-on: ubuntu-latest 21 | name: Ziti Mattermost Action - Py 22 | steps: 23 | - uses: openziti/ziti-mattermost-action-py@main 24 | if: github.event_name != 'pull_request_review' 25 | with: 26 | zitiId: ${{ secrets.ZITI_MATTERMOST_IDENTITY }} 27 | webhookUrl: ${{ secrets.ZHOOK_URL }} 28 | eventJson: ${{ toJson(github.event) }} 29 | senderUsername: "GitHubZ" 30 | destChannel: "dev-notifications" 31 | - uses: openziti/ziti-mattermost-action-py@main 32 | if: github.event_name == 'pull_request_review' && github.event.review.state == 'approved' 33 | with: 34 | zitiId: ${{ secrets.ZITI_MATTERMOST_IDENTITY }} 35 | webhookUrl: ${{ secrets.ZHOOK_URL }} 36 | eventJson: ${{ toJson(github.event) }} 37 | senderUsername: "GitHubZ" 38 | destChannel: "dev-notifications" 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | build-*/ 4 | build/ 5 | cmake-build-*/ 6 | 7 | # visual studio files 8 | .vs 9 | **/obj/ 10 | **/bin/ 11 | **/Debug/ 12 | *.user 13 | ziti_libs/ 14 | 15 | #docfx related 16 | docfx_site 17 | windows/packages 18 | 19 | #ide related 20 | .vscode 21 | .idea 22 | 23 | Testing/ 24 | 25 | #additional stuff for localtesting 26 | local.cmake 27 | /CMakeUserPresets.json 28 | 29 | ## CI dirs 30 | .ci.cache/ 31 | -------------------------------------------------------------------------------- /.idea/fileTemplates/includes/C File Header.h: -------------------------------------------------------------------------------- 1 | #if ($HEADER_COMMENTS) 2 | /* 3 | Copyright (c) $YEAR NetFoundry, Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | https://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | #if ($ORGANIZATION_NAME && $ORGANIZATION_NAME != "") 18 | // Copyright (c) $YEAR ${ORGANIZATION_NAME}#if (!$ORGANIZATION_NAME.endsWith(".")).#end All rights reserved. 19 | #end 20 | 21 | #end 22 | 23 | -------------------------------------------------------------------------------- /BUILD.md: -------------------------------------------------------------------------------- 1 | # Building the Project 2 | 3 | The following steps should get your C SDK for Ziti building. C development is specific to your operating system and 4 | tool chain used. These steps should work properly for you but if your OS has variations you may need to adapt these steps accordingly. 5 | 6 | ## Prerequisites 7 | 8 | This repository expects the user to have at least a basic understanding of what a Ziti Network 9 | is. To use this library it is also required to have a functioning Ziti Network available to use. 10 | To learn more about what Ziti is or how to learn how to setup a Ziti Network head over to [the official documentation 11 | site](https://openziti.github.io/ziti/overview.html). 12 | 13 | ## Building Requirements 14 | 15 | * [cmake](https://cmake.org/install/) 16 | * make sure cmake is on your path or replace the following `cmake` commands with the fully qualified path to the binary 17 | * [vcpkg](https://github.com/microsoft/vcpkg) is now used for dependencies. 18 | 19 | ### Setting up vcpkg 20 | 21 | To setup vcpkg you'll need to clone the actual vcpkg repository. The first step will have you set this environment variable. 22 | It should be set to somewhere durable, such as wherever you check your projects into. The example commands below use $HOME/%USERPROFILE% 23 | but you should probably change this to your liking. 24 | 25 | Linux/MacOS: 26 | 27 | * set/export an environment variable named `VCPKG_ROOT`. for example (use an appropriate location): `export VCPKG_ROOT=${HOME}/vcpkg` 28 | * create the directory: `mkdir -p ${VCPKG_ROOT}` 29 | * clone the vcpkg project: `git clone git@github.com:microsoft/vcpkg.git ${VCPKG_ROOT}` 30 | * run the bootstrap-vcpkg for your platform: `${VCPKG_ROOT}/bootstrap-vcpkg.sh` 31 | 32 | Windows: 33 | * set/export an environment variable named `VCPKG_ROOT`. for example (use an appropriate location): `SET VCPKG_ROOT=%USERPROFILE%\vcpkg` 34 | * create the directory: `mkdir %VCPKG_ROOT%` 35 | * clone the vcpkg project: `git clone git@github.com:microsoft/vcpkg.git %VCPKG_ROOT%` 36 | * run the bootstrap-vcpkg for your platform: `%VCPKG_ROOT%/bootstrap-vcpkg.bat` 37 | 38 | ## Building 39 | 40 | Make sure you have setup vcpkg (see above). Building the SDK is accomplished with the following commands from the 41 | checkout root. Replace the `--preset` value with the one that matches your needs or create your own preset. You 42 | can run `cmake` from the checkout root with an `unknown` param passed to `--preset` to see the list of presets: 43 | `cmake --preset unknown ${ZITI_SDK_C_ROOT}/.` 44 | 45 | Build the SDK with: 46 | 47 | ```bash 48 | mkdir build 49 | cd build 50 | cmake --preset ci-linux-x64 .. 51 | cmake --build . 52 | ``` 53 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | 3 | include(cmake/version.cmake) 4 | get_version(${CMAKE_CURRENT_LIST_DIR}/version.txt GIT_VERSION GIT_BRANCH GIT_COMMIT_HASH) 5 | 6 | project(ziti-sdk 7 | DESCRIPTION "OpenZiti C SDK" 8 | HOMEPAGE_URL "https://github.com/openziti/ziti-sdk-c" 9 | LANGUAGES C CXX 10 | ) 11 | 12 | set(PROJECT_VERSION ${GIT_VERSION}) 13 | include(cmake/variables.cmake) 14 | 15 | set(tlsuv_DIR "" CACHE FILEPATH "developer option: use local tlsuv checkout") 16 | 17 | message("project version: ${PROJECT_VERSION}") 18 | message("git info:") 19 | message(" branch : ${GIT_BRANCH}") 20 | message(" hash : ${GIT_COMMIT_HASH}") 21 | 22 | message("") 23 | message("using ${CMAKE_GENERATOR}") 24 | 25 | if (ziti_DEVELOPER_MODE) 26 | set(complist GNU Clang AppleClang) 27 | if (CMAKE_C_COMPILER_ID IN_LIST complist) 28 | option(ziti_ASAN "build with sanitizers") 29 | option(ziti_TEST_COVERAGE "enable test coverage") 30 | endif () 31 | unset(complist) 32 | endif () 33 | 34 | if (ziti_ASAN) 35 | add_compile_options(-fsanitize=address -fno-omit-frame-pointer) 36 | add_link_options(-fsanitize=address) 37 | endif (ziti_ASAN) 38 | 39 | if (ziti_TEST_COVERAGE) 40 | add_compile_options(--coverage) 41 | add_link_options(--coverage) 42 | endif (ziti_TEST_COVERAGE) 43 | 44 | if (WIN32) 45 | if(MINGW) 46 | #on server 2016 msvcrt.dll does not process %z formatting 47 | #that can lead to a crash if the string format is something like: %zd(%s) 48 | add_compile_definitions(__USE_MINGW_ANSI_STDIO=1) 49 | endif() 50 | set(CMAKE_INSTALL_LIBDIR lib) 51 | set(CMAKE_INSTALL_INCLUDEDIR include) 52 | if(NOT CMAKE_INSTALL_PREFIX) 53 | message("WIN32 build. Creating: ${CMAKE_BINARY_DIR}/cmake_install") 54 | file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_install) 55 | message("WIN32 build. Creating: ${CMAKE_BINARY_DIR}/cmake_install/ziti-sdk-${PROJECT_VERSION}") 56 | file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_install/ziti-sdk-${PROJECT_VERSION}) 57 | set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/cmake_install/ziti-sdk-${PROJECT_VERSION}) 58 | endif() 59 | else() 60 | set(CMAKE_INSTALL_PREFIX /opt/openziti/ziti-sdk-${PROJECT_VERSION}) 61 | endif() 62 | 63 | message("cross-compiling ${CMAKE_CROSSCOMPILING}") 64 | 65 | if (DEFINED ENV{BUILD_NUMBER}) 66 | set(ZITI_BUILDNUM $ENV{BUILD_NUMBER}) 67 | endif () 68 | 69 | link_directories(${CMAKE_BINARY_DIR}/lib) 70 | 71 | add_subdirectory(deps) 72 | 73 | set(CPACK_INSTALL_CMAKE_PROJECTS 74 | "${CMAKE_CURRENT_BINARY_DIR};${PROJECT_NAME};ziti-sdk;/" 75 | ) 76 | set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) 77 | set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0) 78 | set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) 79 | set(CPACK_OUTPUT_FILE_PREFIX ${CMAKE_BINARY_DIR}/package) 80 | set(CPACK_GENERATOR "ZIP") 81 | set(archive_sfx "zip") 82 | 83 | find_program(ZIP NAMES 7z) 84 | if (ZIP) 85 | set(ZIP_OPTS a -tzip) 86 | else () 87 | find_program(ZIP NAMES zip) 88 | if (ZIP) 89 | set(ZIP_OPTS "-jv") 90 | else () 91 | message("zip program not found") 92 | endif () 93 | endif () 94 | 95 | set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") 96 | 97 | if(NOT CPack_CMake_INCLUDED) 98 | include(CPack) 99 | endif() 100 | 101 | # use prefix length to trim path for logging, see utils.c 102 | if (CMAKE_GENERATOR STREQUAL "Ninja" AND CMAKE_BINARY_DIR MATCHES "${CMAKE_SOURCE_DIR}") 103 | # if CMAKE_BINARY_DIR is inside CMAKE_SOURCE_DIR Ninja uses relative paths which screws logging of the filename 104 | # so we just leave it be -- it shows enough information to find the source 105 | set(SOURCE_PATH_SIZE 0) 106 | else() 107 | string(LENGTH "${CMAKE_SOURCE_DIR}/" SOURCE_PATH_SIZE) 108 | endif() 109 | 110 | add_subdirectory(library) 111 | 112 | if (PROJECT_IS_TOP_LEVEL) 113 | option(BUILD_EXAMPLES "Build examples tree." "${ziti_DEVELOPER_MODE}") 114 | if (BUILD_EXAMPLES) 115 | add_subdirectory(programs) 116 | endif () 117 | endif () 118 | 119 | if (ziti_DEVELOPER_MODE AND NOT CMAKE_CROSSCOMPILING) 120 | ENABLE_TESTING() 121 | add_subdirectory(tests) 122 | endif () 123 | 124 | if (ziti-sdk_IS_TOP_LEVEL AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/local.cmake") 125 | include("${CMAKE_CURRENT_LIST_DIR}/local.cmake") 126 | endif () 127 | 128 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | All open source projects managed by OpenZiti share a common [code of conduct](https://docs.openziti.io/policies/CODE_OF_CONDUCT.html) 4 | which all contributors are expected to follow. Please be sure you read, understand and adhere to the guidelines expressed therein. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | NetFoundry welcomes all and any contributions. All open source projects managed by NetFoundry share a common 4 | [guide for contributions](https://docs.openziti.io/policies/CONTRIBUTING.html). 5 | 6 | If you are eager to contribute to a NetFoundry-managed open source project please read and act accordingly. 7 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # Authors ordered by first contribution 2 | Nic Fragale 3 | Tom Carroll 4 | Mario Trangoni 5 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | Please refer to the [openziti-security repository](https://github.com/openziti/openziti-security) for details of the security policies and processes for this repository. -------------------------------------------------------------------------------- /cmake/variables.cmake: -------------------------------------------------------------------------------- 1 | # ---- Developer mode ---- 2 | 3 | # Developer mode enables targets and code paths in the CMake scripts that are 4 | # only relevant for the developer(s) of tlsuv 5 | # Targets necessary to build the project must be provided unconditionally, so 6 | # consumers can trivially build and package the project 7 | if (PROJECT_IS_TOP_LEVEL) 8 | option(ziti_DEVELOPER_MODE "Enable developer mode" OFF) 9 | option(BUILD_SHARED_LIBS "Build shared libs." ON) 10 | option(BUILD_STATIC_LIBS "Build static libs." ON) 11 | 12 | endif () 13 | 14 | # ---- Warning guard ---- 15 | 16 | # target_include_directories with the SYSTEM modifier will request the compiler 17 | # to omit warnings from the provided paths, if the compiler supports that 18 | # This is to provide a user experience similar to find_package when 19 | # add_subdirectory or FetchContent is used to consume this project 20 | set(warning_guard "") 21 | if (NOT PROJECT_IS_TOP_LEVEL) 22 | option( 23 | ziti_INCLUDES_WITH_SYSTEM 24 | "Use SYSTEM modifier for ziti's includes, disabling warnings" 25 | ON 26 | ) 27 | mark_as_advanced(ziti_INCLUDES_WITH_SYSTEM) 28 | if (ziti_INCLUDES_WITH_SYSTEM) 29 | set(warning_guard SYSTEM) 30 | endif () 31 | endif () 32 | -------------------------------------------------------------------------------- /cmake/version.cmake: -------------------------------------------------------------------------------- 1 | macro(do_git out_var err_var) 2 | execute_process( 3 | COMMAND "git" ${ARGN} 4 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 5 | OUTPUT_VARIABLE git_out 6 | OUTPUT_STRIP_TRAILING_WHITESPACE 7 | ERROR_VARIABLE git_err 8 | ECHO_ERROR_VARIABLE 9 | ) 10 | if (git_err) 11 | set(${err_var} ${git_err}) 12 | unset(${out_var}) 13 | else () 14 | set(${out_var} "${git_out}") 15 | unset(${err_var}) 16 | endif () 17 | endmacro(do_git) 18 | 19 | function(get_version version_file version_var branch_var commit_var) 20 | do_git(GIT_INFO GIT_ERROR describe --always) 21 | if (GIT_ERROR) 22 | unset(GIT_INFO) 23 | message(NOTICE "getting version from ${version_file}") 24 | file(STRINGS ${version_file} ver_info) 25 | list(LENGTH ver_info ver_info_len) 26 | list(GET ver_info 0 GIT_INFO) 27 | list(GET ver_info 1 _branch) 28 | list(GET ver_info 2 _commit) 29 | set(${version_var} ${GIT_INFO} PARENT_SCOPE) 30 | set(${branch_var} ${_branch} PARENT_SCOPE) 31 | set(${commit_var} ${_commit} PARENT_SCOPE) 32 | return() 33 | endif () 34 | 35 | do_git(_branch GIT_ERROR rev-parse --abbrev-ref HEAD) 36 | do_git(GIT_INFO GIT_ERROR describe --tags --long --first-parent HEAD) 37 | if (${GIT_INFO} MATCHES "^(.*)-([0-9]+)-([^-]*)") # -- 38 | set(_commit ${CMAKE_MATCH_3}) 39 | if (${CMAKE_MATCH_2} EQUAL "0") #exact tag 40 | set(_ver ${CMAKE_MATCH_1}) 41 | else () 42 | string(JOIN "." _ver ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}) 43 | endif () 44 | endif () 45 | 46 | set(${version_var} ${_ver} PARENT_SCOPE) 47 | set(${branch_var} ${_branch} PARENT_SCOPE) 48 | set(${commit_var} ${_commit} PARENT_SCOPE) 49 | endfunction() -------------------------------------------------------------------------------- /deps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include(FetchContent) 3 | 4 | # allow downstream projects to pull tlsuv on their own 5 | if (NOT TARGET tlsuv) 6 | if (tlsuv_DIR) 7 | add_subdirectory(${tlsuv_DIR} 8 | ${CMAKE_CURRENT_BINARY_DIR}/tlsuv) 9 | else () 10 | FetchContent_Declare(tlsuv 11 | GIT_REPOSITORY https://github.com/openziti/tlsuv.git 12 | GIT_TAG v0.35.0 13 | ) 14 | FetchContent_MakeAvailable(tlsuv) 15 | endif (tlsuv_DIR) 16 | endif () # tlsuv TARGET 17 | -------------------------------------------------------------------------------- /inc_internal/auth_method.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023-2024. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // 6 | // You may obtain a copy of the License at 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ZITI_SDK_AUTH_METHOD_H 16 | #define ZITI_SDK_AUTH_METHOD_H 17 | 18 | #include "ziti_ctrl.h" 19 | 20 | enum AuthenticationMethod { 21 | LEGACY, 22 | HA 23 | }; 24 | 25 | static const ziti_auth_query_mfa ZITI_MFA = { 26 | .type_id = ziti_auth_query_type_MFA, 27 | .provider = "ziti", 28 | }; 29 | 30 | typedef enum { 31 | ZitiAuthStateUnauthenticated, 32 | ZitiAuthStateAuthStarted, 33 | 34 | ZitiAuthStatePartiallyAuthenticated, 35 | ZitiAuthStateFullyAuthenticated, 36 | 37 | ZitiAuthImpossibleToAuthenticate, 38 | } ziti_auth_state; 39 | 40 | typedef struct ziti_ctx *ziti_context; 41 | typedef struct ziti_auth_method_s ziti_auth_method_t; 42 | typedef void (*auth_state_cb)(void *ctx, ziti_auth_state, const void *data); 43 | typedef void (*auth_mfa_cb)(void *ctx, int status); 44 | 45 | struct ziti_auth_method_s { 46 | enum AuthenticationMethod kind; 47 | int (*set_ext_jwt)(ziti_auth_method_t *self, const char *token); 48 | int (*set_endpoint)(ziti_auth_method_t *self, const char *url); 49 | int (*start)(ziti_auth_method_t *self, auth_state_cb cb, void *ctx); 50 | int (*force_refresh)(ziti_auth_method_t *self); 51 | int (*submit_mfa)(ziti_auth_method_t *self, const char *code, auth_mfa_cb); 52 | int (*stop)(ziti_auth_method_t *self); 53 | void (*free)(ziti_auth_method_t *self); 54 | }; 55 | 56 | ziti_auth_method_t *new_legacy_auth(ziti_controller *ctrl); 57 | ziti_auth_method_t *new_ha_auth(uv_loop_t *l, const char *url, tls_context *tls); 58 | 59 | #endif // ZITI_SDK_AUTH_METHOD_H 60 | -------------------------------------------------------------------------------- /inc_internal/auth_queries.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Netfoundry, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef ZITI_SDK_AUTH_QUERIES_H 18 | #define ZITI_SDK_AUTH_QUERIES_H 19 | 20 | #include 21 | #include "zt_internal.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | #include "zt_internal.h" 28 | #include 29 | 30 | typedef struct ziti_mfa_auth_ctx_s ziti_mfa_auth_ctx; 31 | 32 | struct auth_queries { 33 | ziti_mfa_auth_ctx *outstanding_auth_query_ctx; 34 | }; 35 | 36 | extern void ziti_auth_query_init(struct ziti_ctx *ztx); 37 | extern void ziti_auth_query_free(struct auth_queries* aq); 38 | extern void ziti_send_event(ziti_context ztx, const ziti_event_t *e); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | 45 | #endif //ZITI_SDK_AUTH_QUERIES_H 46 | -------------------------------------------------------------------------------- /inc_internal/authenticators.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Netfoundry, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef ZITI_SDK_AUTHENTICATORS_H 18 | #define ZITI_SDK_AUTHENTICATORS_H 19 | 20 | #include "zt_internal.h" 21 | #include "utils.h" 22 | 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | 29 | int ziti_extend_cert_authenticator(ziti_context ztx, const char *csr_pem, ziti_extend_cert_authenticator_cb cb, void *ctx); 30 | 31 | int ziti_verify_extend_cert_authenticator(ziti_context ztx, const char *new_cert, ziti_verify_extend_cert_authenticator_cb cb, void *ctx); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | 38 | #endif //ZITI_SDK_AUTHENTICATORS_H 39 | -------------------------------------------------------------------------------- /inc_internal/buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019-2020 NetFoundry, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef ZITI_SDK_BUFFER_H 18 | #define ZITI_SDK_BUFFER_H 19 | 20 | #include 21 | #include 22 | 23 | #if !defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined) 24 | #if _WIN32 25 | typedef intptr_t ssize_t; 26 | #define __DEFINED_ssize_t 27 | #define __ssize_t_defined 28 | #else 29 | #include 30 | #endif 31 | #endif 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | typedef struct buffer_s buffer; 38 | 39 | buffer *new_buffer(); 40 | void free_buffer(buffer *); 41 | 42 | void buffer_cleanup(buffer *); 43 | ssize_t buffer_get_next(buffer *, size_t want, uint8_t **ptr); 44 | void buffer_push_back(buffer *, size_t); 45 | void buffer_append(buffer *, uint8_t *buf, size_t len); 46 | void buffer_append_copy(buffer *, const uint8_t *, size_t len); 47 | size_t buffer_available(buffer *); 48 | 49 | 50 | struct string_buf_s { 51 | buffer *buf; 52 | bool fixed; 53 | size_t chunk_size; 54 | uint8_t *chunk; 55 | uint8_t *wp; 56 | }; 57 | 58 | void string_buf_init(string_buf_t *wb); 59 | 60 | void string_buf_init_fixed(string_buf_t *wb, char *outbuf, size_t max); 61 | 62 | void string_buf_free(string_buf_t *wb); 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif //ZITI_SDK_BUFFER_H 69 | -------------------------------------------------------------------------------- /inc_internal/connect.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef ZITI_SDK_CONNECT_H 17 | #define ZITI_SDK_CONNECT_H 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | 24 | #define conn_states(XX) \ 25 | XX(Initial)\ 26 | XX(Connecting)\ 27 | XX(Connected)\ 28 | XX(Accepting)\ 29 | XX(CloseWrite)\ 30 | XX(Timedout)\ 31 | XX(Disconnected)\ 32 | XX(Closed) 33 | 34 | enum conn_state { 35 | #define state_enum(ST) ST, 36 | conn_states(state_enum) 37 | }; 38 | 39 | void init_transport_conn(struct ziti_conn *conn); 40 | 41 | int ziti_close_server(struct ziti_conn *conn); 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif //ZITI_SDK_CONNECT_H 48 | -------------------------------------------------------------------------------- /inc_internal/deadline.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright NetFoundry Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #ifndef ZITI_SDK_DEADLINE_H 18 | #define ZITI_SDK_DEADLINE_H 19 | 20 | #include 21 | #include 22 | 23 | typedef struct deadline_s deadline_t; 24 | typedef LIST_HEAD(deadline_list, deadline_s) deadline_list_t; 25 | 26 | struct deadline_s { 27 | LIST_ENTRY(deadline_s) _next; 28 | uint64_t expiration; 29 | void (*expire_cb)(void *ctx); 30 | void *ctx; 31 | }; 32 | 33 | static inline void clear_deadline(deadline_t *dl) { 34 | if (dl->expire_cb == NULL) return; 35 | 36 | dl->expire_cb = NULL; 37 | LIST_REMOVE(dl, _next); 38 | } 39 | 40 | #endif //ZITI_SDK_DEADLINE_H 41 | -------------------------------------------------------------------------------- /inc_internal/metrics.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ZITI_SDK_METRICS_H 16 | #define ZITI_SDK_METRICS_H 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #ifdef __cplusplus 23 | #include 24 | using namespace std; 25 | #else 26 | #if defined(__linux) || defined(__FreeBSD__) 27 | 28 | /* 20230621:NFRAGALE@NETFOUNDRY:Build assurance against a missing macro in features.h. */ 29 | # if defined __GNUC__ && defined __GNUC_MINOR__ && ! __clang__ 30 | # include 31 | # ifndef __GNUC_PREREQ 32 | # define __GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) 33 | # endif 34 | /* gcc 4.8 does not have and does not set the flag */ 35 | # if ! __GNUC_PREREQ(4,9) 36 | # define __STDC_NO_ATOMICS__ 1 37 | # endif 38 | # endif 39 | 40 | # if __STDC_NO_ATOMICS__ 41 | # include 42 | 43 | # define atomic_llong uatomic_fast64_t 44 | # define atomic_long uatomic_fast32_t 45 | # else 46 | # include 47 | # endif 48 | #elif defined(__APPLE__) 49 | # include 50 | #elif _WIN32 51 | #include 52 | #endif 53 | #endif 54 | 55 | struct rate_s { 56 | atomic_llong delta; 57 | atomic_llong rate; 58 | atomic_llong param; 59 | 60 | uint64_t last_tick; 61 | void (*tick_fn)(struct rate_s *); 62 | 63 | atomic_long init; 64 | bool active; 65 | }; 66 | 67 | typedef struct rate_s rate_t; 68 | 69 | #ifdef __cplusplus 70 | extern "C" { 71 | #endif 72 | 73 | // return millisecond precision time 74 | typedef uint64_t (*time_fn)(void *ctx); 75 | extern void metrics_init(long interval_secs, time_fn, void *time_ctx); 76 | 77 | extern int metrics_rate_init(rate_t *r, rate_type type); 78 | extern void metrics_rate_close(rate_t* r); 79 | 80 | extern void metrics_rate_update(rate_t *r, long delta); 81 | extern int metrics_rate_get(rate_t *r, double *rate); 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | 87 | #endif //ZITI_SDK_METRICS_H 88 | -------------------------------------------------------------------------------- /inc_internal/oidc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright NetFoundry Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #ifndef ZITI_SDK_OIDC_H 18 | #define ZITI_SDK_OIDC_H 19 | 20 | #include 21 | #include 22 | #include "tlsuv/http.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | enum oidc_status { 29 | OIDC_TOKEN_OK = 0, 30 | OIDC_TOTP_NEEDED = 1, 31 | OIDC_TOTP_FAILED = 2, 32 | OIDC_TOKEN_FAILED = 3, 33 | OIDC_RESTART = 4, 34 | }; 35 | 36 | typedef struct oidc_client_s oidc_client_t; 37 | typedef void (*oidc_config_cb)(oidc_client_t *, int, const char *); 38 | typedef void (*oidc_token_cb)(oidc_client_t *, enum oidc_status, const char *access_token); 39 | typedef void (*oidc_close_cb)(oidc_client_t *); 40 | typedef void (*oidc_ext_link_cb)(oidc_client_t *, const char *link, void *ctx); 41 | 42 | typedef enum { 43 | oidc_native, 44 | oidc_external, 45 | } oidc_auth_mode; 46 | 47 | struct oidc_client_s { 48 | void *data; 49 | tlsuv_http_t http; 50 | 51 | ziti_jwt_signer signer_cfg; 52 | 53 | oidc_auth_mode mode; 54 | oidc_config_cb config_cb; 55 | oidc_token_cb token_cb; 56 | oidc_close_cb close_cb; 57 | 58 | oidc_ext_link_cb link_cb; 59 | void *link_ctx; 60 | 61 | void *config; 62 | void *tokens; 63 | const char *refresh_grant; 64 | 65 | uv_timer_t *timer; 66 | char *jwt_token_auth; 67 | 68 | struct auth_req *request; 69 | }; 70 | 71 | // init 72 | int oidc_client_init(uv_loop_t *loop, oidc_client_t *clt, 73 | const struct ziti_jwt_signer_s *cfg, tls_context *tls); 74 | int oidc_client_set_cfg(oidc_client_t *clt, const struct ziti_jwt_signer_s *cfg); 75 | 76 | void oidc_client_set_link_cb(oidc_client_t *clt, oidc_ext_link_cb, void *ctx); 77 | 78 | // configure client 79 | int oidc_client_configure(oidc_client_t *clt, oidc_config_cb); 80 | 81 | // acquire access token and start refresh cycle 82 | // oidc_token_cb will be called on first auth and on every refresh 83 | int oidc_client_start(oidc_client_t *clt, oidc_token_cb); 84 | 85 | int oidc_client_mfa(oidc_client_t *clt, const char *code); 86 | 87 | int oidc_client_token(oidc_client_t *clt, const char *token); 88 | 89 | // force token refresh ahead of normal cycle, error if called prior to oidc_client_start 90 | int oidc_client_refresh(oidc_client_t *clt); 91 | 92 | // close 93 | int oidc_client_close(oidc_client_t *clt, oidc_close_cb); 94 | 95 | #ifdef __cplusplus 96 | }; 97 | #endif 98 | 99 | #endif //ZITI_SDK_OIDC_H 100 | -------------------------------------------------------------------------------- /inc_internal/pool.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef ZITI_SDK_POOL_H 17 | #define ZITI_SDK_POOL_H 18 | 19 | #include 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | 27 | typedef struct pool_s pool_t; 28 | 29 | pool_t *pool_new(size_t objsize, size_t count, void (*clear_func)(void *)); 30 | 31 | void pool_destroy(pool_t *pool); 32 | 33 | bool pool_has_available(pool_t *p); 34 | 35 | typedef void (*pool_available_cb)(void *ctx); 36 | void pool_set_available_cb(pool_t *p, pool_available_cb, void *ctx); 37 | 38 | void *pool_alloc_obj(pool_t *pool); 39 | 40 | // allocate object that can be freed by [pool_return_obj] 41 | // useful when you need alloc before pool is available or need an object larger that normal 42 | void *alloc_unpooled_obj(size_t size, void (*clear_func)(void *)); 43 | 44 | void pool_return_obj(void *obj); 45 | 46 | size_t pool_mem_size(pool_t *pool); 47 | 48 | size_t pool_obj_size(void *obj); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif //ZITI_SDK_POOL_H 55 | -------------------------------------------------------------------------------- /inc_internal/posture.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2022. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ZITI_SDK_POSTURE_H 16 | #define ZITI_SDK_POSTURE_H 17 | 18 | #include 19 | #include "zt_internal.h" 20 | #include "deadline.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | struct posture_checks { 27 | deadline_t deadline; 28 | uint64_t send_period; 29 | 30 | // map 31 | model_map responses; 32 | 33 | // map 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "ziti/model_collections.h" 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #if _WIN32 32 | 33 | # if !defined(strncasecmp) 34 | # define strncasecmp _strnicmp 35 | # endif 36 | 37 | # if !defined(strcasecmp) 38 | # define strcasecmp _stricmp 39 | # endif 40 | 41 | # if !defined(MIN) 42 | # define MIN(a,b) ((a)<(b) ? (a) : (b)) 43 | # endif 44 | 45 | # if !defined(MAX) 46 | # define MAX(a,b) ((a) > (b) ? (a) : (b)) 47 | # endif 48 | 49 | typedef unsigned int uint; 50 | 51 | #endif 52 | 53 | #ifndef z_typeof 54 | #if defined(_MSC_VER) 55 | #define z_typeof(x) __typeof__(x) 56 | #else 57 | #define z_typeof(x) typeof(x) 58 | #endif 59 | #endif 60 | extern const char *ziti_get_build_version(int verbose); 61 | 62 | extern const char *ziti_git_branch(); 63 | 64 | extern const char *ziti_git_commit(); 65 | 66 | extern void hexDump(char *desc, void *addr, int len); 67 | 68 | void ziti_fmt_time(char *time_str, size_t time_str_len, uv_timeval64_t *tv); 69 | 70 | int lt_zero(int v); 71 | 72 | typedef const char *(*fmt_error_t)(int); 73 | 74 | typedef int *(*cond_error_t)(int); 75 | 76 | #if __GNUC__ 77 | #define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) 78 | #define THREAD_LOCAL __thread 79 | #elif _MSC_VER 80 | #define THREAD_LOCAL __declspec(thread) 81 | #define UNUSED(x) UNUSED_ ## x 82 | #else 83 | #define THREAD_LOCAL 84 | #define UNUSED(x) UNUSED_ ## x 85 | #endif 86 | 87 | #define TO_STRING(m) to_string_(m) 88 | #define to_string_(m) #m 89 | 90 | #define NEWP(var, type) type *var = calloc(1, sizeof(type)) 91 | #define VAL_OR_ELSE(v, def) ((v) != NULL ? (v) : (def)) 92 | #define FREE(v) do { if ((v) != NULL) { free((void*)(v)); (v) = NULL; } } while(0) 93 | #define FIELD_OR_ELSE(obj, field, def) ((obj) ? ((obj)->field) : (def)) 94 | #define FIELD_OR_NULL(obj, field) FIELD_OR_ELSE(obj, field, (z_typeof((obj)->field))0) 95 | 96 | #define FMT(ex) _##ex##_fmt 97 | #define COND(ex) _##ex##_cond 98 | #define ERR(ex) (_##ex##_error) 99 | #define ERLINE(ex) (_##ex##_line) 100 | #define ERFILE(ex) (_##ex##_file) 101 | #define ERLBL(ex) _##ex##_label 102 | 103 | #define PREPCF(ex, cond, fmt) int ERR(ex) = 0, ERLINE(ex) = 0; const char *_##ex##_op = "", *ERFILE(ex) = ""; \ 104 | fmt_error_t FMT(ex) = (fmt_error_t)(fmt); cond_error_t COND(ex) = (cond_error_t)cond 105 | 106 | #define PREPF(ex, fmt) PREPCF(ex, lt_zero, fmt) 107 | 108 | #define PREP(ex) PREPF(ex, strerror) 109 | 110 | #define TRY(ex, op) ERR(ex) = (op); do {\ 111 | if (COND(ex)(ERR(ex))) { ERFILE(ex) = __FILENAME__; ERLINE(ex) = __LINE__; _##ex##_op = #op; goto ERLBL(ex);}\ 112 | } while(0) 113 | 114 | #define CATCH(ex) { ERLBL(ex):\ 115 | if (COND(ex)(ERR(ex))) {\ 116 | ZITI_LOG(ERROR, "%s:%d - %s => %d (%s)", ERFILE(ex), ERLINE(ex), _##ex##_op, ERR(ex), FMT(ex)(ERR(ex)));\ 117 | }}\ 118 | for (int _##ex##_count = 0;COND(ex)(ERR(ex)) && _##ex##_count == 0; _##ex##_count++) 119 | 120 | #define line_idx(i, l) i ## l 121 | 122 | #define FOR_line(el, arr, LINE) int line_idx(idx,LINE); for ( \ 123 | line_idx(idx,LINE) = 0, (el) = (arr) ? (arr)[line_idx(idx,LINE)] : NULL; \ 124 | el != NULL; \ 125 | line_idx(idx,LINE)++, (el) = (arr)[line_idx(idx,LINE)] ) 126 | 127 | #define FOR(el, arr) FOR_line(el, arr, __LINE__) 128 | 129 | 130 | #define container_of(ptr, type, member) ((type *) ((char*)(ptr) - offsetof(type, member))) 131 | 132 | #define CLOSE_AND_NULL(h) do{ if (h) { \ 133 | if (!uv_is_closing((uv_handle_t*)(h))) uv_close((uv_handle_t*)(h), (uv_close_cb)free); \ 134 | (h) = NULL; \ 135 | }}while(0) 136 | 137 | #define CALL_CB(cb, ...) if ((cb) != NULL) (cb)(__VA_ARGS__) 138 | 139 | /** 140 | * Split string based on delimiters. 141 | * strings are appended to the provided list. Caller is responsible to freeing resulting strings - 142 | * possibly via `model_list_clear(result, free)` 143 | * @param str 144 | * @param delim 145 | * @param result 146 | * @return number of tokens 147 | */ 148 | extern size_t str_split(const char *str, const char *delim, model_list *result); 149 | 150 | int load_key_internal(tls_context *tls, tlsuv_private_key_t *key, const char *keystr); 151 | 152 | int gen_p11_key_internal(tls_context *tls, tlsuv_private_key_t *key, const char *keyuri); 153 | 154 | int load_file(const char *path, size_t pathlen, char **content, size_t *size); 155 | 156 | uint64_t next_backoff(int *count, int max, uint64_t base); 157 | 158 | #ifdef __cplusplus 159 | } 160 | #endif 161 | 162 | #endif //ZITI_UTILS_H 163 | -------------------------------------------------------------------------------- /includes/ziti/enroll.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // 6 | // You may obtain a copy of the License at 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ZITI_ENROLL_H 16 | #define ZITI_ENROLL_H 17 | 18 | #include 19 | #include "ziti_model.h" 20 | 21 | #include 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | 28 | typedef struct ziti_enroll_opts_s { 29 | const char *url; 30 | const char *token; 31 | const char *key; 32 | const char *cert; 33 | const char *name; 34 | bool use_keychain; // use keychain if generating new key 35 | } ziti_enroll_opts; 36 | 37 | /** 38 | * @brief Callback called after ziti_enroll() is complete. 39 | * 40 | * This callback is invoked on the conclusion of the ziti_enroll() function. The result of the 41 | * ziti_enroll() function may be an error condition so it is important to verify the provided 42 | * status code in this callback. 43 | * 44 | * This callback also receives a Ziti identity json salvo if the enrollment was successful. 45 | * This identity should be persisted into a file, and used in subsequent calls to ziti_load_config(). 46 | * 47 | * @param cfg identity config object, NULL if enrollment fails for any reason 48 | * @param status enrollment success or error code 49 | * @param err_message description of error, or NULL if enrollment succeeded 50 | * @param enroll_ctx additional context to be passed into #ziti_enroll_cb callback 51 | * 52 | * @see ziti_enroll(), ZITI_ERRORS 53 | */ 54 | typedef void (*ziti_enroll_cb)(const ziti_config *cfg, int status, const char *err_message, void *enroll_ctx); 55 | 56 | /** 57 | * @brief Performs a Ziti enrollment. 58 | * 59 | * This function is used to enroll a Ziti Edge identity. 60 | * [enroll_cb] is called once enrollment process is complete unless the error is returned. 61 | * 62 | * @param opts enrollment options 63 | * @param loop event loop 64 | * @param enroll_cb callback to be called when enrollment is complete 65 | * @param enroll_ctx additional context to be passed into #ziti_enroll_cb callback 66 | 67 | * @return #ZITI_OK or corresponding #ZITI_ERRORS 68 | */ 69 | ZITI_FUNC extern int ziti_enroll(const ziti_enroll_opts *opts, uv_loop_t *loop, 70 | ziti_enroll_cb enroll_cb, void *enroll_ctx); 71 | 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif //ENROLL_H 78 | -------------------------------------------------------------------------------- /includes/ziti/enums.h: -------------------------------------------------------------------------------- 1 | #ifndef ZITI_ENUM_H 2 | #define ZITI_ENUM_H 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | extern const struct ziti_terminator_precedence_s { 8 | const uint8_t DEFAULT; 9 | const uint8_t REQUIRED; 10 | const uint8_t FAILED; 11 | } PRECEDENCE; 12 | /** 13 | * @brief Represents the type and rate of metric to capture 14 | * 15 | * Each enum contains the rate type and the expected duration metrics will be gathered 16 | * 17 | * CMA - continually moving average 18 | * EWMA - exponentially weighted moving average 19 | * MMA - modified moving average 20 | */ 21 | typedef enum { 22 | EWMA_1m, 23 | EWMA_5m, 24 | EWMA_15m, 25 | MMA_1m, 26 | CMA_1m, 27 | EWMA_5s, 28 | INSTANT, 29 | } rate_type; 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | #endif /* ZITI_ENUM_H */ 35 | -------------------------------------------------------------------------------- /includes/ziti/externs.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef ZITI_SDK_EXTERNS_H 17 | #define ZITI_SDK_EXTERNS_H 18 | 19 | #if defined(BUILDING_ZITI_SHARED) && defined(USING_ZITI_SHARED) 20 | #error "Define either BUILDING_ZITI_SHARED or USING_ZITI_SHARED, not both." 21 | #endif 22 | 23 | #ifndef ZITI_FUNC 24 | 25 | #ifdef _WIN32 26 | # define ZITI_DEPRECATED(msg) __declspec(deprecated(msg)) 27 | # if defined(BUILDING_ZITI_SHARED) 28 | # define ZITI_FUNC __declspec(dllexport) 29 | # elif defined(USING_ZITI_SHARED) 30 | # define ZITI_FUNC __declspec(dllimport) 31 | # else 32 | # define ZITI_FUNC /* nothing */ 33 | # endif 34 | #elif __GNUC__ >= 4 35 | # define ZITI_FUNC __attribute__((visibility("default"))) 36 | # define ZITI_DEPRECATED(msg) __attribute((deprecated((msg)))) 37 | #else 38 | # define ZITI_FUNC /* nothing */ 39 | # define ZITI_DEPRECATED(msg) 40 | #endif 41 | 42 | #endif 43 | 44 | #endif //ZITI_SDK_EXTERNS_H 45 | -------------------------------------------------------------------------------- /includes/ziti/model_collections.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef ZITI_SDK_MODEL_COLLECTIONS_H 17 | #define ZITI_SDK_MODEL_COLLECTIONS_H 18 | 19 | #include "externs.h" 20 | 21 | #include 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | typedef void *model_map_iter; 28 | 29 | typedef struct model_map { 30 | struct model_impl_s *impl; 31 | } model_map; 32 | 33 | ZITI_FUNC size_t model_map_size(const model_map *map); 34 | 35 | ZITI_FUNC void *model_map_set_key(model_map *m, const void *key, size_t key_len, const void *val); 36 | 37 | ZITI_FUNC void *model_map_set(model_map *map, const char *key, const void *val); 38 | 39 | ZITI_FUNC void *model_map_setl(model_map *map, long key, const void *val); 40 | 41 | ZITI_FUNC void *model_map_get_key(const model_map *map, const void *key, size_t key_len); 42 | 43 | ZITI_FUNC void *model_map_get(const model_map *map, const char *key); 44 | 45 | ZITI_FUNC void *model_map_getl(const model_map *map, long key); 46 | 47 | ZITI_FUNC void *model_map_remove_key(model_map *map, const void *key, size_t key_len); 48 | 49 | ZITI_FUNC void *model_map_remove(model_map *map, const char *key); 50 | 51 | ZITI_FUNC void *model_map_removel(model_map *map, long key); 52 | 53 | ZITI_FUNC void model_map_clear(model_map *map, void (*val_free_func)(void *)); 54 | 55 | ZITI_FUNC model_map_iter model_map_iterator(const model_map *map); 56 | 57 | ZITI_FUNC const char *model_map_it_key(model_map_iter it); 58 | 59 | ZITI_FUNC const void *model_map_it_key_s(model_map_iter it, size_t *key_len); 60 | 61 | ZITI_FUNC long model_map_it_lkey(model_map_iter it); 62 | 63 | ZITI_FUNC void *model_map_it_value(model_map_iter it); 64 | 65 | ZITI_FUNC model_map_iter model_map_it_next(model_map_iter it); 66 | 67 | ZITI_FUNC model_map_iter model_map_it_remove(model_map_iter it); 68 | 69 | #define line_var(v) var(v,__LINE__) 70 | #define var(x, y) _var(x,y) 71 | #define _var(x,y) x ## y 72 | 73 | #ifdef __cplusplus 74 | #define z_typeof(v) decltype(v) 75 | #else 76 | #define z_typeof(v) __typeof__(v) 77 | #endif 78 | 79 | #define MODEL_MAP_FOREACH(k, v, map) \ 80 | model_map_iter line_var(e);\ 81 | for (line_var(e) = model_map_iterator(map), \ 82 | (k) = (z_typeof(k))(uintptr_t)model_map_it_key(line_var(e)), \ 83 | (v) = (z_typeof(v))model_map_it_value(line_var(e)), \ 84 | line_var(e) = model_map_it_next(line_var(e)); \ 85 | (k) != (z_typeof(k))(uintptr_t)NULL; \ 86 | (k) = (z_typeof(k))(uintptr_t)model_map_it_key(line_var(e)), \ 87 | (v) = (z_typeof(v))model_map_it_value(line_var(e)), \ 88 | line_var(e) = model_map_it_next(line_var(e))\ 89 | ) 90 | 91 | #define MODEL_MAP_FOR(it, m)\ 92 | model_map_iter line_var(itn) = model_map_it_next(model_map_iterator(&(m)));\ 93 | for(model_map_iter it = model_map_iterator(&(m)); \ 94 | (it) != NULL; \ 95 | (it) = line_var(itn), line_var(itn) = model_map_it_next(line_var(itn))) 96 | 97 | typedef struct model_list_s { 98 | struct model_list_impl_s *impl; 99 | } model_list; 100 | 101 | typedef void *model_list_iter; 102 | 103 | ZITI_FUNC size_t model_list_size(const model_list *l); 104 | 105 | // insert at the head 106 | ZITI_FUNC void model_list_push(model_list *l, const void *el); 107 | 108 | // append to the end 109 | ZITI_FUNC void model_list_append(model_list *l, const void *el); 110 | 111 | // remove from the head 112 | ZITI_FUNC void *model_list_pop(model_list *l); 113 | 114 | ZITI_FUNC const void *model_list_head(const model_list *l); 115 | 116 | ZITI_FUNC void model_list_clear(model_list *l, void (*clear_f)(void *)); 117 | 118 | ZITI_FUNC model_list_iter model_list_iterator(model_list *l); 119 | 120 | ZITI_FUNC model_list_iter model_list_it_next(model_list_iter it); 121 | 122 | ZITI_FUNC model_list_iter model_list_it_remove(model_list_iter it); 123 | 124 | ZITI_FUNC const void *model_list_it_element(model_list_iter it); 125 | 126 | #define MODEL_LIST_FOR(it, m)\ 127 | model_list_iter line_var(itn) = model_list_it_next(model_list_iterator(&(m))); \ 128 | for(model_list_iter it = model_list_iterator(&(m)); (it) != NULL; \ 129 | (it) = line_var(itn), line_var(itn) = model_list_it_next(line_var(itn))) 130 | 131 | 132 | #define MODEL_LIST_FOREACH(el, list) \ 133 | model_list_iter line_var(it); \ 134 | for(line_var(it) = model_list_iterator((model_list*)&(list)); \ 135 | line_var(it) != NULL && ((el) = (z_typeof(el))model_list_it_element(line_var(it)), true); \ 136 | line_var(it) = model_list_it_next(line_var(it))) 137 | 138 | #ifdef __cplusplus 139 | } 140 | #endif 141 | 142 | #endif //ZITI_SDK_MODEL_COLLECTIONS_H 143 | -------------------------------------------------------------------------------- /includes/ziti/types.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef ZITI_SDK_TYPES_H 17 | #define ZITI_SDK_TYPES_H 18 | 19 | #include 20 | #include 21 | 22 | #include "externs.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /** Nanosecond precision time duration, like Golang's time.Duration */ 29 | typedef int64_t duration; 30 | 31 | #define DURATION_MILLISECONDS(d) ((d)/MILLISECOND) 32 | 33 | #define MICROSECOND ((int64_t)1000) 34 | #define MILLISECOND (1000 * MICROSECOND) 35 | #define SECOND (1000 * MILLISECOND) 36 | #define MINUTE (60 * SECOND) 37 | #define HOUR (60 * MINUTE) 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif //ZITI_SDK_TYPES_H 44 | -------------------------------------------------------------------------------- /includes/ziti/ziti_buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2021 NetFoundry Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef ZITI_SDK_ZITI_BUFFER_H 18 | #define ZITI_SDK_ZITI_BUFFER_H 19 | 20 | #include 21 | #include "externs.h" 22 | #include "ziti_log.h" 23 | 24 | #if !defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined) 25 | #if _WIN32 26 | typedef intptr_t ssize_t; 27 | #define __DEFINED_ssize_t 28 | #define __ssize_t_defined 29 | #else 30 | #include 31 | #endif 32 | #endif 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | /** 39 | * Growing string buffer. 40 | * 41 | * string_buf allocates memory internally as needed unless it was created with [new_fixed_string_buf()] 42 | */ 43 | typedef struct string_buf_s string_buf_t; 44 | 45 | /** 46 | * Create new string buffer. 47 | * @return new buffer instance 48 | */ 49 | ZITI_FUNC string_buf_t *new_string_buf(); 50 | 51 | /** 52 | * Create buffer using passed in memory for output. No new memory will be allocated. 53 | * @param outbuf 54 | * @param max 55 | * @return new buffer instance 56 | */ 57 | ZITI_FUNC string_buf_t *new_fixed_string_buf(char *outbuf, size_t max); 58 | 59 | /** 60 | * Deallocate all memory associated with the given string buffer. 61 | * 62 | * The passed in pointer is not valid after the function invocation. 63 | * @param wb 64 | */ 65 | ZITI_FUNC void delete_string_buf(string_buf_t *wb); 66 | 67 | /** 68 | * Append `\0` terminated string to the buffer. 69 | * @param wb string buffer 70 | * @param str string 71 | * @return 0 on success, -1 if `wb` is a fixed buffer and appending would go over its limit. 72 | */ 73 | ZITI_FUNC int string_buf_append(string_buf_t *wb, const char *str); 74 | 75 | /** 76 | * @brief Appends [str] to [wb] converting to urlsafe encoding. 77 | */ 78 | ZITI_FUNC int string_buf_append_urlsafe(string_buf_t *wb, const char *str); 79 | 80 | /** 81 | * Append `len` bytes from `str` to the string buffer. 82 | * @param wb string buffer 83 | * @param str string 84 | * @param len number of bytes to append 85 | * @return 0 on success, -1 if `wb` is a fixed buffer and appending would go over its limit. 86 | */ 87 | ZITI_FUNC int string_buf_appendn(string_buf_t *wb, const char *str, size_t len); 88 | 89 | /** 90 | * Append one byte to the string buffer. 91 | * @param wb string buffer 92 | * @param c byte to append 93 | * @return 0 on success, -1 if `wb` is a fixed buffer and appending would go over its limit. 94 | */ 95 | ZITI_FUNC int string_buf_append_byte(string_buf_t *wb, char c); 96 | 97 | /** 98 | * printf style append operation. 99 | * @param wb string buffer 100 | * @param fmt printf-style format string 101 | * @param ... arguments to the `fmt` argument 102 | * @return 0 on success, -1 if `wb` is a fixed buffer and appending would go over its limit. 103 | */ 104 | ZITI_FUNC int string_buf_fmt(string_buf_t *wb, FORMAT_STRING(const char *fmt), ...) ziti_printf_args(2, 3); 105 | 106 | /** 107 | * number of bytes written to the string buffer so far 108 | * @param wb string buffer 109 | * @return number of bytes in the buffer 110 | */ 111 | ZITI_FUNC size_t string_buf_size(string_buf_t *wb); 112 | 113 | /** 114 | * Allocate string big enough to hold the contents of the buffer with '\0` at the end 115 | * and copy contents into the result. 116 | * String buffer is cleared after operation is complete. 117 | * @param wb string buffer 118 | * @param outlen size of the output not including final `\0' terminator 119 | * @return allocated string filled with buffer content 120 | */ 121 | ZITI_FUNC char *string_buf_to_string(string_buf_t *wb, size_t *outlen); 122 | 123 | 124 | #ifdef __cplusplus 125 | } 126 | #endif 127 | #endif //ZITI_SDK_ZITI_BUFFER_H 128 | -------------------------------------------------------------------------------- /includes/ziti/ziti_events.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef ZITI_SDK_ZITI_EVENTS_H 17 | #define ZITI_SDK_ZITI_EVENTS_H 18 | 19 | #include "ziti_model.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | 26 | /** 27 | * \brief Ziti Event Types. 28 | * 29 | * \see ziti_event_t 30 | * \see ziti_options.events 31 | */ 32 | typedef enum { 33 | ZitiContextEvent = 1, 34 | ZitiRouterEvent = 1 << 1, 35 | ZitiServiceEvent = 1 << 2, 36 | ZitiAuthEvent = 1 << 3, 37 | ZitiConfigEvent = 1 << 4, 38 | } ziti_event_type; 39 | 40 | /** 41 | * \brief Ziti Edge Router status. 42 | * 43 | * \see ziti_router_event 44 | */ 45 | typedef enum { 46 | EdgeRouterAdded, 47 | EdgeRouterConnected, 48 | EdgeRouterDisconnected, 49 | EdgeRouterRemoved, 50 | EdgeRouterUnavailable, 51 | } ziti_router_status; 52 | 53 | /** 54 | * \brief Context event. 55 | * 56 | * Informational event to notify app about issues communicating with Ziti controller. 57 | */ 58 | struct ziti_context_event { 59 | int ctrl_status; 60 | const char *err; 61 | size_t ctrl_count; 62 | struct ctrl_detail_s *ctrl_details; 63 | }; 64 | 65 | struct ctrl_detail_s { 66 | const char *id; 67 | const char *url; 68 | bool online; 69 | bool active; 70 | }; 71 | 72 | struct ziti_config_event { 73 | const char *identity_name; 74 | const ziti_config *config; 75 | }; 76 | /** 77 | * \brief Edge Router Event. 78 | * 79 | * Informational event to notify app about status of edge router connections. 80 | */ 81 | struct ziti_router_event { 82 | ziti_router_status status; 83 | const char *name; 84 | const char *address; 85 | const char *version; 86 | }; 87 | 88 | /** 89 | * \brief Ziti Service Status event. 90 | * 91 | * Event notifying app about service access changes. 92 | * Each field is a NULL-terminated array of `ziti_service*`. 93 | * 94 | * \see ziti_service 95 | */ 96 | struct ziti_service_event { 97 | 98 | /** Services no longer available in the Ziti Context */ 99 | ziti_service_array removed; 100 | 101 | /** Modified services -- name, permissions, configs, etc */ 102 | ziti_service_array changed; 103 | 104 | /** Newly available services in the Ziti Context */ 105 | ziti_service_array added; 106 | }; 107 | 108 | enum ziti_auth_action { 109 | ziti_auth_cannot_continue, 110 | ziti_auth_prompt_totp, 111 | ziti_auth_prompt_pin, 112 | ziti_auth_select_external, 113 | ziti_auth_login_external 114 | }; 115 | /** 116 | * \brief Event notifying the app that additional action is required to continue authentication or normal operation. 117 | * 118 | * The app may request that information from the user and then submit it 119 | * to ziti_context. 120 | * 121 | * the following authentication actions are supported: 122 | * 123 | * [ziti_auth_prompt_totp] - request for MFA code, application must call [ziti_mfa_auth()] when it acquires TOTP code 124 | * 125 | * [ziti_auth_login_external] - request for that app to launch external program (web browser) 126 | * that can authenticate with provided url ([detail] field) 127 | * 128 | * TODO: future 129 | * [ziti_auth_prompt_pin] - request for HSM/TPM key pin, application must call [TBD method] when it acquires PIN 130 | */ 131 | struct ziti_auth_event { 132 | enum ziti_auth_action action; 133 | const char *type; 134 | const char *detail; 135 | ziti_jwt_signer_array providers; 136 | }; 137 | 138 | /** 139 | * \brief Object passed to `ziti_options.event_cb`. 140 | * 141 | * \note event data becomes invalid as soon as callback returns. 142 | * App must copy data if it's needed for further processing. 143 | */ 144 | typedef struct ziti_event_s { 145 | ziti_event_type type; 146 | union { 147 | struct ziti_context_event ctx; 148 | struct ziti_router_event router; 149 | struct ziti_service_event service; 150 | struct ziti_auth_event auth; 151 | struct ziti_config_event cfg; 152 | }; 153 | } ziti_event_t; 154 | 155 | #ifdef __cplusplus 156 | } 157 | #endif 158 | 159 | #endif //ZITI_SDK_ZITI_EVENTS_H 160 | -------------------------------------------------------------------------------- /includes/ziti/ziti_log.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // 16 | // Created by eugene on 4/15/2020. 17 | // 18 | 19 | #ifndef ZITI_SDK_ZITI_LOG_H 20 | #define ZITI_SDK_ZITI_LOG_H 21 | 22 | #include 23 | 24 | #include "externs.h" 25 | 26 | #ifdef SOURCE_PATH_SIZE 27 | #define __FILENAME__ (&__FILE__[SOURCE_PATH_SIZE]) 28 | #else 29 | #define __FILENAME__ __FILE__ 30 | #endif 31 | 32 | #ifndef ZITI_LOG_PREFIX 33 | #define ZITI_LOG_PREFIX 34 | #endif 35 | 36 | #define _to_str(x) #x 37 | #define to_str(x) _to_str(x) 38 | // for windows compilation NOGDI needs to be set: 39 | // right click ziti -> properties -> C/C++ -> Preprocessor - ensure NOGDI is in the list of preprocessor definitions 40 | // if it's not present check the CMakeLists.txt file 41 | #define DEBUG_LEVELS(XX) \ 42 | XX(NONE) \ 43 | XX(ERROR) /*WINDOWS - see comment above wrt NOGDI*/ \ 44 | XX(WARN) \ 45 | XX(INFO) \ 46 | XX(DEBUG) \ 47 | XX(VERBOSE) \ 48 | XX(TRACE) 49 | 50 | enum DebugLevel { 51 | #define _level(n) n, 52 | DEBUG_LEVELS(_level) 53 | #undef _level 54 | }; 55 | 56 | #ifndef ZITI_LOG_MODULE 57 | #define ZITI_LOG_MODULE NULL 58 | #endif 59 | 60 | #define ZITI_LOG(level, fmt, ...) do { \ 61 | if (level <= ziti_log_level(ZITI_LOG_MODULE, __FILENAME__)) { ziti_logger(level, ZITI_LOG_MODULE, __FILENAME__, __LINE__, __func__, fmt, ##__VA_ARGS__); }\ 62 | } while(0) 63 | 64 | #ifdef __cplusplus 65 | extern "C" { 66 | #endif 67 | 68 | #if _MSC_VER >= 1400 69 | # include 70 | # if _MSC_VER > 1400 71 | # define FORMAT_STRING(p) _Printf_format_string_ p 72 | # else 73 | # define FORMAT_STRING(p) __format_string p 74 | # endif /* FORMAT_STRING */ 75 | #else 76 | # define FORMAT_STRING(p) p 77 | #endif /* _MSC_VER */ 78 | 79 | #ifdef __GNUC__ 80 | #define ziti_printf_args(a, b) __attribute__((__format__ (printf,a,b))) 81 | #else 82 | #define ziti_printf_args(a,b) 83 | #endif 84 | 85 | #define ZITI_LOG_DEFAULT_LEVEL (-1) 86 | 87 | typedef void (*log_writer)(int level, const char *loc, const char *msg, size_t msglen); 88 | 89 | ZITI_FUNC extern void 90 | ziti_logger(int level, const char *module, const char *file, unsigned int line, const char *func, 91 | FORMAT_STRING(const char *fmt), ...) 92 | ziti_printf_args(6, 7); 93 | 94 | // call once 95 | // use ZITI_LOG_DEFAULT_LEVEL to use default(INFO)/ZITI_LOG env var 96 | // pass logger = NULL to use default output 97 | ZITI_FUNC extern void ziti_log_init(uv_loop_t *loop, int level, log_writer logger); 98 | 99 | ZITI_FUNC extern void ziti_log_set_logger(log_writer logger); 100 | 101 | // use ZITI_LOG_DEFAULT_LEVEL to reset to default(INFO) or ZITI_LOG env var 102 | ZITI_FUNC extern void ziti_log_set_level(int level, const char *marker); 103 | 104 | // don't use directly 105 | ZITI_FUNC extern int ziti_log_level(const char *module, const char *file); 106 | 107 | ZITI_FUNC extern void ziti_log_set_level_by_label(const char *log_level); 108 | 109 | ZITI_FUNC extern const char *ziti_log_level_label(); 110 | 111 | /** 112 | * can be used to turn on logging of uv-mbed library and send log messages into the ziti_log 113 | * Usage: uv_mbed_set_debug(level, tlsuv_logger); 114 | */ 115 | ZITI_FUNC void tlsuv_logger(int level, const char *file, unsigned int line, const char *msg); 116 | 117 | #ifdef __cplusplus 118 | } 119 | #endif 120 | #endif //ZITI_SDK_ZITI_LOG_H 121 | -------------------------------------------------------------------------------- /includes/ziti/ziti_src.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @file ziti_src.h 17 | * @brief header file for ziti_src, which can be used as a source link in um_http requests 18 | * 19 | * @see programs/sample_http_link.c 20 | */ 21 | 22 | #ifndef ZITI_SDK_ZITI_SRC_H 23 | #define ZITI_SDK_ZITI_SRC_H 24 | 25 | #include 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /** 33 | * Initialize a `um_http_src_t` handle 34 | * 35 | * @param l the uv loop 36 | * @param zl the um_http_src_t to initialize 37 | * @param svc the name of the service to be dialed 38 | * @param ztx the initialized ziti_context 39 | */ 40 | int ziti_src_init(uv_loop_t *l, tlsuv_src_t *zl, const char *svc, ziti_context ztx); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif //ZITI_SDK_ZITI_SRC_H -------------------------------------------------------------------------------- /library/authenticators.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2020 NetFoundry, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "authenticators.h" 18 | 19 | typedef struct authenticator_ctx_s { 20 | ziti_context ztx; 21 | ziti_extend_cert_authenticator_cb extend_cb; 22 | ziti_verify_extend_cert_authenticator_cb verify_cb; 23 | void* ctx; 24 | char* csr_pem; 25 | char* authenticator_id; 26 | } authenticator_ctx; 27 | 28 | const char* CAN_NOT_UPDATE_AUTHENTICATOR = "CAN_NOT_UPDATE_AUTHENTICATOR"; 29 | const char* UNAUTHORIZED = "UNAUTHORIZED"; 30 | 31 | static void extend_cb(ziti_extend_cert_authenticator_resp* resp, const ziti_error* err, void* ctx) { 32 | authenticator_ctx* wrapped_ctx = (authenticator_ctx*)ctx; 33 | ziti_context ztx = wrapped_ctx->ztx; 34 | 35 | if(err){ 36 | ZTX_LOG(ERROR, "error response returned when attempting to extend authenticator: %d %s: %s, calling cb", 37 | (int)err->http_code, err->code, err->message); 38 | if(err->http_code == 404) { 39 | wrapped_ctx->extend_cb(ztx, NULL, ZITI_NOT_FOUND, wrapped_ctx->ctx); 40 | } else if(strncmp(err->code, CAN_NOT_UPDATE_AUTHENTICATOR, strlen(CAN_NOT_UPDATE_AUTHENTICATOR)) == 0){ 41 | wrapped_ctx->extend_cb(ztx, NULL, ZITI_INVALID_AUTHENTICATOR_TYPE, wrapped_ctx->ctx); 42 | } else if (strncmp(err->code, UNAUTHORIZED, strlen(UNAUTHORIZED)) == 0){ 43 | wrapped_ctx->extend_cb(ztx, NULL, ZITI_INVALID_AUTHENTICATOR_CERT, wrapped_ctx->ctx); 44 | } else { 45 | wrapped_ctx->extend_cb(ztx, NULL, ZITI_WTF, wrapped_ctx->ctx); 46 | } 47 | 48 | return; 49 | } else { 50 | ZTX_LOG(INFO, "certificate authenticator extension occurred for id: %s, calling cb", wrapped_ctx->authenticator_id); 51 | wrapped_ctx->extend_cb(ztx, resp->client_cert_pem, ZITI_OK, wrapped_ctx->ctx); 52 | } 53 | 54 | FREE(wrapped_ctx->authenticator_id); 55 | FREE(wrapped_ctx->csr_pem); 56 | FREE(wrapped_ctx); 57 | 58 | free_ziti_extend_cert_authenticator_resp(resp); 59 | } 60 | 61 | static void verify_cb(void* empty, const ziti_error* err, void* ctx){ 62 | authenticator_ctx* wrapped_ctx = (authenticator_ctx*)ctx; 63 | ziti_context ztx = wrapped_ctx->ztx; 64 | 65 | if(err) { 66 | ZTX_LOG(ERROR, "error response returned when attempting to verify extended authenticator: %d %s: %s", 67 | (int)err->http_code, err->code, err->message); 68 | if(err->http_code == 404) { 69 | wrapped_ctx->verify_cb(ztx, ZITI_NOT_FOUND, wrapped_ctx->ctx); 70 | } else if(strncmp(err->code, CAN_NOT_UPDATE_AUTHENTICATOR, strlen(CAN_NOT_UPDATE_AUTHENTICATOR)) == 0){ 71 | wrapped_ctx->verify_cb(ztx, ZITI_INVALID_AUTHENTICATOR_TYPE, wrapped_ctx->ctx); 72 | } else if (strncmp(err->code, UNAUTHORIZED, strlen(UNAUTHORIZED)) == 0){ 73 | wrapped_ctx->verify_cb(ztx, ZITI_INVALID_AUTHENTICATOR_CERT, wrapped_ctx->ctx); 74 | } else { 75 | wrapped_ctx->verify_cb(ztx, ZITI_WTF, wrapped_ctx->ctx); 76 | } 77 | } else { 78 | ZTX_LOG(INFO, "certificate authenticator extension verified successfully for id: %s, raising event", wrapped_ctx->authenticator_id); 79 | wrapped_ctx->verify_cb(ztx, ZITI_OK, wrapped_ctx->ctx); 80 | } 81 | 82 | FREE(wrapped_ctx->authenticator_id); 83 | FREE(wrapped_ctx); 84 | } 85 | 86 | int ziti_extend_cert_authenticator(ziti_context ztx, const char *csr_pem, ziti_extend_cert_authenticator_cb cb, void *ctx) { 87 | // TODO this relies on api_session.authenticator_id 88 | // need to normalize it wrt HA when api_session is not available 89 | ZITI_LOG(ERROR, "not implemented!!!"); 90 | 91 | // ZTX_LOG(INFO, "attempting to extend certificate authenticator id: %s", ztx->api_session->authenticator_id); 92 | // NEWP(wrapped_ctx, authenticator_ctx); 93 | // wrapped_ctx->ztx = ztx; 94 | // wrapped_ctx->ctx = ctx; 95 | // wrapped_ctx->extend_cb = cb; 96 | // wrapped_ctx->authenticator_id = strdup(ztx->api_session->authenticator_id); 97 | // wrapped_ctx->csr_pem = strdup(csr_pem); 98 | 99 | return ZITI_WTF; 100 | } 101 | 102 | int ziti_verify_extend_cert_authenticator(ziti_context ztx, const char *new_cert, ziti_verify_extend_cert_authenticator_cb cb, void *ctx) { 103 | // TODO this relies on api_session.authenticator_id 104 | // need to normalize it wrt HA when api_session is not available 105 | ZITI_LOG(ERROR, "not implemented!!!"); 106 | return ZITI_WTF; 107 | 108 | // if(ztx->api_session == NULL){ 109 | // return ZITI_INVALID_STATE; 110 | // } 111 | // 112 | // ZTX_LOG(INFO, "attempting to verify certificate authenticator %s", ztx->api_session->authenticator_id); 113 | // 114 | // NEWP(wrapped_ctx, authenticator_ctx); 115 | // wrapped_ctx->ztx = ztx; 116 | // wrapped_ctx->ctx = ctx; 117 | // wrapped_ctx->verify_cb = cb; 118 | // wrapped_ctx->authenticator_id = strdup(ztx->api_session->authenticator_id); 119 | // 120 | // ziti_ctrl_verify_extend_cert_authenticator(&ztx->controller, wrapped_ctx->authenticator_id, new_cert, verify_cb, wrapped_ctx); 121 | // 122 | // return ZITI_OK; 123 | } -------------------------------------------------------------------------------- /library/config.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "zt_internal.h" 20 | 21 | const char* APP_ID = NULL; 22 | const char* APP_VERSION = NULL; 23 | 24 | void ziti_set_app_info(const char *app_id, const char *app_version) { 25 | FREE(APP_ID); 26 | FREE(APP_VERSION); 27 | APP_ID = strdup(app_id); 28 | APP_VERSION = strdup(app_version); 29 | } 30 | 31 | static int load_config_file(const char *filename, ziti_config *cfg) { 32 | size_t config_len = 0; 33 | char *config = NULL; 34 | int rc = load_file(filename, 0, &config, &config_len); 35 | 36 | if (rc != 0) { 37 | ZITI_LOG(ERROR, "%s - %s", filename, uv_strerror(rc)); 38 | return ZITI_CONFIG_NOT_FOUND; 39 | } 40 | 41 | if (parse_ziti_config(cfg, config, config_len) < 0) { 42 | free(config); 43 | return ZITI_INVALID_CONFIG; 44 | } 45 | cfg->cfg_source = strdup(filename); 46 | free(config); 47 | return ZITI_OK; 48 | } 49 | 50 | int ziti_load_config(ziti_config *cfg, const char *cfgstr) { 51 | if (!cfgstr) { 52 | return ZITI_INVALID_CONFIG; 53 | } 54 | bool seems_like_json = false; 55 | const char *c = cfgstr; 56 | while (*c && isspace((unsigned char)*c)) { 57 | c++; 58 | } 59 | if (*c == '{') { 60 | seems_like_json = true; 61 | } 62 | 63 | memset(cfg, 0, sizeof(*cfg)); 64 | int rc; 65 | if (seems_like_json) { 66 | rc = parse_ziti_config(cfg, cfgstr, strlen(cfgstr)); 67 | 68 | if (rc < 0) { 69 | ZITI_LOG(DEBUG, "trying to load config from file[%s]", cfgstr); 70 | rc = load_config_file(cfgstr, cfg); 71 | } 72 | } else { 73 | rc = load_config_file(cfgstr, cfg); 74 | } 75 | 76 | if (rc < 0) { 77 | return rc; 78 | } 79 | 80 | if (model_list_size(&cfg->controllers) == 0 && cfg->controller_url == NULL) { 81 | return ZITI_INVALID_CONFIG; 82 | } 83 | 84 | return ZITI_OK; 85 | } 86 | -------------------------------------------------------------------------------- /library/crypto.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include "zt_internal.h" 17 | 18 | int init_key_pair(struct key_pair *kp) { 19 | return crypto_kx_keypair(kp->pk, kp->sk); 20 | } 21 | 22 | int init_crypto(struct key_exchange *key_ex, struct key_pair *kp, const uint8_t *peer_key, bool server) { 23 | free(key_ex->rx); 24 | free(key_ex->tx); 25 | 26 | key_ex->rx = calloc(1, crypto_secretstream_xchacha20poly1305_keybytes()); 27 | key_ex->tx = calloc(1, crypto_secretstream_xchacha20poly1305_keybytes()); 28 | if (server) { 29 | return crypto_kx_server_session_keys(key_ex->rx, key_ex->tx, kp->pk, kp->sk, peer_key); 30 | } else { 31 | return crypto_kx_client_session_keys(key_ex->rx, key_ex->tx, kp->pk, kp->sk, peer_key); 32 | } 33 | } 34 | 35 | void free_key_exchange(struct key_exchange *key_ex) { 36 | FREE(key_ex->rx); 37 | FREE(key_ex->tx); 38 | } -------------------------------------------------------------------------------- /library/edge_protocol.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // 6 | // You may obtain a copy of the License at 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "edge_protocol.h" 16 | #include 17 | #include 18 | 19 | const struct ziti_terminator_precedence_s PRECEDENCE = { 20 | .DEFAULT = ZITI__EDGE_CLIENT__PB__PRECEDENCE_VALUE__Default, 21 | .REQUIRED = ZITI__EDGE_CLIENT__PB__PRECEDENCE_VALUE__Required, 22 | .FAILED = ZITI__EDGE_CLIENT__PB__PRECEDENCE_VALUE__Failed, 23 | }; 24 | 25 | const char* content_type_id(enum content_type ct) { 26 | const ProtobufCEnumValue *val = protobuf_c_enum_descriptor_get_value( 27 | &ziti__edge_client__pb__content_type__descriptor, ct); 28 | return val ? val->name : ""; 29 | } -------------------------------------------------------------------------------- /library/edge_protocol.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2024. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // 6 | // You may obtain a copy of the License at 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef ZITI_SDK_EDGE_PROTOCOL_H 17 | #define ZITI_SDK_EDGE_PROTOCOL_H 18 | 19 | #include 20 | #include "proto/edge_client.pb-c.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | enum content_type { 27 | 28 | ContentTypeHelloType = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__Hello, 29 | ContentTypePingType = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__Ping, 30 | ContentTypeResultType = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__Result, 31 | ContentTypeLatencyType = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__Latency, 32 | 33 | ContentTypeConnect = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__ConnectType, 34 | ContentTypeStateConnected = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__StateConnectedType, 35 | ContentTypeStateClosed = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__StateClosedType, 36 | ContentTypeData = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__DataType, 37 | ContentTypeDial = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__DialType, 38 | ContentTypeDialSuccess = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__DialSuccessType, 39 | ContentTypeDialFailed = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__DialFailedType, 40 | ContentTypeBind = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__BindType, 41 | ContentTypeUnbind = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__UnbindType, 42 | 43 | ContentTypeUpdateToken = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__UpdateTokenType, 44 | ContentTypeUpdateTokenSuccess = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__UpdateTokenSuccessType, 45 | ContentTypeUpdateTokenFailure = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__UpdateTokenFailureType, 46 | 47 | ContentTypeConnInspectRequest = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__ConnInspectRequest, 48 | ContentTypeConnInspectResponse = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__ConnInspectResponse, 49 | ContentTypeBindSuccess = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__BindSuccess, 50 | 51 | ContentTypePostureResponse = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__PostureResponseType, 52 | ContentTypePostureResponseSuccess = ZITI__EDGE_CLIENT__PB__CONTENT_TYPE__PostureResponseSuccessType, 53 | }; 54 | 55 | extern const char* content_type_id(enum content_type ct); 56 | 57 | enum header_id { 58 | ReplyForHeader = 1, 59 | ResultSuccessHeader = 2, 60 | HelloVersionHeader = 4, 61 | 62 | LatencyProbeTime = 128, 63 | UUIDHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__UUID, 64 | 65 | ConnIdHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__ConnId, 66 | SeqHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__Seq, 67 | SessionTokenHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__SessionToken, 68 | PublicKeyHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__PublicKey, 69 | CostHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__Cost, 70 | PrecedenceHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__Precedence, 71 | TerminatorIdentityHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__TerminatorIdentity, 72 | TerminatorIdentitySecretHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__TerminatorIdentitySecret, 73 | CallerIdHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__CallerId, 74 | CryptoMethodHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__CryptoMethod, 75 | FlagsHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__Flags, 76 | AppDataHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__AppData, 77 | RouterProvidedConnId = ZITI__EDGE_CLIENT__PB__HEADER_ID__RouterProvidedConnId, 78 | ErrorCodeHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__ErrorCode, 79 | ListenerId = ZITI__EDGE_CLIENT__PB__HEADER_ID__ListenerId, 80 | ConnTypeHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__ConnType, 81 | SupportsInspectHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__SupportsInspect, 82 | SupportsBindSuccessHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__SupportsBindSuccess, 83 | ConnectionMarkerHeader = ZITI__EDGE_CLIENT__PB__HEADER_ID__ConnectionMarker, 84 | }; 85 | 86 | typedef uint8_t connection_type_t; 87 | enum connection_type { 88 | ConnTypeInvalid, 89 | ConnTypeDial = 1, 90 | ConnTypeBind = 2, 91 | ConnTypeUnknown = 3, 92 | }; 93 | 94 | enum crypto_method { 95 | CryptoMethodLibsodium = 0, 96 | CryptoMethodAES256GCM = 1, 97 | }; 98 | 99 | enum edge_flag { 100 | // half close connection no more data messages are expected 101 | // after receipt of message with this flag 102 | EDGE_FIN = ZITI__EDGE_CLIENT__PB__FLAG__FIN, 103 | // indicates that peer will send data messages with specially constructed UUID headers 104 | EDGE_TRACE_UUID = ZITI__EDGE_CLIENT__PB__FLAG__TRACE_UUID, 105 | // indicates that peer can accept multipart data messages 106 | EDGE_MULTIPART = ZITI__EDGE_CLIENT__PB__FLAG__MULTIPART, 107 | // indicates connection with stream semantics 108 | // this allows consolidation of payloads to lower overhead 109 | EDGE_STREAM = ZITI__EDGE_CLIENT__PB__FLAG__STREAM, 110 | // set on data message with multiple payloads 111 | EDGE_MULTIPART_MSG = ZITI__EDGE_CLIENT__PB__FLAG__MULTIPART_MSG, 112 | }; 113 | 114 | #ifdef __cplusplus 115 | } 116 | #endif 117 | 118 | #endif //ZITI_SDK_EDGE_PROTOCOL_H 119 | -------------------------------------------------------------------------------- /library/endian_internal.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ZITI_SDK_ENDIAN_INTERNAL_H 16 | #define ZITI_SDK_ENDIAN_INTERNAL_H 17 | 18 | #if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__) 19 | # define __WINDOWS__ 20 | #endif 21 | 22 | 23 | #if defined(__linux__) || defined(__FreeBSD__) 24 | # include 25 | #elif defined (__APPLE__) 26 | # include 27 | # define htole16(x) OSSwapHostToLittleInt16(x) 28 | # define htole32(x) OSSwapHostToLittleInt32(x) 29 | # define htole64(x) OSSwapHostToLittleInt64(x) 30 | # define le32toh(x) OSSwapLittleToHostInt32(x) 31 | #elif defined(__WINDOWS__) 32 | // thanks to https://gist.github.com/PkmX/63dd23f28ba885be53a5 33 | # include 34 | # if BYTE_ORDER == LITTLE_ENDIAN 35 | # if defined(_MSC_VER) 36 | # include 37 | # define htobe16(x) _byteswap_ushort(x) 38 | # define htole16(x) (x) 39 | # define be16toh(x) _byteswap_ushort(x) 40 | # define le16toh(x) (x) 41 | # define htobe32(x) _byteswap_ulong(x) 42 | # define htole32(x) (x) 43 | # define be32toh(x) _byteswap_ulong(x) 44 | # define le32toh(x) (x) 45 | # define htobe64(x) _byteswap_uint64(x) 46 | # define htole64(x) (x) 47 | # define be64toh(x) _byteswap_uint64(x) 48 | # define le64toh(x) (x) 49 | # elif defined(__GNUC__) || defined(__clang__) 50 | # define htobe16(x) __builtin_bswap16(x) 51 | # define htole16(x) (x) 52 | # define be16toh(x) __builtin_bswap16(x) 53 | # define le16toh(x) (x) 54 | # define htobe32(x) __builtin_bswap32(x) 55 | # define htole32(x) (x) 56 | # define be32toh(x) __builtin_bswap32(x) 57 | # define le32toh(x) (x) 58 | # define htobe64(x) __builtin_bswap64(x) 59 | # define htole64(x) (x) 60 | # define be64toh(x) __builtin_bswap64(x) 61 | # define le64toh(x) (x) 62 | # else 63 | # error platform not supported 64 | # endif 65 | # else 66 | # error byte order not supported 67 | # endif 68 | # define __BYTE_ORDER BYTE_ORDER 69 | # define __BIG_ENDIAN BIG_ENDIAN 70 | # define __LITTLE_ENDIAN LITTLE_ENDIAN 71 | # define __PDP_ENDIAN PDP_ENDIAN 72 | 73 | #else // other 74 | # error Please port endian macros! 75 | #endif 76 | 77 | #endif //ZITI_SDK_ENDIAN_INTERNAL_H 78 | -------------------------------------------------------------------------------- /library/errors.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ziti/errors.h" 16 | 17 | #define ZITI_ERRORS(XX) \ 18 | XX(OK, "OK") \ 19 | XX(CONFIG_NOT_FOUND, "configuration not found") \ 20 | XX(JWT_NOT_FOUND, "JWT not found") \ 21 | XX(JWT_INVALID, "JWT not accepted by controller") \ 22 | XX(JWT_INVALID_FORMAT, "JWT has invalid format") \ 23 | XX(PKCS7_ASN1_PARSING_FAILED, "PKCS7/ASN.1 parsing failed") \ 24 | XX(JWT_SIGNING_ALG_UNSUPPORTED, "unsupported JWT signing algorithm") \ 25 | XX(JWT_VERIFICATION_FAILED, "JWT verification failed") \ 26 | XX(ENROLLMENT_METHOD_UNSUPPORTED, "unsupported enrollment method") \ 27 | XX(ENROLLMENT_CERTIFICATE_REQUIRED, "enrollment method requires certificate") \ 28 | XX(KEY_GENERATION_FAILED, "error generating private key") \ 29 | XX(KEY_LOAD_FAILED, "error loading TLS key") \ 30 | XX(CSR_GENERATION_FAILED, "error generating a CSR") \ 31 | XX(INVALID_CONFIG, "configuration is invalid") \ 32 | XX(AUTHENTICATION_FAILED, "failed to authenticate") \ 33 | XX(NOT_AUTHORIZED, "not authorized") \ 34 | XX(CONTROLLER_UNAVAILABLE, "ziti controller is not available") \ 35 | XX(GATEWAY_UNAVAILABLE, "ziti edge router is not available") \ 36 | XX(SERVICE_UNAVAILABLE, "service not available") \ 37 | XX(EOF, "end of data") \ 38 | XX(TIMEOUT, "operation did not complete in time") \ 39 | XX(CONNABORT, "connection to edge router terminated") \ 40 | XX(INVALID_STATE, "invalid state") \ 41 | XX(CRYPTO_FAIL, "crypto failure") \ 42 | XX(CONN_CLOSED, "connection is closed") \ 43 | XX(INVALID_POSTURE, "failed posture check") \ 44 | XX(MFA_EXISTS, "an MFA enrollment already exists") \ 45 | XX(MFA_INVALID_TOKEN, "the token provided was invalid") \ 46 | XX(MFA_NOT_ENROLLED, "the current identity has not completed MFA enrollment") \ 47 | XX(NOT_FOUND, "entity no longer exists or is no longer accessible") \ 48 | XX(DISABLED, "ziti context is disabled") \ 49 | XX(PARTIALLY_AUTHENTICATED, "api session is partially authenticated, waiting for auth query resolution") \ 50 | XX(INVALID_AUTHENTICATOR_TYPE, "the authenticator could not be extended as it is the incorrect type") \ 51 | XX(INVALID_AUTHENTICATOR_CERT, "the authenticator could not be extended as the current client certificate does not match") \ 52 | XX(INVALID_CERT_KEY_PAIR, "the active certificate and key could not be set, invalid pair, or could not parse") \ 53 | XX(CERT_IN_USE,"the provided certificate already in use") \ 54 | XX(CERT_FAILED_VALIDATION, "the provided key/cert are invalid") \ 55 | XX(MISSING_CERT_CLAIM, "the certificate is expected to contain an externalId but none was not found") \ 56 | XX(ALLOC_FAILED, "memory allocation failed") \ 57 | XX(WTF, "WTF: programming error") 58 | 59 | 60 | #define ERR_NAME(e, s) case ZITI_##e: return s; 61 | 62 | const char *ziti_errorstr(int err) { 63 | switch (err) { 64 | ZITI_ERRORS(ERR_NAME) 65 | 66 | default: 67 | return "unexpected error"; 68 | } 69 | } 70 | 71 | #undef ERR_NAME -------------------------------------------------------------------------------- /library/message.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ZITI_SDK_MESSAGE_H 16 | #define ZITI_SDK_MESSAGE_H 17 | 18 | #include "pool.h" 19 | #include "edge_protocol.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #define HEADER_SIZE 20 27 | 28 | #define MAGIC_INIT {0x3, 0x6, 0x9, 0xC} 29 | 30 | typedef union { 31 | char magic[4]; 32 | int32_t magint; 33 | } magic_t; 34 | 35 | #define HEADER_FIELDS(XX) \ 36 | XX(content, uint32_t)\ 37 | XX(seq, uint32_t)\ 38 | XX(headers_len, uint32_t)\ 39 | XX(body_len, uint32_t) 40 | 41 | typedef struct { 42 | magic_t magic; 43 | #define field_decl(n, t) t n; 44 | 45 | HEADER_FIELDS(field_decl) 46 | 47 | #undef field_decl 48 | 49 | } header_t; 50 | 51 | static header_t EMPTY_HEADER = { 52 | MAGIC_INIT, 53 | }; 54 | 55 | typedef struct hdr_s { 56 | uint32_t header_id; 57 | uint32_t length; 58 | const uint8_t *value; 59 | } hdr_t; 60 | 61 | #define var_header(id, var) header(id, sizeof(var), &(var)) 62 | #define header(id, l, v) (hdr_t){ .header_id = (uint32_t)(id), .length = (uint32_t)(l), .value = (uint8_t*)(v)} 63 | 64 | typedef struct message_s { 65 | TAILQ_ENTRY(message_s) _next; 66 | 67 | header_t header; 68 | uint8_t *headers; 69 | uint8_t *body; 70 | hdr_t *hdrs; 71 | int nhdrs; 72 | 73 | size_t msgbuflen; 74 | uint8_t *msgbufp; 75 | uint8_t msgbuf[]; 76 | } message; 77 | 78 | #ifdef __cplusplus 79 | extern "C" { 80 | #endif 81 | 82 | 83 | void header_init(header_t *h, uint32_t seq); 84 | 85 | void header_to_buffer(header_t *h, uint8_t *buf); 86 | 87 | void header_from_buffer(header_t *h, uint8_t *buf); 88 | 89 | void message_init(message *m); 90 | 91 | void message_free(message *m); 92 | 93 | bool message_get_bool_header(message *m, int header_id, bool *v); 94 | 95 | bool message_get_int32_header(message *m, int header_id, int32_t *v); 96 | 97 | bool message_get_uint64_header(message *m, int header_id, uint64_t *v); 98 | 99 | bool message_get_bytes_header(message *m, int header_id, const uint8_t **ptr, size_t *len); 100 | 101 | uint8_t *write_hdr(const hdr_t *h, uint8_t *buf); 102 | 103 | int parse_hdrs(const uint8_t *buf, uint32_t len, hdr_t **hp); 104 | 105 | int message_new_from_header(pool_t *pool, uint8_t buf[HEADER_SIZE], message **msg_p); 106 | 107 | message *message_new(pool_t *pool, uint32_t content, const hdr_t *headers, int nheaders, size_t body_len); 108 | 109 | void message_set_seq(message *m, uint32_t *seq); 110 | 111 | message* new_inspect_result(uint32_t req_seq, uint32_t conn_id, connection_type_t type, const char *msg, size_t msglen); 112 | 113 | #ifdef __cplusplus 114 | }; 115 | #endif 116 | 117 | #endif //ZITI_SDK_MESSAGE_H 118 | -------------------------------------------------------------------------------- /library/metrics.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2020 NetFoundry, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "metrics.h" 18 | 19 | #define _USE_MATH_DEFINES 20 | 21 | #include 22 | #include 23 | 24 | #if defined(__unix__) || defined(__APPLE__) 25 | # if __STDC_NO_ATOMICS__ 26 | # include 27 | 28 | # define InterlockedAdd64(p, v) (*p) += (v) 29 | # define InterlockedExchange64(p, v) (*p) = (v) 30 | # define InterlockedExchange(p, v) (*p) = (v) 31 | # else 32 | #include 33 | # endif 34 | #endif 35 | 36 | #if defined(_MSC_VER) 37 | #include 38 | #endif 39 | 40 | #define NANOS(s) ((s) * 1e9) 41 | #define MILLIS(s) ((s) * 1000) 42 | 43 | static const double SECOND = NANOS(1); // one second in nanos 44 | 45 | static time_fn clock_fn; 46 | static void *clock_ctx; 47 | 48 | static double interval = 5; // 5 seconds is default 49 | static double intervalNanos = NANOS(5); 50 | 51 | static void tick_ewma(rate_t *ewma); 52 | static void tick_cma(rate_t *cma); 53 | static void tick_instant(rate_t *inst); 54 | 55 | extern void metrics_init(long interval_secs, time_fn f, void *time_ctx) { 56 | 57 | if (clock_fn == NULL) { 58 | clock_fn = f; 59 | clock_ctx = time_ctx; 60 | 61 | interval = (double)interval_secs; 62 | intervalNanos = NANOS(interval); 63 | } 64 | 65 | } 66 | 67 | extern void metrics_rate_close(rate_t* r) { 68 | if (r->active) { 69 | r->active = false; 70 | r->tick_fn = NULL; 71 | atomic_exchange(&r->delta, 0); 72 | r->rate = 0; 73 | } 74 | } 75 | 76 | extern int metrics_rate_init(rate_t *r, rate_type type) { 77 | if (r->active) { 78 | metrics_rate_close(r); 79 | } 80 | memset(r, 0, sizeof(rate_t)); 81 | switch (type) { 82 | case EWMA_5s: 83 | r->tick_fn = tick_ewma; 84 | *(double*)(&r->param) = 1.0 - pow(M_E, -(interval / 12)); 85 | break; 86 | case EWMA_1m: 87 | r->tick_fn = tick_ewma; 88 | *(double*)(&r->param) = 1.0 - pow(M_E, -(interval / 60.0)); 89 | break; 90 | 91 | case EWMA_5m: 92 | r->tick_fn = tick_ewma; 93 | *(double*)(&r->param) = 1.0 - pow(M_E, -(interval / 60.0 / 5.0)); 94 | break; 95 | 96 | case EWMA_15m: 97 | r->tick_fn = tick_ewma; 98 | *(double*)(&r->param) = 1.0 - pow(M_E, -(interval / 60.0 / 15.0)); 99 | break; 100 | 101 | case MMA_1m: 102 | r->tick_fn = tick_ewma; 103 | *(double*)(&r->param) = interval/60.0; 104 | break; 105 | 106 | case CMA_1m: 107 | r->tick_fn = tick_cma; 108 | break; 109 | 110 | case INSTANT: 111 | r->tick_fn = tick_instant; 112 | r->param = 1; 113 | break; 114 | default: 115 | return -1; 116 | } 117 | if (clock_fn) { 118 | r->last_tick = clock_fn(clock_ctx); 119 | } 120 | 121 | r->active = true; 122 | return 0; 123 | } 124 | 125 | static void rate_catchup(rate_t *r) { 126 | if (clock_fn) { 127 | uint64_t now = clock_fn(clock_ctx); 128 | while (now > r->last_tick + (uint64_t) MILLIS(interval)) { 129 | r->tick_fn(r); 130 | r->last_tick = r->last_tick + (uint64_t) MILLIS(interval); 131 | } 132 | } 133 | } 134 | 135 | extern void metrics_rate_update(rate_t *r, long delta) { 136 | if (r == NULL || !r->active) return; 137 | 138 | rate_catchup(r); 139 | atomic_fetch_add(&r->delta, delta); 140 | } 141 | 142 | extern int metrics_rate_get(rate_t *r, double *rate) { 143 | if (r == NULL || !r->active) return -1; 144 | rate_catchup(r); 145 | *rate = (*(double*)&r->rate) * (SECOND); 146 | return 0; 147 | } 148 | 149 | static double instant_rate(rate_t *r) { 150 | int64_t c = r->delta; 151 | atomic_fetch_add(&r->delta, -c); 152 | return ((double) c) / (intervalNanos); 153 | } 154 | 155 | static void tick_cma(rate_t *cma) { 156 | double r = instant_rate(cma); 157 | double current_rate = *(double*)&cma->rate; 158 | current_rate = (r + current_rate * cma->param) / ((double) cma->param + 1); 159 | 160 | atomic_exchange(&cma->rate, *(int64_t *) (¤t_rate)); 161 | atomic_exchange(&cma->param, cma->param + 1); 162 | } 163 | 164 | static void tick_ewma(rate_t *ewma) { 165 | double r = instant_rate(ewma); 166 | 167 | if (ewma->init == 1) { 168 | double currRate = *(double*)&ewma->rate; 169 | currRate += *(double*)(&ewma->param) * (r - currRate); 170 | atomic_exchange(&ewma->rate, *(int64_t *) (&currRate)); 171 | } else { 172 | atomic_exchange(&ewma->rate, *(int64_t *) (&r)); 173 | atomic_exchange(&ewma->init, 1); 174 | } 175 | } 176 | 177 | static void tick_instant(rate_t *inst) { 178 | double r = instant_rate(inst); 179 | atomic_exchange(&inst->delta, 0); //reset the delta 180 | atomic_exchange(&inst->rate, *(int64_t*)(&r)); 181 | } 182 | -------------------------------------------------------------------------------- /library/pool.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "pool.h" 16 | #include "utils.h" 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | struct pool_obj_s { 24 | pool_t *pool; 25 | size_t size; 26 | 27 | LIST_ENTRY(pool_obj_s) _next; 28 | void (*clear_func)(void *); 29 | char obj[]; 30 | }; 31 | 32 | struct pool_s { 33 | LIST_HEAD(objs, pool_obj_s) pool; 34 | size_t memsize; 35 | size_t capacity; 36 | size_t out; 37 | bool is_closed; 38 | 39 | void (*clear_func)(void *); 40 | 41 | pool_available_cb avail_cb; 42 | void *avail_ctx; 43 | }; 44 | 45 | pool_t *pool_new(size_t objsize, size_t count, void (*clear_func)(void *)) { 46 | pool_t *p = calloc(1, sizeof(pool_t)); 47 | p->memsize = objsize; 48 | p->capacity = count; 49 | p->clear_func = clear_func; 50 | return p; 51 | } 52 | 53 | void pool_destroy(pool_t *pool) { 54 | pool->is_closed = true; 55 | 56 | while (!LIST_EMPTY(&pool->pool)) { 57 | struct pool_obj_s *m = LIST_FIRST(&pool->pool); 58 | LIST_REMOVE(m, _next); 59 | free(m); 60 | } 61 | 62 | if (pool->out == 0) { 63 | free(pool); 64 | } 65 | } 66 | 67 | void pool_set_available_cb(pool_t *p, pool_available_cb cb, void *ctx) { 68 | assert(p); 69 | assert(!p->is_closed); 70 | p->avail_cb = cb; 71 | p->avail_ctx = ctx; 72 | } 73 | bool pool_has_available(pool_t *pool) { 74 | assert(pool); 75 | assert(!pool->is_closed); 76 | return !LIST_EMPTY(&pool->pool) || pool->capacity > pool->out; 77 | } 78 | 79 | void *alloc_unpooled_obj(size_t size, void (*clear_func)(void *)) { 80 | struct pool_obj_s *obj = calloc(1, sizeof(struct pool_obj_s) + size); 81 | if (obj) { 82 | obj->size = size; 83 | obj->pool = NULL; 84 | obj->clear_func = clear_func; 85 | return obj->obj; 86 | } 87 | return NULL; 88 | } 89 | 90 | void *pool_alloc_obj(pool_t *pool) { 91 | if (pool == NULL) { 92 | return NULL; 93 | } 94 | assert(!pool->is_closed); 95 | 96 | struct pool_obj_s *member = NULL; 97 | if (!LIST_EMPTY(&pool->pool)) { 98 | member = LIST_FIRST(&pool->pool); 99 | LIST_REMOVE(member, _next); 100 | } 101 | else if (pool->capacity > pool->out) { 102 | member = calloc(1, sizeof(struct pool_obj_s) + pool->memsize); 103 | member->size = pool->memsize; 104 | member->pool = pool; 105 | member->clear_func = pool->clear_func; 106 | } 107 | 108 | if (member) { 109 | pool->out++; 110 | return &member->obj; 111 | } 112 | 113 | return NULL; 114 | } 115 | 116 | size_t pool_mem_size(pool_t *pool) { 117 | return pool ? pool->memsize : 0; 118 | } 119 | 120 | size_t pool_obj_size(void *o) { 121 | if (o == NULL) { return 0; } 122 | 123 | struct pool_obj_s *m = container_of((char *) o, struct pool_obj_s, obj); 124 | return m->size; 125 | } 126 | 127 | void pool_return_obj(void *o) { 128 | if (o == NULL) { return; } 129 | 130 | struct pool_obj_s *m = container_of((char *) o, struct pool_obj_s, obj); 131 | if (m->clear_func) { 132 | m->clear_func(o); 133 | } 134 | pool_t *pool = m->pool; 135 | if (pool == NULL) { 136 | free(m); 137 | return; 138 | } 139 | 140 | memset(o, 0, m->size); 141 | pool->out--; 142 | 143 | if (pool->is_closed) { 144 | free(m); 145 | if (pool->out == 0) { 146 | free(pool); 147 | } 148 | } else { 149 | bool was_empty = LIST_EMPTY(&pool->pool); 150 | LIST_INSERT_HEAD(&pool->pool, m, _next); 151 | if (was_empty && pool->avail_cb) { 152 | pool->avail_cb(pool->avail_ctx); 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /library/proto/README.md: -------------------------------------------------------------------------------- 1 | Ziti Protobuf 2 | ------ 3 | 4 | This folder contains protobuf support files. 5 | 6 | This guide is only targeted for OpenZiti developers making changes to the library. 7 | A consuming application just needs to add `protobuf-c` dependency 8 | 9 | The source of protobuf definitions comes from https://github.com/openziti/sdk-golang/blob/main/pb/edge_client_pb/edge_client.proto 10 | Any time definitions are modified, this project has to be updated. 11 | 12 | # Prerequisites 13 | - Protobuf compilers: `protoc`, `protoc-gen-c`. Install them according to your development environment 14 | 15 | # Steps 16 | - copy `edge_client.proto` from the link above 17 | - generate protobuf implementation files: 18 | in your build directory: `$ cmake --build . --target generate-protobuf`. 19 | - make necessary changes in the code that uses protobuf objects/functions 20 | - commit the content of this directory, create PR, etc -------------------------------------------------------------------------------- /library/proto/google/protobuf/timestamp.pb-c.c: -------------------------------------------------------------------------------- 1 | /* Generated by the protocol buffer compiler. DO NOT EDIT! */ 2 | /* Generated from: google/protobuf/timestamp.proto */ 3 | 4 | /* Do not generate deprecated warnings for self */ 5 | #ifndef PROTOBUF_C__NO_DEPRECATED 6 | #define PROTOBUF_C__NO_DEPRECATED 7 | #endif 8 | 9 | #include "google/protobuf/timestamp.pb-c.h" 10 | void google__protobuf__timestamp__init 11 | (Google__Protobuf__Timestamp *message) 12 | { 13 | static const Google__Protobuf__Timestamp init_value = GOOGLE__PROTOBUF__TIMESTAMP__INIT; 14 | *message = init_value; 15 | } 16 | size_t google__protobuf__timestamp__get_packed_size 17 | (const Google__Protobuf__Timestamp *message) 18 | { 19 | assert(message->base.descriptor == &google__protobuf__timestamp__descriptor); 20 | return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); 21 | } 22 | size_t google__protobuf__timestamp__pack 23 | (const Google__Protobuf__Timestamp *message, 24 | uint8_t *out) 25 | { 26 | assert(message->base.descriptor == &google__protobuf__timestamp__descriptor); 27 | return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); 28 | } 29 | size_t google__protobuf__timestamp__pack_to_buffer 30 | (const Google__Protobuf__Timestamp *message, 31 | ProtobufCBuffer *buffer) 32 | { 33 | assert(message->base.descriptor == &google__protobuf__timestamp__descriptor); 34 | return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); 35 | } 36 | Google__Protobuf__Timestamp * 37 | google__protobuf__timestamp__unpack 38 | (ProtobufCAllocator *allocator, 39 | size_t len, 40 | const uint8_t *data) 41 | { 42 | return (Google__Protobuf__Timestamp *) 43 | protobuf_c_message_unpack (&google__protobuf__timestamp__descriptor, 44 | allocator, len, data); 45 | } 46 | void google__protobuf__timestamp__free_unpacked 47 | (Google__Protobuf__Timestamp *message, 48 | ProtobufCAllocator *allocator) 49 | { 50 | if(!message) 51 | return; 52 | assert(message->base.descriptor == &google__protobuf__timestamp__descriptor); 53 | protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); 54 | } 55 | static const ProtobufCFieldDescriptor google__protobuf__timestamp__field_descriptors[2] = 56 | { 57 | { 58 | "seconds", 59 | 1, 60 | PROTOBUF_C_LABEL_NONE, 61 | PROTOBUF_C_TYPE_INT64, 62 | 0, /* quantifier_offset */ 63 | offsetof(Google__Protobuf__Timestamp, seconds), 64 | NULL, 65 | NULL, 66 | 0, /* flags */ 67 | 0,NULL,NULL /* reserved1,reserved2, etc */ 68 | }, 69 | { 70 | "nanos", 71 | 2, 72 | PROTOBUF_C_LABEL_NONE, 73 | PROTOBUF_C_TYPE_INT32, 74 | 0, /* quantifier_offset */ 75 | offsetof(Google__Protobuf__Timestamp, nanos), 76 | NULL, 77 | NULL, 78 | 0, /* flags */ 79 | 0,NULL,NULL /* reserved1,reserved2, etc */ 80 | }, 81 | }; 82 | static const unsigned google__protobuf__timestamp__field_indices_by_name[] = { 83 | 1, /* field[1] = nanos */ 84 | 0, /* field[0] = seconds */ 85 | }; 86 | static const ProtobufCIntRange google__protobuf__timestamp__number_ranges[1 + 1] = 87 | { 88 | { 1, 0 }, 89 | { 0, 2 } 90 | }; 91 | const ProtobufCMessageDescriptor google__protobuf__timestamp__descriptor = 92 | { 93 | PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, 94 | "google.protobuf.Timestamp", 95 | "Timestamp", 96 | "Google__Protobuf__Timestamp", 97 | "google.protobuf", 98 | sizeof(Google__Protobuf__Timestamp), 99 | 2, 100 | google__protobuf__timestamp__field_descriptors, 101 | google__protobuf__timestamp__field_indices_by_name, 102 | 1, google__protobuf__timestamp__number_ranges, 103 | (ProtobufCMessageInit) google__protobuf__timestamp__init, 104 | NULL,NULL,NULL /* reserved[123] */ 105 | }; 106 | -------------------------------------------------------------------------------- /library/sdk_info.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright NetFoundry Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | #include 17 | #include 18 | 19 | #if _WIN32 20 | #include 21 | #include 22 | #include 23 | #pragma comment(lib, "netapi32.lib") 24 | 25 | typedef uint32_t in_addr_t; 26 | #define strcasecmp stricmp 27 | #else 28 | 29 | #if __APPLE__ 30 | #include 31 | #endif 32 | 33 | #include 34 | #include 35 | 36 | #if defined(ANDROID) 37 | #include 38 | #endif 39 | 40 | #endif 41 | 42 | 43 | static uv_once_t info_once; 44 | static ziti_env_info s_info; 45 | static void ziti_info_init() { 46 | static uv_utsname_t os_info; 47 | static char s_hostname[UV_MAXHOSTNAMESIZE]; 48 | static char s_domain[UV_MAXHOSTNAMESIZE]; 49 | 50 | uv_os_uname(&os_info); 51 | #if ANDROID 52 | static char android_release[PROP_VALUE_MAX + 1]; 53 | static char android_version[PROP_VALUE_MAX + 1]; 54 | __system_property_get("ro.build.version.release", android_release); 55 | __system_property_get("ro.build.version.security_patch", android_version); 56 | s_info.os = "Android"; 57 | s_info.os_release = android_release; 58 | s_info.os_version = android_version; 59 | #else 60 | s_info.os = os_info.sysname; 61 | s_info.os_release = os_info.release; 62 | s_info.os_version = os_info.version; 63 | 64 | #if __APPLE__ 65 | static char vers[256]; 66 | size_t sz = sizeof vers; 67 | sysctlbyname("kern.osproductversion", vers, &sz, NULL, 0); 68 | #if TARGET_OS_IPHONE 69 | s_info.os = "iOS"; 70 | #elif TARGET_OS_MAC 71 | s_info.os = "macOS"; 72 | #endif 73 | s_info.os_release = vers; 74 | s_info.os_version = os_info.release; // Darwin kernel version 75 | #endif // __APPLE__ 76 | 77 | #endif 78 | s_info.arch = os_info.machine; 79 | size_t len = sizeof(s_hostname); 80 | uv_os_gethostname(s_hostname, &len); 81 | #if _WIN32 82 | DWORD domain_len = sizeof(s_domain); 83 | DWORD rc = 0; 84 | rc = GetComputerNameExA(ComputerNameDnsDomain, s_domain, &domain_len); 85 | 86 | if (domain_len == 0) { 87 | WKSTA_INFO_100 *info; 88 | rc = NetWkstaGetInfo(NULL, 100, (LPBYTE *) &info); 89 | if (rc == 0) { 90 | wsprintfA(s_domain, "%ls", info->wki100_langroup); 91 | } 92 | NetApiBufferFree(info); 93 | } 94 | #else 95 | len = sizeof(s_domain); 96 | getdomainname(s_domain, (int)len); 97 | #endif 98 | 99 | s_info.hostname = s_hostname; 100 | s_info.domain = s_domain; 101 | } 102 | 103 | const ziti_env_info* get_env_info() { 104 | uv_once(&info_once, ziti_info_init); 105 | return &s_info; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /library/util/future.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright NetFoundry Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "future.h" 22 | 23 | typedef struct future_s { 24 | uv_mutex_t lock; 25 | uv_cond_t cond; 26 | bool completed; 27 | void *result; 28 | int err; 29 | } future_t; 30 | 31 | 32 | future_t *new_future() { 33 | future_t *f = calloc(1, sizeof(future_t)); 34 | int rc = uv_mutex_init(&f->lock); 35 | if (rc != 0) { 36 | fprintf(stderr, "failed to init lock %d/%s\n", rc, uv_strerror(rc)); 37 | } 38 | rc = uv_cond_init(&f->cond); 39 | if (rc != 0) { 40 | fprintf(stderr, "failed to init cond %d/%s\n", rc, uv_strerror(rc)); 41 | } 42 | return f; 43 | } 44 | 45 | void destroy_future(future_t *f) { 46 | uv_mutex_destroy(&f->lock); 47 | uv_cond_destroy(&f->cond); 48 | free(f); 49 | } 50 | 51 | int await_future(future_t *f, void **result) { 52 | if (f == NULL) { 53 | return 0; 54 | } 55 | 56 | uv_mutex_lock(&f->lock); 57 | while (!f->completed) { 58 | uv_cond_wait(&f->cond, &f->lock); 59 | } 60 | int err = f->err; 61 | uv_mutex_unlock(&f->lock); 62 | if (!err && result != NULL) { 63 | *result = f->result; 64 | } 65 | return err; 66 | } 67 | 68 | int complete_future(future_t *f, void *result) { 69 | if (f == NULL) return 0; 70 | 71 | int rc = UV_EINVAL; 72 | uv_mutex_lock(&f->lock); 73 | if (!f->completed) { 74 | f->completed = true; 75 | f->result = result; 76 | uv_cond_broadcast(&f->cond); 77 | rc = 0; 78 | } 79 | uv_mutex_unlock(&f->lock); 80 | return rc; 81 | } 82 | 83 | int fail_future(future_t *f, int err) { 84 | if (f == NULL) return 0; 85 | 86 | int rc = UV_EINVAL; 87 | uv_mutex_lock(&f->lock); 88 | if (!f->completed) { 89 | f->completed = true; 90 | f->err = err; 91 | uv_cond_broadcast(&f->cond); 92 | rc = 0; 93 | } 94 | uv_mutex_unlock(&f->lock); 95 | return rc; 96 | } 97 | -------------------------------------------------------------------------------- /library/util/future.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright NetFoundry Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #ifndef ZITI_SDK_FUTURE_H 18 | #define ZITI_SDK_FUTURE_H 19 | 20 | typedef struct future_s future_t; 21 | 22 | future_t *new_future(void); 23 | 24 | void destroy_future(future_t *f); 25 | 26 | int await_future(future_t *f, void **result); 27 | 28 | int complete_future(future_t *f, void *result); 29 | 30 | int fail_future(future_t *f, int err); 31 | 32 | #endif //ZITI_SDK_FUTURE_H 33 | -------------------------------------------------------------------------------- /programs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | find_package(CLI11 CONFIG REQUIRED) 3 | 4 | add_subdirectory(ziti-prox-c) 5 | add_subdirectory(host-proxy) 6 | 7 | add_subdirectory(sample_wttr) 8 | add_subdirectory(sample_http_link) 9 | add_subdirectory(sample-host) 10 | add_subdirectory(sample_enroll) 11 | add_subdirectory(wzcat) 12 | 13 | add_subdirectory(sample-bridge) 14 | 15 | add_subdirectory(zitilib-samples) 16 | 17 | add_subdirectory(auth-samples) 18 | -------------------------------------------------------------------------------- /programs/auth-samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(ziti_mfa ziti_mfa.cpp) 2 | set_target_properties(ziti_mfa PROPERTIES 3 | CXX_STANDARD 20 4 | ) 5 | 6 | target_link_libraries(ziti_mfa 7 | PUBLIC ziti 8 | PRIVATE CLI11::CLI11 9 | ) 10 | 11 | add_executable(jwt-auth jwt_auth.cpp) 12 | set_target_properties(jwt-auth PROPERTIES 13 | CXX_STANDARD 20 14 | ) 15 | target_link_libraries(jwt-auth ziti CLI11::CLI11) -------------------------------------------------------------------------------- /programs/host-proxy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(host-proxy host-proxy.c) 2 | target_link_libraries(host-proxy PRIVATE ziti) -------------------------------------------------------------------------------- /programs/sample-bridge/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(ziti-ncat ziti-ncat.c) 2 | target_link_libraries(ziti-ncat PUBLIC ziti) 3 | 4 | add_executable(ziti-socket-sample ziti-fd-client.c) 5 | target_link_libraries(ziti-socket-sample PUBLIC ziti) 6 | 7 | add_executable(ziti-http-get ziti-http-get.c) 8 | target_link_libraries(ziti-http-get PUBLIC ziti) -------------------------------------------------------------------------------- /programs/sample-bridge/ziti-fd-client.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #if !defined(_WIN32) 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #else 28 | 29 | #include 30 | #include 31 | 32 | #define write(s,b,l) send(s,b,l,0) 33 | #define read(s,b,l) recv(s,b,l,0) 34 | #define close(s) closesocket(s) 35 | 36 | #define SHUT_WR SD_SEND 37 | #endif 38 | 39 | int main(int argc, char *argv[]) { 40 | if (argc < 3) { return -1; } 41 | 42 | const char *path = argv[1]; 43 | const char *service = NULL; 44 | const char *hostname = NULL; 45 | int port = -1; 46 | if (argc == 3) { 47 | service = argv[2]; 48 | } else if (argc == 4) { 49 | hostname = argv[2]; 50 | port = atol(argv[3]); 51 | } 52 | 53 | Ziti_lib_init(); 54 | 55 | ziti_context ztx = Ziti_load_context(path); 56 | if (ztx == NULL) { 57 | int err = Ziti_last_error(); 58 | fprintf(stderr, "failed to load Ziti: %d(%s)\n", err, ziti_errorstr(err)); 59 | } 60 | ziti_socket_t socket = Ziti_socket(SOCK_STREAM); 61 | 62 | long rc = service ? Ziti_connect(socket, ztx, service, "ziggy") : Ziti_connect_addr(socket, hostname, port); 63 | 64 | if (rc != 0) { 65 | fprintf(stderr, "failed to connect: %ld(%s)\n", rc, ziti_errorstr(Ziti_last_error())); 66 | goto DONE; 67 | } 68 | 69 | const char msg[] = "this is a test"; 70 | write(socket, msg, strlen(msg)); 71 | shutdown(socket, SHUT_WR); 72 | char buf[1024]; 73 | do { 74 | rc = read(socket, buf, sizeof(buf)); 75 | if (rc > 0) { 76 | printf("read rc=%ld(%.*s)\n", rc, (int)rc, buf); 77 | } 78 | } while (rc > 0); 79 | printf("rc = %ld, errno = %d\n", rc, errno); 80 | 81 | DONE: 82 | close(socket); 83 | Ziti_lib_shutdown(); 84 | } 85 | -------------------------------------------------------------------------------- /programs/sample-bridge/ziti-http-get.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #if !defined(_WIN32) 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #else 30 | 31 | #include 32 | #include 33 | 34 | #define write(s,b,l) send(s,b,l,0) 35 | #define read(s,b,l) recv(s,b,l,0) 36 | #define close(s) closesocket(s) 37 | 38 | #define SHUT_WR SD_SEND 39 | #endif 40 | 41 | int main(int argc, char *argv[]) { 42 | if (argc < 3) { return -1; } 43 | 44 | const char *prog = strrchr(argv[0], '/'); 45 | if (prog == NULL) { 46 | prog = argv[0]; 47 | } 48 | else { 49 | prog++; 50 | } 51 | 52 | const char *path = argv[1]; 53 | 54 | struct tlsuv_url_s url = {0}; 55 | tlsuv_parse_url(&url, argv[2]); 56 | 57 | char hostname[256]; 58 | snprintf(hostname, sizeof(hostname), "%.*s", (int) url.hostname_len, url.hostname); 59 | int port = (url.port != 0) ? url.port : 80; 60 | 61 | Ziti_lib_init(); 62 | ziti_socket_t soc = socket(AF_INET, SOCK_STREAM, 0); //Ziti_socket(SOCK_STREAM); 63 | 64 | ziti_context ztx = Ziti_load_context(path); 65 | if (ztx == NULL) { 66 | int err = Ziti_last_error(); 67 | fprintf(stderr, "failed to load Ziti: %d(%s)\n", err, ziti_errorstr(err)); 68 | goto DONE; 69 | } 70 | 71 | 72 | long rc = Ziti_connect_addr(soc, hostname, port); 73 | 74 | if (rc != 0) { 75 | fprintf(stderr, "failed to connect: %ld(%s)\n", rc, ziti_errorstr((int)rc)); 76 | goto DONE; 77 | } 78 | 79 | char req[1024]; 80 | int len = snprintf(req, sizeof(req), 81 | "GET %.*s HTTP/1.1\r\n" 82 | "Host: %.*s\r\n" 83 | "User-Agent: %s/%s\r\n" 84 | "Connection: close\r\n" 85 | "Accept: */*\r\n\r\n", 86 | (int) url.path_len, url.path, 87 | (int) url.hostname_len, url.hostname, 88 | prog, ziti_get_version()->version); 89 | 90 | rc = write(soc, req, len); 91 | fprintf(stderr, "rc = %ld, errno = %d\n", rc, errno); 92 | 93 | //shutdown(socket, SHUT_WR); 94 | char buf[1024]; 95 | do { 96 | rc = read(soc, buf, sizeof(buf)); 97 | if (rc > 0) { 98 | printf("%.*s", (int) rc, buf); 99 | } 100 | } while (rc > 0); 101 | if (rc < 0) { 102 | fprintf(stderr, "rc = %ld, errno = %d\n", rc, errno); 103 | } 104 | 105 | DONE: 106 | close(soc); 107 | Ziti_lib_shutdown(); 108 | } 109 | -------------------------------------------------------------------------------- /programs/sample-bridge/ziti-ncat.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #include 17 | #include 18 | #include "ziti/ziti_log.h" 19 | 20 | #define STDIN 0 21 | #define STDOUT 1 22 | 23 | typedef struct { 24 | uv_loop_t *loop; 25 | const char *service; 26 | } zcat_opts; 27 | 28 | // on successful connect bridge Ziti connection to standard input and output 29 | void on_connect(ziti_connection conn, int status) { 30 | if (status == ZITI_OK) { 31 | ziti_conn_bridge_fds(conn, STDIN, STDOUT, (void (*)(void *)) ziti_shutdown, ziti_conn_context(conn)); 32 | } else { 33 | fprintf(stderr, "ziti connection failed: %s", ziti_errorstr(status)); 34 | ziti_shutdown(ziti_conn_context(conn)); 35 | } 36 | } 37 | 38 | void on_ziti_event(ziti_context ztx, const ziti_event_t *ev) { 39 | if (ev->type == ZitiContextEvent && ev->ctx.ctrl_status == ZITI_OK) { 40 | zcat_opts *opts = ziti_app_ctx(ztx); 41 | ziti_connection zconn; 42 | ziti_conn_init(ztx, &zconn, NULL); 43 | ziti_dial(zconn, opts->service, on_connect, NULL); 44 | } 45 | } 46 | 47 | int main(int argc, char *argv[]) { 48 | uv_loop_t *l = uv_loop_new(); 49 | zcat_opts opts = { 50 | .loop = l, 51 | .service = argv[2] 52 | }; 53 | ziti_options zopts = { 54 | .event_cb = on_ziti_event, 55 | .events = ZitiContextEvent, 56 | .app_ctx = &opts 57 | }; 58 | 59 | ziti_config cfg; 60 | ziti_context ztx = NULL; 61 | 62 | ziti_log_init(l, ZITI_LOG_DEFAULT_LEVEL, NULL); 63 | 64 | #define check(op) do{ \ 65 | int err = (op); if (err != ZITI_OK) { \ 66 | fprintf(stderr, "ERROR: %s", ziti_errorstr(err)); \ 67 | exit(err);\ 68 | }}while(0) 69 | 70 | check(ziti_load_config(&cfg, argv[1])); 71 | check(ziti_context_init(&ztx, &cfg)); 72 | check(ziti_context_set_options(ztx, &zopts)); 73 | 74 | ziti_context_run(ztx, l); 75 | 76 | uv_run(l, UV_RUN_DEFAULT); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /programs/sample-host/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(sample-host sample-host.c) 2 | target_link_libraries(sample-host PUBLIC ziti) -------------------------------------------------------------------------------- /programs/sample_enroll/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(sample_enroll sample_enroll.c) 2 | target_link_libraries(sample_enroll PUBLIC ziti) 3 | -------------------------------------------------------------------------------- /programs/sample_enroll/sample_enroll.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | #if _WIN32 24 | #define realpath(in, out) _fullpath(out, in, FILENAME_MAX) 25 | #endif 26 | #define DIE(v) do { \ 27 | int code = (v);\ 28 | if (code != ZITI_OK) {\ 29 | fprintf(stderr, "ERROR: " #v " => %s\n", ziti_errorstr(code));\ 30 | exit(code);\ 31 | }} while(0) 32 | 33 | const char *output_file; 34 | 35 | static int write_identity_file(ziti_config *cfg) { 36 | FILE *f; 37 | 38 | size_t len; 39 | char *output_buf = ziti_config_to_json(cfg, 0, &len); 40 | 41 | if ((f = fopen(output_file, "wb")) == NULL) { 42 | return (-1); 43 | } 44 | 45 | int rc = ZITI_OK; 46 | if (fwrite(output_buf, 1, len, f) != len) { 47 | rc = -1; 48 | } 49 | 50 | free(output_buf); 51 | fclose( f ); 52 | 53 | return rc; 54 | } 55 | 56 | void on_ziti_enroll(ziti_config *cfg, int status, char *err_message, void *ctx) { 57 | 58 | if (status != ZITI_OK) { 59 | fprintf(stderr, "ERROR: => %d => %s\n", status, err_message); 60 | exit(status); 61 | } 62 | 63 | 64 | int rc = write_identity_file(cfg); 65 | 66 | DIE(rc); 67 | } 68 | 69 | struct enroll_cert { 70 | const char *key; 71 | const char *cert; 72 | }; 73 | #include 74 | 75 | int main(int argc, char **argv) { 76 | if (argc < 3) { 77 | fprintf(stderr, "Usage: %s [ [ ] ]\n", argv[0]); 78 | exit(1); 79 | } 80 | 81 | #if _WIN32 82 | //changes the output to UTF-8 so that the windows output looks correct and not all jumbly 83 | SetConsoleOutputCP(65001); 84 | #endif 85 | #if 0 86 | uv_loop_t *loop = uv_default_loop(); 87 | 88 | output_file = argv[2]; 89 | 90 | ziti_enroll_opts opts = {0}; 91 | struct enroll_cert cert; 92 | opts.jwt = argv[1]; 93 | 94 | if (argc > 3) { 95 | opts.enroll_key = realpath(argv[3], NULL); 96 | } 97 | 98 | if (argc > 4) { 99 | opts.enroll_cert = realpath(argv[4], NULL); 100 | } 101 | 102 | DIE(ziti_enroll(&opts, loop, on_ziti_enroll, NULL)); 103 | 104 | // loop will finish after the request is complete and ziti_shutdown is called 105 | uv_run(loop, UV_RUN_DEFAULT); 106 | 107 | printf("\nSuccess\n"); 108 | #endif 109 | FILE *jwt_file = fopen(argv[1], "r"); 110 | if (jwt_file == NULL) { 111 | perror("failed to open JWT file"); 112 | return 1; 113 | } 114 | char jwt[8 * 1024]; 115 | fgets(jwt, sizeof(jwt), jwt_file); 116 | fclose(jwt_file); 117 | 118 | const char *key = NULL; 119 | const char *cert = NULL; 120 | if (argc >= 4) { 121 | key = argv[3]; 122 | if (argc >= 5) { 123 | cert = argv[4]; 124 | } 125 | } 126 | 127 | Ziti_lib_init(); 128 | char *cfg = NULL; 129 | size_t len; 130 | int rc = Ziti_enroll_identity(jwt, key, cert, &cfg, &len); 131 | if (rc == ZITI_OK) { 132 | FILE *id_file = fopen(argv[2], "w"); 133 | if (id_file) { 134 | fprintf(id_file, "%.*s", (int) len, cfg); 135 | printf("ziti identity is saved in %s\n", argv[2]); 136 | } 137 | else { 138 | printf("err = %d(%s)\n", errno, strerror(errno)); 139 | } 140 | } else { 141 | printf("err = %d(%s)\n", rc, ziti_errorstr(rc)); 142 | } 143 | free(cfg); 144 | Ziti_lib_shutdown(); 145 | } 146 | -------------------------------------------------------------------------------- /programs/sample_http_link/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(sample_http_link sample_http_link.c) 2 | target_link_libraries(sample_http_link PUBLIC ziti) 3 | -------------------------------------------------------------------------------- /programs/sample_http_link/README.md: -------------------------------------------------------------------------------- 1 | # Sample HTTP Link 2 | 3 | ## OpenZiti Concepts Demonstrated 4 | This sample demonstrates some key OpenZiti concepts: 5 | * Application-embedded zero trust client. 6 | * Offloading traffic from an identity. OpenZiti allows you to configure a tunneler to offload traffic towards another. This sample offloads traffic from a router to http://httpbin.org using a `host.v1` config. 7 | * Using a `host.v1` config to specify an address and port to dial in order to reach the service 8 | * Creating a service and adding a single (host) config to configure the service. 9 | * Service Policies to authorize identities to perform `dial` or `bind`. 10 | 11 | ## Prerequisites 12 | * You'll want to follow the steps in [BUILD.md](../../BUILD.md) to compile the sample programs. 13 | * You will need an OpenZiti network, if you don't have one, try one of the [quickstarts](https://openziti.io/docs/learn/quickstarts/). 14 | 15 | ## Setup 16 | ### Create Identities 17 | There will be one identity for the server side, hosting the server, and another for the client side, which will be 18 | allowed to reach (dial) the service. 19 | 20 | We will need a host and client identity. If you already have a network with identities, you can reuse them, just 21 | ensure you update the attributes. Here's how you would generate them. 22 | ``` 23 | ziti edge create identity device httpbin.server -a httpbinServerEndpoints -o httpbin.server.jwt 24 | ziti edge create identity device httpbin.client -a httpbinClientEndpoints -o httpbin.client.jwt 25 | ``` 26 | ### Enroll the Identities 27 | The identities need to be [enrolled](https://openziti.io/docs/learn/core-concepts/identities/enrolling) so the 28 | controller knows about them. 29 | ``` 30 | ziti edge enroll httpbin.server.jwt 31 | ziti edge enroll httpbin.client.jwt 32 | ``` 33 | 34 | ### Create a Host Service Config 35 | It is easier to create the service config before the actual service. The config can then be supplied when creating the 36 | service. 37 | ``` 38 | ziti edge create config httpbin-host.v1 host.v1 '{"protocol":"tcp", "address":"httpbin.org","port":80}' 39 | ``` 40 | ### Create a Service 41 | Create a service and attach the previously created host config using the `--configs` flag. 42 | ``` 43 | ziti edge create service httpbin --configs httpbin-host.v1 44 | ``` 45 | ### Create Service Policies 46 | Lastly, we need to create service policies. Service policies define which identities interact with which services, and 47 | the actions they are authorized to perform on a service. In this case, we create a Bind policy that allows identities 48 | with the `httpbinServerEndpoints` attribute to bind to this service. The Dial policy defines which identities can dial 49 | the service. In this case, any identity with the `httpbinClientEndpoints` attribute can dial this service. 50 | ``` 51 | ziti edge create service-policy httpbin-binding Bind --service-roles '@httpbin' --identity-roles '#httpbinServerEndpoints' 52 | ziti edge create service-policy httpbin-dialing Dial --service-roles '@httpbin' --identity-roles '#httpbinClientEndpoints' 53 | ``` 54 | 55 | ### Start a Tunneler 56 | Download the appropriate Ziti Tunneler for your operating system [here](https://github.com/openziti/ziti-tunnel-sdk-c/releases/latest). 57 | 58 | Start the tunneler, providing it with the server identity file (`httpbin.server.json`). Be sure to update the path to 59 | point to your identity file as necessary. The tunneler will handle offloading traffic from the OpenZiti network to its 60 | final destination (http://httpbin.org). 61 | ``` 62 | sudo ./ziti-edge-tunnel run -i httpbin.server.json 63 | ``` 64 | ## Run the Sample 65 | Run the sample, providing it with the client identity file (`httpbin.client.json`). Be sure to update the path to point 66 | to your identity file as necessary 67 | ``` 68 | ./sample_http_link httpbin.client.json 69 | ``` 70 | ## Cleanup 71 | To clean up the network, use the following commands 72 | ``` 73 | # Remove Service Policies 74 | ziti edge delete service-policies httpbin-binding httpbin-dialing 75 | # Remove the Service 76 | ziti edge delete service httpbin 77 | # Remove the configs 78 | ziti edge delete configs httpbin-host.v1 79 | # Remove the identities 80 | ziti edge delete identities httpbin.client httpbin.server 81 | ``` 82 | -------------------------------------------------------------------------------- /programs/sample_http_link/sample_http_link.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019-2020 NetFoundry, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | static uv_loop_t *loop; 24 | static ziti_context ziti; 25 | static tlsuv_http_t clt; 26 | static tlsuv_src_t zs; 27 | 28 | #define DIE(v) do { \ 29 | int code = (v);\ 30 | if (code != ZITI_OK) {\ 31 | fprintf(stderr, "ERROR: " #v " => %s\n", ziti_errorstr(code));\ 32 | exit(code);\ 33 | }} while(0) 34 | 35 | void resp_cb(tlsuv_http_resp_t *resp, void *data) { 36 | if (resp->code < 0) { 37 | fprintf(stderr, "ERROR: %d(%s)", resp->code, uv_strerror(resp->code)); 38 | exit(-1); 39 | } 40 | tlsuv_http_hdr *h; 41 | printf("Response (%d) >>>\nHeaders >>>\n", resp->code); 42 | LIST_FOREACH(h, &resp->headers, _next) { 43 | printf("\t%s: %s\n", h->name, h->value); 44 | } 45 | printf("\n"); 46 | } 47 | 48 | void body_cb(tlsuv_http_req_t *req, char *body, ssize_t len) { 49 | if (len == UV_EOF) { 50 | printf("\n\n====================\nRequest completed\n"); 51 | ziti_shutdown(ziti); 52 | } else if (len < 0) { 53 | fprintf(stderr, "error(%zd) %s", len, uv_strerror(len)); 54 | exit(-1); 55 | } else { 56 | printf("%*.*s", (int) len, (int) len, body); 57 | } 58 | } 59 | 60 | void on_ziti_init(ziti_context ztx, const ziti_event_t *ev) { 61 | 62 | DIE(ev->ctx.ctrl_status); 63 | 64 | ziti = ztx; 65 | ziti_src_init(loop, &zs, "httpbin", ziti); 66 | tlsuv_http_init_with_src(loop, &clt, "http://httpbin.org", (tlsuv_src_t *) &zs); 67 | 68 | tlsuv_http_req_t *r = tlsuv_http_req(&clt, "GET", "/json", resp_cb, NULL); 69 | r->resp.body_cb = body_cb; 70 | } 71 | 72 | int main(int argc, char** argv) { 73 | #if _WIN32 74 | //changes the output to UTF-8 so that the windows output looks correct and not all jumbly 75 | SetConsoleOutputCP(65001); 76 | #endif 77 | 78 | loop = uv_default_loop(); 79 | 80 | ziti_config cfg; 81 | ziti_context ztx; 82 | DIE(ziti_load_config(&cfg, argv[1])); 83 | DIE(ziti_context_init(&ztx, &cfg)); 84 | DIE(ziti_context_set_options(ztx, &(ziti_options){ 85 | .event_cb = on_ziti_init, 86 | .events = ZitiContextEvent, 87 | })); 88 | DIE(ziti_context_run(ztx, loop)); 89 | 90 | // loop will finish after the request is complete and ziti_shutdown is called 91 | uv_run(loop, UV_RUN_DEFAULT); 92 | 93 | printf("========================\n"); 94 | } -------------------------------------------------------------------------------- /programs/sample_wttr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(sample_wttr sample_wttr.c) 2 | target_link_libraries(sample_wttr PUBLIC ziti) 3 | -------------------------------------------------------------------------------- /programs/sample_wttr/sample_wttr.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define DIE(v) do { \ 23 | int code = (v);\ 24 | if (code != ZITI_OK) {\ 25 | fprintf(stderr, "ERROR: " #v " => %s\n", ziti_errorstr(code));\ 26 | exit(code);\ 27 | }} while(0) 28 | 29 | static size_t total; 30 | static ziti_context ziti; 31 | 32 | ssize_t on_data(ziti_connection c, const uint8_t *buf, ssize_t len) { 33 | if (len == ZITI_EOF) { 34 | 35 | printf("request completed: %s\n", ziti_errorstr(len)); 36 | ziti_close(c, NULL); 37 | ziti_shutdown(ziti); 38 | 39 | } 40 | else if (len < 0) { 41 | fprintf(stderr, "unexpected error: %s\n", ziti_errorstr(len)); 42 | ziti_close(c, NULL); 43 | ziti_shutdown(ziti); 44 | } 45 | else { 46 | total += len; 47 | printf("%.*s", (int)len, buf); 48 | } 49 | return len; 50 | } 51 | 52 | static void on_write(ziti_connection conn, ssize_t status, void *ctx) { 53 | if (status < 0) { 54 | fprintf(stderr, "request failed to submit status[%zd]: %s\n", status, ziti_errorstr((int) status)); 55 | } 56 | else { 57 | printf("request success: %zd bytes sent\n", status); 58 | } 59 | } 60 | 61 | void on_connect(ziti_connection conn, int status) { 62 | DIE(status); 63 | 64 | printf("sending HTTP request\n"); 65 | 66 | uint8_t *req = "GET /Rochester HTTP/1.0\r\n" 67 | "Accept: */*\r\n" 68 | "Connection: close\r\n" 69 | "Host: wttr.in\r\n" 70 | "User-Agent: curl/7.59.0\r\n" 71 | "\r\n"; 72 | 73 | DIE(ziti_write(conn, req, strlen(req), on_write, NULL)); 74 | } 75 | 76 | void on_ziti_init(ziti_context ztx, const ziti_event_t *ev) { 77 | DIE(ev->ctx.ctrl_status); 78 | ziti = ztx; 79 | 80 | ziti_connection conn; 81 | DIE(ziti_conn_init(ziti, &conn, NULL)); 82 | DIE(ziti_dial(conn, "demo-weather", on_connect, on_data)); 83 | } 84 | 85 | int main(int argc, char** argv) { 86 | #if _WIN32 87 | //changes the output to UTF-8 so that the windows output looks correct and not all jumbly 88 | SetConsoleOutputCP(65001); 89 | #endif 90 | uv_loop_t *loop = uv_default_loop(); 91 | ziti_config cfg; 92 | ziti_context ztx; 93 | ziti_options options = (ziti_options) { 94 | .event_cb = on_ziti_init, 95 | .events = ZitiContextEvent, 96 | }; 97 | 98 | DIE(ziti_load_config(&cfg, argv[1])); 99 | DIE(ziti_context_init(&ztx, &cfg)); 100 | DIE(ziti_context_set_options(ztx, &options)); 101 | DIE(ziti_context_run(ztx, loop)); 102 | 103 | // loop will finish after the request is complete and ziti_shutdown is called 104 | uv_run(loop, UV_RUN_DEFAULT); 105 | 106 | printf("========================\n"); 107 | 108 | ziti_shutdown(ziti); 109 | } -------------------------------------------------------------------------------- /programs/wzcat/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(wzcat ziti_ws.c) 2 | target_link_libraries(wzcat PUBLIC ziti) 3 | -------------------------------------------------------------------------------- /programs/wzcat/ziti_ws.c: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2020-2023. NetFoundry Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #define NEWP(var,t) t* var = calloc(1, sizeof(t)) 25 | 26 | static struct app_ctx { 27 | const char *service; 28 | uv_loop_t *l; 29 | } appCtx; 30 | 31 | static void init_cb(ziti_context ztx, const ziti_event_t *ev); 32 | 33 | int main(int argc, char *argv[]) { 34 | if (argc != 3) { 35 | fprintf(stderr, "Usage: %s ", argv[0]); 36 | exit(1); 37 | } 38 | 39 | const char *config = argv[1]; 40 | appCtx.service = argv[2]; 41 | 42 | uv_loop_t *l = uv_loop_new(); 43 | ziti_config cfg; 44 | ziti_context ztx = NULL; 45 | 46 | ziti_log_init(l, ZITI_LOG_DEFAULT_LEVEL, NULL); 47 | 48 | #define check(op) do{ \ 49 | int err = (op); if (err != ZITI_OK) { \ 50 | fprintf(stderr, "ERROR: %s", ziti_errorstr(err)); \ 51 | exit(err);\ 52 | }}while(0) 53 | 54 | check(ziti_load_config(&cfg, config)); 55 | check(ziti_context_init(&ztx, &cfg)); 56 | check(ziti_context_set_options(ztx, &(ziti_options){ 57 | .app_ctx = &appCtx, 58 | .event_cb = init_cb, 59 | .events = ZitiContextEvent, 60 | })); 61 | 62 | ziti_context_run(ztx, l); 63 | 64 | uv_run(l, UV_RUN_DEFAULT); 65 | 66 | return 0; 67 | } 68 | static void on_ws_write(uv_write_t *wr, int status) { 69 | printf("websocket write: %d\n", status); 70 | free(wr->data); 71 | free(wr); 72 | } 73 | 74 | static void input_read(uv_stream_t *s, ssize_t len, const uv_buf_t *buf) { 75 | tlsuv_websocket_t *ws = s->data; 76 | if (len > 0) { 77 | NEWP(wr, uv_write_t); 78 | uv_buf_t wb = uv_buf_init(buf->base, len); 79 | wr->data = buf->base; 80 | tlsuv_websocket_write(wr, ws, &wb, on_ws_write); 81 | } else { 82 | tlsuv_websocket_close(ws, NULL); 83 | } 84 | } 85 | 86 | static void alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { 87 | buf->base = malloc(suggested_size); 88 | buf->len = suggested_size; 89 | } 90 | 91 | static uv_pipe_t input; 92 | static void on_connect(uv_connect_t *r, int status) { 93 | tlsuv_websocket_t *ws = r->data; 94 | if (status == 0) { 95 | printf("websocket connected\n"); 96 | uv_pipe_init(ws->loop, &input, 0); 97 | input.data = ws; 98 | uv_pipe_open(&input, 0); 99 | uv_read_start((uv_stream_t *) &input, alloc, input_read); 100 | } else { 101 | 102 | } 103 | } 104 | 105 | static void on_ws_data(uv_stream_t *s, ssize_t len, const uv_buf_t *buf) { 106 | ziti_context ctx = s->data; 107 | if (len > 0) { 108 | printf("< %.*s", (int)len, buf->base); 109 | } else if (len < 0) { 110 | fprintf(stderr, "=========================\nwebsocket error[%zd]: %s\n", len, ziti_errorstr(len)); 111 | tlsuv_websocket_close((tlsuv_websocket_t *) s, (uv_close_cb) free); 112 | uv_close((uv_handle_t *) &input, NULL); 113 | ziti_shutdown(ctx); 114 | } 115 | } 116 | 117 | static void init_cb(ziti_context ztx, const ziti_event_t *ev) { 118 | struct app_ctx *ctx = ziti_app_ctx(ztx); 119 | NEWP(src, tlsuv_src_t); 120 | ziti_src_init(ctx->l, src, ctx->service, ztx); 121 | 122 | NEWP(ws, tlsuv_websocket_t); 123 | ws->data = ztx; 124 | tlsuv_websocket_init_with_src(ctx->l, ws, src); 125 | 126 | NEWP(connr, uv_connect_t); 127 | connr->data = ws; 128 | tlsuv_websocket_connect(connr, ws, "wss://echo.websocket.org", on_connect, on_ws_data); 129 | } -------------------------------------------------------------------------------- /programs/ziti-prox-c/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_executable(ziti-prox-c proxy.c 3 | main.cpp 4 | proxy.h) 5 | 6 | 7 | target_link_libraries(ziti-prox-c PUBLIC ziti CLI11::CLI11) 8 | if (MSVC) 9 | target_link_libraries(ziti-prox-c PUBLIC shlwapi) 10 | endif (MSVC) 11 | target_include_directories(ziti-prox-c PRIVATE ${ziti-sdk_SOURCE_DIR}/inc_internal) 12 | 13 | set(ZITI_ARCHIVE_NAME "ziti-prox-c-${PROJECT_VERSION}-${CPACK_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}.${archive_sfx}") 14 | 15 | add_custom_target(ziti-prox-c-pack 16 | BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${ZITI_ARCHIVE_NAME} 17 | DEPENDS ziti-prox-c 18 | COMMAND ${ZIP} ${ZIP_OPTS} ${ZITI_ARCHIVE_NAME} $ 19 | ) 20 | -------------------------------------------------------------------------------- /programs/ziti-prox-c/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // 6 | // You may obtain a copy of the License at 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #include 17 | #include 18 | 19 | #if _WIN32 20 | #include 21 | #include 22 | #define basename(p) PathFindFileName(p) 23 | #else 24 | #include 25 | #endif 26 | 27 | 28 | #include "proxy.h" 29 | 30 | class Run: public CLI::App { 31 | public: 32 | 33 | Run(): App("run proxy", "run"), 34 | debug(2) { 35 | add_option("--debug,-d", debug, "log level"); 36 | add_option("--identity,-i", identity, "identity config")->required(); 37 | add_option("listener", intercepts, ""); 38 | add_option("--bind,-b", bindings, "bind service "); 39 | add_option("--bind-udp,-B", udp_bindings, "bind udp service "); 40 | add_option("--proxy,-p", proxy, "proxy url"); 41 | 42 | final_callback([this] { 43 | this->execute(); 44 | }); 45 | } 46 | 47 | 48 | private: 49 | int debug; 50 | std::string identity; 51 | std::vector intercepts; 52 | std::vector bindings; 53 | std::vector udp_bindings; 54 | std::string proxy; 55 | 56 | void execute() const { 57 | run_opts opts{}; 58 | opts.identity = this->identity.c_str(); 59 | opts.debug = this->debug; 60 | for (auto &intercept: this->intercepts) { 61 | model_list_append(&opts.intercepts, intercept.c_str()); 62 | } 63 | for (auto &binding: this->bindings) { 64 | model_list_append(&opts.bindings, binding.c_str()); 65 | } 66 | for (auto &udp: this->udp_bindings) { 67 | model_list_append(&opts.udp_bindings, udp.c_str()); 68 | } 69 | if (!proxy.empty()) opts.proxy = this->proxy.c_str(); 70 | int rc = run_proxy(&opts); 71 | ::exit(rc); 72 | } 73 | }; 74 | 75 | int main(int argc, char *argv[]) { 76 | const char *name = basename(argv[0]); 77 | CLI::App app{name}; 78 | 79 | bool verbose = false; 80 | auto ver = app.add_subcommand("version", "print version information"); 81 | ver->add_flag("--verbose,-v", verbose, "verbose output"); 82 | ver->final_callback([&verbose] { 83 | std::cout << ziti_get_build_version(verbose) << std::endl; 84 | }); 85 | 86 | app.add_subcommand(std::make_shared()); 87 | app.require_subcommand(1); 88 | CLI11_PARSE(app, argc, argv); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /programs/ziti-prox-c/proxy.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // 6 | // You may obtain a copy of the License at 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // 16 | // Created by eugene on 11/25/24. 17 | // 18 | 19 | #ifndef PROXY_H 20 | #define PROXY_H 21 | 22 | #include 23 | 24 | struct run_opts { 25 | int debug; 26 | const char *identity; 27 | model_list intercepts; 28 | model_list bindings; 29 | model_list udp_bindings; 30 | const char *proxy; 31 | }; 32 | 33 | #if __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | extern int run_proxy(struct run_opts*); 38 | 39 | #if __cplusplus 40 | } 41 | #endif 42 | 43 | #endif //PROXY_H 44 | -------------------------------------------------------------------------------- /programs/zitilib-samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_executable(zitilib-server server.c) 3 | target_link_libraries(zitilib-server PUBLIC ziti) 4 | 5 | #add_executable(forky forky-client.c) 6 | #target_link_libraries(forky PUBLIC ziti) -------------------------------------------------------------------------------- /programs/zitilib-samples/server.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #if _WIN32 21 | #include 22 | #define close(s) closesocket(s) 23 | #define write(s,b,l) send(s,b,l,0) 24 | #define read(s,b,l) recv(s,b,l,0) 25 | #else 26 | #include 27 | #include 28 | #include 29 | #include 30 | #endif 31 | 32 | #ifndef SOCKET_ERROR 33 | #define SOCKET_ERROR (-1) 34 | #endif 35 | 36 | // This sample runs a simple byte counting server 37 | // - binds to the service 38 | // - for each client receives all data from client 39 | // - replies with message how many bytes where received 40 | // - clients are processed on at a time, client queue is managed by Ziti server socket implementation. 41 | 42 | // set this to 1 to verify that Ziti server socket works in non-blocking mode 43 | #define NON_BLOCKING_SERVER 1 44 | 45 | #define CHECK(desc, op) do{ \ 46 | int rc = (op); \ 47 | if (rc != 0) { \ 48 | int err = Ziti_last_error(); \ 49 | const char *msg = rc > 0 ? strerror(err) : ziti_errorstr(err); \ 50 | fprintf(stderr, desc"{" #op "} err=%d(%s)\n", err, msg); \ 51 | goto DONE;\ 52 | } \ 53 | } while(0) 54 | 55 | static ziti_socket_t non_blocking_accept(ziti_socket_t srv, char *caller, int caller_len) { 56 | #if _WIN32 57 | u_long opt = 1; 58 | ioctlsocket(srv, FIONBIO, &opt); 59 | #else 60 | int opt = fcntl(srv, F_GETFL); 61 | fcntl(srv, F_SETFL, opt | O_NONBLOCK); 62 | #endif 63 | 64 | fd_set rdfds; 65 | FD_ZERO(&rdfds); 66 | FD_SET(srv, &rdfds); 67 | struct timeval to = { 68 | .tv_sec = 60 * 60, // one hour 69 | }; 70 | do { 71 | int src = select(srv + 1, &rdfds, NULL, NULL, &to); 72 | if (src < 0) { 73 | perror("select"); 74 | return -1; 75 | } 76 | 77 | if (src == 0) { 78 | perror("timeout"); 79 | return -1; 80 | } 81 | 82 | if (!FD_ISSET(srv, &rdfds)) { 83 | fprintf(stderr, "select failure"); 84 | break; 85 | } 86 | // srv socket is readable, accept should succeed 87 | ziti_socket_t clt = Ziti_accept(srv, caller, caller_len); 88 | if (clt != SOCKET_ERROR) { return clt; } 89 | 90 | if (Ziti_last_error() != EWOULDBLOCK) { 91 | break; 92 | } 93 | } while (1); 94 | 95 | return -1; 96 | } 97 | 98 | int main(int argc, char *argv[]) { 99 | 100 | if (argc < 3) { 101 | fprintf(stderr, "Usage: %s [terminator]\n", argv[0]); 102 | exit(1); 103 | } 104 | 105 | Ziti_lib_init(); 106 | const char *service = argv[2]; 107 | const char *terminator = argc > 3 ? argv[3] : NULL; 108 | 109 | ziti_context ztx = Ziti_load_context(argv[1]); 110 | ziti_socket_t srv = socket(AF_INET, SOCK_STREAM, 0); 111 | 112 | CHECK("socket", srv == SOCKET_ERROR); 113 | 114 | CHECK("bind", Ziti_bind(srv, ztx, service, terminator)); 115 | 116 | CHECK("listen", Ziti_listen(srv, 10)); 117 | 118 | ziti_socket_t clt; 119 | char readbuf[8 * 1024]; 120 | int keep_going = 1; 121 | 122 | do { 123 | char caller[128]; 124 | #if NON_BLOCKING_SERVER 125 | CHECK("non blocking accept", (clt = non_blocking_accept(srv, caller, sizeof(caller))) < 0); 126 | #else 127 | CHECK("accept", (clt = Ziti_accept(srv, caller, sizeof(caller))) < 0); 128 | #endif 129 | 130 | printf("client[%s] connected\n", caller); 131 | long count = 0; 132 | size_t total = 0; 133 | char msg[128]; 134 | int len; 135 | do { 136 | count = read(clt, readbuf, sizeof(readbuf)); 137 | if (count > 0) { 138 | printf("read %zd bytes\n", count); 139 | if (strncmp("quit", readbuf, strlen("quit")) == 0) { 140 | keep_going = 0; 141 | break; 142 | } 143 | total += count; 144 | len = snprintf(msg, sizeof(msg), "you[%s] sent %zd bytes", caller, total); 145 | write(clt, msg, len); 146 | } 147 | } while (count > 0); 148 | 149 | len = snprintf(msg, sizeof(msg), "you[%s] sent %zd total bytes", caller, total); 150 | write(clt, msg, len); 151 | close(clt); 152 | printf("client is done after sending %zd bytes\n", total); 153 | } while (keep_going); 154 | 155 | DONE: 156 | if (srv != SOCKET_ERROR) 157 | Ziti_close(srv); 158 | Ziti_lib_shutdown(); 159 | } -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | find_package(Catch2 CONFIG REQUIRED) 3 | message("catch2 is ${Catch2_CONFIG}") 4 | 5 | add_executable(all_tests 6 | test_ziti_model.cpp 7 | test_jwt.cpp 8 | model_tests.cpp 9 | test_metrics.cpp 10 | enum_tests.cpp 11 | collections_tests.cpp 12 | buffer_tests.cpp 13 | pool_tests.cpp 14 | catch2_includes.hpp 15 | ziti_src_tests.cpp 16 | message_tests.cpp 17 | util_tests.cpp) 18 | 19 | if (WIN32) 20 | set_property(TARGET all_tests PROPERTY CXX_STANDARD 20) 21 | else () 22 | set_property(TARGET all_tests PROPERTY CXX_STANDARD 14) 23 | endif () 24 | 25 | target_compile_definitions(all_tests 26 | PRIVATE ZITI_TEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}) 27 | target_include_directories(all_tests 28 | PRIVATE ${ziti-sdk_SOURCE_DIR}/inc_internal 29 | PRIVATE ${ziti-sdk_SOURCE_DIR}/library 30 | ) 31 | 32 | target_link_libraries(all_tests 33 | PRIVATE ziti 34 | PRIVATE Catch2::Catch2 Catch2::Catch2WithMain) 35 | 36 | add_executable(zitilib-tests zitilib-tests.cpp) 37 | target_link_libraries(zitilib-tests 38 | PRIVATE ziti 39 | PRIVATE Catch2::Catch2WithMain) 40 | 41 | include(CTest) 42 | add_test(quick_tests all_tests -d yes "~[integ]~[metrics]") 43 | 44 | add_test(zitilib_tests zitilib-tests -d yes) 45 | 46 | add_subdirectory(integ) 47 | 48 | -------------------------------------------------------------------------------- /tests/buffer_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2021 NetFoundry, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "catch2_includes.hpp" 18 | 19 | #include 20 | #include 21 | 22 | TEST_CASE("fixed buffer overflow", "[util]") { 23 | char b[10]; 24 | auto buf = new_fixed_string_buf(b, sizeof(b)); 25 | 26 | REQUIRE(string_buf_fmt(buf, "This will not fit!") == -1); 27 | REQUIRE(string_buf_size(buf) == 0); 28 | delete_string_buf(buf); 29 | } 30 | 31 | TEST_CASE("buffer appendn", "[util]") { 32 | auto buf = new_string_buf(); 33 | 34 | std::string test_str; 35 | 36 | std::string str("this is a string\n"); 37 | for (int i = 0; i < 10; i++) { 38 | string_buf_appendn(buf, str.c_str(), str.size()); 39 | test_str += str; 40 | } 41 | 42 | CHECK(string_buf_size(buf) == test_str.size()); 43 | 44 | size_t len; 45 | char *result = string_buf_to_string(buf, &len); 46 | 47 | CHECK_THAT(result, Catch::Matchers::Equals(test_str)); 48 | CHECK(len == test_str.size()); 49 | 50 | delete_string_buf(buf); 51 | free(result); 52 | } 53 | 54 | TEST_CASE("buffer append", "[util]") { 55 | string_buf_t json_buf; 56 | string_buf_init(&json_buf); 57 | 58 | std::string test_str; 59 | 60 | for (int i = 0; i < 10; i++) { 61 | string_buf_append(&json_buf, "this is a string\n"); 62 | test_str += "this is a string\n"; 63 | } 64 | 65 | size_t len; 66 | char *result = string_buf_to_string(&json_buf, &len); 67 | 68 | CHECK_THAT(result, Catch::Matchers::Equals(test_str)); 69 | CHECK(len == test_str.size()); 70 | 71 | string_buf_free(&json_buf); 72 | free(result); 73 | } 74 | 75 | TEST_CASE("buffer fmt", "[util]") { 76 | string_buf_t fmt_buf; 77 | string_buf_init(&fmt_buf); 78 | 79 | fmt_buf.chunk_size = 160; 80 | 81 | std::string test_str; 82 | 83 | for (int i = 0; i < 1000; i++) { 84 | string_buf_fmt(&fmt_buf, "%04d\n", i); 85 | char num[16]; 86 | snprintf(num, 16, "%04d\n", i); 87 | test_str += num; 88 | } 89 | 90 | size_t size = string_buf_size(&fmt_buf); 91 | CHECK(size == test_str.size()); 92 | CHECK(size == 1000 * 5); 93 | 94 | size_t len; 95 | char *result = string_buf_to_string(&fmt_buf, &len); 96 | CHECK(len == test_str.size()); 97 | CHECK(string_buf_size(&fmt_buf) == 0); 98 | CHECK_THAT(result, Catch::Matchers::Equals(test_str)); 99 | 100 | free(result); 101 | string_buf_free(&fmt_buf); 102 | } 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /tests/catch2_includes.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef ZITI_SDK_CATCH2_INCLUDES_HPP 17 | #define ZITI_SDK_CATCH2_INCLUDES_HPP 18 | 19 | #include 20 | #include 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif //ZITI_SDK_CATCH2_INCLUDES_HPP 31 | -------------------------------------------------------------------------------- /tests/enum_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #include "catch2_includes.hpp" 17 | 18 | #include 19 | 20 | #define States(XX,...)\ 21 | XX(Good, __VA_ARGS__) \ 22 | XX(Bad, __VA_ARGS__) \ 23 | XX(Ugly, __VA_ARGS__) 24 | 25 | DECLARE_ENUM(State, States) 26 | IMPL_ENUM(State, States) 27 | 28 | TEST_CASE("test enum", "[model]") { 29 | State good = States.value_of("Good"); 30 | 31 | CHECK(State_Unknown == 0); 32 | CHECK(good == States.Good); 33 | CHECK_THAT(States.name(good), Catch::Matchers::Matches("Good")); 34 | } 35 | 36 | #define ModelWithEnum(XX, ...) \ 37 | XX(name, model_string, none, name, __VA_ARGS__) \ 38 | XX(state, State, none, state, __VA_ARGS__) 39 | 40 | DECLARE_MODEL(FooWithEnum, ModelWithEnum) 41 | IMPL_MODEL(FooWithEnum, ModelWithEnum) 42 | 43 | TEST_CASE("parse enum", "[model]") { 44 | const char *json = R"({ 45 | "name": "this is a name", 46 | "state": "Ugly" 47 | })"; 48 | 49 | FooWithEnum f1; 50 | REQUIRE(parse_FooWithEnum(&f1, json, strlen(json)) == strlen(json)); 51 | 52 | CHECK_THAT(f1.name, Catch::Matchers::Equals("this is a name")); 53 | CHECK(f1.state == States.Ugly); 54 | 55 | free_FooWithEnum(&f1); 56 | } 57 | 58 | TEST_CASE("parse null enum", "[model]") { 59 | const char *json = R"({ 60 | "name": "this is a name", 61 | "state": null 62 | })"; 63 | 64 | FooWithEnum f1; 65 | REQUIRE(parse_FooWithEnum(&f1, json, strlen(json)) == strlen(json)); 66 | 67 | CHECK_THAT(f1.name, Catch::Matchers::Equals("this is a name")); 68 | CHECK(f1.state == 0); 69 | 70 | free_FooWithEnum(&f1); 71 | } 72 | 73 | TEST_CASE("default enum", "[model]") { 74 | FooWithEnum f = {0}; 75 | f.name = (char *) "awesome foo"; 76 | 77 | CHECK(f.state == State_Unknown); 78 | 79 | char *json = FooWithEnum_to_json(&f, 0, nullptr); 80 | 81 | REQUIRE(json); 82 | 83 | REQUIRE_THAT(json, Catch::Matchers::ContainsSubstring("\"state\":null")); 84 | 85 | FooWithEnum f2; 86 | REQUIRE(parse_FooWithEnum(&f2, json, strlen(json)) == strlen(json)); 87 | CHECK(f2.state == State_Unknown); 88 | 89 | free_FooWithEnum(&f2); 90 | free(json); 91 | } 92 | 93 | TEST_CASE("enum to json", "[model]") { 94 | FooWithEnum f = {0}; 95 | f.name = (char *) "awesome foo"; 96 | f.state = States.Bad; 97 | 98 | char *json = FooWithEnum_to_json(&f, 0, nullptr); 99 | 100 | REQUIRE(json); 101 | 102 | REQUIRE_THAT(json, Catch::Matchers::ContainsSubstring("\"state\":\"Bad\"")); 103 | free(json); 104 | } 105 | 106 | TEST_CASE("enum compare", "[model]") { 107 | FooWithEnum f1,f2; 108 | f1.name = (char*)"awesome"; 109 | f2.name = f1.name; 110 | f1.state = States.Bad; 111 | f2.state = States.Bad; 112 | 113 | CHECK(cmp_FooWithEnum(&f1, &f2) == 0); 114 | 115 | f2.state = States.Good; 116 | CHECK(cmp_FooWithEnum(&f1, &f2) > 0); 117 | CHECK(cmp_FooWithEnum(&f2, &f1) < 0); 118 | } 119 | 120 | #define ModelWithEnumArray(XX, ...) \ 121 | XX(name, model_string, none, name, __VA_ARGS__) \ 122 | XX(states, State, array, states, __VA_ARGS__) 123 | 124 | DECLARE_MODEL(FooWithEnumArray, ModelWithEnumArray) 125 | IMPL_MODEL(FooWithEnumArray, ModelWithEnumArray) 126 | 127 | TEST_CASE("parse enum array", "[model]") { 128 | const char *json = R"({ 129 | "name": "this is a name", 130 | "states": ["Ugly", "Bad"] 131 | })"; 132 | 133 | FooWithEnumArray f1; 134 | REQUIRE(parse_FooWithEnumArray(&f1, json, strlen(json)) == strlen(json)); 135 | 136 | CHECK_THAT(f1.name, Catch::Matchers::Equals("this is a name")); 137 | CHECK(*f1.states[0] == States.Ugly); 138 | CHECK(*f1.states[1] == States.Bad); 139 | CHECK(f1.states[2] == nullptr); 140 | 141 | size_t json_len; 142 | auto js = FooWithEnumArray_to_json(&f1, MODEL_JSON_COMPACT, &json_len); 143 | 144 | CHECK_THAT(js, Catch::Matchers::ContainsSubstring(R"("states":["Ugly","Bad"])")); 145 | 146 | free_FooWithEnumArray(&f1); 147 | free(js); 148 | } 149 | 150 | #define ModelWithEnumList(XX, ...) \ 151 | XX(name, model_string, none, name, __VA_ARGS__) \ 152 | XX(states, State, list, states, __VA_ARGS__) 153 | 154 | DECLARE_MODEL(FooWithEnumList, ModelWithEnumList) 155 | 156 | IMPL_MODEL(FooWithEnumList, ModelWithEnumList) 157 | 158 | TEST_CASE("parse enum list", "[model]") { 159 | const char *json = R"({ 160 | "name": "this is a name", 161 | "states": ["Ugly", "Bad"] 162 | })"; 163 | 164 | FooWithEnumList f1; 165 | REQUIRE(parse_FooWithEnumList(&f1, json, strlen(json)) == strlen(json)); 166 | 167 | CHECK_THAT(f1.name, Catch::Matchers::Equals("this is a name")); 168 | auto it = model_list_iterator(&f1.states); 169 | CHECK(*(State *) model_list_it_element(it) == States.Ugly); 170 | it = model_list_it_next(it); 171 | CHECK(*(State *) model_list_it_element(it) == States.Bad); 172 | CHECK(model_list_it_next(it) == nullptr); 173 | 174 | 175 | size_t json_len; 176 | auto js = FooWithEnumList_to_json(&f1, MODEL_JSON_COMPACT, &json_len); 177 | 178 | CHECK_THAT(js, Catch::Matchers::ContainsSubstring(R"("states":["Ugly","Bad"])")); 179 | 180 | free_FooWithEnumList(&f1); 181 | free(js); 182 | } -------------------------------------------------------------------------------- /tests/integ/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | find_program(EXPECTOR NAMES expect) 3 | if (NOT EXPECTOR) 4 | message(WARNING "expect not found: integration testing is not enabled") 5 | return() 6 | endif () 7 | 8 | execute_process(COMMAND ${EXPECTOR} -v) 9 | 10 | find_program(GOLANG_EXE NAMES go REQUIRED) 11 | 12 | set(qs_home ${CMAKE_CURRENT_BINARY_DIR}/qs-home) 13 | set(test_client_jwt ${qs_home}/test-client.jwt) 14 | set(test_server_jwt ${qs_home}/test-server.jwt) 15 | set(test_client_json ${qs_home}/test-client.json) 16 | set(test_server_json ${qs_home}/test-server.json) 17 | set(test_service test-service) 18 | set(ZITI_CLI ${CMAKE_CURRENT_BINARY_DIR}/ziti) 19 | 20 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test-data.h.in 21 | ${CMAKE_CURRENT_BINARY_DIR}/include/test-data.h 22 | @ONLY 23 | ) 24 | 25 | add_executable(integ-tests 26 | main.cpp 27 | legacy-auth.cpp 28 | oidc-tests.cpp 29 | ctrl_tests.cpp 30 | enroll_tests.cpp 31 | ) 32 | target_include_directories(integ-tests 33 | PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include 34 | PRIVATE ${ziti-sdk_SOURCE_DIR}/inc_internal) 35 | target_link_libraries(integ-tests 36 | PRIVATE ziti 37 | PRIVATE Catch2::Catch2WithMain 38 | ) 39 | 40 | if (WIN32) 41 | set_property(TARGET integ-tests PROPERTY CXX_STANDARD 20) 42 | else () 43 | set_property(TARGET integ-tests PROPERTY CXX_STANDARD 14) 44 | endif () 45 | 46 | set(ZITI_CLI_VER "v1.4.3" CACHE STRING "ziti version for integration tests") 47 | add_custom_target(ziti-cli ALL 48 | COMMAND ${CMAKE_COMMAND} -E env GOBIN=${CMAKE_CURRENT_BINARY_DIR} 49 | ${GOLANG_EXE} install github.com/openziti/ziti/ziti@${ZITI_CLI_VER} 50 | BYPRODUCTS ${ZITI_CLI} 51 | ) 52 | 53 | add_custom_target(cleanup-qs 54 | COMMAND cat -n /etc/hosts 55 | COMMAND cat -n ${qs_home}/ctrl.yaml || true 56 | COMMAND ${CMAKE_COMMAND} -E remove_directory "${qs_home}" 57 | ) 58 | 59 | add_custom_target(run-qs 60 | DEPENDS ziti-cli cleanup-qs 61 | COMMAND ${CMAKE_COMMAND} -E env 62 | ZITI_CLI=${ZITI_CLI};ZITI_CONFIG_DIR=${qs_home};QUICKSTART_HOME=${qs_home};ENROLLER=$ 63 | ${EXPECTOR} ${CMAKE_CURRENT_SOURCE_DIR}/bootstrap.exp 64 | COMMAND ${ZITI_CLI} edge quickstart --home ${qs_home} 65 | USES_TERMINAL 66 | VERBATIM 67 | ) 68 | 69 | set_target_properties(run-qs PROPERTIES 70 | ADDITIONAL_CLEAN_FILES ${qs_home} 71 | ) 72 | 73 | add_test(NAME quickstart-bootstrap 74 | COMMAND ${EXPECTOR} ${CMAKE_CURRENT_SOURCE_DIR}/bootstrap.exp 75 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 76 | COMMAND_EXPAND_LISTS 77 | ) 78 | set_tests_properties(quickstart-bootstrap PROPERTIES 79 | FIXTURES_SETUP QS 80 | ENVIRONMENT "ZITI_CLI=${ZITI_CLI};ZITI_CONFIG_DIR=${qs_home};QUICKSTART_HOME=${qs_home};ENROLLER=$" 81 | DEPENDS "sample_enroll;ziti-cli" 82 | ) 83 | 84 | add_test(NAME quickstart-test 85 | COMMAND ${EXPECTOR} ${CMAKE_CURRENT_SOURCE_DIR}/integ-test.exp 86 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 87 | ) 88 | set_tests_properties(quickstart-test PROPERTIES 89 | FIXTURES_REQUIRED QS 90 | DEPENDS "integ-tests" 91 | ENVIRONMENT "ZITI_CLI=${ZITI_CLI};ZITI_CONFIG_DIR=${qs_home};QUICKSTART_HOME=${qs_home};TEST_EXE=$" 92 | ) 93 | 94 | add_test(NAME quickstart-cleanup 95 | COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target cleanup-qs 96 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 97 | ) 98 | set_tests_properties(quickstart-cleanup PROPERTIES 99 | FIXTURES_CLEANUP QS 100 | ) 101 | 102 | -------------------------------------------------------------------------------- /tests/integ/bootstrap.exp: -------------------------------------------------------------------------------- 1 | #!expect 2 | 3 | set timeout 600 4 | proc abort errs { 5 | puts "test failed: $errs" 6 | exit 2 7 | } 8 | set ziti $env(ZITI_CLI) 9 | puts "ziti = $ziti" 10 | 11 | set enroller $env(ENROLLER) 12 | puts "enroller = $env(ENROLLER)" 13 | 14 | puts "Starting Ziti Quickstart" 15 | puts "========================" 16 | 17 | spawn $ziti edge quickstart --home $env(QUICKSTART_HOME) --ctrl-address=127.0.0.1 --router-address=127.0.0.1 18 | set qs_id @spawn_id 19 | # wait until ER is connected 20 | expect { 21 | "controller and router started" { } 22 | timeout { error "qs not started in time" } 23 | eof { error "qs not started" } 24 | } 25 | 26 | puts "Configure model" 27 | puts "===============" 28 | log_user 1 29 | 30 | expect_before { 31 | timeout { abort "timeout" } 32 | "connection refused" { abort "QS not started" } 33 | } 34 | 35 | spawn $ziti edge create identity test-client -a client -o $env(QUICKSTART_HOME)/test-client.jwt 36 | expect { 37 | "New identity test-client created" {} 38 | "error" { abort $expect_out(buffer) } 39 | eof { abort "unexpected" } 40 | } 41 | 42 | spawn $ziti edge create identity test-server -a server -o $env(QUICKSTART_HOME)/test-server.jwt 43 | expect { 44 | "New identity test-server created" {} 45 | "error" { error $expect_out(buffer) } 46 | } 47 | 48 | spawn $ziti edge create service test-service 49 | expect { 50 | "New service test-service created" { } 51 | -re "error(.*)" { error $expect_out(1,string) } 52 | eof { error "not cool" } 53 | } 54 | 55 | spawn $ziti edge create service-policy servers-bind Bind --identity-roles \#server --service-roles \#all 56 | expect { 57 | "New service policy servers-bind created" {} 58 | -re "error(.*)" { error $expect_out(1,string) } 59 | eof { error "not cool" } 60 | } 61 | 62 | spawn $ziti edge create service-policy clients-dial Dial --identity-roles \#client --service-roles \#all 63 | expect { 64 | "New service policy clients-dial created" {} 65 | -re "error(.*)" { error $expect_out(1,string) } 66 | eof { error "not cool" } 67 | } 68 | 69 | spawn $enroller $env(QUICKSTART_HOME)/test-server.jwt $env(QUICKSTART_HOME)/test-server.json 70 | expect { 71 | "ziti identity is saved" {} 72 | eof { error "test-server not enrolled" } 73 | } 74 | wait 75 | 76 | spawn $enroller $env(QUICKSTART_HOME)/test-client.jwt $env(QUICKSTART_HOME)/test-client.json 77 | expect { 78 | "ziti identity is saved" {} 79 | eof { error "test-client not enrolled" } 80 | } 81 | wait 82 | -------------------------------------------------------------------------------- /tests/integ/enroll_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 NetFoundry Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "../catch2_includes.hpp" 18 | #include "fixtures.h" 19 | 20 | #include 21 | 22 | TEST_CASE_METHOD(LoopTestCase, "enroll-invalid-url", "[enroll][integration]") { 23 | ziti_enroll_opts opts { 24 | .url = "not a valid url", 25 | }; 26 | 27 | struct test_ctx_t { 28 | bool called{false}; 29 | int status{INT32_MAX}; 30 | std::string error; 31 | 32 | } test_ctx; 33 | auto rc = ziti_enroll(&opts, loop(), [](const ziti_config *cfg, int status, const char *err_message, void *enroll_ctx){ 34 | auto tctx = (test_ctx_t*)enroll_ctx; 35 | tctx->called = true; 36 | tctx->status = status; 37 | tctx->error = err_message ? err_message : "OK"; 38 | }, &test_ctx); 39 | 40 | uv_run(loop(), UV_RUN_DEFAULT); 41 | 42 | CHECK(rc == ZITI_INVALID_CONFIG); 43 | CHECK(!test_ctx.called); 44 | } 45 | 46 | TEST_CASE_METHOD(LoopTestCase, "enroll-unknown-url", "[enroll][integration]") { 47 | ziti_enroll_opts opts { 48 | .url = "https://this.is.not.a.valid.address:18443", 49 | }; 50 | 51 | struct test_ctx_t { 52 | bool called{false}; 53 | int status{INT32_MAX}; 54 | std::string error; 55 | 56 | } test_ctx; 57 | auto rc = ziti_enroll(&opts, loop(), [](const ziti_config *cfg, int status, const char *err_message, void *enroll_ctx){ 58 | auto tctx = (test_ctx_t*)enroll_ctx; 59 | tctx->called = true; 60 | tctx->status = status; 61 | tctx->error = err_message ? err_message : "OK"; 62 | }, &test_ctx); 63 | 64 | uv_run(loop(), UV_RUN_DEFAULT); 65 | 66 | CHECK(rc == ZITI_OK); 67 | CHECK(test_ctx.called); 68 | CHECK(test_ctx.status == ZITI_CONTROLLER_UNAVAILABLE); 69 | CHECK(test_ctx.error == uv_strerror(UV_EAI_NONAME)); 70 | } 71 | 72 | TEST_CASE_METHOD(LoopTestCase, "enroll-nonziti-url", "[enroll][integration]") { 73 | ziti_enroll_opts opts { 74 | .url = "https://google.com", 75 | }; 76 | 77 | struct test_ctx_t { 78 | bool called{false}; 79 | int status{INT32_MAX}; 80 | std::string error; 81 | 82 | } test_ctx; 83 | auto rc = ziti_enroll(&opts, loop(), [](const ziti_config *cfg, int status, const char *err_message, void *enroll_ctx){ 84 | auto tctx = (test_ctx_t*)enroll_ctx; 85 | tctx->called = true; 86 | tctx->status = status; 87 | tctx->error = err_message ? err_message : "OK"; 88 | }, &test_ctx); 89 | 90 | uv_run(loop(), UV_RUN_DEFAULT); 91 | 92 | CHECK(rc == ZITI_OK); 93 | CHECK(test_ctx.called); 94 | CHECK(test_ctx.status == ZITI_INVALID_STATE); 95 | INFO(test_ctx.error); 96 | CHECK(test_ctx.error != "OK"); 97 | } -------------------------------------------------------------------------------- /tests/integ/fixtures.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // 6 | // You may obtain a copy of the License at 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ZITI_SDK_FIXTURES_H 16 | #define ZITI_SDK_FIXTURES_H 17 | 18 | #include 19 | #include 20 | #include "ziti_ctrl.h" 21 | 22 | class LoopTestCase { 23 | uv_loop_t *m_loop; 24 | 25 | protected: 26 | LoopTestCase(): 27 | m_loop(uv_loop_new()) 28 | {} 29 | 30 | ~LoopTestCase() { 31 | int rc = uv_loop_close(loop()); 32 | INFO("uv_loop_close() => " << uv_strerror(rc)); 33 | CHECK(rc == 0); 34 | free(m_loop); 35 | } 36 | 37 | uv_loop_t *loop() { return m_loop; } 38 | }; 39 | 40 | template 41 | class resp_capture { 42 | public: 43 | T *resp; 44 | ziti_error error; 45 | resp_capture(): error{} { 46 | resp = nullptr; 47 | } 48 | 49 | void set_error(const ziti_error * e) { 50 | error.message = strdup(e->message); 51 | error.code = strdup(e->code); 52 | error.err = e->err; 53 | error.http_code = e->http_code; 54 | } 55 | 56 | ~resp_capture() { 57 | free_ziti_error(&error); 58 | } 59 | }; 60 | 61 | template 62 | void resp_cb(T *r, const ziti_error *err, void *ctx) { 63 | auto *rc = static_cast *>(ctx); 64 | if (err) { rc->set_error(err); } 65 | rc->resp = r; 66 | } 67 | 68 | template 69 | T *ctrl_get(ziti_controller &ctrl, 70 | void (*method)(ziti_controller *, void (*cb)(T *, const ziti_error *err, void *), void *)) { 71 | resp_capture resp; 72 | method(&ctrl, resp_cb, &resp); 73 | uv_run(ctrl.loop, UV_RUN_DEFAULT); 74 | CHECK(resp.error.err == 0); 75 | return resp.resp; 76 | } 77 | 78 | 79 | template 80 | T *ctrl_get1( 81 | ziti_controller &ctrl, 82 | void (*method)(ziti_controller *, A, void (*cb)(T *, const ziti_error *err, void *), void *), A arg) { 83 | resp_capture resp; 84 | method(&ctrl, arg, resp_cb, &resp); 85 | uv_run(ctrl.loop, UV_RUN_DEFAULT); 86 | if (resp.error.err != 0) { throw resp.error; } 87 | return resp.resp; 88 | } 89 | 90 | template 91 | T *ctrl_get2( 92 | ziti_controller &ctrl, 93 | void (*method)(ziti_controller *, A1, A2, void (*cb)(T *, const ziti_error *err, void *), void *), A1 arg1, 94 | A2 arg2) { 95 | resp_capture resp; 96 | method(&ctrl, arg1, arg2, resp_cb, &resp); 97 | uv_run(ctrl.loop, UV_RUN_DEFAULT); 98 | if (resp.error.err != 0) { throw resp.error; } 99 | return resp.resp; 100 | } 101 | 102 | static inline ziti_api_session *ctrl_login(ziti_controller &ctrl) { 103 | resp_capture session; 104 | model_list l = {nullptr}; 105 | auto s = ctrl_get1(ctrl, ziti_ctrl_login, &l); 106 | return s; 107 | } 108 | 109 | 110 | #endif // ZITI_SDK_FIXTURES_H 111 | -------------------------------------------------------------------------------- /tests/integ/integ-test.exp: -------------------------------------------------------------------------------- 1 | #!expect 2 | 3 | set ziti $env(ZITI_CLI) 4 | puts "ziti = $ziti" 5 | 6 | set tester $env(TEST_EXE) 7 | puts "test driver = $tester" 8 | 9 | puts "Starting Ziti Quickstart" 10 | puts "========================" 11 | spawn $ziti edge quickstart --home $env(QUICKSTART_HOME) 12 | set qs_id $spawn_id 13 | 14 | expect { 15 | "finished synchronizing api sessions" { } 16 | timeout { error "qs not started in time" } 17 | eof { error "qs not started" } 18 | } 19 | 20 | spawn $tester 21 | expect { 22 | -re "test cases: (.*) failed" { error "$expect_out(1,string)" } 23 | } 24 | -------------------------------------------------------------------------------- /tests/integ/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright NetFoundry Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | class ZitilibManager: public Catch::EventListenerBase{ 22 | 23 | public: 24 | using Catch::EventListenerBase::EventListenerBase; 25 | 26 | void testRunStarting(Catch::TestRunInfo const &) override { 27 | Ziti_lib_init(); 28 | } 29 | 30 | void testRunEnded(const Catch::TestRunStats &testRunStats) override { 31 | Ziti_lib_shutdown(); 32 | } 33 | }; 34 | 35 | CATCH_REGISTER_LISTENER(ZitilibManager) 36 | 37 | TEST_CASE("version", "[integ]") { 38 | const ziti_version *version = ziti_get_version(); 39 | REQUIRE(version != nullptr); 40 | } -------------------------------------------------------------------------------- /tests/integ/oidc-tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023-2024. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // 6 | // You may obtain a copy of the License at 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "fixtures.h" 21 | #include "oidc.h" 22 | #include "ziti/ziti_log.h" 23 | #include "test-data.h" 24 | 25 | 26 | TEST_CASE_METHOD(LoopTestCase, "ha-oidc", "[integ]") { 27 | auto l = loop(); 28 | ziti_log_init(l, 4, NULL); 29 | ziti_config cfg; 30 | REQUIRE(ziti_load_config(&cfg, TEST_CLIENT) == ZITI_OK); 31 | auto tls = default_tls_context(cfg.id.ca, strlen(cfg.id.ca)); 32 | tlsuv_certificate_t cert; 33 | tlsuv_private_key_t key; 34 | tls->load_cert(&cert, cfg.id.cert, strlen(cfg.id.cert)); 35 | tls->load_key(&key, cfg.id.key, strlen(cfg.id.key)); 36 | tls->set_own_cert(tls, key, cert); 37 | 38 | const ziti_jwt_signer ha_oidc = { 39 | .name = "ziti-internal-oidc", 40 | .enabled = true, 41 | .provider_url = (char*) model_list_head(&cfg.controllers), 42 | .client_id = "native", 43 | }; 44 | 45 | oidc_client_t oidcClient{}; 46 | oidc_client_init(l, &oidcClient, &ha_oidc, tls); 47 | struct oidc_cfg_result { 48 | bool called; 49 | int status; 50 | } cfg_result = {false, -1}; 51 | bool called = false; 52 | int oidc_status = -1; 53 | oidcClient.data = &cfg_result; 54 | 55 | oidc_client_configure(&oidcClient, [](oidc_client_t *clt, int status, const char *err) { 56 | auto res = (oidc_cfg_result *)clt->data; 57 | res->called = true; 58 | res->status = status; 59 | }); 60 | 61 | uv_run(l, UV_RUN_DEFAULT); 62 | 63 | CHECK(cfg_result.called); 64 | if (cfg_result.status == 404) { 65 | oidc_client_close(&oidcClient, [](oidc_client_t* clt){ 66 | }); 67 | uv_run(l, UV_RUN_DEFAULT); 68 | SKIP("OIDC endpoint not found"); 69 | } 70 | CHECK(oidcClient.config != NULL); 71 | 72 | std::string token; 73 | oidcClient.data = &token; 74 | oidc_client_start(&oidcClient, [](oidc_client_t *clt, enum oidc_status status, const char *token) { 75 | auto out = (std::string *) clt->data; 76 | REQUIRE(status == OIDC_TOKEN_OK); 77 | *out = token; 78 | }); 79 | 80 | uv_run(l, UV_RUN_DEFAULT); 81 | 82 | REQUIRE(!token.empty()); 83 | 84 | std::string old = token; 85 | token.clear(); 86 | 87 | oidc_client_refresh(&oidcClient); 88 | uv_run(l, UV_RUN_DEFAULT); 89 | 90 | REQUIRE(!token.empty()); 91 | REQUIRE(token != old); 92 | 93 | bool closed = false; 94 | oidcClient.data = &closed; 95 | oidc_client_close(&oidcClient, [](oidc_client_t *clt){ 96 | *(bool*)clt->data = true; 97 | }); 98 | 99 | uv_run(l, UV_RUN_DEFAULT); 100 | REQUIRE(closed); 101 | 102 | // key->free(key); 103 | cert->free(cert); 104 | tls->free_ctx(tls); 105 | 106 | free_ziti_config(&cfg); 107 | } -------------------------------------------------------------------------------- /tests/integ/test-data.h.in: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2024. NetFoundry Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // 7 | // You may obtain a copy of the License at 8 | // https://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #define TEST_CLIENT "@test_client_json@" 17 | #define TEST_SERVER "@test_server_json@" 18 | #define TEST_SERVICE "@test_service@" -------------------------------------------------------------------------------- /tests/pool_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2022 NetFoundry, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "catch2_includes.hpp" 18 | #include 19 | #include 20 | 21 | struct foo { 22 | uint32_t num; 23 | char *str; 24 | }; 25 | 26 | void clear_foo(void *f) { 27 | auto *f1 = static_cast(f); 28 | free(f1->str); 29 | } 30 | 31 | TEST_CASE("pool1", "[util]") { 32 | pool_t *pool = pool_new(sizeof(foo), 2, clear_foo); 33 | 34 | struct foo *f1, *f2, *f3; 35 | 36 | f1 = (foo *) pool_alloc_obj(pool); 37 | CHECK(f1->num == 0); 38 | CHECK(f1->str == nullptr); 39 | f1->num = 100; 40 | f1->str = strdup("this is a message"); 41 | pool_return_obj(f1); 42 | 43 | f1 = (foo *) pool_alloc_obj(pool); 44 | CHECK(f1->num == 0); 45 | CHECK(f1->str == nullptr); 46 | 47 | f2 = (foo *) pool_alloc_obj(pool); 48 | CHECK(f2->num == 0); 49 | CHECK(f2->str == nullptr); 50 | 51 | f3 = (foo *) pool_alloc_obj(pool); 52 | CHECK(f3 == nullptr); 53 | 54 | pool_return_obj(f1); 55 | pool_return_obj(f2); 56 | pool_destroy(pool); 57 | } 58 | 59 | TEST_CASE("return after destroy", "[util]") { 60 | pool_t *pool = pool_new(sizeof(foo), 2, clear_foo); 61 | 62 | struct foo *f1, *f2, *f3; 63 | 64 | f1 = (foo *) pool_alloc_obj(pool); 65 | CHECK(f1->num == 0); 66 | CHECK(f1->str == nullptr); 67 | f1->num = 100; 68 | f1->str = strdup("this is a message"); 69 | pool_return_obj(f1); 70 | 71 | f1 = (foo *) pool_alloc_obj(pool); 72 | CHECK(f1->num == 0); 73 | CHECK(f1->str == nullptr); 74 | 75 | f2 = (foo *) pool_alloc_obj(pool); 76 | CHECK(f2->num == 0); 77 | CHECK(f2->str == nullptr); 78 | 79 | f3 = (foo *) pool_alloc_obj(pool); 80 | CHECK(f3 == nullptr); 81 | 82 | pool_destroy(pool); 83 | 84 | pool_return_obj(f1); 85 | pool_return_obj(f2); 86 | } 87 | -------------------------------------------------------------------------------- /tests/test_jwt.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "catch2/catch_test_macros.hpp" 16 | #include "catch2/matchers/catch_matchers_string.hpp" 17 | #include 18 | #include 19 | #include 20 | #include "internal_model.h" 21 | 22 | static char* url64to64(const char* in, size_t ilen, size_t *olen) { 23 | size_t size = ((ilen - 1)/4 + 1) * 4; 24 | assert(size >= ilen); 25 | assert(size - ilen <= 3); 26 | 27 | char *out = (char*)malloc(size); 28 | size_t i; 29 | for(i = 0; i < ilen; i++) { 30 | switch (in[i]) { 31 | case '_': out[i] = '/'; break; 32 | case '-': out[i] = '+';break; 33 | default: out[i] = in[i]; 34 | } 35 | } 36 | 37 | while(i < size) { 38 | out[i++] = '='; 39 | } 40 | *olen = size; 41 | return out; 42 | } 43 | 44 | 45 | TEST_CASE("load_jwt","[model]") { 46 | 47 | char jwt[] = 48 | "eyJhbGciOiJSUzI1NiIsImtpZCI6ImUwYzZhZTkxYzE0YzljOTViOGMwYTUyMzY4NmEzNzF" 49 | "jOGY1MGUxNDAiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2ZkMjAwZmQzLWEyZDk" 50 | "tNDU3Zi1iYzBiLWY5YjhlZTdkMjg5OC5wcm9kdWN0aW9uLm5ldGZvdW5kcnkuaW86NDQzIi" 51 | "wic3ViIjoiQVo1allCLTBGIiwiYXVkIjpbIiJdLCJleHAiOjE3MDQ2NjE2OTUsImp0aSI6I" 52 | "jA5Mjk3NDc5LTQ4OTQtNDBhMC1iYjQyLTkwMzBkNGJkZDA1YSIsImVtIjoib3R0In0.M8bE" 53 | "8bz9DvgYG6AERBXv597g5vK6tkhFBT_bBZeiL6s8hFkft-6YLNAz6pR13y0SD7di4afcXmf" 54 | "BdqILF7pPiX8qaSC7bfHyrBfa0iLtNmkxensJqQul2sTLtiqa8_hlLen8y000_kaXKqdzsk" 55 | "2X5QcyRLh1C_5AUkyWrzIPQ7JUIlpzIE1yo4Ac0jfB7TF36he9eY1ap_ruST8I4iWA6Nlid" 56 | "1zMDw2ET0ANTbm5Gu5KBaGQ_Sc7ZDjC_LRAOeO4lH5_XhxpT-0ehHqsJxP2YwR8OIppkYUm" 57 | "OtNr2uRdLNjMdHNWtpF7A3igNMyqZMfv1eOnEV9GsqT56kM34qozCKF3VCJrRZo63feehKY" 58 | "sMdm_HHcDUPm4GiBp2z9zc1xiJeZVrSXzpOecULq8o3163XvTE8uF-chJGMFa5O3dYQxbzj" 59 | "6YlrHQol8C5FQjZwyO88-jR8ZlEANNYMQNVzE0ZdC-YAW-0aXRyv9XdoYuKY2Ba9YJ-wqrp" 60 | "5yr0QxpWjpJAPj7VAvBDb91HYXFA4VpvbLeCuhgJSchMK0w_RDGdd5Td-27DIQOIMaf17Hy" 61 | "5iYxWOfCa0G_2zDMxMCTuxmQksMata0uaEdf6bE_Uj4ZfWd3oY7ExINm_oXjhG7lcZvzd9y" 62 | "EgJuxV98N7JfQwVkGynSEiivjd2hvRuUYnJXxszI"; 63 | 64 | 65 | ziti_enrollment_jwt_header zejh{}; 66 | ziti_enrollment_jwt zej{}; 67 | 68 | size_t siglen; 69 | char * sig; 70 | parse_enrollment_jwt(jwt, &zejh, &zej, &sig, &siglen); 71 | 72 | CHECK(zejh.alg == jwt_sig_method_RS256); 73 | 74 | CHECK_THAT(zej.controller, Catch::Matchers::Equals("https://fd200fd3-a2d9-457f-bc0b-f9b8ee7d2898.production.netfoundry.io:443")); 75 | CHECK(zej.method == ziti_enrollment_methods.ott); 76 | CHECK_THAT(zej.subject, Catch::Matchers::Equals("AZ5jYB-0F")); 77 | CHECK_THAT(zej.token, Catch::Matchers::Equals("09297479-4894-40a0-bb42-9030d4bdd05a")); 78 | 79 | free(sig); 80 | free_ziti_enrollment_jwt(&zej); 81 | free_ziti_enrollment_jwt_header(&zejh); 82 | } 83 | -------------------------------------------------------------------------------- /tests/test_metrics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019-2020 NetFoundry, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | https://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "catch2_includes.hpp" 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | TEST_CASE("test-metrics", "[metrics]") { 24 | rate_t exp; 25 | rate_t cma; 26 | memset(&exp, 0, sizeof(exp)); 27 | memset(&cma, 0, sizeof(cma)); 28 | 29 | metrics_rate_init(&exp, EWMA_1m); 30 | metrics_rate_init(&cma, MMA_1m); 31 | 32 | metrics_rate_update(&exp, 1000); 33 | metrics_rate_update(&cma, 1000); 34 | 35 | double e, c; 36 | for (int i = 0; i < 100; i++) { 37 | exp.tick_fn(&exp); 38 | cma.tick_fn(&cma); 39 | metrics_rate_get(&exp, &e); 40 | metrics_rate_get(&cma, &c); 41 | printf("%d:\tewma=%.10lf\tmma=%lf\n", i, e, c); 42 | } 43 | }; 44 | 45 | TEST_CASE("init-metrics", "[metrics]") { 46 | rate_t m1; 47 | memset(&m1, 0, sizeof(m1)); 48 | 49 | metrics_rate_close(&m1); 50 | 51 | metrics_rate_init(&m1, EWMA_1m); 52 | metrics_rate_close(&m1); 53 | metrics_rate_close(&m1); 54 | } 55 | -------------------------------------------------------------------------------- /tests/util_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "catch2/catch_test_macros.hpp" 16 | #include "catch2/matchers/catch_matchers_string.hpp" 17 | #include "utils.h" 18 | #include "internal_model.h" 19 | #include "zt_internal.h" 20 | 21 | #if _WIN32 22 | #include 23 | #define dup2(o,n) _dup2(o,n) 24 | #else 25 | #include 26 | #endif 27 | 28 | TEST_CASE("read_file", "[util]") { 29 | const char *test_path = TO_STRING(ZITI_TEST_DIR) "/buffer_tests.cpp"; 30 | char *content = nullptr; 31 | size_t size; 32 | int rc = load_file(test_path, 0, &content, &size); 33 | CHECK(rc == 0); 34 | CHECK(size > 0); 35 | 36 | char *orig_content = content; 37 | size_t orig_size = size; 38 | CHECK(load_file(test_path, 0, &content, &size) == 0); 39 | CHECK(orig_content == content); // copy into provided buffer 40 | CHECK(orig_size == size); 41 | 42 | size = size / 2; 43 | CHECK(load_file(test_path, 0, &content, &size) == UV_ENOMEM); 44 | 45 | free(content); 46 | } 47 | 48 | TEST_CASE("read_file_not_found", "[util]") { 49 | const char *test_path = TO_STRING(ZITI_TEST_DIR) "/ctrl_tests.cpp.not-there"; 50 | char *content = nullptr; 51 | size_t size; 52 | int rc = load_file(test_path, 0, &content, &size); 53 | CHECK(rc == UV_ENOENT); 54 | CHECK(content == nullptr); 55 | } 56 | 57 | TEST_CASE("read_file_stdin", "[util]") { 58 | const char *test_path = TO_STRING(ZITI_TEST_DIR) "/buffer_tests.cpp"; 59 | uv_fs_t req = {0}; 60 | REQUIRE(uv_fs_stat(nullptr, &req, test_path, nullptr) == 0); 61 | auto file_size = req.statbuf.st_size; 62 | uv_fs_req_cleanup(&req); 63 | 64 | auto input = uv_fs_open(nullptr, &req, test_path, 0, O_RDONLY, nullptr); 65 | REQUIRE(input > 0); 66 | REQUIRE(dup2(input, fileno(stdin)) == 0); 67 | 68 | 69 | char *content = nullptr; 70 | size_t size; 71 | int rc = load_file("-", 0, &content, &size); 72 | CHECK(rc == UV_EINVAL); 73 | CHECK(content == nullptr); 74 | 75 | size = file_size + 16; 76 | content = static_cast(malloc(size)); 77 | rc = load_file("-", 0, &content, &size); 78 | CHECK(rc == 0); 79 | CHECK(content != nullptr); 80 | CHECK(size == file_size); 81 | 82 | free(content); 83 | uv_fs_req_cleanup(&req); 84 | } 85 | 86 | TEST_CASE("check hostname/domainname") { 87 | 88 | const ziti_env_info *info = get_env_info(); 89 | REQUIRE(info != nullptr); 90 | CHECK(info->hostname != nullptr); 91 | CHECK(info->domain != nullptr); 92 | 93 | printf("hostname = %s\n", info->hostname); 94 | printf("domain = %s\n", info->domain); 95 | } -------------------------------------------------------------------------------- /tests/ziti_src_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2023. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "catch2_includes.hpp" 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | struct source_test { 22 | source_test(): err(0), loop(nullptr), done(false), code(-1) {} 23 | int err; 24 | uv_loop_t *loop; 25 | ziti_context ztx; 26 | tlsuv_src_t src; 27 | tlsuv_http_t clt; 28 | int code; 29 | std::string body; 30 | bool done; 31 | }; 32 | 33 | TEST_CASE("httpbin.ziti:ziti_src", "[integ]") { 34 | auto cfg = getenv("ZITI_TEST_IDENTITY"); 35 | 36 | if (cfg == nullptr) { 37 | WARN("ZITI_TEST_IDENTITY is not set"); 38 | return; 39 | } 40 | 41 | source_test test; 42 | test.loop = uv_loop_new(); 43 | 44 | auto handler = [](ziti_context ztx, const ziti_event_t *ev) { 45 | auto t = (source_test *) ziti_app_ctx(ztx); 46 | switch (ev->type) { 47 | case ZitiContextEvent: { 48 | auto ctx_ev = ev->ctx; 49 | t->ztx = ztx; 50 | if (!t->done && ctx_ev.ctrl_status != ZITI_OK) 51 | t->err = ctx_ev.ctrl_status; 52 | break; 53 | } 54 | case ZitiServiceEvent: 55 | if (t->done) break; 56 | 57 | ziti_src_init(t->loop, &t->src, nullptr, ztx); 58 | tlsuv_http_init_with_src(t->loop, &t->clt, "http://httpbin.ziti", &t->src); 59 | tlsuv_http_req(&t->clt, "GET", "/json", [](tlsuv_http_resp_t *resp, void *ctx) { 60 | auto t = (source_test *) ctx; 61 | t->code = resp->code; 62 | 63 | resp->body_cb = [](tlsuv_http_req_t *req, char *body, ssize_t len) { 64 | auto t = (source_test *) req->data; 65 | if (len > 0) 66 | t->body.append(body, len); 67 | else if (len == UV_EOF) { 68 | t->done = true; 69 | ziti_shutdown(t->ztx); 70 | } else { 71 | t->err = (int) len; 72 | t->done = true; 73 | ziti_shutdown(t->ztx); 74 | } 75 | }; 76 | }, t); 77 | break; 78 | default: 79 | FAIL("unexpected event"); 80 | } 81 | }; 82 | 83 | ziti_config zfg; 84 | ziti_context ztx; 85 | ziti_options zopts = {}; 86 | zopts.app_ctx = &test; 87 | zopts.events = ZitiContextEvent | ZitiServiceEvent; 88 | zopts.event_cb = handler; 89 | 90 | REQUIRE(ziti_load_config(&zfg, cfg) == ZITI_OK); 91 | REQUIRE(ziti_context_init(&ztx, &zfg) == ZITI_OK); 92 | REQUIRE(ziti_context_set_options(ztx, &zopts) == ZITI_OK); 93 | REQUIRE(ziti_context_run(ztx, test.loop) == ZITI_OK); 94 | 95 | uv_timer_t t = {0}; 96 | uv_timer_init(test.loop, &t); 97 | t.data = &test; 98 | uv_unref((uv_handle_t *)&t); 99 | uv_timer_start(&t, [](uv_timer_t *timer){ 100 | uv_print_active_handles(timer->loop, stderr); 101 | uv_stop(timer->loop); 102 | }, 103 | 20000, 0); 104 | 105 | uv_run(test.loop, UV_RUN_DEFAULT); 106 | 107 | printf("%s", test.body.c_str()); 108 | CHECK_THAT(test.body, Catch::Matchers::ContainsSubstring(R"("title": "Wake up to WonderWidgets!")")); 109 | CHECK(test.err == 0); 110 | } 111 | -------------------------------------------------------------------------------- /tests/zitilib-tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022. NetFoundry Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | #include "catch2/reporters/catch_reporters_all.hpp" 20 | #include "catch2/matchers/catch_matchers.hpp" 21 | #include "catch2/matchers/catch_matchers_string.hpp" 22 | 23 | #if _WIN32 24 | #else 25 | #include 26 | #include 27 | #endif 28 | 29 | class testRunListener : public Catch::EventListenerBase { 30 | protected: 31 | static ziti_context _ztx; 32 | public: 33 | using Catch::EventListenerBase::EventListenerBase; 34 | 35 | void testRunStarting(Catch::TestRunInfo const &) override { 36 | Ziti_lib_init(); 37 | const char *id = getenv("ZITI_TEST_IDENTITY"); 38 | if (id) { 39 | _ztx = Ziti_load_context(id); 40 | } 41 | } 42 | 43 | void testRunEnded(const Catch::TestRunStats &testRunStats) override { 44 | Ziti_lib_shutdown(); 45 | } 46 | 47 | static ziti_context ztx() { 48 | return _ztx; 49 | } 50 | }; 51 | 52 | ziti_context testRunListener::_ztx; 53 | 54 | CATCH_REGISTER_LISTENER(testRunListener) 55 | using namespace Catch::Matchers; 56 | 57 | TEST_CASE("httpbin.ziti", "[zitilib]") { 58 | ziti_socket_t sock = Ziti_socket(SOCK_STREAM); 59 | REQUIRE(Ziti_connect_addr(sock, "httpbin.ziti", 80) == 0); 60 | 61 | auto req = "GET /json HTTP/1.1\r\n" 62 | "Accept: */*\r\n" 63 | "Accept-Encoding: gzip, deflate\r\n" 64 | "Connection: keep-alive\r\n" 65 | "Host: httpbin.org\r\n" 66 | "User-Agent: HTTPie/3.1.0\r\n" 67 | "\r\n"; 68 | #if _WIN32 69 | send(sock, req, strlen(req), 0); 70 | #else 71 | write(sock, req, strlen(req)); 72 | #endif 73 | 74 | char resp[1024]; 75 | size_t rlen = 0; 76 | int r; 77 | do { 78 | #if _WIN32 79 | r = recv(sock, resp + rlen, sizeof(resp) - rlen, 0); 80 | #else 81 | r = (int)read(sock, resp + rlen, sizeof(resp) - rlen); 82 | #endif 83 | if (r < 0) { 84 | fprintf(stderr, "failed to read: %d\n", errno); 85 | break; 86 | } 87 | rlen += r; 88 | } while (r > 0); 89 | resp[rlen] = '\0'; 90 | 91 | #if _WIN32 92 | closesocket(sock); 93 | #else 94 | close(sock); 95 | #endif 96 | 97 | CHECK_THAT(resp, StartsWith("HTTP/1.1 200 OK")); 98 | CHECK_THAT(resp, ContainsSubstring(R"("title": "Sample Slide Show")")); 99 | } -------------------------------------------------------------------------------- /toolchains/Linux-arm.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Linux) 2 | set(CMAKE_SYSTEM_PROCESSOR arm) 3 | 4 | set(triple arm-linux-gnueabihf) 5 | 6 | set(CMAKE_C_COMPILER ${triple}-gcc) 7 | set(CMAKE_CXX_COMPILER ${triple}-g++) 8 | 9 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 10 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 11 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 12 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 13 | -------------------------------------------------------------------------------- /toolchains/Linux-arm64.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Linux) 2 | set(CMAKE_SYSTEM_PROCESSOR arm64) 3 | 4 | set(triple aarch64-linux-gnu) 5 | 6 | set(CMAKE_C_COMPILER ${triple}-gcc) 7 | set(CMAKE_CXX_COMPILER ${triple}-g++) 8 | 9 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 10 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 11 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 12 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 13 | -------------------------------------------------------------------------------- /toolchains/Windows-arm64-msvc.cmake: -------------------------------------------------------------------------------- 1 | # cross-compile for windows/arm64 on windows/x64 host with visual studio 2 | set(CMAKE_SYSTEM_NAME Windows) 3 | set(CMAKE_SYSTEM_PROCESSOR ARM64) 4 | # setting CMAKE_GENERATOR_PLATFORM should be sufficient if you believe the doc, it results in build files 5 | # that cause msbuild to that the ZERO_CHECK project doesn't contain the "Debug|x64" platform/config 6 | # combination. running cmake with '-A ARCH64' avoids the msbuild failure. 7 | set(CMAKE_GENERATOR_PLATFORM ARM64) 8 | set(CMAKE_C_COMPILER cl.exe) -------------------------------------------------------------------------------- /toolchains/Windows-x86.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Windows) 2 | set(CMAKE_SYSTEM_PROCESSOR x86) 3 | 4 | set(triple i686-w64-mingw32) 5 | 6 | set(CMAKE_C_COMPILER ${triple}-gcc) 7 | set(CMAKE_CXX_COMPILER ${triple}-g++) 8 | 9 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 10 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 11 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 12 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 13 | -------------------------------------------------------------------------------- /toolchains/Windows-x86_64.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Windows) 2 | set(CMAKE_SYSTEM_PROCESSOR x86_64) 3 | 4 | set(triple x86_64-w64-mingw32) 5 | 6 | set(CMAKE_C_COMPILER ${triple}-gcc) 7 | set(CMAKE_CXX_COMPILER ${triple}-g++) 8 | 9 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 10 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 11 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 12 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 13 | -------------------------------------------------------------------------------- /toolchains/iOS-arm64.cmake: -------------------------------------------------------------------------------- 1 | # build-iphoneos-arm64 2 | 3 | set(CMAKE_SYSTEM_NAME iOS) 4 | set(CMAKE_SYSTEM_PROCESSOR arm64) 5 | 6 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch arm64") 7 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch arm64") 8 | 9 | # for libsodium 10 | set(triple arm-apple-darwin10) 11 | execute_process(COMMAND /usr/bin/xcrun -sdk iphoneos --show-sdk-path 12 | OUTPUT_VARIABLE CMAKE_OSX_SYSROOT 13 | OUTPUT_STRIP_TRAILING_WHITESPACE) 14 | 15 | set(ENV{CFLAGS} "-arch arm64 -isysroot ${CMAKE_OSX_SYSROOT}") 16 | set(ENV{LDFLAGS} "-arch arm64 -isysroot ${CMAKE_OSX_SYSROOT}") 17 | 18 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 19 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 20 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 21 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 22 | -------------------------------------------------------------------------------- /toolchains/iOS-x86_64.cmake: -------------------------------------------------------------------------------- 1 | # build-iphonesimulator-x86_64 2 | 3 | set(CMAKE_SYSTEM_NAME iOS) 4 | set(CMAKE_SYSTEM_PROCESSOR x86_64) 5 | 6 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch x86_64") 7 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch x86_64") 8 | 9 | # for libsodium 10 | set(triple x86_64-apple-darwin10) 11 | execute_process(COMMAND /usr/bin/xcrun -sdk iphonesimulator --show-sdk-path 12 | OUTPUT_VARIABLE CMAKE_OSX_SYSROOT 13 | OUTPUT_STRIP_TRAILING_WHITESPACE) 14 | 15 | set(ENV{CFLAGS} "-arch x86_64 -isysroot ${CMAKE_OSX_SYSROOT}") 16 | set(ENV{LDFLAGS} "-arch x86_64 -isysroot ${CMAKE_OSX_SYSROOT}") 17 | 18 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 19 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 20 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 21 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 22 | -------------------------------------------------------------------------------- /toolchains/linux-embedded.cmake: -------------------------------------------------------------------------------- 1 | if (NOT DEFINED ENV{TOOLCHAIN}) 2 | message(FATAL_ERROR "TOOLCHAIN environment variable is not set") 3 | endif () 4 | 5 | set(triple mips-openwrt-linux) 6 | 7 | set(CMAKE_SYSTEM_NAME Linux) 8 | set(CMAKE_SYSTEM_PROCESSOR mips) 9 | 10 | set(CMAKE_SYSROOT $ENV{TOOLCHAIN}/) 11 | set(CMAKE_C_COMPILER $ENV{TOOLCHAIN}/bin/${triple}-gcc) 12 | set(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN}/bin/${triple}-g++) 13 | 14 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 15 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 16 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 17 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 18 | -------------------------------------------------------------------------------- /toolchains/macOS-arm64.cmake: -------------------------------------------------------------------------------- 1 | # build-macOS-arm64 2 | 3 | if (NOT (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") AND 4 | NOT(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64") ) 5 | set(CMAKE_SYSTEM_NAME Darwin) 6 | set(CMAKE_SYSTEM_PROCESSOR arm64) 7 | endif () 8 | 9 | set(ZITI_BUILD_TESTS OFF CACHE BOOL "" FORCE) 10 | 11 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch arm64") 12 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch arm64") 13 | 14 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 15 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 16 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 17 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 18 | -------------------------------------------------------------------------------- /toolchains/macOS-x86_64.cmake: -------------------------------------------------------------------------------- 1 | # build-macOS-x86_64 2 | 3 | set(CMAKE_SYSTEM_NAME Darwin) 4 | set(CMAKE_SYSTEM_PROCESSOR x86_64) 5 | 6 | set(ZITI_BUILD_TESTS OFF CACHE BOOL "" FORCE) 7 | 8 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch x86_64") 9 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch x86_64") 10 | 11 | # for libsodium 12 | set(triple x86_64-apple-macos11) 13 | execute_process(COMMAND /usr/bin/xcrun -sdk macosx --show-sdk-path 14 | OUTPUT_VARIABLE CMAKE_OSX_SYSROOT 15 | OUTPUT_STRIP_TRAILING_WHITESPACE) 16 | 17 | set(ENV{CFLAGS} "-arch x86_64 -isysroot ${CMAKE_OSX_SYSROOT}") 18 | set(ENV{LDFLAGS} "-arch x86_64 -isysroot ${CMAKE_OSX_SYSROOT}") 19 | 20 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 21 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 22 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 23 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 24 | -------------------------------------------------------------------------------- /vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ziti", 3 | "version-semver": "1.0.0", 4 | "dependencies": [ 5 | "libuv", 6 | "openssl", 7 | "zlib", 8 | "llhttp", 9 | "libsodium", 10 | "json-c", 11 | "protobuf-c" 12 | ], 13 | "features": { 14 | "test": { 15 | "description": "Dependencies for testing", 16 | "dependencies": [ 17 | { 18 | "version>=": "3.3.1", 19 | "name": "catch2" 20 | } 21 | ] 22 | }, 23 | "samples": { 24 | "description": "Dependencies for samples", 25 | "dependencies": [ 26 | { 27 | "name": "cli11" 28 | } 29 | ] 30 | }, 31 | "dev-features": { 32 | "description": "features for development", 33 | "dependencies": [ 34 | { 35 | "name": "ziti", 36 | "features": [ "test", "samples" ] 37 | } 38 | ] 39 | } 40 | }, 41 | "builtin-baseline": "b322364f06308bdd24823f9d8f03fe0cc86fd46f" 42 | } 43 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | $Format: %(describe:tags)$ 2 | ref: $Format: %D$ 3 | hash: $Format: %h$ -------------------------------------------------------------------------------- /ziti.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=${prefix} 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: ziti 7 | Version: @PROJECT_VERSION@ 8 | Description: multi-platform support library to build Ziti Enabled Applications 9 | URL: http://netfoundry.io/ 10 | 11 | Libs: -L${libdir} -lziti -luv_mbed -lmbedtls -lmbedx509 -lmbedcrypto -luv_a -lpthread -lprotobuf-c 12 | Cflags: -I${includedir} --------------------------------------------------------------------------------