diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index 302ce48..0000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,6 +0,0 @@ -[target.'cfg(unix)'] -runner = "sudo -E" - -[alias] # command aliases -rr = "run --release" -bb = "build --release" diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index e855853..0000000 --- a/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -# Xcode -Apple/ - -# Rust -target/ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9a9b5b2..20c920e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1 @@ -* @conradev @malted @JettChenT @jdogcoder -burrow/ @conradev @malted @JettChenT @jdogcoder @Muirrum -tun/ @conradev @malted @JettChenT @jdogcoder @Muirrum -burrow-gtk/ @conradev @malted @JettChenT @jdogcoder @davnotdev +* @conradev diff --git a/.github/actions/archive/action.yml b/.github/actions/archive/action.yml index e49eb0d..c34bd3c 100644 --- a/.github/actions/archive/action.yml +++ b/.github/actions/archive/action.yml @@ -26,18 +26,18 @@ runs: run: | echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8 - xcodebuild clean archive \ + xcodebuild archive \ -allowProvisioningUpdates \ -allowProvisioningDeviceRegistration \ - -skipPackagePluginValidation \ - -skipMacroValidation \ - -onlyUsePackageVersionsFromResolvedFile \ -authenticationKeyID ${{ inputs.app-store-key-id }} \ -authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \ -authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \ + -onlyUsePackageVersionsFromResolvedFile \ -scheme '${{ inputs.scheme }}' \ -destination '${{ inputs.destination }}' \ -archivePath '${{ inputs.archive-path }}' \ -resultBundlePath BuildResults.xcresult + ./Tools/xcresulttool-github BuildResults.xcresult + rm -rf AuthKey_${{ inputs.app-store-key-id }}.p8 diff --git a/.github/actions/build-for-testing/action.yml b/.github/actions/build-for-testing/action.yml index 185c4ab..9691122 100644 --- a/.github/actions/build-for-testing/action.yml +++ b/.github/actions/build-for-testing/action.yml @@ -18,36 +18,18 @@ inputs: runs: using: composite steps: - - name: Xcode Cache - uses: actions/cache@v3 - with: - path: | - Apple/PackageCache - Apple/SourcePackages - Apple/DerivedData - key: ${{ runner.os }}-${{ inputs.scheme }}-${{ hashFiles('**/Package.resolved') }} - restore-keys: | - ${{ runner.os }}-${{ inputs.scheme }}-${{ hashFiles('**/Package.resolved') }} - ${{ runner.os }}-${{ inputs.scheme }}- - ${{ runner.os }}- - - name: Build - shell: bash + - shell: bash working-directory: Apple run: | echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8 - xcodebuild build-for-testing \ + xcodebuild clean build-for-testing \ -allowProvisioningUpdates \ -allowProvisioningDeviceRegistration \ - -skipPackagePluginValidation \ - -skipMacroValidation \ - -onlyUsePackageVersionsFromResolvedFile \ -authenticationKeyID ${{ inputs.app-store-key-id }} \ -authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \ -authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \ - -clonedSourcePackagesDirPath SourcePackages \ - -packageCachePath $PWD/PackageCache \ - -derivedDataPath $PWD/DerivedData \ + -onlyUsePackageVersionsFromResolvedFile \ -scheme '${{ inputs.scheme }}' \ -destination '${{ inputs.destination }}' \ -resultBundlePath BuildResults.xcresult diff --git a/.github/actions/download-profiles/action.yml b/.github/actions/download-profiles/action.yml deleted file mode 100644 index 32b615c..0000000 --- a/.github/actions/download-profiles/action.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Download Provisioning Profiles -inputs: - app-store-key: - description: App Store key in PEM PKCS#8 format - required: true - app-store-key-id: - description: App Store key ID - required: true - app-store-key-issuer-id: - description: App Store key issuer ID - required: true -runs: - using: composite - steps: - - shell: bash - env: - FASTLANE_OPT_OUT_USAGE: 'YES' - run: | - APP_STORE_KEY=$(echo "${{ inputs.app-store-key }}" | jq -sR .) - cat << EOF > api-key.json - { - "key_id": "${{ inputs.app-store-key-id }}", - "issuer_id": "${{ inputs.app-store-key-issuer-id }}", - "key": $APP_STORE_KEY - } - EOF - - fastlane sigh download_all --api_key_path api-key.json - - rm -rf api-key.json diff --git a/.github/actions/export/action.yml b/.github/actions/export/action.yml index 75b748f..bf007a7 100644 --- a/.github/actions/export/action.yml +++ b/.github/actions/export/action.yml @@ -1,4 +1,4 @@ -name: Export +name: Notarize inputs: app-store-key: description: App Store key in PEM PKCS#8 format @@ -12,8 +12,11 @@ inputs: archive-path: description: Xcode archive path required: true - export-options: - description: The export options in JSON format + destination: + description: The Xcode export destination. This can either be "export" or "upload" + required: true + method: + description: The Xcode export method. This can be one of app-store, validation, ad-hoc, package, enterprise, development, developer-id, or mac-application. required: true export-path: description: The path to export the archive to @@ -21,20 +24,19 @@ inputs: runs: using: composite steps: - - shell: bash + - id: notarize + shell: bash working-directory: Apple run: | echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8 - echo '${{ inputs.export-options }}' | plutil -convert xml1 -o ExportOptions.plist - + echo '{"destination":"${{ inputs.destination }}","method":"${{ inputs.method }}"}' \ + | plutil -convert xml1 -o ExportOptions.plist - xcodebuild \ -exportArchive \ -allowProvisioningUpdates \ -allowProvisioningDeviceRegistration \ - -skipPackagePluginValidation \ - -skipMacroValidation \ - -onlyUsePackageVersionsFromResolvedFile \ -authenticationKeyID ${{ inputs.app-store-key-id }} \ -authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \ -authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \ diff --git a/.github/actions/notarize/action.yml b/.github/actions/notarize/action.yml deleted file mode 100644 index efd2159..0000000 --- a/.github/actions/notarize/action.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Notarize -inputs: - app-store-key: - description: App Store key in PEM PKCS#8 format - required: true - app-store-key-id: - description: App Store key ID - required: true - app-store-key-issuer-id: - description: App Store key issuer ID - required: true -runs: - using: composite - steps: - - id: notarize - shell: bash - working-directory: Apple - run: | - echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8 - - ditto -c -k --keepParent Release/Burrow.app Upload.zip - xcrun notarytool submit --wait --issuer ${{ inputs.app-store-key-issuer-id }} --key-id ${{ inputs.app-store-key-id }} --key "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" Upload.zip - xcrun stapler staple Release/Burrow.app - - rm -rf AuthKey_${{ inputs.app-store-key-id }}.p8 Release diff --git a/.github/actions/test-without-building/action.yml b/.github/actions/test-without-building/action.yml index a097d4a..5903d07 100644 --- a/.github/actions/test-without-building/action.yml +++ b/.github/actions/test-without-building/action.yml @@ -18,6 +18,9 @@ inputs: runs: using: composite steps: + - shell: bash + id: vars + run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - shell: bash working-directory: Apple run: | @@ -25,10 +28,10 @@ runs: -scheme '${{ inputs.scheme }}' \ -destination '${{ inputs.destination }}' \ ${{ inputs.test-plan && '-testPlan ' }}${{ inputs.test-plan }} \ - -resultBundlePath "${{ inputs.artifact-prefix }}.xcresult" + -resultBundlePath "${{ inputs.artifact-prefix }}-${{ steps.vars.outputs.sha_short }}.xcresult" - uses: kishikawakatsumi/xcresulttool@v1 if: always() with: - path: Apple/${{ inputs.artifact-prefix }}.xcresult + path: Apple/${{ inputs.artifact-prefix }}-${{ steps.vars.outputs.sha_short }}.xcresult title: ${{ inputs.check-name }} show-passed-tests: false diff --git a/.github/workflows/build-appimage.yml b/.github/workflows/build-appimage.yml deleted file mode 100644 index bd29b07..0000000 --- a/.github/workflows/build-appimage.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Build AppImage -on: - push: - branches: - - main - pull_request: - branches: - - "*" -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true -jobs: - appimage: - name: Build AppImage - runs-on: ubuntu-latest - container: docker - steps: - - uses: actions/checkout@v4 - - name: Build AppImage - run: | - docker build -t appimage-builder . -f burrow-gtk/build-aux/Dockerfile - docker create --name temp appimage-builder - docker cp temp:/app/burrow-gtk/build-appimage/Burrow-x86_64.AppImage . - docker rm temp - - uses: actions/upload-artifact@v4 - name: Upload to GitHub - with: - name: AppImage - path: Burrow-x86_64.AppImage diff --git a/.github/workflows/build-apple.yml b/.github/workflows/build-apple.yml index 7ae8c4c..d1dba49 100644 --- a/.github/workflows/build-apple.yml +++ b/.github/workflows/build-apple.yml @@ -1,45 +1,33 @@ -name: Build Apple Apps +name: Apple Build on: push: - branches: + branches: - main pull_request: branches: - "*" -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true jobs: build: name: Build App (${{ matrix.platform }}) - runs-on: macos-14 + runs-on: macos-12 strategy: fail-fast: false matrix: include: - - scheme: App + - scheme: Burrow destination: generic/platform=iOS platform: iOS sdk-name: iphoneos - rust-targets: - - aarch64-apple-ios - - scheme: App - destination: platform=iOS Simulator,OS=18.0,name=iPhone 15 Pro + - scheme: Burrow + destination: platform=iOS Simulator,OS=16.2,name=iPhone 14 Pro platform: iOS Simulator sdk-name: iphonesimulator - rust-targets: - - aarch64-apple-ios-sim - - x86_64-apple-ios - - scheme: App + - scheme: Burrow destination: platform=macOS platform: macOS sdk-name: macos - rust-targets: - - x86_64-apple-darwin - - aarch64-apple-darwin env: - DEVELOPER_DIR: /Applications/Xcode_16.0.app/Contents/Developer - PROTOC_PATH: /opt/homebrew/bin/protoc + DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@v3 @@ -51,13 +39,6 @@ jobs: with: certificate: ${{ secrets.DEVELOPER_CERT }} password: ${{ secrets.DEVELOPER_CERT_PASSWORD }} - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - with: - targets: ${{ join(matrix.rust-targets, ', ') }} - - name: Install Protobuf - shell: bash - run: brew install protobuf - name: Build id: build uses: ./.github/actions/build-for-testing @@ -67,7 +48,7 @@ jobs: app-store-key: ${{ secrets.APPSTORE_KEY }} app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }} app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }} - - name: Run Unit Tests + - name: Xcode Unit Test if: ${{ matrix.xcode-unit-test != '' }} continue-on-error: true uses: ./.github/actions/test-without-building @@ -77,7 +58,7 @@ jobs: test-plan: ${{ matrix.xcode-unit-test }} artifact-prefix: unit-tests-${{ matrix.sdk-name }} check-name: Xcode Unit Tests (${{ matrix.platform }}) - - name: Run UI Tests + - name: Xcode UI Test if: ${{ matrix.xcode-ui-test != '' }} continue-on-error: true uses: ./.github/actions/test-without-building @@ -86,4 +67,4 @@ jobs: destination: ${{ matrix.destination }} test-plan: ${{ matrix.xcode-ui-test }} artifact-prefix: ui-tests-${{ matrix.sdk-name }} - check-name: Xcode UI Tests (${{ matrix.platform }}) \ No newline at end of file + check-name: Xcode UI Tests (${{ matrix.platform }}) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml deleted file mode 100644 index 6a3dae1..0000000 --- a/.github/workflows/build-docker.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build Docker -on: - push: - branches: - - main - pull_request: - branches: - - "*" -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true -jobs: - build: - name: Build Docker Image - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - steps: - - name: Setup QEMU - uses: docker/setup-qemu-action@v2 - with: - platforms: arm64 - - name: Setup BuildKit - uses: docker/setup-buildx-action@v2 - - name: Authenticate - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract Metadata - id: meta - uses: docker/metadata-action@v4 - with: - images: ghcr.io/${{ github.repository }} - tags: | - type=sha - type=match,pattern=builds/(.*),group=1 - type=raw,value=latest,enable={{is_default_branch}} - - name: Build and Push - uses: docker/build-push-action@v4 - with: - platforms: ${{ github.event_name != 'pull_request' && 'linux/amd64,linux/arm64' || 'linux/amd64' }} - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/.github/workflows/build-flatpak.yml b/.github/workflows/build-flatpak.yml deleted file mode 100644 index d74eec3..0000000 --- a/.github/workflows/build-flatpak.yml +++ /dev/null @@ -1,16 +0,0 @@ -on: workflow_dispatch -name: Build Flatpak -jobs: - flatpak: - name: Build Flatpak - runs-on: ubuntu-latest - container: - image: bilelmoussaoui/flatpak-github-actions:gnome-45 - options: --privileged - steps: - - uses: actions/checkout@v4 - - uses: flatpak/flatpak-github-actions/flatpak-builder@v6 - with: - bundle: Burrow.flatpak - manifest-path: burrow-gtk/build-aux/com.hackclub.burrow.devel.json - cache-key: flatpak-builder-${{ github.sha }} diff --git a/.github/workflows/build-rpm.yml b/.github/workflows/build-rpm.yml deleted file mode 100644 index 029bf16..0000000 --- a/.github/workflows/build-rpm.yml +++ /dev/null @@ -1,17 +0,0 @@ -on: workflow_dispatch -name: Build RPM -jobs: - build: - name: Build RPM - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - name: Install RPM - run: cargo install cargo-generate-rpm - - name: Build RPM - run: | - cargo build --release - strip -s target/release/burrow - - name: Build RPM - run: cargo generate-rpm -p burrow diff --git a/.github/workflows/build-rust.yml b/.github/workflows/build-rust.yml index 95fc628..8048a3a 100644 --- a/.github/workflows/build-rust.yml +++ b/.github/workflows/build-rust.yml @@ -1,7 +1,7 @@ -name: Build Rust Crate +name: Rust Build on: push: - branches: + branches: - main pull_request: branches: @@ -17,38 +17,28 @@ jobs: platform: Linux packages: - gcc-aarch64-linux-gnu - test-targets: + targets: - x86_64-unknown-linux-gnu - targets: - aarch64-unknown-linux-gnu - - os: macos-13 - platform: macOS (Intel) - xcode: /Applications/Xcode_15.2.app - test-targets: - - x86_64-apple-darwin - targets: - - x86_64-apple-ios - - os: macos-14 + - os: macos-12 platform: macOS - xcode: /Applications/Xcode_16.0.app - test-targets: - - aarch64-apple-darwin targets: + - x86_64-apple-darwin + - aarch64-apple-darwin - aarch64-apple-ios - aarch64-apple-ios-sim + - x86_64-apple-ios - os: windows-2022 platform: Windows - test-targets: - - x86_64-pc-windows-msvc targets: + - x86_64-pc-windows-msvc - aarch64-pc-windows-msvc runs-on: ${{ matrix.os }} env: - DEVELOPER_DIR: ${{ matrix.xcode }}/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer CARGO_INCREMENTAL: 0 CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc RUST_BACKTRACE: short - PROTOC_VERSION: 3.25.1 steps: - name: Checkout uses: actions/checkout@v3 @@ -58,28 +48,13 @@ jobs: - name: Install Packages if: matrix.os == 'ubuntu-latest' shell: bash - run: | - sudo apt-get update - sudo apt-get install -y ${{ join(matrix.packages, ' ') }} - - name: Configure LLVM - if: matrix.os == 'windows-2022' - shell: bash - run: echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH - - name: Install protoc - uses: taiki-e/install-action@v2 - with: - tool: protoc@${{ env.PROTOC_VERSION }} + run: sudo apt-get install -y ${{ join(matrix.packages, ' ') }} - name: Install Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@master with: toolchain: stable components: rustfmt targets: ${{ join(matrix.targets, ', ') }} - - name: Setup Rust Cache - uses: Swatinem/rust-cache@v2 - name: Build shell: bash - run: cargo build --verbose --workspace --all-features --target ${{ join(matrix.targets, ' --target ') }} --target ${{ join(matrix.test-targets, ' --target ') }} - - name: Test - shell: bash - run: cargo test --verbose --workspace --all-features --target ${{ join(matrix.test-targets, ' --target ') }} \ No newline at end of file + run: cargo build --verbose --workspace --all-features --target ${{ join(matrix.targets, ' --target ') }} diff --git a/.github/workflows/lint-git.yml b/.github/workflows/lint-git.yml index 2f7c72e..aefe199 100644 --- a/.github/workflows/lint-git.yml +++ b/.github/workflows/lint-git.yml @@ -8,14 +8,13 @@ jobs: name: Git Lint runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - name: Install - shell: bash - run: python -m pip install gitlint - - name: Lint - shell: bash - run: gitlint --commits "${{ github.event.pull_request.base.sha }}..HEAD" + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + - name: Install Gitlint + shell: bash + run: python -m pip install gitlint + - name: Run Gitlint + shell: bash + run: gitlint --commits "${{ github.event.pull_request.base.sha }}..HEAD" diff --git a/.github/workflows/lint-swift.yml b/.github/workflows/lint-swift.yml index 857f575..7e62afd 100644 --- a/.github/workflows/lint-swift.yml +++ b/.github/workflows/lint-swift.yml @@ -1,5 +1,8 @@ name: Swift Lint on: + push: + branches: + - main pull_request: branches: - "*" @@ -11,6 +14,8 @@ jobs: image: ghcr.io/realm/swiftlint:latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v3 + with: + ssh-key: ${{ secrets.DEPLOY_KEY }} - name: Lint - run: swiftlint lint --strict --reporter github-actions-logging + run: swiftlint lint --reporter github-actions-logging diff --git a/.github/workflows/release-apple.yml b/.github/workflows/release-apple.yml index c869d6a..8b8a76c 100644 --- a/.github/workflows/release-apple.yml +++ b/.github/workflows/release-apple.yml @@ -1,119 +1,65 @@ -name: Release (Apple) +name: Build Apple Release on: release: types: - created jobs: build: - name: Build ${{ matrix.platform }} Release - runs-on: macos-14 - permissions: - contents: write + name: Build ${{ matrix.configuration['platform'] }} Release + runs-on: macos-12 strategy: fail-fast: false matrix: - include: - - platform: iOS - rust-targets: - - aarch64-apple-ios - - platform: macOS - rust-targets: - - x86_64-apple-darwin - - aarch64-apple-darwin + configuration: + - scheme: App (iOS) + destination: generic/platform=iOS + platform: iOS + method: ad-hoc + artifact-file: Apple/Release/Burrow.ipa + - scheme: App (macOS) + destination: generic/platform=macOS + platform: macOS + method: mac-application + artifact-file: Burrow.app.txz env: - DEVELOPER_DIR: /Applications/Xcode_16.0.app/Contents/Developer - PROTOC_PATH: /opt/homebrew/bin/protoc + DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v3 with: - fetch-depth: 0 + ssh-key: ${{ secrets.DEPLOY_KEY }} + submodules: recursive - name: Import Certificate uses: ./.github/actions/import-cert with: certificate: ${{ secrets.DEVELOPER_CERT }} password: ${{ secrets.DEVELOPER_CERT_PASSWORD }} - - name: Download Provisioning Profiles - uses: ./.github/actions/download-profiles - with: - app-store-key: ${{ secrets.APPSTORE_KEY }} - app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }} - app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }} - - name: Install Provisioning Profiles - shell: bash - run: | - mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles/ - cp -f Apple/Profiles/* ~/Library/MobileDevice/Provisioning\ Profiles/ - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - with: - targets: ${{ join(matrix.rust-targets, ', ') }} - - name: Install Protobuf - shell: bash - run: brew install protobuf - - name: Configure Version - id: version - shell: bash - run: echo "BUILD_NUMBER=$(Tools/version.sh)" >> $GITHUB_OUTPUT - name: Archive uses: ./.github/actions/archive with: - scheme: App - destination: generic/platform=${{ matrix.platform }} + scheme: ${{ matrix.configuration['scheme'] }} + destination: ${{ matrix.configuration['destination'] }} app-store-key: ${{ secrets.APPSTORE_KEY }} app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }} app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }} archive-path: Burrow.xcarchive - - name: Export + - name: Export Locally uses: ./.github/actions/export with: - method: ${{ matrix.platform == 'macOS' && 'developer-id' || 'ad-hoc' }} + method: ${{ matrix.configuration['method'] }} destination: export app-store-key: ${{ secrets.APPSTORE_KEY }} app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }} app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }} archive-path: Burrow.xcarchive - export-options: | - {"teamID":"P6PV2R9443","destination":"export","method":"developer-id","provisioningProfiles":{"com.hackclub.burrow":"Burrow Developer ID","com.hackclub.burrow.network":"Burrow Network Developer ID"},"signingCertificate":"Developer ID Application","signingStyle":"manual"} export-path: Release - - name: Notarize - if: ${{ matrix.platform == 'macOS' }} - uses: ./.github/actions/notarize - with: - app-store-key: ${{ secrets.APPSTORE_KEY }} - app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }} - app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }} - - name: Compress (iOS) - if: ${{ matrix.platform == 'iOS' }} + - name: Compress + if: ${{ matrix.configuration['platform'] == 'macOS' }} shell: bash - run: | - cp Apple/Release/Burrow.ipa Burrow.ipa - aa archive -a lzma -b 8m -d Apple -subdir Burrow.xcarchive -o Burrow-${{ matrix.platform }}.xcarchive.aar - rm -rf Apple/Release - - name: Compress (macOS) - if: ${{ matrix.platform == 'macOS' }} - shell: bash - run: | - aa archive -a lzma -b 8m -d Apple/Release -subdir Burrow.app -o Burrow.app.aar - aa archive -a lzma -b 8m -d Apple -subdir Burrow.xcarchive -o Burrow-${{ matrix.platform }}.xcarchive.aar - rm -rf Apple/Release - - name: Upload to GitHub - uses: SierraSoftworks/gh-releases@v1.0.7 + run: tar --options xz:compression-level=9 -C Apple/Release -cJf Burrow.app.txz ./ + - name: Attach Artifact + uses: SierraSoftworks/gh-releases@v1.0.6 with: token: ${{ secrets.GITHUB_TOKEN }} - release_tag: ${{ github.ref_name }} - overwrite: 'true' - files: | - ${{ matrix.platform == 'macOS' && 'Burrow.aap.aar' || 'Burrow.ipa' }} - Burrow-${{ matrix.platform }}.xcarchive.aar - - name: Upload to App Store Connect - if: ${{ matrix.platform == 'iOS' }} - uses: ./.github/actions/export - with: - app-store-key: ${{ secrets.APPSTORE_KEY }} - app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }} - app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }} - archive-path: Burrow.xcarchive - export-options: | - {"method": "app-store", "destination": "upload"} - export-path: Release + overwrite: 'false' + files: ${{ matrix.configuration['artifact-file'] }} diff --git a/.github/workflows/release-if-needed.yaml b/.github/workflows/release-if-needed.yaml deleted file mode 100644 index 79f0d63..0000000 --- a/.github/workflows/release-if-needed.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Create Release If Needed -on: - workflow_dispatch: - schedule: - - cron: '0 10 * * *' -concurrency: - group: ${{ github.workflow }} -jobs: - create: - name: Create Release If Needed - runs-on: ubuntu-latest - env: - GH_TOKEN: ${{ github.token }} - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - shell: bash - run: | - if [[ $(Tools/version.sh status) == "dirty" ]]; then - gh workflow run release-now.yml - fi diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml deleted file mode 100644 index 7db9bcf..0000000 --- a/.github/workflows/release-linux.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Release (Linux) -on: - release: - types: - - created -jobs: - appimage: - name: Build AppImage - runs-on: ubuntu-latest - container: docker - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Build AppImage - run: | - docker build -t appimage-builder . -f burrow-gtk/build-aux/Dockerfile - docker create --name temp appimage-builder - docker cp temp:/app/burrow-gtk/build-appimage/Burrow-x86_64.AppImage . - docker rm temp - - name: Attach Artifacts - uses: SierraSoftworks/gh-releases@v1.0.7 - with: - token: ${{ secrets.GITHUB_TOKEN }} - release_tag: ${{ github.ref_name }} - overwrite: "true" - files: | - Burrow-x86_64.AppImage diff --git a/.github/workflows/release-now.yml b/.github/workflows/release-now.yml deleted file mode 100644 index 229f6c9..0000000 --- a/.github/workflows/release-now.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Create Release -on: workflow_dispatch -concurrency: - group: ${{ github.workflow }} -jobs: - create: - env: - GH_TOKEN: ${{ secrets.GH_RELEASE_TOKEN }} - name: Create Release - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - shell: bash - run: Tools/version.sh increment diff --git a/.gitignore b/.gitignore index 1b300b4..102ee0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,5 @@ # Xcode xcuserdata -# Swift -Apple/Package/.swiftpm/ - # Rust target/ -.env - -.DS_STORE -.idea/ - -tmp/ - -*.db -*.sock \ No newline at end of file diff --git a/.gitlint b/.gitlint index a72a004..b185b1c 100644 --- a/.gitlint +++ b/.gitlint @@ -1,5 +1,5 @@ [general] -ignore=body-changed-file-mention,body-is-missing +ignore=body-changed-file-mention ignore-merge-commits=false ignore-fixup-commits=false ignore-squash-commits=false diff --git a/.rustfmt.toml b/.rustfmt.toml deleted file mode 100644 index 2a12e19..0000000 --- a/.rustfmt.toml +++ /dev/null @@ -1,12 +0,0 @@ -condense_wildcard_suffixes = true -format_macro_matchers = true -imports_layout = "HorizontalVertical" -imports_granularity = "Crate" -newline_style = "Unix" -overflow_delimited_expr = true -reorder_impl_items = true -group_imports = "StdExternalCrate" -trailing_semicolon = false -use_field_init_shorthand = true -use_try_shorthand = true -struct_lit_width = 30 diff --git a/.swiftlint.yml b/.swiftlint.yml index 8efc85e..d609718 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -30,6 +30,7 @@ opt_in_rules: - function_default_parameter_at_end - ibinspectable_in_extension - identical_operands +- implicitly_unwrapped_optional - indentation_width - joined_default_parameter - last_where @@ -45,6 +46,7 @@ opt_in_rules: - multiline_parameters - multiline_parameters_brackets - no_extension_access_modifier +- no_grouping_extension - nslocalizedstring_key - nslocalizedstring_require_bundle - number_separator @@ -74,7 +76,9 @@ opt_in_rules: - sorted_first_last - sorted_imports - static_operator +- strict_fileprivate - strong_iboutlet +- switch_case_on_newline - test_case_accessibility - toggle_bool - trailing_closure @@ -93,5 +97,3 @@ disabled_rules: - force_try - nesting - todo -- trailing_comma -- switch_case_on_newline diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e40eae1..c5c0dd4 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,5 @@ { "recommendations": [ "rust-lang.rust-analyzer", - "vadimcn.vscode-lldb", ] -} \ No newline at end of file +} diff --git a/.vscode/settings.json b/.vscode/settings.json index eb85504..55c07df 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,26 +1,15 @@ { - "files.autoSave": "onFocusChange", - "files.defaultLanguage": "rust", - "editor.formatOnPaste": true, - "editor.formatOnSave": true, - "files.trimTrailingWhitespace": true, - "editor.suggest.preview": true, - "editor.acceptSuggestionOnEnter": "on", - "rust-analyzer.restartServerOnConfigChange": true, - "rust-analyzer.cargo.features": "all", - "rust-analyzer.rustfmt.extraArgs": ["+nightly"], - "[rust]": { - "editor.defaultFormatter": "rust-lang.rust-analyzer" - }, - "rust-analyzer.inlayHints.typeHints.enable": false, - "rust-analyzer.linkedProjects": [ - "./burrow/Cargo.toml" - ], - "[yaml]": { - "editor.insertSpaces": true, - "editor.tabSize": 2, - "editor.autoIndent": "advanced", - "diffEditor.ignoreTrimWhitespace": false, - "editor.formatOnSave": false - } + "files.autoSave": "onFocusChange", + "files.defaultLanguage": "rust", + "editor.formatOnPaste": true, + "editor.formatOnSave": true, + "files.trimTrailingWhitespace": true, + "editor.suggest.preview": true, + "editor.acceptSuggestionOnEnter": "on", + "rust-analyzer.checkOnSave.command": "clippy", + "rust-analyzer.restartServerOnConfigChange": true, + "rust-analyzer.cargo.features": "all", + "[rust]": { + "editor.defaultFormatter": "rust-lang.rust-analyzer", + }, } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3eb24be..eb2a68a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,7 +3,7 @@ "tasks": [ { "type": "cargo", - "command": "clippy", + "command": "check", "problemMatcher": [ "$rustc" ], @@ -11,13 +11,7 @@ "kind": "build", "isDefault": true }, - "label": "rust: cargo clippy", - "args": [ - "--workspace", - "--all-targets", - "--all-features", - "--all" - ] - }, + "label": "Check" + } ] } \ No newline at end of file diff --git a/Apple/.DS_Store b/Apple/.DS_Store new file mode 100644 index 0000000..6bf97d7 Binary files /dev/null and b/Apple/.DS_Store differ diff --git a/Apple/App/App-iOS.entitlements b/Apple/App/App-iOS.entitlements index 53fcbb7..02ee960 100644 --- a/Apple/App/App-iOS.entitlements +++ b/Apple/App/App-iOS.entitlements @@ -2,11 +2,6 @@ - com.apple.developer.associated-domains - - applinks:burrow.rs?mode=developer - webcredentials:burrow.rs?mode=developer - com.apple.developer.networking.networkextension packet-tunnel-provider diff --git a/Apple/App/App-macOS.entitlements b/Apple/App/App-macOS.entitlements index 53fcbb7..7395b5c 100644 --- a/Apple/App/App-macOS.entitlements +++ b/Apple/App/App-macOS.entitlements @@ -2,11 +2,6 @@ - com.apple.developer.associated-domains - - applinks:burrow.rs?mode=developer - webcredentials:burrow.rs?mode=developer - com.apple.developer.networking.networkextension packet-tunnel-provider @@ -14,6 +9,7 @@ com.apple.security.application-groups $(APP_GROUP_IDENTIFIER) + group.ThomasStubblefield.Unifriend.onesignal diff --git a/Apple/App/AppDelegate.swift b/Apple/App/AppDelegate.swift index 0ea93f4..25c9baf 100644 --- a/Apple/App/AppDelegate.swift +++ b/Apple/App/AppDelegate.swift @@ -1,53 +1,14 @@ #if os(macOS) import AppKit -import BurrowUI -import SwiftUI +import FluidMenuBarExtra -@main -@MainActor class AppDelegate: NSObject, NSApplicationDelegate { - private let quitItem: NSMenuItem = { - let quitItem = NSMenuItem( - title: "Quit Burrow", - action: #selector(NSApplication.terminate(_:)), - keyEquivalent: "q" - ) - quitItem.target = NSApplication.shared - quitItem.keyEquivalentModifierMask = .command - return quitItem - }() - - private let toggleItem: NSMenuItem = { - let toggleView = NSHostingView(rootView: MenuItemToggleView()) - toggleView.frame.size = CGSize(width: 300, height: 32) - toggleView.autoresizingMask = [.width] - - let toggleItem = NSMenuItem() - toggleItem.view = toggleView - return toggleItem - }() - - private lazy var menu: NSMenu = { - let menu = NSMenu() - menu.items = [ - toggleItem, - .separator(), - quitItem - ] - return menu - }() - - private lazy var statusItem: NSStatusItem = { - let statusBar = NSStatusBar.system - let statusItem = statusBar.statusItem(withLength: NSStatusItem.squareLength) - if let button = statusItem.button { - button.image = NSImage(systemSymbolName: "network.badge.shield.half.filled", accessibilityDescription: nil) - } - return statusItem - }() - + private var menuBarExtra: FluidMenuBarExtra? + func applicationDidFinishLaunching(_ notification: Notification) { - statusItem.menu = menu + self.menuBarExtra = FluidMenuBarExtra(title: "Burrow", systemImage: "network.badge.shield.half.filled") { + ContentView() + } } } #endif diff --git a/Apple/UI/Assets.xcassets/AccentColor.colorset/Contents.json b/Apple/App/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from Apple/UI/Assets.xcassets/AccentColor.colorset/Contents.json rename to Apple/App/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/Apple/App/Assets.xcassets/AppIcon.appiconset/Contents.json b/Apple/App/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..532cd72 --- /dev/null +++ b/Apple/App/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,63 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Apple/UI/Assets.xcassets/Contents.json b/Apple/App/Assets.xcassets/Contents.json similarity index 100% rename from Apple/UI/Assets.xcassets/Contents.json rename to Apple/App/Assets.xcassets/Contents.json diff --git a/Apple/UI/Assets.xcassets/WireGuardTitle.imageset/Contents.json b/Apple/App/Assets.xcassets/hackClubLogo.imageset/Contents.json similarity index 86% rename from Apple/UI/Assets.xcassets/WireGuardTitle.imageset/Contents.json rename to Apple/App/Assets.xcassets/hackClubLogo.imageset/Contents.json index 782dd12..76da2cb 100644 --- a/Apple/UI/Assets.xcassets/WireGuardTitle.imageset/Contents.json +++ b/Apple/App/Assets.xcassets/hackClubLogo.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "WireGuardTitle.svg", + "filename" : "hackClubLogo.png", "idiom" : "universal", "scale" : "1x" }, diff --git a/Apple/App/Assets.xcassets/hackClubLogo.imageset/hackClubLogo.png b/Apple/App/Assets.xcassets/hackClubLogo.imageset/hackClubLogo.png new file mode 100644 index 0000000..6823ccf Binary files /dev/null and b/Apple/App/Assets.xcassets/hackClubLogo.imageset/hackClubLogo.png differ diff --git a/Apple/App/App.xcconfig b/Apple/App/Burrow.xcconfig similarity index 67% rename from Apple/App/App.xcconfig rename to Apple/App/Burrow.xcconfig index 4e42ddc..a4922de 100644 --- a/Apple/App/App.xcconfig +++ b/Apple/App/Burrow.xcconfig @@ -2,7 +2,6 @@ PRODUCT_NAME = Burrow PRODUCT_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER) -PRODUCT_MODULE_NAME = BurrowApp INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphone*] = YES INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphone*] = YES @@ -11,13 +10,8 @@ INFOPLIST_KEY_UIStatusBarStyle[sdk=iphone*] = UIStatusBarStyleDefault INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad[sdk=iphone*] = UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone[sdk=iphone*] = UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight TARGETED_DEVICE_FAMILY[sdk=iphone*] = 1,2 -EXCLUDED_SOURCE_FILE_NAMES = MainMenu.xib -EXCLUDED_SOURCE_FILE_NAMES[sdk=macosx*] = -INFOPLIST_KEY_LSUIElement[sdk=macosx*] = YES -INFOPLIST_KEY_NSMainNibFile[sdk=macosx*] = MainMenu -INFOPLIST_KEY_NSPrincipalClass[sdk=macosx*] = NSApplication -INFOPLIST_KEY_LSApplicationCategoryType[sdk=macosx*] = public.app-category.utilities +INFOPLIST_KEY_LSApplicationCategoryType[sdk=macos*] = public.app-category.utilities CODE_SIGN_ENTITLEMENTS = App/App-iOS.entitlements -CODE_SIGN_ENTITLEMENTS[sdk=macosx*] = App/App-macOS.entitlements +CODE_SIGN_ENTITLEMENTS[sdk=macos*] = App/App-macOS.entitlements diff --git a/Apple/App/BurrowApp.swift b/Apple/App/BurrowApp.swift index 838ef54..fc05084 100644 --- a/Apple/App/BurrowApp.swift +++ b/Apple/App/BurrowApp.swift @@ -1,14 +1,34 @@ -#if !os(macOS) -import BurrowUI -import SwiftUI +// +// burrow_barApp.swift +// burrow-bar +// +// Created by Thomas Stubblefield on 4/19/23. +// + +import SwiftUI +import NetworkExtension -@MainActor @main -struct BurrowApp: App { +struct burrowBarApp: App { + #if os(macOS) + @NSApplicationDelegateAdaptor private var appDelegate: AppDelegate + #endif + var body: some Scene { WindowGroup { - BurrowView() + PermissionView() + } + } +} + +struct PermissionView: View { + @ObservedObject + var configuration = NetworkConfiguration() + + + var body: some View { + VStack { + Text(verbatim: "Status is \(configuration.status)") } } } -#endif diff --git a/Apple/App/ContentView.swift b/Apple/App/ContentView.swift new file mode 100644 index 0000000..aa92046 --- /dev/null +++ b/Apple/App/ContentView.swift @@ -0,0 +1,73 @@ +import SwiftUI + +struct ContentView: View { + + @ObservedObject var viewModel = NetworkConfiguration() + + var body: some View { + VStack(alignment: .leading) { + + HStack { + Text(verbatim: "Networks \(viewModel.model.status)") + .font(.title3) + Spacer() + Image(systemName: "badge.plus.radiowaves.forward") + .symbolRenderingMode(.palette) + .foregroundStyle(.blue, .black) + .opacity(0.4) + .imageScale(.large) } + Divider() + VStack(alignment: .leading) { + Text("Burrows") + .padding(.top, 2) + .font(.subheadline.weight(.bold)) + HStack { + if (viewModel.status == .unknown) { + + + Image("hackClubLogo") + .resizable() + .frame(width: 32, height: 32) + .cornerRadius(100).onTapGesture { + viewModel.connectToBurrow() + print(viewModel.status) + } + + } else if (viewModel.status == .loading) { + ZStack { + Image("hackClubLogo") + .resizable() + .frame(width: 32, height: 32) + .cornerRadius(100) + .overlay(Color.white.opacity(0.6).cornerRadius(100)) + + ProgressView() + .progressViewStyle(CircularProgressViewStyle()) + .scaleEffect(0.6) + } + } + VStack(alignment: .leading) { + + Text("Hack Club Network") + .fontWeight(.medium) + + + Text("􁠲 Recently Validated Certificate") + .font(.caption2) + .foregroundColor(.blue) + }.onTapGesture { + print(true) + } + } + } + + } + .padding() + } +} + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} diff --git a/Apple/App/MainMenu.xib b/Apple/App/MainMenu.xib deleted file mode 100644 index 50ba431..0000000 --- a/Apple/App/MainMenu.xib +++ /dev/null @@ -1,679 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Apple/App/Model.swift b/Apple/App/Model.swift new file mode 100644 index 0000000..68d63fd --- /dev/null +++ b/Apple/App/Model.swift @@ -0,0 +1,42 @@ +// +// MemoryGame.swift +// Memorize +// +// Created by Thomas Stubblefield on 3/12/23. +// + +import Foundation + +struct Model { + + var status: Status = .unknown + + mutating func connectToBurrow() { + print("let's get this working") + status = .valid + print(status) + } +} + +enum Status: CustomStringConvertible { + case unknown + case blank + case valid + case error + case loading + + var description: String { + switch self { + case .unknown: + return "Unknown" + case .blank: + return "Blank" + case .valid: + return "Valid" + case .loading: + return "Loading" + default: + return "Default" + } + } +} diff --git a/Apple/App/NetworkConfiguration.swift b/Apple/App/NetworkConfiguration.swift new file mode 100644 index 0000000..89bc601 --- /dev/null +++ b/Apple/App/NetworkConfiguration.swift @@ -0,0 +1,87 @@ +import SwiftUI +import NetworkExtension + +@MainActor +class NetworkConfiguration: ObservableObject { + func connectToBurrow() { + objectWillChange.send() + model.connectToBurrow() + } + + @Published var model = Model() + + @Published + var status: Status = .unknown + + init() { + update() + + + } + + func connectToNetwork() { + print(self.status) + self.status = .loading + print(self.status) + + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { + let random = Int.random(in: 0...1) + if random == 0 { + self.status = .valid + print(self.status) + + } else { + self.status = .error + print(self.status) + + } + } + } + + func update() { + Task { + do { + let configurations = try await NETunnelProviderManager.loadAll() + + await MainActor.run { + self.status = configurations.isEmpty ? .blank : .valid + print(self.status) + self.objectWillChange.send() + } + } catch { + await MainActor.run { + self.status = .error + self.objectWillChange.send() + + } + } + } + } + + func request() { + let configuration = NETunnelProviderProtocol() + configuration.providerBundleIdentifier = "" + configuration.serverAddress = "Hack Club" + + let manager = NETunnelProviderManager() + manager.protocolConfiguration = configuration + manager.localizedDescription = "Hack Club Burrow" + manager.saveToPreferences { error in + print(error) + } + } +} + +extension NETunnelProviderManager { + static func loadAll() async throws -> [NETunnelProviderManager] { + try await withUnsafeThrowingContinuation { continuation in + NETunnelProviderManager.loadAllFromPreferences { managers, error in + if let error = error { + continuation.resume(throwing: error) + } else { + continuation.resume(returning: managers ?? []) + } + } + } + } +} diff --git a/Apple/Burrow.xcodeproj/project.pbxproj b/Apple/Burrow.xcodeproj/project.pbxproj index 617b88f..be8f359 100644 --- a/Apple/Burrow.xcodeproj/project.pbxproj +++ b/Apple/Burrow.xcodeproj/project.pbxproj @@ -7,47 +7,15 @@ objects = { /* Begin PBXBuildFile section */ - D00AA8972A4669BC005C8102 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00AA8962A4669BC005C8102 /* AppDelegate.swift */; }; + 43E50D6D29FA050600BD2280 /* FluidMenuBarExtra in Frameworks */ = {isa = PBXBuildFile; platformFilters = (macos, ); productRef = 43E50D6C29FA050600BD2280 /* FluidMenuBarExtra */; }; + 43EBDB2B29FD7557005D8CFF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBDB2A29FD754A005D8CFF /* AppDelegate.swift */; }; + 43EBDB2D29FD759E005D8CFF /* NetworkConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBDB2C29FD759E005D8CFF /* NetworkConfiguration.swift */; }; + 43EBDB2F29FDE85F005D8CFF /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBDB2E29FDE85F005D8CFF /* Model.swift */; }; D020F65829E4A697002790F6 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D020F65729E4A697002790F6 /* PacketTunnelProvider.swift */; }; D020F65D29E4A697002790F6 /* BurrowNetworkExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D020F65329E4A697002790F6 /* BurrowNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - D03383AD2C8E67E300F7C44E /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = D078F7E22C8DA375008A8CEC /* SwiftProtobuf */; }; - D03383AE2C8E67E300F7C44E /* NIO in Frameworks */ = {isa = PBXBuildFile; productRef = D044EE902C8DAB2000778185 /* NIO */; }; - D03383AF2C8E67E300F7C44E /* NIOConcurrencyHelpers in Frameworks */ = {isa = PBXBuildFile; productRef = D044EE922C8DAB2000778185 /* NIOConcurrencyHelpers */; }; - D03383B02C8E67E300F7C44E /* NIOTransportServices in Frameworks */ = {isa = PBXBuildFile; productRef = D044EE952C8DAB2800778185 /* NIOTransportServices */; }; D05B9F7629E39EEC008CB1F9 /* BurrowApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05B9F7529E39EEC008CB1F9 /* BurrowApp.swift */; }; - D09150422B9D2AF700BE3CB0 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = D09150412B9D2AF700BE3CB0 /* MainMenu.xib */; platformFilters = (macos, ); }; - D0B1D1102C436152004B7823 /* AsyncAlgorithms in Frameworks */ = {isa = PBXBuildFile; productRef = D0B1D10F2C436152004B7823 /* AsyncAlgorithms */; }; - D0BCC6092A09A03E00AD070D /* libburrow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCC6032A09535900AD070D /* libburrow.a */; }; - D0BF09522C8E66F6000D8DEC /* BurrowConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D4E5622C8D9BF4007F820A /* BurrowConfiguration.framework */; }; - D0BF09552C8E66FD000D8DEC /* BurrowConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D4E5622C8D9BF4007F820A /* BurrowConfiguration.framework */; }; - D0D4E53A2C8D996F007F820A /* BurrowCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D0D4E5312C8D996F007F820A /* BurrowCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D0D4E56B2C8D9C2F007F820A /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E49A2C8D921A007F820A /* Logging.swift */; }; - D0D4E5702C8D9C62007F820A /* BurrowCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D4E5312C8D996F007F820A /* BurrowCore.framework */; }; - D0D4E5712C8D9C6F007F820A /* HackClub.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E49D2C8D921A007F820A /* HackClub.swift */; }; - D0D4E5722C8D9C6F007F820A /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E49E2C8D921A007F820A /* Network.swift */; }; - D0D4E5732C8D9C6F007F820A /* WireGuard.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E49F2C8D921A007F820A /* WireGuard.swift */; }; - D0D4E5742C8D9C6F007F820A /* BurrowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4A22C8D921A007F820A /* BurrowView.swift */; }; - D0D4E5752C8D9C6F007F820A /* FloatingButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4A32C8D921A007F820A /* FloatingButtonStyle.swift */; }; - D0D4E5762C8D9C6F007F820A /* MenuItemToggleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4A42C8D921A007F820A /* MenuItemToggleView.swift */; }; - D0D4E5772C8D9C6F007F820A /* NetworkCarouselView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4A52C8D921A007F820A /* NetworkCarouselView.swift */; }; - D0D4E5782C8D9C6F007F820A /* NetworkExtension+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4A62C8D921A007F820A /* NetworkExtension+Async.swift */; }; - D0D4E5792C8D9C6F007F820A /* NetworkExtensionTunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4A72C8D921A007F820A /* NetworkExtensionTunnel.swift */; }; - D0D4E57A2C8D9C6F007F820A /* NetworkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4A82C8D921A007F820A /* NetworkView.swift */; }; - D0D4E57B2C8D9C6F007F820A /* OAuth2.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4A92C8D921A007F820A /* OAuth2.swift */; }; - D0D4E57C2C8D9C6F007F820A /* Tunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4AA2C8D921A007F820A /* Tunnel.swift */; }; - D0D4E57D2C8D9C6F007F820A /* TunnelButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4AB2C8D921A007F820A /* TunnelButton.swift */; }; - D0D4E57E2C8D9C6F007F820A /* TunnelStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4AC2C8D921A007F820A /* TunnelStatusView.swift */; }; - D0D4E5892C8D9C94007F820A /* BurrowUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D4E5582C8D9BF2007F820A /* BurrowUI.framework */; }; - D0D4E58A2C8D9C9E007F820A /* BurrowUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D0D4E5582C8D9BF2007F820A /* BurrowUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D0D4E58B2C8D9CA4007F820A /* BurrowConfiguration.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D0D4E5622C8D9BF4007F820A /* BurrowConfiguration.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D0D4E5922C8D9D15007F820A /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E58F2C8D9D0A007F820A /* Constants.swift */; }; - D0D4E5A62C8D9E65007F820A /* BurrowCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D4E5312C8D996F007F820A /* BurrowCore.framework */; }; - D0F4FAD32C8DC79C0068730A /* BurrowCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D4E5312C8D996F007F820A /* BurrowCore.framework */; }; - D0F7594E2C8DAB6B00126CF3 /* GRPC in Frameworks */ = {isa = PBXBuildFile; productRef = D078F7E02C8DA375008A8CEC /* GRPC */; }; - D0F759612C8DB24B00126CF3 /* grpc-swift-config.json in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4962C8D921A007F820A /* grpc-swift-config.json */; }; - D0F759622C8DB24B00126CF3 /* swift-protobuf-config.json in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4972C8D921A007F820A /* swift-protobuf-config.json */; }; - D0F7597E2C8DB30500126CF3 /* CGRPCZlib in Frameworks */ = {isa = PBXBuildFile; productRef = D0F7597D2C8DB30500126CF3 /* CGRPCZlib */; }; - D0F7598D2C8DB3DA00126CF3 /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D4E4992C8D921A007F820A /* Client.swift */; }; + D05B9F7829E39EEC008CB1F9 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05B9F7729E39EEC008CB1F9 /* ContentView.swift */; }; + D05B9F7A29E39EED008CB1F9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D05B9F7929E39EED008CB1F9 /* Assets.xcassets */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -58,48 +26,6 @@ remoteGlobalIDString = D020F65229E4A697002790F6; remoteInfo = BurrowNetworkExtension; }; - D0BF09502C8E66F1000D8DEC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D05B9F6A29E39EEC008CB1F9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D0D4E55A2C8D9BF4007F820A; - remoteInfo = Configuration; - }; - D0BF09532C8E66FA000D8DEC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D05B9F6A29E39EEC008CB1F9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D0D4E55A2C8D9BF4007F820A; - remoteInfo = Configuration; - }; - D0D4E56E2C8D9C5D007F820A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D05B9F6A29E39EEC008CB1F9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D0D4E5302C8D996F007F820A; - remoteInfo = Core; - }; - D0D4E57F2C8D9C78007F820A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D05B9F6A29E39EEC008CB1F9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D0D4E5302C8D996F007F820A; - remoteInfo = Core; - }; - D0D4E5872C8D9C88007F820A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D05B9F6A29E39EEC008CB1F9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D0D4E5502C8D9BF2007F820A; - remoteInfo = UI; - }; - D0F4FAD12C8DC7960068730A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D05B9F6A29E39EEC008CB1F9 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D0D4E5302C8D996F007F820A; - remoteInfo = Core; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -114,28 +40,16 @@ name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; }; - D0D4E53F2C8D996F007F820A /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - D0D4E58B2C8D9CA4007F820A /* BurrowConfiguration.framework in Embed Frameworks */, - D0D4E58A2C8D9C9E007F820A /* BurrowUI.framework in Embed Frameworks */, - D0D4E53A2C8D996F007F820A /* BurrowCore.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - D00117422B30348D00D87C25 /* Configuration.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Configuration.xcconfig; sourceTree = ""; }; - D00AA8962A4669BC005C8102 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 43EBDB2A29FD754A005D8CFF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 43EBDB2C29FD759E005D8CFF /* NetworkConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConfiguration.swift; sourceTree = ""; }; + 43EBDB2E29FDE85F005D8CFF /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; }; D020F63D29E4A1FF002790F6 /* Identity.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Identity.xcconfig; sourceTree = ""; }; D020F64029E4A1FF002790F6 /* Compiler.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Compiler.xcconfig; sourceTree = ""; }; D020F64229E4A1FF002790F6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D020F64929E4A34B002790F6 /* App.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = App.xcconfig; sourceTree = ""; }; + D020F64929E4A34B002790F6 /* Burrow.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Burrow.xcconfig; sourceTree = ""; }; D020F64A29E4A452002790F6 /* App.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = App.xcconfig; sourceTree = ""; }; D020F65329E4A697002790F6 /* BurrowNetworkExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = BurrowNetworkExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; D020F65729E4A697002790F6 /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = ""; }; @@ -146,43 +60,10 @@ D020F66729E4A95D002790F6 /* NetworkExtension-iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "NetworkExtension-iOS.entitlements"; sourceTree = ""; }; D020F66829E4AA74002790F6 /* App-iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "App-iOS.entitlements"; sourceTree = ""; }; D020F66929E4AA74002790F6 /* App-macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "App-macOS.entitlements"; sourceTree = ""; }; - D04A3E1D2BAF465F0043EC85 /* Version.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = ""; }; D05B9F7229E39EEC008CB1F9 /* Burrow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Burrow.app; sourceTree = BUILT_PRODUCTS_DIR; }; D05B9F7529E39EEC008CB1F9 /* BurrowApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurrowApp.swift; sourceTree = ""; }; - D09150412B9D2AF700BE3CB0 /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = ""; }; - D0B98FBF29FD8072004E7149 /* build-rust.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "build-rust.sh"; sourceTree = ""; }; - D0B98FD829FDDB6F004E7149 /* libburrow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libburrow.h; sourceTree = ""; }; - D0B98FDC29FDDDCF004E7149 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; - D0BCC6032A09535900AD070D /* libburrow.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libburrow.a; sourceTree = BUILT_PRODUCTS_DIR; }; - D0BF09582C8E6789000D8DEC /* UI.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = UI.xcconfig; sourceTree = ""; }; - D0D4E4952C8D921A007F820A /* burrow.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = burrow.proto; sourceTree = ""; }; - D0D4E4962C8D921A007F820A /* grpc-swift-config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "grpc-swift-config.json"; sourceTree = ""; }; - D0D4E4972C8D921A007F820A /* swift-protobuf-config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "swift-protobuf-config.json"; sourceTree = ""; }; - D0D4E4992C8D921A007F820A /* Client.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Client.swift; sourceTree = ""; }; - D0D4E49A2C8D921A007F820A /* Logging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logging.swift; sourceTree = ""; }; - D0D4E49D2C8D921A007F820A /* HackClub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HackClub.swift; sourceTree = ""; }; - D0D4E49E2C8D921A007F820A /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = ""; }; - D0D4E49F2C8D921A007F820A /* WireGuard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuard.swift; sourceTree = ""; }; - D0D4E4A12C8D921A007F820A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - D0D4E4A22C8D921A007F820A /* BurrowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BurrowView.swift; sourceTree = ""; }; - D0D4E4A32C8D921A007F820A /* FloatingButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatingButtonStyle.swift; sourceTree = ""; }; - D0D4E4A42C8D921A007F820A /* MenuItemToggleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemToggleView.swift; sourceTree = ""; }; - D0D4E4A52C8D921A007F820A /* NetworkCarouselView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkCarouselView.swift; sourceTree = ""; }; - D0D4E4A62C8D921A007F820A /* NetworkExtension+Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NetworkExtension+Async.swift"; sourceTree = ""; }; - D0D4E4A72C8D921A007F820A /* NetworkExtensionTunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkExtensionTunnel.swift; sourceTree = ""; }; - D0D4E4A82C8D921A007F820A /* NetworkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkView.swift; sourceTree = ""; }; - D0D4E4A92C8D921A007F820A /* OAuth2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OAuth2.swift; sourceTree = ""; }; - D0D4E4AA2C8D921A007F820A /* Tunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tunnel.swift; sourceTree = ""; }; - D0D4E4AB2C8D921A007F820A /* TunnelButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelButton.swift; sourceTree = ""; }; - D0D4E4AC2C8D921A007F820A /* TunnelStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelStatusView.swift; sourceTree = ""; }; - D0D4E4F62C8D932D007F820A /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - D0D4E4F72C8D941D007F820A /* Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Framework.xcconfig; sourceTree = ""; }; - D0D4E5312C8D996F007F820A /* BurrowCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BurrowCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D0D4E5582C8D9BF2007F820A /* BurrowUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BurrowUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D0D4E5622C8D9BF4007F820A /* BurrowConfiguration.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BurrowConfiguration.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D0D4E58E2C8D9D0A007F820A /* Constants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = ""; }; - D0D4E58F2C8D9D0A007F820A /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; - D0D4E5902C8D9D0A007F820A /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; + D05B9F7729E39EEC008CB1F9 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + D05B9F7929E39EED008CB1F9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -190,10 +71,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D0BF09522C8E66F6000D8DEC /* BurrowConfiguration.framework in Frameworks */, - D0D4E5A62C8D9E65007F820A /* BurrowCore.framework in Frameworks */, - D0BCC6092A09A03E00AD070D /* libburrow.a in Frameworks */, - D0B1D1102C436152004B7823 /* AsyncAlgorithms in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -201,56 +78,21 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D0BF09552C8E66FD000D8DEC /* BurrowConfiguration.framework in Frameworks */, - D0F4FAD32C8DC79C0068730A /* BurrowCore.framework in Frameworks */, - D0D4E5892C8D9C94007F820A /* BurrowUI.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D078F7CF2C8DA213008A8CEC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D03383B02C8E67E300F7C44E /* NIOTransportServices in Frameworks */, - D03383AF2C8E67E300F7C44E /* NIOConcurrencyHelpers in Frameworks */, - D03383AE2C8E67E300F7C44E /* NIO in Frameworks */, - D03383AD2C8E67E300F7C44E /* SwiftProtobuf in Frameworks */, - D0F7594E2C8DAB6B00126CF3 /* GRPC in Frameworks */, - D0F7597E2C8DB30500126CF3 /* CGRPCZlib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D0D4E5532C8D9BF2007F820A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D0D4E5702C8D9C62007F820A /* BurrowCore.framework in Frameworks */, + 43E50D6D29FA050600BD2280 /* FluidMenuBarExtra in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - D00117432B30372900D87C25 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; D020F63C29E4A1FF002790F6 /* Configuration */ = { isa = PBXGroup; children = ( D020F63D29E4A1FF002790F6 /* Identity.xcconfig */, D020F64A29E4A452002790F6 /* App.xcconfig */, D020F66329E4A703002790F6 /* Extension.xcconfig */, - D0D4E4F72C8D941D007F820A /* Framework.xcconfig */, D020F64029E4A1FF002790F6 /* Compiler.xcconfig */, - D0D4E4F62C8D932D007F820A /* Debug.xcconfig */, - D04A3E1D2BAF465F0043EC85 /* Version.xcconfig */, D020F64229E4A1FF002790F6 /* Info.plist */, - D0D4E5912C8D9D0A007F820A /* Constants */, - D00117422B30348D00D87C25 /* Configuration.xcconfig */, ); path = Configuration; sourceTree = ""; @@ -263,7 +105,6 @@ D020F66729E4A95D002790F6 /* NetworkExtension-iOS.entitlements */, D020F66629E4A95D002790F6 /* NetworkExtension-macOS.entitlements */, D020F66229E4A6E5002790F6 /* NetworkExtension.xcconfig */, - D0B98FD729FDDB57004E7149 /* libburrow */, ); path = NetworkExtension; sourceTree = ""; @@ -273,11 +114,8 @@ children = ( D05B9F7429E39EEC008CB1F9 /* App */, D020F65629E4A697002790F6 /* NetworkExtension */, - D0D4E49C2C8D921A007F820A /* Core */, - D0D4E4AD2C8D921A007F820A /* UI */, D020F63C29E4A1FF002790F6 /* Configuration */, D05B9F7329E39EEC008CB1F9 /* Products */, - D00117432B30372900D87C25 /* Frameworks */, ); sourceTree = ""; }; @@ -286,10 +124,6 @@ children = ( D05B9F7229E39EEC008CB1F9 /* Burrow.app */, D020F65329E4A697002790F6 /* BurrowNetworkExtension.appex */, - D0BCC6032A09535900AD070D /* libburrow.a */, - D0D4E5312C8D996F007F820A /* BurrowCore.framework */, - D0D4E5582C8D9BF2007F820A /* BurrowUI.framework */, - D0D4E5622C8D9BF4007F820A /* BurrowConfiguration.framework */, ); name = Products; sourceTree = ""; @@ -298,86 +132,18 @@ isa = PBXGroup; children = ( D05B9F7529E39EEC008CB1F9 /* BurrowApp.swift */, - D00AA8962A4669BC005C8102 /* AppDelegate.swift */, - D09150412B9D2AF700BE3CB0 /* MainMenu.xib */, + 43EBDB2A29FD754A005D8CFF /* AppDelegate.swift */, + D05B9F7729E39EEC008CB1F9 /* ContentView.swift */, + 43EBDB2C29FD759E005D8CFF /* NetworkConfiguration.swift */, + 43EBDB2E29FDE85F005D8CFF /* Model.swift */, + D05B9F7929E39EED008CB1F9 /* Assets.xcassets */, D020F66829E4AA74002790F6 /* App-iOS.entitlements */, D020F66929E4AA74002790F6 /* App-macOS.entitlements */, - D020F64929E4A34B002790F6 /* App.xcconfig */, + D020F64929E4A34B002790F6 /* Burrow.xcconfig */, ); path = App; sourceTree = ""; }; - D0B98FD729FDDB57004E7149 /* libburrow */ = { - isa = PBXGroup; - children = ( - D0B98FBF29FD8072004E7149 /* build-rust.sh */, - D0B98FDC29FDDDCF004E7149 /* module.modulemap */, - D0B98FD829FDDB6F004E7149 /* libburrow.h */, - ); - path = libburrow; - sourceTree = ""; - }; - D0D4E4982C8D921A007F820A /* Client */ = { - isa = PBXGroup; - children = ( - D0D4E4952C8D921A007F820A /* burrow.proto */, - D0D4E4962C8D921A007F820A /* grpc-swift-config.json */, - D0D4E4972C8D921A007F820A /* swift-protobuf-config.json */, - ); - path = Client; - sourceTree = ""; - }; - D0D4E49C2C8D921A007F820A /* Core */ = { - isa = PBXGroup; - children = ( - D0D4E49A2C8D921A007F820A /* Logging.swift */, - D0D4E4992C8D921A007F820A /* Client.swift */, - D0D4E4982C8D921A007F820A /* Client */, - ); - path = Core; - sourceTree = ""; - }; - D0D4E4A02C8D921A007F820A /* Networks */ = { - isa = PBXGroup; - children = ( - D0D4E49D2C8D921A007F820A /* HackClub.swift */, - D0D4E49E2C8D921A007F820A /* Network.swift */, - D0D4E49F2C8D921A007F820A /* WireGuard.swift */, - ); - path = Networks; - sourceTree = ""; - }; - D0D4E4AD2C8D921A007F820A /* UI */ = { - isa = PBXGroup; - children = ( - D0D4E4A22C8D921A007F820A /* BurrowView.swift */, - D0D4E4A02C8D921A007F820A /* Networks */, - D0D4E4A32C8D921A007F820A /* FloatingButtonStyle.swift */, - D0D4E4A42C8D921A007F820A /* MenuItemToggleView.swift */, - D0D4E4A52C8D921A007F820A /* NetworkCarouselView.swift */, - D0D4E4A62C8D921A007F820A /* NetworkExtension+Async.swift */, - D0D4E4A72C8D921A007F820A /* NetworkExtensionTunnel.swift */, - D0D4E4A82C8D921A007F820A /* NetworkView.swift */, - D0D4E4A92C8D921A007F820A /* OAuth2.swift */, - D0D4E4AA2C8D921A007F820A /* Tunnel.swift */, - D0D4E4AB2C8D921A007F820A /* TunnelButton.swift */, - D0D4E4AC2C8D921A007F820A /* TunnelStatusView.swift */, - D0D4E4A12C8D921A007F820A /* Assets.xcassets */, - D0BF09582C8E6789000D8DEC /* UI.xcconfig */, - ); - path = UI; - sourceTree = ""; - }; - D0D4E5912C8D9D0A007F820A /* Constants */ = { - isa = PBXGroup; - children = ( - D0D4E58E2C8D9D0A007F820A /* Constants.h */, - D0D4E58F2C8D9D0A007F820A /* Constants.swift */, - D0D4E5902C8D9D0A007F820A /* module.modulemap */, - ); - path = Constants; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -385,109 +151,41 @@ isa = PBXNativeTarget; buildConfigurationList = D020F65E29E4A697002790F6 /* Build configuration list for PBXNativeTarget "NetworkExtension" */; buildPhases = ( - D0BCC60B2A09A0C100AD070D /* Compile Rust */, D020F64F29E4A697002790F6 /* Sources */, D020F65029E4A697002790F6 /* Frameworks */, + D020F65129E4A697002790F6 /* Resources */, ); buildRules = ( ); dependencies = ( - D0BF09512C8E66F1000D8DEC /* PBXTargetDependency */, - D0D4E5802C8D9C78007F820A /* PBXTargetDependency */, ); name = NetworkExtension; productName = BurrowNetworkExtension; productReference = D020F65329E4A697002790F6 /* BurrowNetworkExtension.appex */; productType = "com.apple.product-type.app-extension"; }; - D05B9F7129E39EEC008CB1F9 /* App */ = { + D05B9F7129E39EEC008CB1F9 /* Burrow */ = { isa = PBXNativeTarget; - buildConfigurationList = D05B9F8129E39EED008CB1F9 /* Build configuration list for PBXNativeTarget "App" */; + buildConfigurationList = D05B9F8129E39EED008CB1F9 /* Build configuration list for PBXNativeTarget "Burrow" */; buildPhases = ( D05B9F6E29E39EEC008CB1F9 /* Sources */, D05B9F6F29E39EEC008CB1F9 /* Frameworks */, D05B9F7029E39EEC008CB1F9 /* Resources */, - D0D4E53F2C8D996F007F820A /* Embed Frameworks */, D020F66129E4A697002790F6 /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( - D0BF09542C8E66FA000D8DEC /* PBXTargetDependency */, - D0F4FAD22C8DC7960068730A /* PBXTargetDependency */, - D0D4E5882C8D9C88007F820A /* PBXTargetDependency */, D020F65C29E4A697002790F6 /* PBXTargetDependency */, ); - name = App; + name = Burrow; + packageProductDependencies = ( + 43E50D6C29FA050600BD2280 /* FluidMenuBarExtra */, + ); productName = Burrow; productReference = D05B9F7229E39EEC008CB1F9 /* Burrow.app */; productType = "com.apple.product-type.application"; }; - D0D4E5302C8D996F007F820A /* Core */ = { - isa = PBXNativeTarget; - buildConfigurationList = D0D4E53C2C8D996F007F820A /* Build configuration list for PBXNativeTarget "Core" */; - buildPhases = ( - D0D4E52D2C8D996F007F820A /* Sources */, - D078F7CF2C8DA213008A8CEC /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - D0F7598A2C8DB34200126CF3 /* PBXTargetDependency */, - D0F7595E2C8DB24400126CF3 /* PBXTargetDependency */, - D0F759602C8DB24400126CF3 /* PBXTargetDependency */, - ); - name = Core; - packageProductDependencies = ( - D078F7E02C8DA375008A8CEC /* GRPC */, - D078F7E22C8DA375008A8CEC /* SwiftProtobuf */, - D044EE902C8DAB2000778185 /* NIO */, - D044EE922C8DAB2000778185 /* NIOConcurrencyHelpers */, - D044EE952C8DAB2800778185 /* NIOTransportServices */, - D0F7597D2C8DB30500126CF3 /* CGRPCZlib */, - ); - productName = Core; - productReference = D0D4E5312C8D996F007F820A /* BurrowCore.framework */; - productType = "com.apple.product-type.framework"; - }; - D0D4E5502C8D9BF2007F820A /* UI */ = { - isa = PBXNativeTarget; - buildConfigurationList = D0D4E5552C8D9BF2007F820A /* Build configuration list for PBXNativeTarget "UI" */; - buildPhases = ( - D0D4E5522C8D9BF2007F820A /* Sources */, - D0D4E5532C8D9BF2007F820A /* Frameworks */, - D0D4E5542C8D9BF2007F820A /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - D0D4E56F2C8D9C5D007F820A /* PBXTargetDependency */, - ); - name = UI; - packageProductDependencies = ( - ); - productName = Core; - productReference = D0D4E5582C8D9BF2007F820A /* BurrowUI.framework */; - productType = "com.apple.product-type.framework"; - }; - D0D4E55A2C8D9BF4007F820A /* Configuration */ = { - isa = PBXNativeTarget; - buildConfigurationList = D0D4E55F2C8D9BF4007F820A /* Build configuration list for PBXNativeTarget "Configuration" */; - buildPhases = ( - D0F759912C8DB49E00126CF3 /* Configure Version */, - D0D4E55C2C8D9BF4007F820A /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Configuration; - packageProductDependencies = ( - ); - productName = Core; - productReference = D0D4E5622C8D9BF4007F820A /* BurrowConfiguration.framework */; - productType = "com.apple.product-type.framework"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -495,8 +193,8 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1600; - LastUpgradeCheck = 1520; + LastSwiftUpdateCheck = 1430; + LastUpgradeCheck = 1430; TargetAttributes = { D020F65229E4A697002790F6 = { CreatedOnToolsVersion = 14.3; @@ -504,9 +202,6 @@ D05B9F7129E39EEC008CB1F9 = { CreatedOnToolsVersion = 14.3; }; - D0D4E5302C8D996F007F820A = { - CreatedOnToolsVersion = 16.0; - }; }; }; buildConfigurationList = D05B9F6D29E39EEC008CB1F9 /* Build configuration list for PBXProject "Burrow" */; @@ -519,88 +214,36 @@ ); mainGroup = D05B9F6929E39EEC008CB1F9; packageReferences = ( - D0B1D10E2C436152004B7823 /* XCRemoteSwiftPackageReference "swift-async-algorithms" */, - D0D4E4822C8D8EF6007F820A /* XCRemoteSwiftPackageReference "grpc-swift" */, - D0D4E4852C8D8F29007F820A /* XCRemoteSwiftPackageReference "swift-protobuf" */, - D044EE8F2C8DAB2000778185 /* XCRemoteSwiftPackageReference "swift-nio" */, - D044EE942C8DAB2800778185 /* XCRemoteSwiftPackageReference "swift-nio-transport-services" */, + 43E50D6B29FA050600BD2280 /* XCRemoteSwiftPackageReference "fluid-menu-bar-extra" */, ); productRefGroup = D05B9F7329E39EEC008CB1F9 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - D05B9F7129E39EEC008CB1F9 /* App */, + D05B9F7129E39EEC008CB1F9 /* Burrow */, D020F65229E4A697002790F6 /* NetworkExtension */, - D0D4E5502C8D9BF2007F820A /* UI */, - D0D4E5302C8D996F007F820A /* Core */, - D0D4E55A2C8D9BF4007F820A /* Configuration */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + D020F65129E4A697002790F6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; D05B9F7029E39EEC008CB1F9 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - D09150422B9D2AF700BE3CB0 /* MainMenu.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D0D4E5542C8D9BF2007F820A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( + D05B9F7A29E39EED008CB1F9 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - D0BCC60B2A09A0C100AD070D /* Compile Rust */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Compile Rust"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PROJECT_DIR}/NetworkExtension/libburrow/build-rust.sh\"\n"; - showEnvVarsInLog = 0; - }; - D0F759912C8DB49E00126CF3 /* Configure Version */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "$(PROJECT_DIR)/../Tools/version.sh", - "$(PROJECT_DIR)/../.git", - ); - name = "Configure Version"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(PROJECT_DIR)/Configuration/Version.xcconfig", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"$PROJECT_DIR/../Tools/version.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ D020F64F29E4A697002790F6 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -614,48 +257,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D00AA8972A4669BC005C8102 /* AppDelegate.swift in Sources */, + 43EBDB2F29FDE85F005D8CFF /* Model.swift in Sources */, + 43EBDB2B29FD7557005D8CFF /* AppDelegate.swift in Sources */, + D05B9F7829E39EEC008CB1F9 /* ContentView.swift in Sources */, D05B9F7629E39EEC008CB1F9 /* BurrowApp.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D0D4E52D2C8D996F007F820A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D0F759612C8DB24B00126CF3 /* grpc-swift-config.json in Sources */, - D0F759622C8DB24B00126CF3 /* swift-protobuf-config.json in Sources */, - D0F7598D2C8DB3DA00126CF3 /* Client.swift in Sources */, - D0D4E56B2C8D9C2F007F820A /* Logging.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D0D4E5522C8D9BF2007F820A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D0D4E5712C8D9C6F007F820A /* HackClub.swift in Sources */, - D0D4E5722C8D9C6F007F820A /* Network.swift in Sources */, - D0D4E5732C8D9C6F007F820A /* WireGuard.swift in Sources */, - D0D4E5742C8D9C6F007F820A /* BurrowView.swift in Sources */, - D0D4E5752C8D9C6F007F820A /* FloatingButtonStyle.swift in Sources */, - D0D4E5762C8D9C6F007F820A /* MenuItemToggleView.swift in Sources */, - D0D4E5772C8D9C6F007F820A /* NetworkCarouselView.swift in Sources */, - D0D4E5782C8D9C6F007F820A /* NetworkExtension+Async.swift in Sources */, - D0D4E5792C8D9C6F007F820A /* NetworkExtensionTunnel.swift in Sources */, - D0D4E57A2C8D9C6F007F820A /* NetworkView.swift in Sources */, - D0D4E57B2C8D9C6F007F820A /* OAuth2.swift in Sources */, - D0D4E57C2C8D9C6F007F820A /* Tunnel.swift in Sources */, - D0D4E57D2C8D9C6F007F820A /* TunnelButton.swift in Sources */, - D0D4E57E2C8D9C6F007F820A /* TunnelStatusView.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D0D4E55C2C8D9BF4007F820A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D0D4E5922C8D9D15007F820A /* Constants.swift in Sources */, + 43EBDB2D29FD759E005D8CFF /* NetworkConfiguration.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -667,48 +273,6 @@ target = D020F65229E4A697002790F6 /* NetworkExtension */; targetProxy = D020F65B29E4A697002790F6 /* PBXContainerItemProxy */; }; - D0BF09512C8E66F1000D8DEC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D0D4E55A2C8D9BF4007F820A /* Configuration */; - targetProxy = D0BF09502C8E66F1000D8DEC /* PBXContainerItemProxy */; - }; - D0BF09542C8E66FA000D8DEC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D0D4E55A2C8D9BF4007F820A /* Configuration */; - targetProxy = D0BF09532C8E66FA000D8DEC /* PBXContainerItemProxy */; - }; - D0D4E56F2C8D9C5D007F820A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D0D4E5302C8D996F007F820A /* Core */; - targetProxy = D0D4E56E2C8D9C5D007F820A /* PBXContainerItemProxy */; - }; - D0D4E5802C8D9C78007F820A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D0D4E5302C8D996F007F820A /* Core */; - targetProxy = D0D4E57F2C8D9C78007F820A /* PBXContainerItemProxy */; - }; - D0D4E5882C8D9C88007F820A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D0D4E5502C8D9BF2007F820A /* UI */; - targetProxy = D0D4E5872C8D9C88007F820A /* PBXContainerItemProxy */; - }; - D0F4FAD22C8DC7960068730A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D0D4E5302C8D996F007F820A /* Core */; - targetProxy = D0F4FAD12C8DC7960068730A /* PBXContainerItemProxy */; - }; - D0F7595E2C8DB24400126CF3 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = D0F7595D2C8DB24400126CF3 /* GRPCSwiftPlugin */; - }; - D0F759602C8DB24400126CF3 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = D0F7595F2C8DB24400126CF3 /* SwiftProtobufPlugin */; - }; - D0F7598A2C8DB34200126CF3 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = D0F759892C8DB34200126CF3 /* GRPC */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -716,6 +280,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = D020F66229E4A6E5002790F6 /* NetworkExtension.xcconfig */; buildSettings = { + DEVELOPMENT_TEAM = 2H4LMN3ZLG; }; name = Debug; }; @@ -723,6 +288,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = D020F66229E4A6E5002790F6 /* NetworkExtension.xcconfig */; buildSettings = { + DEVELOPMENT_TEAM = 2H4LMN3ZLG; }; name = Release; }; @@ -742,57 +308,19 @@ }; D05B9F8229E39EED008CB1F9 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D020F64929E4A34B002790F6 /* App.xcconfig */; + baseConfigurationReference = D020F64929E4A34B002790F6 /* Burrow.xcconfig */; buildSettings = { + DEVELOPMENT_TEAM = 2H4LMN3ZLG; + MACOSX_DEPLOYMENT_TARGET = 13.0; }; name = Debug; }; D05B9F8329E39EED008CB1F9 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D020F64929E4A34B002790F6 /* App.xcconfig */; - buildSettings = { - }; - name = Release; - }; - D0D4E53D2C8D996F007F820A /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D0D4E4F72C8D941D007F820A /* Framework.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - D0D4E53E2C8D996F007F820A /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D0D4E4F72C8D941D007F820A /* Framework.xcconfig */; - buildSettings = { - }; - name = Release; - }; - D0D4E5562C8D9BF2007F820A /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D0BF09582C8E6789000D8DEC /* UI.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - D0D4E5572C8D9BF2007F820A /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D0BF09582C8E6789000D8DEC /* UI.xcconfig */; - buildSettings = { - }; - name = Release; - }; - D0D4E5602C8D9BF4007F820A /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D00117422B30348D00D87C25 /* Configuration.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - D0D4E5612C8D9BF4007F820A /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D00117422B30348D00D87C25 /* Configuration.xcconfig */; + baseConfigurationReference = D020F64929E4A34B002790F6 /* Burrow.xcconfig */; buildSettings = { + DEVELOPMENT_TEAM = 2H4LMN3ZLG; + MACOSX_DEPLOYMENT_TARGET = 13.0; }; name = Release; }; @@ -817,7 +345,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D05B9F8129E39EED008CB1F9 /* Build configuration list for PBXNativeTarget "App" */ = { + D05B9F8129E39EED008CB1F9 /* Build configuration list for PBXNativeTarget "Burrow" */ = { isa = XCConfigurationList; buildConfigurations = ( D05B9F8229E39EED008CB1F9 /* Debug */, @@ -826,128 +354,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D0D4E53C2C8D996F007F820A /* Build configuration list for PBXNativeTarget "Core" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D0D4E53D2C8D996F007F820A /* Debug */, - D0D4E53E2C8D996F007F820A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D0D4E5552C8D9BF2007F820A /* Build configuration list for PBXNativeTarget "UI" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D0D4E5562C8D9BF2007F820A /* Debug */, - D0D4E5572C8D9BF2007F820A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D0D4E55F2C8D9BF4007F820A /* Build configuration list for PBXNativeTarget "Configuration" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D0D4E5602C8D9BF4007F820A /* Debug */, - D0D4E5612C8D9BF4007F820A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - D044EE8F2C8DAB2000778185 /* XCRemoteSwiftPackageReference "swift-nio" */ = { + 43E50D6B29FA050600BD2280 /* XCRemoteSwiftPackageReference "fluid-menu-bar-extra" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/apple/swift-nio.git"; + repositoryURL = "https://github.com/lfroms/fluid-menu-bar-extra.git"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 2.72.0; - }; - }; - D044EE942C8DAB2800778185 /* XCRemoteSwiftPackageReference "swift-nio-transport-services" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/apple/swift-nio-transport-services.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.21.0; - }; - }; - D0B1D10E2C436152004B7823 /* XCRemoteSwiftPackageReference "swift-async-algorithms" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/apple/swift-async-algorithms.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.0.1; - }; - }; - D0D4E4822C8D8EF6007F820A /* XCRemoteSwiftPackageReference "grpc-swift" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/grpc/grpc-swift.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.23.0; - }; - }; - D0D4E4852C8D8F29007F820A /* XCRemoteSwiftPackageReference "swift-protobuf" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/apple/swift-protobuf.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.28.1; + branch = main; + kind = branch; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - D044EE902C8DAB2000778185 /* NIO */ = { + 43E50D6C29FA050600BD2280 /* FluidMenuBarExtra */ = { isa = XCSwiftPackageProductDependency; - package = D044EE8F2C8DAB2000778185 /* XCRemoteSwiftPackageReference "swift-nio" */; - productName = NIO; - }; - D044EE922C8DAB2000778185 /* NIOConcurrencyHelpers */ = { - isa = XCSwiftPackageProductDependency; - package = D044EE8F2C8DAB2000778185 /* XCRemoteSwiftPackageReference "swift-nio" */; - productName = NIOConcurrencyHelpers; - }; - D044EE952C8DAB2800778185 /* NIOTransportServices */ = { - isa = XCSwiftPackageProductDependency; - package = D044EE942C8DAB2800778185 /* XCRemoteSwiftPackageReference "swift-nio-transport-services" */; - productName = NIOTransportServices; - }; - D078F7E02C8DA375008A8CEC /* GRPC */ = { - isa = XCSwiftPackageProductDependency; - package = D0D4E4822C8D8EF6007F820A /* XCRemoteSwiftPackageReference "grpc-swift" */; - productName = GRPC; - }; - D078F7E22C8DA375008A8CEC /* SwiftProtobuf */ = { - isa = XCSwiftPackageProductDependency; - package = D0D4E4852C8D8F29007F820A /* XCRemoteSwiftPackageReference "swift-protobuf" */; - productName = SwiftProtobuf; - }; - D0B1D10F2C436152004B7823 /* AsyncAlgorithms */ = { - isa = XCSwiftPackageProductDependency; - package = D0B1D10E2C436152004B7823 /* XCRemoteSwiftPackageReference "swift-async-algorithms" */; - productName = AsyncAlgorithms; - }; - D0F7595D2C8DB24400126CF3 /* GRPCSwiftPlugin */ = { - isa = XCSwiftPackageProductDependency; - package = D0D4E4822C8D8EF6007F820A /* XCRemoteSwiftPackageReference "grpc-swift" */; - productName = "plugin:GRPCSwiftPlugin"; - }; - D0F7595F2C8DB24400126CF3 /* SwiftProtobufPlugin */ = { - isa = XCSwiftPackageProductDependency; - package = D0D4E4852C8D8F29007F820A /* XCRemoteSwiftPackageReference "swift-protobuf" */; - productName = "plugin:SwiftProtobufPlugin"; - }; - D0F7597D2C8DB30500126CF3 /* CGRPCZlib */ = { - isa = XCSwiftPackageProductDependency; - package = D0D4E4822C8D8EF6007F820A /* XCRemoteSwiftPackageReference "grpc-swift" */; - productName = CGRPCZlib; - }; - D0F759892C8DB34200126CF3 /* GRPC */ = { - isa = XCSwiftPackageProductDependency; - package = D0D4E4822C8D8EF6007F820A /* XCRemoteSwiftPackageReference "grpc-swift" */; - productName = GRPC; + package = 43E50D6B29FA050600BD2280 /* XCRemoteSwiftPackageReference "fluid-menu-bar-extra" */; + productName = FluidMenuBarExtra; }; /* End XCSwiftPackageProductDependency section */ }; diff --git a/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 08de0be..0000000 --- a/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded - - - diff --git a/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 739b77c..569a50e 100644 --- a/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,123 +1,14 @@ { - "originHash" : "fa512b990383b7e309c5854a5279817052294a8191a6d3c55c49cfb38e88c0c3", "pins" : [ { - "identity" : "grpc-swift", + "identity" : "fluid-menu-bar-extra", "kind" : "remoteSourceControl", - "location" : "https://github.com/grpc/grpc-swift.git", + "location" : "https://github.com/lfroms/fluid-menu-bar-extra.git", "state" : { - "revision" : "6a90b7e77e29f9bda6c2b3a4165a40d6c02cfda1", - "version" : "1.23.0" - } - }, - { - "identity" : "swift-async-algorithms", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-async-algorithms.git", - "state" : { - "revision" : "6ae9a051f76b81cc668305ceed5b0e0a7fd93d20", - "version" : "1.0.1" - } - }, - { - "identity" : "swift-atomics", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-atomics.git", - "state" : { - "revision" : "cd142fd2f64be2100422d658e7411e39489da985", - "version" : "1.2.0" - } - }, - { - "identity" : "swift-collections", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-collections.git", - "state" : { - "revision" : "9bf03ff58ce34478e66aaee630e491823326fd06", - "version" : "1.1.3" - } - }, - { - "identity" : "swift-http-types", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-http-types", - "state" : { - "revision" : "ae67c8178eb46944fd85e4dc6dd970e1f3ed6ccd", - "version" : "1.3.0" - } - }, - { - "identity" : "swift-log", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-log.git", - "state" : { - "revision" : "9cb486020ebf03bfa5b5df985387a14a98744537", - "version" : "1.6.1" - } - }, - { - "identity" : "swift-nio", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio.git", - "state" : { - "revision" : "9746cf80e29edfef2a39924a66731249223f42a3", - "version" : "2.72.0" - } - }, - { - "identity" : "swift-nio-extras", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-extras.git", - "state" : { - "revision" : "d1ead62745cc3269e482f1c51f27608057174379", - "version" : "1.24.0" - } - }, - { - "identity" : "swift-nio-http2", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-http2.git", - "state" : { - "revision" : "b5f7062b60e4add1e8c343ba4eb8da2e324b3a94", - "version" : "1.34.0" - } - }, - { - "identity" : "swift-nio-ssl", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-ssl.git", - "state" : { - "revision" : "7b84abbdcef69cc3be6573ac12440220789dcd69", - "version" : "2.27.2" - } - }, - { - "identity" : "swift-nio-transport-services", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-transport-services.git", - "state" : { - "revision" : "38ac8221dd20674682148d6451367f89c2652980", - "version" : "1.21.0" - } - }, - { - "identity" : "swift-protobuf", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-protobuf.git", - "state" : { - "revision" : "edb6ed4919f7756157fe02f2552b7e3850a538e5", - "version" : "1.28.1" - } - }, - { - "identity" : "swift-system", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-system.git", - "state" : { - "revision" : "d2ba781702a1d8285419c15ee62fd734a9437ff5", - "version" : "1.3.2" + "branch" : "main", + "revision" : "b8d41bc1c2609c3943c47d00fb539de38f90b817" } } ], - "version" : 3 + "version" : 2 } diff --git a/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme b/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme deleted file mode 100644 index a524e87..0000000 --- a/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/NetworkExtension.xcscheme b/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/NetworkExtension.xcscheme deleted file mode 100644 index 316c96e..0000000 --- a/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/NetworkExtension.xcscheme +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Apple/Configuration/App.xcconfig b/Apple/Configuration/App.xcconfig index e0946f4..f536e9d 100644 --- a/Apple/Configuration/App.xcconfig +++ b/Apple/Configuration/App.xcconfig @@ -1,8 +1,10 @@ -LD_EXPORT_SYMBOLS = NO + SKIP_INSTALL = NO -LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks +LD_RUNPATH_SEARCH_PATHS[sdk=iphone*] = $(inherited) @executable_path/Frameworks LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor + +ENABLE_PREVIEWS = YES diff --git a/Apple/Configuration/Compiler.xcconfig b/Apple/Configuration/Compiler.xcconfig index 6b071f1..ebf6136 100644 --- a/Apple/Configuration/Compiler.xcconfig +++ b/Apple/Configuration/Compiler.xcconfig @@ -1,44 +1,61 @@ #include "Identity.xcconfig" -#include "Debug.xcconfig" -#include "Version.xcconfig" SDKROOT = auto ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx -SWIFT_VERSION = 6.0 -IPHONEOS_DEPLOYMENT_TARGET = 17.0 -MACOSX_DEPLOYMENT_TARGET = 14.0 +IPHONEOS_DEPLOYMENT_TARGET = 15.0 +MACOSX_DEPLOYMENT_TARGET = 12.0 SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO SUPPORTS_MACCATALYST = NO +ALWAYS_SEARCH_USER_PATHS = NO PRODUCT_NAME = $(TARGET_NAME:c99extidentifier) PRODUCT_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).$(PRODUCT_NAME) +CURRENT_PROJECT_VERSION = 1 MARKETING_VERSION = 0.1 SKIP_INSTALL = YES CODE_SIGN_IDENTITY = Apple Development -GENERATE_INFOPLIST_FILE = YES INFOPLIST_FILE = Configuration/Info.plist -INFOPLIST_KEY_NSHumanReadableCopyright = Copyright © 2023-2024 Hack Club +GENERATE_INFOPLIST_FILE = YES +INFOPLIST_KEY_NSHumanReadableCopyright = Copyright © 2023 Hack Club INFOPLIST_KEY_CFBundleDisplayName = Burrow -ENABLE_APP_SANDBOX[sdk=macosx*] = YES - ENABLE_BITCODE = NO -ALWAYS_SEARCH_USER_PATHS = NO + +ENABLE_APP_SANDBOX[sdk=macosx*] = YES +ENABLE_HARDENED_RUNTIME[sdk=macosx*] = YES COMBINE_HIDPI_IMAGES = YES -EAGER_LINKING = YES +COPY_PHASE_STRIP = NO + FUSE_BUILD_SCRIPT_PHASES = YES -SWIFT_EMIT_LOC_STRINGS = YES -LOCALIZATION_PREFERS_STRING_CATALOGS = YES -ENABLE_DEBUG_DYLIB = NO APP_GROUP_IDENTIFIER = group.$(APP_BUNDLE_IDENTIFIER) APP_GROUP_IDENTIFIER[sdk=macosx*] = $(DEVELOPMENT_TEAM).$(APP_BUNDLE_IDENTIFIER) -NETWORK_EXTENSION_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).network -// https://github.com/grpc/grpc-swift/issues/683#issuecomment-1130118953 -OTHER_SWIFT_FLAGS = $(inherited) -Xcc -fmodule-map-file=$(GENERATED_MODULEMAP_DIR)/CNIOAtomics.modulemap -Xcc -fmodule-map-file=$(GENERATED_MODULEMAP_DIR)/CNIODarwin.modulemap -Xcc -fmodule-map-file=$(GENERATED_MODULEMAP_DIR)/CGRPCZlib.modulemap +// Swift +SWIFT_VERSION = 5.0 +SWIFT_EMIT_LOC_STRINGS = YES + +// Release +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym +SWIFT_REFLECTION_METADATA_LEVEL = none +SWIFT_COMPILATION_MODE = wholemodule +SWIFT_OPTIMIZATION_LEVEL = -Osize +LLVM_LTO = YES +DEAD_CODE_STRIPPING = YES +VALIDATE_PRODUCT = YES + +// Debug +ONLY_ACTIVE_ARCH[config=Debug] = YES +DEBUG_INFORMATION_FORMAT[config=Debug] = dwarf +ENABLE_TESTABILITY[config=Debug] = YES +SWIFT_OPTIMIZATION_LEVEL[config=Debug] = -Onone +SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug] = DEBUG +SWIFT_COMPILATION_MODE[config=Debug] = singlefile +LLVM_LTO[config=Debug] = NO +DEAD_CODE_STRIPPING[config=Debug] = NO +VALIDATE_PRODUCT[config=Debug] = NO diff --git a/Apple/Configuration/Configuration.xcconfig b/Apple/Configuration/Configuration.xcconfig deleted file mode 100644 index 622950a..0000000 --- a/Apple/Configuration/Configuration.xcconfig +++ /dev/null @@ -1,4 +0,0 @@ -#include "Framework.xcconfig" - -SWIFT_INCLUDE_PATHS = $(PROJECT_DIR)/Configuration/Constants -GCC_PREPROCESSOR_DEFINITIONS = APP_BUNDLE_IDENTIFIER=$(APP_BUNDLE_IDENTIFIER) APP_GROUP_IDENTIFIER=$(APP_GROUP_IDENTIFIER) NETWORK_EXTENSION_BUNDLE_IDENTIFIER=$(NETWORK_EXTENSION_BUNDLE_IDENTIFIER) diff --git a/Apple/Configuration/Constants/Constants.h b/Apple/Configuration/Constants/Constants.h deleted file mode 100644 index 5278b61..0000000 --- a/Apple/Configuration/Constants/Constants.h +++ /dev/null @@ -1,12 +0,0 @@ -#import - -#define MACRO_STRING_(m) #m -#define MACRO_STRING(m) @MACRO_STRING_(m) - -NS_ASSUME_NONNULL_BEGIN - -static NSString * const AppBundleIdentifier = MACRO_STRING(APP_BUNDLE_IDENTIFIER); -static NSString * const AppGroupIdentifier = MACRO_STRING(APP_GROUP_IDENTIFIER); -static NSString * const NetworkExtensionBundleIdentifier = MACRO_STRING(NETWORK_EXTENSION_BUNDLE_IDENTIFIER); - -NS_ASSUME_NONNULL_END diff --git a/Apple/Configuration/Constants/Constants.swift b/Apple/Configuration/Constants/Constants.swift deleted file mode 100644 index 3f8ae95..0000000 --- a/Apple/Configuration/Constants/Constants.swift +++ /dev/null @@ -1,38 +0,0 @@ -@_implementationOnly import CConstants -import OSLog - -public enum Constants { - enum Error: Swift.Error { - case invalidAppGroupIdentifier - } - - public static let bundleIdentifier = AppBundleIdentifier - public static let appGroupIdentifier = AppGroupIdentifier - public static let networkExtensionBundleIdentifier = NetworkExtensionBundleIdentifier - - public static var socketURL: URL { - get throws { - try groupContainerURL.appending(component: "burrow.sock", directoryHint: .notDirectory) - } - } - public static var databaseURL: URL { - get throws { - try groupContainerURL.appending(component: "burrow.db", directoryHint: .notDirectory) - } - } - - private static var groupContainerURL: URL { - get throws { try _groupContainerURL.get() } - } - private static let _groupContainerURL: Result = { - switch FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier) { - case .some(let url): .success(url) - case .none: .failure(.invalidAppGroupIdentifier) - } - }() -} - -extension Logger { - @_dynamicReplacement(for: subsystem) - public static var subsystem: String { Constants.bundleIdentifier } -} diff --git a/Apple/Configuration/Constants/module.modulemap b/Apple/Configuration/Constants/module.modulemap deleted file mode 100644 index 0e60f32..0000000 --- a/Apple/Configuration/Constants/module.modulemap +++ /dev/null @@ -1,4 +0,0 @@ -module CConstants { - header "Constants.h" - export * -} diff --git a/Apple/Configuration/Debug.xcconfig b/Apple/Configuration/Debug.xcconfig deleted file mode 100644 index 9529dbd..0000000 --- a/Apple/Configuration/Debug.xcconfig +++ /dev/null @@ -1,26 +0,0 @@ -// Release -DEBUG_INFORMATION_FORMAT = dwarf-with-dsym -SWIFT_COMPILATION_MODE = wholemodule -SWIFT_OPTIMIZATION_LEVEL = -Osize -LLVM_LTO = YES -DEAD_CODE_STRIPPING = YES -STRIP_INSTALLED_PRODUCT = YES -STRIP_SWIFT_SYMBOLS = YES -COPY_PHASE_STRIP = NO -VALIDATE_PRODUCT = YES -ENABLE_MODULE_VERIFIER = YES - -// Debug -ONLY_ACTIVE_ARCH[config=Debug] = YES -DEBUG_INFORMATION_FORMAT[config=Debug] = dwarf -ENABLE_TESTABILITY[config=Debug] = YES -GCC_PREPROCESSOR_DEFINITIONS[config=Debug] = DEBUG=1 $(inherited) -SWIFT_OPTIMIZATION_LEVEL[config=Debug] = -Onone -SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug] = DEBUG -SWIFT_COMPILATION_MODE[config=Debug] = singlefile -LLVM_LTO[config=Debug] = NO -DEAD_CODE_STRIPPING[config=Debug] = NO -VALIDATE_PRODUCT[config=Debug] = NO -STRIP_INSTALLED_PRODUCT[config=Debug] = NO -STRIP_SWIFT_SYMBOLS[config=Debug] = NO -ENABLE_MODULE_VERIFIER[config=Debug] = NO diff --git a/Apple/Configuration/Extension.xcconfig b/Apple/Configuration/Extension.xcconfig index 5885c31..dfe9f5c 100644 --- a/Apple/Configuration/Extension.xcconfig +++ b/Apple/Configuration/Extension.xcconfig @@ -1,6 +1,2 @@ -LD_EXPORT_SYMBOLS = NO - -OTHER_SWIFT_FLAGS = $(inherited) -Xfrontend -disable-autolink-framework -Xfrontend UIKit -Xfrontend -disable-autolink-framework -Xfrontend AppKit -Xfrontend -disable-autolink-framework -Xfrontend SwiftUI - LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @executable_path/../../Frameworks -LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks +LD_RUNPATH_SEARCH_PATHS[sdk=macos*] = $(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks diff --git a/Apple/Configuration/Framework.xcconfig b/Apple/Configuration/Framework.xcconfig deleted file mode 100644 index 6fa4f19..0000000 --- a/Apple/Configuration/Framework.xcconfig +++ /dev/null @@ -1,14 +0,0 @@ -PRODUCT_NAME = Burrow$(TARGET_NAME:c99extidentifier) -PRODUCT_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).$(TARGET_NAME:c99extidentifier) -APPLICATION_EXTENSION_API_ONLY = YES -SWIFT_INSTALL_OBJC_HEADER = NO -SWIFT_SKIP_AUTOLINKING_FRAMEWORKS = YES -SWIFT_SKIP_AUTOLINKING_LIBRARIES = YES - -LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @loader_path/Frameworks -LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks @loader_path/Frameworks - -DYLIB_INSTALL_NAME_BASE = @rpath -DYLIB_COMPATIBILITY_VERSION = 1 -DYLIB_CURRENT_VERSION = 1 -VERSIONING_SYSTEM = diff --git a/Apple/Configuration/Identity.xcconfig b/Apple/Configuration/Identity.xcconfig index e9ca78d..6ff2392 100644 --- a/Apple/Configuration/Identity.xcconfig +++ b/Apple/Configuration/Identity.xcconfig @@ -1,2 +1,2 @@ -DEVELOPMENT_TEAM = P6PV2R9443 -APP_BUNDLE_IDENTIFIER = com.hackclub.burrow +DEVELOPMENT_TEAM = 2H4LMN3ZLG +APP_BUNDLE_IDENTIFIER = com.ThomasStubblefield.burrow diff --git a/Apple/Configuration/Version.xcconfig b/Apple/Configuration/Version.xcconfig deleted file mode 100644 index e69de29..0000000 diff --git a/Apple/Core/Client.swift b/Apple/Core/Client.swift deleted file mode 100644 index 8874e3b..0000000 --- a/Apple/Core/Client.swift +++ /dev/null @@ -1,32 +0,0 @@ -import GRPC -import NIOTransportServices - -public typealias TunnelClient = Burrow_TunnelAsyncClient -public typealias NetworksClient = Burrow_NetworksAsyncClient - -public protocol Client { - init(channel: GRPCChannel) -} - -extension Client { - public static func unix(socketURL: URL) -> Self { - let group = NIOTSEventLoopGroup() - let configuration = ClientConnection.Configuration.default( - target: .unixDomainSocket(socketURL.path), - eventLoopGroup: group - ) - return Self(channel: ClientConnection(configuration: configuration)) - } -} - -extension TunnelClient: Client { - public init(channel: any GRPCChannel) { - self.init(channel: channel, defaultCallOptions: .init(), interceptors: .none) - } -} - -extension NetworksClient: Client { - public init(channel: any GRPCChannel) { - self.init(channel: channel, defaultCallOptions: .init(), interceptors: .none) - } -} diff --git a/Apple/Core/Client/burrow.proto b/Apple/Core/Client/burrow.proto deleted file mode 120000 index 03e86a5..0000000 --- a/Apple/Core/Client/burrow.proto +++ /dev/null @@ -1 +0,0 @@ -../../../proto/burrow.proto \ No newline at end of file diff --git a/Apple/Core/Client/grpc-swift-config.json b/Apple/Core/Client/grpc-swift-config.json deleted file mode 100644 index 2d89698..0000000 --- a/Apple/Core/Client/grpc-swift-config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "invocations": [ - { - "protoFiles": [ - "burrow.proto", - ], - "server": false, - "visibility": "public" - } - ] -} diff --git a/Apple/Core/Client/swift-protobuf-config.json b/Apple/Core/Client/swift-protobuf-config.json deleted file mode 100644 index 87aaec3..0000000 --- a/Apple/Core/Client/swift-protobuf-config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "invocations": [ - { - "protoFiles": [ - "burrow.proto", - ], - "visibility": "public" - } - ] -} diff --git a/Apple/Core/Logging.swift b/Apple/Core/Logging.swift deleted file mode 100644 index ba40888..0000000 --- a/Apple/Core/Logging.swift +++ /dev/null @@ -1,19 +0,0 @@ -import os -@_exported import OSLog - -extension Logger { - private static let loggers: OSAllocatedUnfairLock<[String: Logger]> = OSAllocatedUnfairLock(initialState: [:]) - - public dynamic static var subsystem: String { "com.hackclub.burrow" } - - public static func logger(for type: Any.Type) -> Logger { - let category = String(describing: type) - let logger = loggers.withLock { loggers in - if let logger = loggers[category] { return logger } - let logger = Logger(subsystem: subsystem, category: category) - loggers[category] = logger - return logger - } - return logger - } -} diff --git a/Apple/NetworkExtension/Info.plist b/Apple/NetworkExtension/Info.plist index e2cf604..3059459 100644 --- a/Apple/NetworkExtension/Info.plist +++ b/Apple/NetworkExtension/Info.plist @@ -2,8 +2,6 @@ - CFBundleName - $(INFOPLIST_KEY_CFBundleDisplayName) NSExtension NSExtensionPointIdentifier diff --git a/Apple/NetworkExtension/NetworkExtension-iOS.entitlements b/Apple/NetworkExtension/NetworkExtension-iOS.entitlements index 02ee960..d9849a8 100644 --- a/Apple/NetworkExtension/NetworkExtension-iOS.entitlements +++ b/Apple/NetworkExtension/NetworkExtension-iOS.entitlements @@ -2,10 +2,6 @@ - com.apple.developer.networking.networkextension - - packet-tunnel-provider - com.apple.security.application-groups $(APP_GROUP_IDENTIFIER) diff --git a/Apple/NetworkExtension/NetworkExtension-macOS.entitlements b/Apple/NetworkExtension/NetworkExtension-macOS.entitlements index 63efcfc..d9849a8 100644 --- a/Apple/NetworkExtension/NetworkExtension-macOS.entitlements +++ b/Apple/NetworkExtension/NetworkExtension-macOS.entitlements @@ -2,19 +2,9 @@ - com.apple.developer.networking.networkextension - - packet-tunnel-provider - - com.apple.security.app-sandbox - com.apple.security.application-groups $(APP_GROUP_IDENTIFIER) - com.apple.security.network.client - - com.apple.security.network.server - diff --git a/Apple/NetworkExtension/NetworkExtension.xcconfig b/Apple/NetworkExtension/NetworkExtension.xcconfig index 35c7198..f606079 100644 --- a/Apple/NetworkExtension/NetworkExtension.xcconfig +++ b/Apple/NetworkExtension/NetworkExtension.xcconfig @@ -1,11 +1,8 @@ #include "../Configuration/Extension.xcconfig" PRODUCT_NAME = BurrowNetworkExtension -PRODUCT_BUNDLE_IDENTIFIER = $(NETWORK_EXTENSION_BUNDLE_IDENTIFIER) - +PRODUCT_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).network INFOPLIST_FILE = NetworkExtension/Info.plist CODE_SIGN_ENTITLEMENTS = NetworkExtension/NetworkExtension-iOS.entitlements -CODE_SIGN_ENTITLEMENTS[sdk=macosx*] = NetworkExtension/NetworkExtension-macOS.entitlements - -SWIFT_INCLUDE_PATHS = $(inherited) $(PROJECT_DIR)/NetworkExtension +CODE_SIGN_ENTITLEMENTS[sdk=macos*] = NetworkExtension/NetworkExtension-macOS.entitlements diff --git a/Apple/NetworkExtension/PacketTunnelProvider.swift b/Apple/NetworkExtension/PacketTunnelProvider.swift index a8e42e0..c8a87cf 100644 --- a/Apple/NetworkExtension/PacketTunnelProvider.swift +++ b/Apple/NetworkExtension/PacketTunnelProvider.swift @@ -1,74 +1,29 @@ -import AsyncAlgorithms -import BurrowConfiguration -import BurrowCore -import libburrow import NetworkExtension -import os class PacketTunnelProvider: NEPacketTunnelProvider { - enum Error: Swift.Error { - case missingTunnelConfiguration - } - private let logger = Logger.logger(for: PacketTunnelProvider.self) - - private var client: TunnelClient { - get throws { try _client.get() } + override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) { + // Add code here to start the process of connecting the tunnel. } - private let _client: Result = Result { - try TunnelClient.unix(socketURL: Constants.socketURL) + + override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { + // Add code here to start the process of stopping the tunnel. + completionHandler() } - - override init() { - do { - libburrow.spawnInProcess( - socketPath: try Constants.socketURL.path(percentEncoded: false), - databasePath: try Constants.databaseURL.path(percentEncoded: false) - ) - } catch { - logger.error("Failed to spawn networking thread: \(error)") + + override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { + // Add code here to handle the message. + if let handler = completionHandler { + handler(messageData) } } - - override func startTunnel(options: [String: NSObject]? = nil) async throws { - do { - let configuration = try await Array(client.tunnelConfiguration(.init()).prefix(1)).first - guard let settings = configuration?.settings else { - throw Error.missingTunnelConfiguration - } - try await setTunnelNetworkSettings(settings) - _ = try await client.tunnelStart(.init()) - logger.log("Started tunnel with network settings: \(settings)") - } catch { - logger.error("Failed to start tunnel: \(error)") - throw error - } + + override func sleep(completionHandler: @escaping () -> Void) { + // Add code here to get ready to sleep. + completionHandler() } - - override func stopTunnel(with reason: NEProviderStopReason) async { - do { - _ = try await client.tunnelStop(.init()) - logger.log("Stopped client") - } catch { - logger.error("Failed to stop tunnel: \(error)") - } - } -} - -extension Burrow_TunnelConfigurationResponse { - fileprivate var settings: NEPacketTunnelNetworkSettings { - let ipv6Addresses = addresses.filter { IPv6Address($0) != nil } - - let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "1.1.1.1") - settings.mtu = NSNumber(value: mtu) - settings.ipv4Settings = NEIPv4Settings( - addresses: addresses.filter { IPv4Address($0) != nil }, - subnetMasks: ["255.255.255.0"] - ) - settings.ipv6Settings = NEIPv6Settings( - addresses: ipv6Addresses, - networkPrefixLengths: ipv6Addresses.map { _ in 64 } - ) - return settings + + override func wake() { + // Add code here to wake up. } } diff --git a/Apple/NetworkExtension/libburrow/build-rust.sh b/Apple/NetworkExtension/libburrow/build-rust.sh deleted file mode 100755 index 6f455a9..0000000 --- a/Apple/NetworkExtension/libburrow/build-rust.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash - -# This is a build script. It is run by Xcode as a build step. -# The type of build is described in various environment variables set by Xcode. - -export PATH="${PATH}:${HOME}/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:/etc/profiles/per-user/${USER}/bin" - -if ! [[ -x "$(command -v cargo)" ]]; then - echo 'error: Unable to find cargo' - exit 127 -fi - -set -e - -# Change directories relative to the location of this script -cd -- "$(dirname -- "${BASH_SOURCE[0]}")"/../../../burrow - -RUST_TARGETS=() - -# Match the PLATFORM_NAME (iphoneos) and ARCHS (arm64) to a set of RUST_TARGETS (aarch64-apple-ios) -IFS=' ' read -a BURROW_ARCHS <<< "${ARCHS[@]}" -for ARCH in "${BURROW_ARCHS[@]}"; do - case $PLATFORM_NAME in - iphonesimulator) - case $ARCH in - arm64) RUST_TARGETS+=("aarch64-apple-ios-sim") ;; - x86_64) RUST_TARGETS+=("x86_64-apple-ios") ;; - *) echo "error: Unknown $PLATFORM_NAME arch, $ARCH"; exit 1 ;; - esac - ;; - iphoneos) - case $ARCH in - arm64) RUST_TARGETS+=("aarch64-apple-ios") ;; - *) echo "error: Unknown $PLATFORM_NAME arch, $ARCH"; exit 1 ;; - esac - ;; - macos*) - case $ARCH in - arm64) RUST_TARGETS+=("aarch64-apple-darwin") ;; - x86_64) RUST_TARGETS+=("x86_64-apple-darwin") ;; - *) echo "error: Unknown $PLATFORM_NAME arch, $ARCH"; exit 1 ;; - esac - ;; - *) echo "error: Unsupported platform $PLATFORM_NAME"; exit 1 ;; - esac -done - -# Pass all RUST_TARGETS in a single invocation -CARGO_ARGS=() -for TARGET in "${RUST_TARGETS[@]}"; do - CARGO_ARGS+=("--target") - CARGO_ARGS+=("$TARGET") -done - -CARGO_ARGS+=("--lib") - -# Pass the configuration (Debug or Release) through to cargo -if [[ $SWIFT_ACTIVE_COMPILATION_CONDITIONS == *DEBUG* ]]; then - CARGO_TARGET_SUBDIR="debug" -else - CARGO_ARGS+=("--release") - CARGO_TARGET_SUBDIR="release" -fi - -if [[ -x "$(command -v rustup)" ]]; then - CARGO_PATH="$(dirname $(rustup which cargo)):/usr/bin" -else - CARGO_PATH="$(dirname $(readlink -f $(which cargo))):/usr/bin" -fi - -PROTOC=$(readlink -f $(which protoc)) -CARGO_PATH="$(dirname $PROTOC):$CARGO_PATH" - -# Run cargo without the various environment variables set by Xcode. -# Those variables can confuse cargo and the build scripts it runs. -env -i PATH="$CARGO_PATH" PROTOC="$PROTOC" CARGO_TARGET_DIR="${CONFIGURATION_TEMP_DIR}/target" IPHONEOS_DEPLOYMENT_TARGET="$IPHONEOS_DEPLOYMENT_TARGET" MACOSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET" cargo build "${CARGO_ARGS[@]}" - -mkdir -p "${BUILT_PRODUCTS_DIR}" - -# Use `lipo` to merge the architectures together into BUILT_PRODUCTS_DIR -/usr/bin/xcrun --sdk $PLATFORM_NAME lipo \ - -create $(printf "${CONFIGURATION_TEMP_DIR}/target/%q/${CARGO_TARGET_SUBDIR}/libburrow.a " "${RUST_TARGETS[@]}") \ - -output "${BUILT_PRODUCTS_DIR}/libburrow.a" diff --git a/Apple/NetworkExtension/libburrow/libburrow.h b/Apple/NetworkExtension/libburrow/libburrow.h deleted file mode 100644 index 59b4734..0000000 --- a/Apple/NetworkExtension/libburrow/libburrow.h +++ /dev/null @@ -1,2 +0,0 @@ -__attribute__((__swift_name__("spawnInProcess(socketPath:databasePath:)"))) -extern void spawn_in_process(const char * __nullable socket_path, const char * __nullable db_path); diff --git a/Apple/NetworkExtension/libburrow/module.modulemap b/Apple/NetworkExtension/libburrow/module.modulemap deleted file mode 100644 index c53a032..0000000 --- a/Apple/NetworkExtension/libburrow/module.modulemap +++ /dev/null @@ -1,4 +0,0 @@ -module libburrow { - header "libburrow.h" - export * -} diff --git a/Apple/Profiles/Burrow_Developer_ID.provisionprofile b/Apple/Profiles/Burrow_Developer_ID.provisionprofile deleted file mode 100644 index 3ecd831..0000000 Binary files a/Apple/Profiles/Burrow_Developer_ID.provisionprofile and /dev/null differ diff --git a/Apple/Profiles/Burrow_Network_Developer_ID.provisionprofile b/Apple/Profiles/Burrow_Network_Developer_ID.provisionprofile deleted file mode 100644 index 3ce7e37..0000000 Binary files a/Apple/Profiles/Burrow_Network_Developer_ID.provisionprofile and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/100.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/100.png deleted file mode 100644 index f86c139..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/100.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/1024.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/1024.png deleted file mode 100644 index 872c9ce..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/1024.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/114.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/114.png deleted file mode 100644 index 3bb278d..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/114.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/120.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/120.png deleted file mode 100644 index 185615e..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/120.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/128.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/128.png deleted file mode 100644 index 51bd97c..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/128.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/144.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/144.png deleted file mode 100644 index b05e371..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/144.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/152.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/152.png deleted file mode 100644 index c95ea8a..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/152.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/16.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/16.png deleted file mode 100644 index 3cb15a5..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/16.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/167.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/167.png deleted file mode 100644 index a3ad6a2..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/167.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/172.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/172.png deleted file mode 100644 index 9f3bdb4..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/172.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/180.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/180.png deleted file mode 100644 index 53c1237..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/180.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/196.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/196.png deleted file mode 100644 index ea95961..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/196.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/20.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/20.png deleted file mode 100644 index aec8236..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/20.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/216.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/216.png deleted file mode 100644 index 9f0e3ce..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/216.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/256.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/256.png deleted file mode 100644 index a82ce93..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/256.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/29.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/29.png deleted file mode 100644 index 8dc25c1..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/29.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/32.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/32.png deleted file mode 100644 index 655a424..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/32.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/40.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/40.png deleted file mode 100644 index 1f7f5e9..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/40.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/48.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/48.png deleted file mode 100644 index 4a67ebf..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/48.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/50.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/50.png deleted file mode 100644 index 88985d8..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/50.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/512.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/512.png deleted file mode 100644 index e5cbf6a..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/512.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/55.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/55.png deleted file mode 100644 index dc079ea..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/55.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/57.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/57.png deleted file mode 100644 index de4fddc..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/57.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/58.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/58.png deleted file mode 100644 index 961adad..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/58.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/60.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/60.png deleted file mode 100644 index 2a9e939..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/60.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/64.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/64.png deleted file mode 100644 index c67e407..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/64.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/72.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/72.png deleted file mode 100644 index d09aebe..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/72.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/76.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/76.png deleted file mode 100644 index 3e649b6..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/76.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/80.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/80.png deleted file mode 100644 index 6dad29f..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/80.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/87.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/87.png deleted file mode 100644 index a8ccb38..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/87.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/88.png b/Apple/UI/Assets.xcassets/AppIcon.appiconset/88.png deleted file mode 100644 index b1a478a..0000000 Binary files a/Apple/UI/Assets.xcassets/AppIcon.appiconset/88.png and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/AppIcon.appiconset/Contents.json b/Apple/UI/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index f78687a..0000000 --- a/Apple/UI/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,344 +0,0 @@ -{ - "images" : [ - { - "filename" : "40.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "filename" : "60.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "filename" : "29.png", - "idiom" : "iphone", - "scale" : "1x", - "size" : "29x29" - }, - { - "filename" : "58.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "filename" : "87.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "filename" : "80.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "filename" : "120.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "filename" : "57.png", - "idiom" : "iphone", - "scale" : "1x", - "size" : "57x57" - }, - { - "filename" : "114.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "57x57" - }, - { - "filename" : "120.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "filename" : "180.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "filename" : "20.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" - }, - { - "filename" : "40.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "20x20" - }, - { - "filename" : "29.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" - }, - { - "filename" : "58.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "29x29" - }, - { - "filename" : "40.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" - }, - { - "filename" : "80.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "40x40" - }, - { - "filename" : "50.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "50x50" - }, - { - "filename" : "100.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "50x50" - }, - { - "filename" : "72.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "72x72" - }, - { - "filename" : "144.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "72x72" - }, - { - "filename" : "76.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" - }, - { - "filename" : "152.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "76x76" - }, - { - "filename" : "167.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "83.5x83.5" - }, - { - "filename" : "1024.png", - "idiom" : "ios-marketing", - "scale" : "1x", - "size" : "1024x1024" - }, - { - "filename" : "16.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" - }, - { - "filename" : "32.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" - }, - { - "filename" : "32.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" - }, - { - "filename" : "64.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" - }, - { - "filename" : "128.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" - }, - { - "filename" : "256.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" - }, - { - "filename" : "256.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" - }, - { - "filename" : "512.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "256x256" - }, - { - "filename" : "512.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" - }, - { - "filename" : "1024.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" - }, - { - "filename" : "48.png", - "idiom" : "watch", - "role" : "notificationCenter", - "scale" : "2x", - "size" : "24x24", - "subtype" : "38mm" - }, - { - "filename" : "55.png", - "idiom" : "watch", - "role" : "notificationCenter", - "scale" : "2x", - "size" : "27.5x27.5", - "subtype" : "42mm" - }, - { - "filename" : "58.png", - "idiom" : "watch", - "role" : "companionSettings", - "scale" : "2x", - "size" : "29x29" - }, - { - "filename" : "87.png", - "idiom" : "watch", - "role" : "companionSettings", - "scale" : "3x", - "size" : "29x29" - }, - { - "idiom" : "watch", - "role" : "notificationCenter", - "scale" : "2x", - "size" : "33x33", - "subtype" : "45mm" - }, - { - "filename" : "80.png", - "idiom" : "watch", - "role" : "appLauncher", - "scale" : "2x", - "size" : "40x40", - "subtype" : "38mm" - }, - { - "filename" : "88.png", - "idiom" : "watch", - "role" : "appLauncher", - "scale" : "2x", - "size" : "44x44", - "subtype" : "40mm" - }, - { - "idiom" : "watch", - "role" : "appLauncher", - "scale" : "2x", - "size" : "46x46", - "subtype" : "41mm" - }, - { - "filename" : "100.png", - "idiom" : "watch", - "role" : "appLauncher", - "scale" : "2x", - "size" : "50x50", - "subtype" : "44mm" - }, - { - "idiom" : "watch", - "role" : "appLauncher", - "scale" : "2x", - "size" : "51x51", - "subtype" : "45mm" - }, - { - "idiom" : "watch", - "role" : "appLauncher", - "scale" : "2x", - "size" : "54x54", - "subtype" : "49mm" - }, - { - "filename" : "172.png", - "idiom" : "watch", - "role" : "quickLook", - "scale" : "2x", - "size" : "86x86", - "subtype" : "38mm" - }, - { - "filename" : "196.png", - "idiom" : "watch", - "role" : "quickLook", - "scale" : "2x", - "size" : "98x98", - "subtype" : "42mm" - }, - { - "filename" : "216.png", - "idiom" : "watch", - "role" : "quickLook", - "scale" : "2x", - "size" : "108x108", - "subtype" : "44mm" - }, - { - "idiom" : "watch", - "role" : "quickLook", - "scale" : "2x", - "size" : "117x117", - "subtype" : "45mm" - }, - { - "idiom" : "watch", - "role" : "quickLook", - "scale" : "2x", - "size" : "129x129", - "subtype" : "49mm" - }, - { - "filename" : "1024.png", - "idiom" : "watch-marketing", - "scale" : "1x", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Apple/UI/Assets.xcassets/HackClub.colorset/Contents.json b/Apple/UI/Assets.xcassets/HackClub.colorset/Contents.json deleted file mode 100644 index 911b4b1..0000000 --- a/Apple/UI/Assets.xcassets/HackClub.colorset/Contents.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "colors" : [ - { - "color" : { - "color-space" : "srgb", - "components" : { - "alpha" : "1.000", - "blue" : "0x50", - "green" : "0x37", - "red" : "0xEC" - } - }, - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Apple/UI/Assets.xcassets/HackClub.imageset/Contents.json b/Apple/UI/Assets.xcassets/HackClub.imageset/Contents.json deleted file mode 100644 index ddd0664..0000000 --- a/Apple/UI/Assets.xcassets/HackClub.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "filename" : "flag-standalone-wtransparent.pdf", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Apple/UI/Assets.xcassets/HackClub.imageset/flag-standalone-wtransparent.pdf b/Apple/UI/Assets.xcassets/HackClub.imageset/flag-standalone-wtransparent.pdf deleted file mode 100644 index 1506fe9..0000000 Binary files a/Apple/UI/Assets.xcassets/HackClub.imageset/flag-standalone-wtransparent.pdf and /dev/null differ diff --git a/Apple/UI/Assets.xcassets/WireGuard.colorset/Contents.json b/Apple/UI/Assets.xcassets/WireGuard.colorset/Contents.json deleted file mode 100644 index 092ec69..0000000 --- a/Apple/UI/Assets.xcassets/WireGuard.colorset/Contents.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "colors" : [ - { - "color" : { - "color-space" : "srgb", - "components" : { - "alpha" : "1.000", - "blue" : "0x1A", - "green" : "0x17", - "red" : "0x88" - } - }, - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Apple/UI/Assets.xcassets/WireGuard.imageset/Contents.json b/Apple/UI/Assets.xcassets/WireGuard.imageset/Contents.json deleted file mode 100644 index e7fe15a..0000000 --- a/Apple/UI/Assets.xcassets/WireGuard.imageset/Contents.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "images" : [ - { - "filename" : "WireGuard.svg", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - }, - "properties" : { - "preserves-vector-representation" : true - } -} diff --git a/Apple/UI/Assets.xcassets/WireGuard.imageset/WireGuard.svg b/Apple/UI/Assets.xcassets/WireGuard.imageset/WireGuard.svg deleted file mode 100644 index 9520f89..0000000 --- a/Apple/UI/Assets.xcassets/WireGuard.imageset/WireGuard.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Apple/UI/Assets.xcassets/WireGuardTitle.imageset/WireGuardTitle.svg b/Apple/UI/Assets.xcassets/WireGuardTitle.imageset/WireGuardTitle.svg deleted file mode 100644 index 64946da..0000000 --- a/Apple/UI/Assets.xcassets/WireGuardTitle.imageset/WireGuardTitle.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/Apple/UI/BurrowView.swift b/Apple/UI/BurrowView.swift deleted file mode 100644 index 96467c7..0000000 --- a/Apple/UI/BurrowView.swift +++ /dev/null @@ -1,75 +0,0 @@ -import AuthenticationServices -import SwiftUI - -#if !os(macOS) -public struct BurrowView: View { - @Environment(\.webAuthenticationSession) - private var webAuthenticationSession - - public var body: some View { - NavigationStack { - VStack { - HStack { - Text("Networks") - .font(.largeTitle) - .fontWeight(.bold) - Spacer() - Menu { - Button("Hack Club", action: addHackClubNetwork) - Button("WireGuard", action: addWireGuardNetwork) - } label: { - Image(systemName: "plus.circle.fill") - .font(.title) - .accessibilityLabel("Add") - } - } - .padding(.top) - NetworkCarouselView() - Spacer() - TunnelStatusView() - TunnelButton() - .padding(.bottom) - } - .padding() - .handleOAuth2Callback() - } - } - - public init() { - } - - private func addHackClubNetwork() { - Task { - try await authenticateWithSlack() - } - } - - private func addWireGuardNetwork() { - } - - private func authenticateWithSlack() async throws { - guard - let authorizationEndpoint = URL(string: "https://slack.com/openid/connect/authorize"), - let tokenEndpoint = URL(string: "https://slack.com/api/openid.connect.token"), - let redirectURI = URL(string: "https://burrow.rs/callback/oauth2") else { return } - let session = OAuth2.Session( - authorizationEndpoint: authorizationEndpoint, - tokenEndpoint: tokenEndpoint, - redirectURI: redirectURI, - scopes: ["openid", "profile"], - clientID: "2210535565.6884042183125", - clientSecret: "2793c8a5255cae38830934c664eeb62d" - ) - let response = try await session.authorize(webAuthenticationSession) - } -} - -#if DEBUG -struct NetworkView_Previews: PreviewProvider { - static var previews: some View { - BurrowView() - .environment(\.tunnel, PreviewTunnel()) - } -} -#endif -#endif diff --git a/Apple/UI/FloatingButtonStyle.swift b/Apple/UI/FloatingButtonStyle.swift deleted file mode 100644 index 53ab5ed..0000000 --- a/Apple/UI/FloatingButtonStyle.swift +++ /dev/null @@ -1,50 +0,0 @@ -import SwiftUI - -struct FloatingButtonStyle: ButtonStyle { - static let duration = 0.08 - - var color: Color - var cornerRadius: CGFloat - - func makeBody(configuration: Configuration) -> some View { - configuration.label - .font(.headline) - .foregroundColor(.white) - .frame(minHeight: 48) - .padding(.horizontal) - .background( - RoundedRectangle(cornerRadius: cornerRadius) - .fill( - LinearGradient( - colors: [ - configuration.isPressed ? color.opacity(0.9) : color.opacity(0.9), - configuration.isPressed ? color.opacity(0.9) : color - ], - startPoint: .init(x: 0.2, y: 0), - endPoint: .init(x: 0.8, y: 1) - ) - ) - .background( - RoundedRectangle(cornerRadius: cornerRadius) - .fill(configuration.isPressed ? .black : .white) - ) - ) - .shadow(color: .black.opacity(configuration.isPressed ? 0.0 : 0.1), radius: 2.5, x: 0, y: 2) - .scaleEffect(configuration.isPressed ? 0.975 : 1.0) - .padding(.bottom, 2) - .animation( - configuration.isPressed ? .easeOut(duration: Self.duration) : .easeIn(duration: Self.duration), - value: configuration.isPressed - ) - } -} - -extension ButtonStyle where Self == FloatingButtonStyle { - static var floating: FloatingButtonStyle { - floating() - } - - static func floating(color: Color = .accentColor, cornerRadius: CGFloat = 10) -> FloatingButtonStyle { - FloatingButtonStyle(color: color, cornerRadius: cornerRadius) - } -} diff --git a/Apple/UI/MenuItemToggleView.swift b/Apple/UI/MenuItemToggleView.swift deleted file mode 100644 index ef5e8ee..0000000 --- a/Apple/UI/MenuItemToggleView.swift +++ /dev/null @@ -1,67 +0,0 @@ -// -// MenuItemToggleView.swift -// App -// -// Created by Thomas Stubblefield on 5/13/23. -// - -import SwiftUI - -public struct MenuItemToggleView: View { - @Environment(\.tunnel) - var tunnel: Tunnel - - public var body: some View { - HStack { - VStack(alignment: .leading) { - Text("Burrow") - .font(.headline) - Text(tunnel.status.description) - .font(.subheadline) - } - Spacer() - Toggle(isOn: tunnel.toggleIsOn) { - } - .disabled(tunnel.toggleDisabled) - .toggleStyle(.switch) - } - .accessibilityElement(children: .combine) - .padding(.horizontal, 4) - .padding(10) - .frame(minWidth: 300, minHeight: 32, maxHeight: 32) - } - - public init() { - } -} - -extension Tunnel { - @MainActor fileprivate var toggleDisabled: Bool { - switch status { - case .disconnected, .permissionRequired, .connected, .disconnecting: - false - case .unknown, .disabled, .connecting, .reasserting, .invalid, .configurationReadWriteFailed: - true - } - } - - @MainActor var toggleIsOn: Binding { - Binding { - switch status { - case .connecting, .reasserting, .connected: - true - default: - false - } - } set: { newValue in - switch (status, newValue) { - case (.permissionRequired, true): - enable() - case (_, true): - start() - case (_, false): - stop() - } - } - } -} diff --git a/Apple/UI/NetworkCarouselView.swift b/Apple/UI/NetworkCarouselView.swift deleted file mode 100644 index f969356..0000000 --- a/Apple/UI/NetworkCarouselView.swift +++ /dev/null @@ -1,39 +0,0 @@ -import SwiftUI - -struct NetworkCarouselView: View { - var networks: [any Network] = [ - HackClub(id: 1), - HackClub(id: 2), - WireGuard(id: 4), - HackClub(id: 5) - ] - - var body: some View { - ScrollView(.horizontal) { - LazyHStack { - ForEach(networks, id: \.id) { network in - NetworkView(network: network) - .containerRelativeFrame(.horizontal, count: 10, span: 7, spacing: 0, alignment: .center) - .scrollTransition(.interactive, axis: .horizontal) { content, phase in - content - .scaleEffect(1.0 - abs(phase.value) * 0.1) - } - } - } - } - .scrollTargetLayout() - .scrollClipDisabled() - .scrollIndicators(.hidden) - .defaultScrollAnchor(.center) - .scrollTargetBehavior(.viewAligned) - .containerRelativeFrame(.horizontal) - } -} - -#if DEBUG -struct NetworkCarouselView_Previews: PreviewProvider { - static var previews: some View { - NetworkCarouselView() - } -} -#endif diff --git a/Apple/UI/NetworkExtension+Async.swift b/Apple/UI/NetworkExtension+Async.swift deleted file mode 100644 index 5820e7f..0000000 --- a/Apple/UI/NetworkExtension+Async.swift +++ /dev/null @@ -1,45 +0,0 @@ -import NetworkExtension - -extension NEVPNManager: @unchecked @retroactive Sendable { - func remove() async throws { - _ = try await withUnsafeThrowingContinuation { continuation in - removeFromPreferences(completionHandler: completion(continuation)) - } - } - - func save() async throws { - _ = try await withUnsafeThrowingContinuation { continuation in - saveToPreferences(completionHandler: completion(continuation)) - } - } -} - -extension NETunnelProviderManager: @unchecked @retroactive Sendable { - class var managers: [NETunnelProviderManager] { - get async throws { - try await withUnsafeThrowingContinuation { continuation in - loadAllFromPreferences(completionHandler: completion(continuation)) - } - } - } -} - -private func completion(_ continuation: UnsafeContinuation) -> (Error?) -> Void { - return { error in - if let error { - continuation.resume(throwing: error) - } else { - continuation.resume(returning: ()) - } - } -} - -private func completion(_ continuation: UnsafeContinuation) -> (T?, Error?) -> Void { - return { value, error in - if let error { - continuation.resume(throwing: error) - } else if let value { - continuation.resume(returning: value) - } - } -} diff --git a/Apple/UI/NetworkExtensionTunnel.swift b/Apple/UI/NetworkExtensionTunnel.swift deleted file mode 100644 index 7aaa3b1..0000000 --- a/Apple/UI/NetworkExtensionTunnel.swift +++ /dev/null @@ -1,171 +0,0 @@ -import BurrowCore -import NetworkExtension - -@Observable -public final class NetworkExtensionTunnel: Tunnel { - @MainActor public private(set) var status: TunnelStatus = .unknown - @MainActor private var error: NEVPNError? - - private let logger = Logger.logger(for: Tunnel.self) - private let bundleIdentifier: String - private let configurationChanged: Task - private let statusChanged: Task - - // Each manager corresponds to one entry in the Settings app. - // Our goal is to maintain a single manager, so we create one if none exist and delete any extra. - @MainActor private var managers: [NEVPNManager]? { - didSet { Task { await updateStatus() } } - } - - @MainActor private var currentStatus: TunnelStatus { - guard let managers = managers else { - guard let error = error else { - return .unknown - } - - switch error.code { - case .configurationReadWriteFailed: - return .configurationReadWriteFailed - default: - return .unknown - } - } - - guard let manager = managers.first else { - return .permissionRequired - } - - guard manager.isEnabled else { - return .disabled - } - - return manager.connection.tunnelStatus - } - - public init(bundleIdentifier: String) { - self.bundleIdentifier = bundleIdentifier - - let center = NotificationCenter.default - let tunnel: OSAllocatedUnfairLock = .init(initialState: .none) - configurationChanged = Task { - for try await _ in center.notifications(named: .NEVPNConfigurationChange) { - try Task.checkCancellation() - await tunnel.withLock { $0 }?.update() - } - } - statusChanged = Task { - for try await _ in center.notifications(named: .NEVPNStatusDidChange) { - try Task.checkCancellation() - await tunnel.withLock { $0 }?.updateStatus() - } - } - tunnel.withLock { $0 = self } - - Task { await update() } - } - - private func update() async { - do { - let result = try await NETunnelProviderManager.managers - await MainActor.run { - managers = result - status = currentStatus - } - await self.updateStatus() - } catch let vpnError as NEVPNError { - await MainActor.run { - error = vpnError - } - } catch { - logger.error("Failed to update VPN configurations: \(error)") - } - } - - private func updateStatus() async { - await MainActor.run { - status = currentStatus - } - } - - func configure() async throws { - let managers = try await NETunnelProviderManager.managers - if managers.count > 1 { - try await withThrowingTaskGroup(of: Void.self, returning: Void.self) { group in - for manager in managers.suffix(from: 1) { - group.addTask { try await manager.remove() } - } - try await group.waitForAll() - } - } - - guard managers.isEmpty else { return } - - let manager = NETunnelProviderManager() - manager.localizedDescription = "Burrow" - - let proto = NETunnelProviderProtocol() - proto.providerBundleIdentifier = bundleIdentifier - proto.serverAddress = "hackclub.com" - - manager.protocolConfiguration = proto - try await manager.save() - } - - public func start() { - Task { - guard let manager = try await NETunnelProviderManager.managers.first else { return } - do { - if !manager.isEnabled { - manager.isEnabled = true - try await manager.save() - } - try manager.connection.startVPNTunnel() - } catch { - logger.error("Failed to start: \(error)") - } - } - } - - public func stop() { - Task { - guard let manager = try await NETunnelProviderManager.managers.first else { return } - manager.connection.stopVPNTunnel() - } - } - - public func enable() { - Task { - do { - try await configure() - } catch { - logger.error("Failed to enable: \(error)") - } - } - } - - deinit { - configurationChanged.cancel() - statusChanged.cancel() - } -} - -extension NEVPNConnection { - fileprivate var tunnelStatus: TunnelStatus { - switch status { - case .connected: - .connected(connectedDate!) - case .connecting: - .connecting - case .disconnecting: - .disconnecting - case .disconnected: - .disconnected - case .reasserting: - .reasserting - case .invalid: - .invalid - @unknown default: - .unknown - } - } -} diff --git a/Apple/UI/NetworkView.swift b/Apple/UI/NetworkView.swift deleted file mode 100644 index b839d65..0000000 --- a/Apple/UI/NetworkView.swift +++ /dev/null @@ -1,38 +0,0 @@ -import SwiftUI - -struct NetworkView: View { - var color: Color - var content: () -> Content - - private var gradient: LinearGradient { - LinearGradient( - colors: [ - color.opacity(0.8), - color - ], - startPoint: .init(x: 0.2, y: 0), - endPoint: .init(x: 0.8, y: 1) - ) - } - - var body: some View { - content() - .frame(maxWidth: .infinity, minHeight: 175, maxHeight: 175) - .background( - RoundedRectangle(cornerRadius: 10) - .fill(gradient) - .background( - RoundedRectangle(cornerRadius: 10) - .fill(.white) - ) - ) - .shadow(color: .black.opacity(0.1), radius: 3.0, x: 0, y: 2) - } -} - -extension NetworkView where Content == AnyView { - init(network: any Network) { - color = network.backgroundColor - content = { AnyView(network.label) } - } -} diff --git a/Apple/UI/Networks/HackClub.swift b/Apple/UI/Networks/HackClub.swift deleted file mode 100644 index b1c2023..0000000 --- a/Apple/UI/Networks/HackClub.swift +++ /dev/null @@ -1,27 +0,0 @@ -import BurrowCore -import SwiftUI - -struct HackClub: Network { - typealias NetworkType = Burrow_WireGuardNetwork - static let type: Burrow_NetworkType = .hackClub - - var id: Int32 - var backgroundColor: Color { .init("HackClub") } - - @MainActor var label: some View { - GeometryReader { reader in - VStack(alignment: .leading) { - Image("HackClub") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(height: reader.size.height / 4) - Spacer() - Text("@conradev") - .foregroundStyle(.white) - .font(.body.monospaced()) - } - .padding() - .frame(maxWidth: .infinity) - } - } -} diff --git a/Apple/UI/Networks/Network.swift b/Apple/UI/Networks/Network.swift deleted file mode 100644 index c6d5fba..0000000 --- a/Apple/UI/Networks/Network.swift +++ /dev/null @@ -1,36 +0,0 @@ -import Atomics -import BurrowCore -import SwiftProtobuf -import SwiftUI - -protocol Network { - associatedtype NetworkType: Message - associatedtype Label: View - - static var type: Burrow_NetworkType { get } - - var id: Int32 { get } - var backgroundColor: Color { get } - - @MainActor var label: Label { get } -} - -@Observable -@MainActor -final class NetworkViewModel: Sendable { - private(set) var networks: [Burrow_Network] = [] - - private var task: Task! - - init(socketURL: URL) { - task = Task { [weak self] in - let client = NetworksClient.unix(socketURL: socketURL) - for try await networks in client.networkList(.init()) { - guard let viewModel = self else { continue } - Task { @MainActor in - viewModel.networks = networks.network - } - } - } - } -} diff --git a/Apple/UI/Networks/WireGuard.swift b/Apple/UI/Networks/WireGuard.swift deleted file mode 100644 index cba67ef..0000000 --- a/Apple/UI/Networks/WireGuard.swift +++ /dev/null @@ -1,34 +0,0 @@ -import BurrowCore -import SwiftUI - -struct WireGuard: Network { - typealias NetworkType = Burrow_WireGuardNetwork - static let type: BurrowCore.Burrow_NetworkType = .wireGuard - - var id: Int32 - var backgroundColor: Color { .init("WireGuard") } - - @MainActor var label: some View { - GeometryReader { reader in - VStack(alignment: .leading) { - HStack { - Image("WireGuard") - .resizable() - .aspectRatio(contentMode: .fit) - Image("WireGuardTitle") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: reader.size.width / 2) - Spacer() - } - .frame(maxWidth: .infinity, maxHeight: reader.size.height / 4) - Spacer() - Text("@conradev") - .foregroundStyle(.white) - .font(.body.monospaced()) - } - .padding() - .frame(maxWidth: .infinity) - } - } -} diff --git a/Apple/UI/OAuth2.swift b/Apple/UI/OAuth2.swift deleted file mode 100644 index 0fafc8d..0000000 --- a/Apple/UI/OAuth2.swift +++ /dev/null @@ -1,293 +0,0 @@ -import AuthenticationServices -import Foundation -import os -import SwiftUI - -enum OAuth2 { - enum Error: Swift.Error { - case unknown - case invalidAuthorizationURL - case invalidCallbackURL - case invalidRedirectURI - } - - struct Credential { - var accessToken: String - var refreshToken: String? - var expirationDate: Date? - } - - struct Session { - var authorizationEndpoint: URL - var tokenEndpoint: URL - var redirectURI: URL - var responseType = OAuth2.ResponseType.code - var scopes: Set - var clientID: String - var clientSecret: String - - fileprivate static let queue: OSAllocatedUnfairLock<[Int: CheckedContinuation]> = { - .init(initialState: [:]) - }() - - fileprivate static func handle(url: URL) { - let continuations = queue.withLock { continuations in - let copy = continuations - continuations.removeAll() - return copy - } - for (_, continuation) in continuations { - continuation.resume(returning: url) - } - } - - init( - authorizationEndpoint: URL, - tokenEndpoint: URL, - redirectURI: URL, - scopes: Set, - clientID: String, - clientSecret: String - ) { - self.authorizationEndpoint = authorizationEndpoint - self.tokenEndpoint = tokenEndpoint - self.redirectURI = redirectURI - self.scopes = scopes - self.clientID = clientID - self.clientSecret = clientSecret - } - - private var authorizationURL: URL { - get throws { - var queryItems: [URLQueryItem] = [ - .init(name: "client_id", value: clientID), - .init(name: "response_type", value: responseType.rawValue), - .init(name: "redirect_uri", value: redirectURI.absoluteString) - ] - if !scopes.isEmpty { - queryItems.append(.init(name: "scope", value: scopes.joined(separator: ","))) - } - guard var components = URLComponents(url: authorizationEndpoint, resolvingAgainstBaseURL: false) else { - throw OAuth2.Error.invalidAuthorizationURL - } - components.queryItems = queryItems - guard let authorizationURL = components.url else { throw OAuth2.Error.invalidAuthorizationURL } - return authorizationURL - } - } - - private func handle(callbackURL: URL) async throws -> OAuth2.AccessTokenResponse { - switch responseType { - case .code: - guard let components = URLComponents(url: callbackURL, resolvingAgainstBaseURL: false) else { - throw OAuth2.Error.invalidCallbackURL - } - return try await handle(response: try components.decode(OAuth2.CodeResponse.self)) - default: - throw OAuth2.Error.invalidCallbackURL - } - } - - private func handle(response: OAuth2.CodeResponse) async throws -> OAuth2.AccessTokenResponse { - var components = URLComponents() - components.queryItems = [ - .init(name: "client_id", value: clientID), - .init(name: "client_secret", value: clientSecret), - .init(name: "grant_type", value: GrantType.authorizationCode.rawValue), - .init(name: "code", value: response.code), - .init(name: "redirect_uri", value: redirectURI.absoluteString) - ] - let httpBody = Data(components.percentEncodedQuery!.utf8) - - var request = URLRequest(url: tokenEndpoint) - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - request.httpMethod = "POST" - request.httpBody = httpBody - - let session = URLSession(configuration: .ephemeral) - let (data, _) = try await session.data(for: request) - return try OAuth2.decoder.decode(OAuth2.AccessTokenResponse.self, from: data) - } - - func authorize(_ session: WebAuthenticationSession) async throws -> Credential { - let authorizationURL = try authorizationURL - let callbackURL = try await session.start( - url: authorizationURL, - redirectURI: redirectURI - ) - return try await handle(callbackURL: callbackURL).credential - } - } - - private struct CodeResponse: Codable { - var code: String - var state: String? - } - - private struct AccessTokenResponse: Codable { - var accessToken: String - var tokenType: TokenType - var expiresIn: Double? - var refreshToken: String? - - var credential: Credential { - .init( - accessToken: accessToken, - refreshToken: refreshToken, - expirationDate: expiresIn.map { Date(timeIntervalSinceNow: $0) } - ) - } - } - - enum TokenType: Codable, RawRepresentable { - case bearer - case unknown(String) - - init(rawValue: String) { - self = switch rawValue.lowercased() { - case "bearer": .bearer - default: .unknown(rawValue) - } - } - - var rawValue: String { - switch self { - case .bearer: "bearer" - case .unknown(let type): type - } - } - } - - enum GrantType: Codable, RawRepresentable { - case authorizationCode - case unknown(String) - - init(rawValue: String) { - self = switch rawValue.lowercased() { - case "authorization_code": .authorizationCode - default: .unknown(rawValue) - } - } - - var rawValue: String { - switch self { - case .authorizationCode: "authorization_code" - case .unknown(let type): type - } - } - } - - enum ResponseType: Codable, RawRepresentable { - case code - case idToken - case unknown(String) - - init(rawValue: String) { - self = switch rawValue.lowercased() { - case "code": .code - case "id_token": .idToken - default: .unknown(rawValue) - } - } - - var rawValue: String { - switch self { - case .code: "code" - case .idToken: "id_token" - case .unknown(let type): type - } - } - } - - fileprivate static var decoder: JSONDecoder { - let decoder = JSONDecoder() - decoder.keyDecodingStrategy = .convertFromSnakeCase - return decoder - } - - fileprivate static var encoder: JSONEncoder { - let encoder = JSONEncoder() - encoder.keyEncodingStrategy = .convertToSnakeCase - return encoder - } -} - -extension WebAuthenticationSession: @unchecked @retroactive Sendable { -} - -extension WebAuthenticationSession { -#if canImport(BrowserEngineKit) - @available(iOS 17.4, macOS 14.4, tvOS 17.4, watchOS 10.4, *) - fileprivate static func callback(for redirectURI: URL) throws -> ASWebAuthenticationSession.Callback { - switch redirectURI.scheme { - case "https": - guard let host = redirectURI.host else { throw OAuth2.Error.invalidRedirectURI } - return .https(host: host, path: redirectURI.path) - case "http": - throw OAuth2.Error.invalidRedirectURI - case .some(let scheme): - return .customScheme(scheme) - case .none: - throw OAuth2.Error.invalidRedirectURI - } - } -#endif - - fileprivate func start(url: URL, redirectURI: URL) async throws -> URL { - #if canImport(BrowserEngineKit) - if #available(iOS 17.4, macOS 14.4, tvOS 17.4, watchOS 10.4, *) { - return try await authenticate( - using: url, - callback: try Self.callback(for: redirectURI), - additionalHeaderFields: [:] - ) - } - #endif - - return try await withThrowingTaskGroup(of: URL.self) { group in - group.addTask { - return try await authenticate(using: url, callbackURLScheme: redirectURI.scheme ?? "") - } - - let id = Int.random(in: 0.. some View { - onOpenURL { url in OAuth2.Session.handle(url: url) } - } -} - -extension URLComponents { - fileprivate func decode(_ type: T.Type) throws -> T { - guard let queryItems else { - throw DecodingError.valueNotFound( - T.self, - .init(codingPath: [], debugDescription: "Missing query items") - ) - } - let data = try OAuth2.encoder.encode(try queryItems.values) - return try OAuth2.decoder.decode(T.self, from: data) - } -} - -extension Sequence where Element == URLQueryItem { - fileprivate var values: [String: String?] { - get throws { - try Dictionary(map { ($0.name, $0.value) }) { _, _ in - throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "Duplicate query items")) - } - } - } -} diff --git a/Apple/UI/Tunnel.swift b/Apple/UI/Tunnel.swift deleted file mode 100644 index 4ec9320..0000000 --- a/Apple/UI/Tunnel.swift +++ /dev/null @@ -1,61 +0,0 @@ -import BurrowConfiguration -import NetworkExtension -import SwiftUI - -protocol Tunnel: Sendable { - @MainActor var status: TunnelStatus { get } - - func start() - func stop() - func enable() -} - -public enum TunnelStatus: Sendable, Equatable, Hashable { - case unknown - case permissionRequired - case disabled - case connecting - case connected(Date) - case disconnecting - case disconnected - case reasserting - case invalid - case configurationReadWriteFailed -} - -struct TunnelKey: EnvironmentKey { - static var defaultValue: any Tunnel { - NetworkExtensionTunnel(bundleIdentifier: Constants.networkExtensionBundleIdentifier) - } -} - -extension EnvironmentValues { - var tunnel: any Tunnel { - get { self[TunnelKey.self] } - set { self[TunnelKey.self] = newValue } - } -} - -#if DEBUG -@Observable -@MainActor -final class PreviewTunnel: Tunnel { - private(set) var status: TunnelStatus = .permissionRequired - - nonisolated func start() { - set(.connected(.now)) - } - - nonisolated func stop() { - set(.disconnected) - } - - nonisolated func enable() { - set(.disconnected) - } - - nonisolated private func set(_ status: TunnelStatus) { - Task { @MainActor in self.status = status } - } -} -#endif diff --git a/Apple/UI/TunnelButton.swift b/Apple/UI/TunnelButton.swift deleted file mode 100644 index d0222d4..0000000 --- a/Apple/UI/TunnelButton.swift +++ /dev/null @@ -1,73 +0,0 @@ -import SwiftUI - -struct TunnelButton: View { - @Environment(\.tunnel) - var tunnel: any Tunnel - - private var action: Action? { tunnel.action } - - var body: some View { - Button { - if let action { - tunnel.perform(action) - } - } label: { - Text(action.description) - } - .disabled(action.isDisabled) - .padding(.horizontal) - .buttonStyle(.floating) - } -} - -extension Tunnel { - @MainActor fileprivate var action: TunnelButton.Action? { - switch status { - case .permissionRequired, .invalid: - .enable - case .disabled, .disconnecting, .disconnected: - .start - case .connecting, .connected, .reasserting: - .stop - case .unknown, .configurationReadWriteFailed: - nil - } - } -} - -extension TunnelButton { - fileprivate enum Action { - case enable - case start - case stop - } -} - -extension TunnelButton.Action? { - var description: LocalizedStringKey { - switch self { - case .enable: "Enable" - case .start: "Start" - case .stop: "Stop" - case .none: "Start" - } - } - - var isDisabled: Bool { - if case .none = self { - true - } else { - false - } - } -} - -extension Tunnel { - fileprivate func perform(_ action: TunnelButton.Action) { - switch action { - case .enable: enable() - case .start: start() - case .stop: stop() - } - } -} diff --git a/Apple/UI/TunnelStatusView.swift b/Apple/UI/TunnelStatusView.swift deleted file mode 100644 index 15717ec..0000000 --- a/Apple/UI/TunnelStatusView.swift +++ /dev/null @@ -1,37 +0,0 @@ -import SwiftUI - -struct TunnelStatusView: View { - @Environment(\.tunnel) - var tunnel: any Tunnel - - var body: some View { - Text(tunnel.status.description) - } -} - -extension TunnelStatus: CustomStringConvertible { - public var description: String { - switch self { - case .unknown: - "Unknown" - case .permissionRequired: - "Permission Required" - case .disconnected: - "Disconnected" - case .disabled: - "Disabled" - case .connecting: - "Connecting…" - case .connected: - "Connected" - case .disconnecting: - "Disconnecting…" - case .reasserting: - "Reasserting…" - case .invalid: - "Invalid" - case .configurationReadWriteFailed: - "System Error" - } - } -} diff --git a/Apple/UI/UI.xcconfig b/Apple/UI/UI.xcconfig deleted file mode 100644 index b44d676..0000000 --- a/Apple/UI/UI.xcconfig +++ /dev/null @@ -1,3 +0,0 @@ -#include "../Configuration/Framework.xcconfig" - -ENABLE_PREVIEWS = YES diff --git a/Cargo.lock b/Cargo.lock index a5554fb..0817761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,342 +2,55 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" -dependencies = [ - "gimli", -] - [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - [[package]] name = "aes" -version = "0.8.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ "cfg-if", "cipher", "cpufeatures", -] - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anstream" -version = "0.6.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" - -[[package]] -name = "anstyle-parse" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", + "opaque-debug", ] [[package]] name = "anyhow" -version = "1.0.87" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5" -dependencies = [ - "async-stream-impl 0.2.1", - "futures-core", -] - -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl 0.3.5", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "async-trait" -version = "0.1.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core 0.3.4", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.30", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper 0.1.2", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" -dependencies = [ - "async-trait", - "axum-core 0.4.3", - "bytes", - "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "http-body-util", - "hyper 1.4.1", - "hyper-util", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sync_wrapper 1.0.1", - "tokio", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "sync_wrapper 0.1.2", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "backtrace" -version = "0.3.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide 0.7.4", - "object", - "rustc-demangle", -] +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.21.7" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" [[package]] name = "bindgen" -version = "0.64.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" +checksum = "8a022e58a142a46fea340d68012b9201c094e93ec3d033a944a24f8fd4a4f09a" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cexpr", "clang-sys", "lazy_static", @@ -347,32 +60,9 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash 1.1.0", + "rustc-hash", "shlex", - "syn 1.0.109", - "which", -] - -[[package]] -name = "bindgen" -version = "0.65.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.77", + "syn", "which", ] @@ -382,108 +72,46 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest", -] - [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ "generic-array", ] [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "burrow" version = "0.1.0" dependencies = [ - "aead", - "anyhow", - "async-channel", - "async-stream 0.2.1", - "axum 0.7.5", - "base64 0.21.7", - "blake2", - "caps", - "chacha20poly1305", - "clap", - "console", - "console-subscriber", - "dotenv", - "fehler", - "futures", - "hmac", - "hyper-util", - "insta", - "ip_network", - "ip_network_table", - "libsystemd", - "log", - "nix 0.27.1", - "once_cell", - "parking_lot", - "prost 0.13.2", - "prost-types 0.13.2", - "rand", - "rand_core", - "reqwest 0.12.7", - "ring", - "rusqlite", - "rust-ini", - "schemars", - "serde", - "serde_json", "tokio", - "tokio-stream", - "toml", - "tonic 0.12.2", - "tonic-build", - "tower", - "tracing", - "tracing-journald", - "tracing-log 0.1.4", - "tracing-oslog", - "tracing-subscriber", "tun", - "x25519-dalek", ] [[package]] name = "byteorder" -version = "1.5.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.7.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "bzip2" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0" dependencies = [ "bzip2-sys", "libc", @@ -500,25 +128,13 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "caps" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190baaad529bcfbde9e1a19022c42781bdb6ff9de25721abdb8fd98c0807730b" -dependencies = [ - "libc", - "thiserror", -] - [[package]] name = "cc" -version = "1.1.18" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" +checksum = "581f5dba903aac52ea3feb5ec4810848460ee833876f1f9b0fdeab1f19091574" dependencies = [ "jobserver", - "libc", - "shlex", ] [[package]] @@ -536,175 +152,24 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - [[package]] name = "cipher" -version = "0.4.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "crypto-common", - "inout", - "zeroize", + "generic-array", ] [[package]] name = "clang-sys" -version = "1.8.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" dependencies = [ "glob", "libc", - "libloading 0.8.5", -] - -[[package]] -name = "clap" -version = "4.5.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "clap_lex" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" - -[[package]] -name = "colorchoice" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "console" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.52.0", -] - -[[package]] -name = "console-api" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd326812b3fd01da5bb1af7d340d0d555fd3d4b641e7f1dfcf5962a902952787" -dependencies = [ - "futures-core", - "prost 0.12.6", - "prost-types 0.12.6", - "tonic 0.10.2", - "tracing-core", -] - -[[package]] -name = "console-subscriber" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7481d4c57092cd1c19dd541b92bdce883de840df30aa5d03fd48a3935c01842e" -dependencies = [ - "console-api", - "crossbeam-channel", - "crossbeam-utils", - "futures-task", - "hdrhistogram", - "humantime", - "prost-types 0.12.6", - "serde", - "serde_json", - "thread_local", - "tokio", - "tokio-stream", - "tonic 0.10.2", - "tracing", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "const-random" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" -dependencies = [ - "const-random-macro", -] - -[[package]] -name = "const-random-macro" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" -dependencies = [ - "getrandom", - "once_cell", - "tiny-keccak", + "libloading", ] [[package]] @@ -715,9 +180,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -725,48 +190,36 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +dependencies = [ + "cfg-if", +] [[package]] name = "crypto-common" @@ -775,152 +228,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", "typenum", ] -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "fiat-crypto", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - [[package]] name = "digest" -version = "0.10.7" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ "block-buffer", "crypto-common", "subtle", ] -[[package]] -name = "dlv-list" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" -dependencies = [ - "const-random", -] - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - [[package]] name = "either" -version = "1.13.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if", ] -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "event-listener" -version = "5.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - [[package]] name = "fastrand" -version = "2.1.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] [[package]] name = "fehler" @@ -939,29 +283,17 @@ checksum = "ccb5acb1045ebbfa222e2c50679e392a71dd77030b78fb0189f2d9c5974400f9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ "crc32fast", - "miniz_oxide 0.8.0", + "miniz_oxide", ] [[package]] @@ -987,167 +319,81 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", - "futures-sink", ] [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ - "futures-channel", "futures-core", - "futures-io", - "futures-macro", - "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", - "slab", ] [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", ] -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gimli" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" - [[package]] name = "glob" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "h2" -version = "0.3.26" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.12", - "indexmap 2.5.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.1.0", - "indexmap 2.5.0", + "http", + "indexmap", "slab", "tokio", "tokio-util", @@ -1161,53 +407,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] -name = "hashbrown" -version = "0.14.5" +name = "hex-literal" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashlink" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "hdrhistogram" -version = "7.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" -dependencies = [ - "base64 0.21.7", - "byteorder", - "flate2", - "nom", - "num-traits", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" [[package]] name = "hmac" @@ -1218,31 +421,11 @@ dependencies = [ "digest", ] -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - [[package]] name = "http" -version = "0.2.12" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", @@ -1251,69 +434,40 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http 1.1.0", -] - -[[package]] -name = "http-body-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" -dependencies = [ - "bytes", - "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.9.4" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", + "h2", + "http", + "http-body", "httparse", "httpdate", "itoa", @@ -1325,70 +479,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2 0.4.6", - "http 1.1.0", - "http-body 1.0.1", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" -dependencies = [ - "futures-util", - "http 1.1.0", - "hyper 1.4.1", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper 0.14.30", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "hyper-timeout" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" -dependencies = [ - "hyper 1.4.1", - "hyper-util", - "pin-project-lite", - "tokio", - "tower-service", -] - [[package]] name = "hyper-tls" version = "0.5.0" @@ -1396,37 +486,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.30", + "hyper", "native-tls", "tokio", "tokio-native-tls", ] -[[package]] -name = "hyper-util" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "hyper 1.4.1", - "pin-project-lite", - "socket2", - "tokio", - "tower", - "tower-service", - "tracing", -] - [[package]] name = "idna" -version = "0.5.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1434,127 +504,58 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.3" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", - "hashbrown 0.12.3", + "hashbrown", ] [[package]] -name = "indexmap" -version = "2.5.0" +name = "instant" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "equivalent", - "hashbrown 0.14.5", + "cfg-if", ] -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "insta" -version = "1.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" -dependencies = [ - "console", - "lazy_static", - "linked-hash-map", - "serde", - "similar", -] - -[[package]] -name = "ip_network" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" - -[[package]] -name = "ip_network_table" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4099b7cfc5c5e2fe8c5edf3f6f7adf7a714c9cc697534f63a5a5da30397cb2c0" -dependencies = [ - "ip_network", - "ip_network_table-deps-treebitmap", -] - -[[package]] -name = "ip_network_table-deps-treebitmap" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e537132deb99c0eb4b752f0346b6a836200eaaa3516dd7e5514b63930a09e5d" - [[package]] name = "ipnet" -version = "2.10.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] [[package]] name = "lazy_static" -version = "1.5.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" @@ -1564,154 +565,49 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "libloading" -version = "0.7.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" dependencies = [ "cfg-if", "winapi", ] [[package]] -name = "libloading" -version = "0.8.5" +name = "log" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", - "windows-targets 0.52.6", ] -[[package]] -name = "libsqlite3-sys" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "libsystemd" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c592dc396b464005f78a5853555b9f240bc5378bf5221acc4e129910b2678869" -dependencies = [ - "hmac", - "libc", - "log", - "nix 0.27.1", - "nom", - "once_cell", - "serde", - "sha2", - "thiserror", - "uuid", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - [[package]] name = "memchr" -version = "2.7.4" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.7.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "miette" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" -dependencies = [ - "miette-derive", - "once_cell", - "thiserror", - "unicode-width", -] - -[[package]] -name = "miette-derive" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - [[package]] name = "mime" -version = "0.3.17" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "minimal-lexical" @@ -1721,46 +617,32 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - [[package]] name = "mio" -version = "1.0.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ - "hermit-abi", "libc", + "log", "wasi", - "windows-sys 0.52.0", + "windows-sys 0.42.0", ] -[[package]] -name = "multimap" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" - [[package]] name = "native-tls" -version = "0.2.12" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" dependencies = [ + "lazy_static", "libc", "log", "openssl", @@ -1774,92 +656,56 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.4" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" dependencies = [ - "bitflags 1.3.2", + "autocfg", + "bitflags", "cfg-if", "libc", - "memoffset 0.7.1", + "memoffset", "pin-utils", ] -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "libc", - "memoffset 0.9.1", -] - [[package]] name = "nom" -version = "7.1.3" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ "memchr", "minimal-lexical", ] [[package]] -name = "nu-ansi-term" -version = "0.46.0" +name = "num_threads" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "object" -version = "0.36.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", + "libc", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "opaque-debug" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -1870,13 +716,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn", ] [[package]] @@ -1887,61 +733,17 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a" dependencies = [ + "autocfg", "cc", "libc", "pkg-config", "vcpkg", ] -[[package]] -name = "ordered-multimap" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" -dependencies = [ - "dlv-list", - "hashbrown 0.14.5", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.6", -] - [[package]] name = "password-hash" version = "0.4.2" @@ -1973,45 +775,15 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "petgraph" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" -dependencies = [ - "fixedbitset", - "indexmap 2.5.0", -] - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -2021,295 +793,88 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] -name = "poly1305" -version = "0.8.0" +name = "platforms" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" -dependencies = [ - "proc-macro2", - "syn 2.0.77", -] +checksum = "d8ec293fd25f7fcfeb7c70129241419a62c6200a26a725f680aff07c91d0ed05" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" -dependencies = [ - "bytes", - "prost-derive 0.12.6", -] - -[[package]] -name = "prost" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" -dependencies = [ - "bytes", - "prost-derive 0.13.2", -] - -[[package]] -name = "prost-build" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302" -dependencies = [ - "bytes", - "heck", - "itertools 0.13.0", - "log", - "multimap", - "once_cell", - "petgraph", - "prettyplease", - "prost 0.13.2", - "prost-types 0.13.2", - "regex", - "syn 2.0.77", - "tempfile", -] - -[[package]] -name = "prost-derive" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" -dependencies = [ - "anyhow", - "itertools 0.12.1", - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "prost-derive" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" -dependencies = [ - "anyhow", - "itertools 0.13.0", - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "prost-types" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" -dependencies = [ - "prost 0.12.6", -] - -[[package]] -name = "prost-types" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" -dependencies = [ - "prost 0.13.2", -] - -[[package]] -name = "quinn" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" -dependencies = [ - "bytes", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash 2.0.0", - "rustls", - "socket2", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "quinn-proto" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" -dependencies = [ - "bytes", - "rand", - "ring", - "rustc-hash 2.0.0", - "rustls", - "slab", - "thiserror", - "tinyvec", - "tracing", -] - -[[package]] -name = "quinn-udp" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" -dependencies = [ - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.59.0", -] - [[package]] name = "quote" -version = "1.0.37" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.4", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] -name = "regex-syntax" -version = "0.8.4" +name = "remove_dir_all" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] [[package]] name = "reqwest" -version = "0.11.27" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" dependencies = [ - "base64 0.21.7", + "base64", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.30", + "h2", + "http", + "http-body", + "hyper", "hyper-tls", "ipnet", "js-sys", @@ -2319,12 +884,9 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -2335,236 +897,35 @@ dependencies = [ "winreg", ] -[[package]] -name = "reqwest" -version = "0.12.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-core", - "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "http-body-util", - "hyper 1.4.1", - "hyper-rustls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pemfile 2.1.3", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 1.0.1", - "tokio", - "tokio-rustls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "windows-registry", -] - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rusqlite" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" -dependencies = [ - "bitflags 2.6.0", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec", -] - -[[package]] -name = "rust-ini" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" -dependencies = [ - "cfg-if", - "ordered-multimap", - "trim-in-place", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc-hash" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.23.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "rustls-pemfile" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" -dependencies = [ - "base64 0.22.1", - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" - -[[package]] -name = "rustls-webpki" -version = "0.102.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "schannel" -version = "0.1.24" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ - "windows-sys 0.59.0", + "lazy_static", + "windows-sys 0.36.1", ] -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.77", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "security-framework" -version = "2.11.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ - "bitflags 2.6.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -2573,82 +934,31 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" dependencies = [ "core-foundation-sys", "libc", ] -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - [[package]] name = "serde" -version = "1.0.210" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ "itoa", - "memchr", "ryu", "serde", ] -[[package]] -name = "serde_path_to_error" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" -dependencies = [ - "itoa", - "serde", -] - -[[package]] -name = "serde_spanned" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2661,22 +971,11 @@ dependencies = [ "serde", ] -[[package]] -name = "sha-1" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", @@ -2685,687 +984,264 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", "digest", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shlex" -version = "1.3.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "similar" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" dependencies = [ "autocfg", ] -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - [[package]] name = "socket2" -version = "0.5.7" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", - "windows-sys 0.52.0", + "winapi", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "ssri" -version = "9.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da7a2b3c2bc9693bcb40870c4e9b5bf0d79f9cb46273321bf855ec513e919082" -dependencies = [ - "base64 0.21.7", - "digest", - "hex", - "miette", - "sha-1", - "sha2", - "thiserror", - "xxhash-rust", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "subtle" -version = "2.6.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.109" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn" -version = "2.0.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "sync_wrapper" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -dependencies = [ - "futures-core", -] - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tempfile" -version = "3.12.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if", "fastrand", - "once_cell", - "rustix", - "windows-sys 0.59.0", -] - -[[package]] -name = "thiserror" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", ] [[package]] name = "time" -version = "0.3.36" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "0fab5c8b9980850e06d92ddbe3ab839c062c801f3927c0fb8abd6fc8e918fbca" dependencies = [ - "deranged", - "num-conv", - "powerfmt", + "itoa", + "libc", + "num_threads", "serde", "time-core", + "time-macros", ] [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" [[package]] -name = "tiny-keccak" -version = "2.0.2" +name = "time-macros" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +checksum = "65bb801831d812c562ae7d2bfb531f26e66e4e1f6b17307ba4149c5064710e5b" dependencies = [ - "crunchy", + "time-core", ] [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" -version = "0.1.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.40.0" +version = "1.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" dependencies = [ - "backtrace", + "autocfg", "bytes", "libc", + "memchr", "mio", "pin-project-lite", - "signal-hook-registry", "socket2", "tokio-macros", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", + "winapi", ] [[package]] name = "tokio-macros" -version = "2.4.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn", ] [[package]] name = "tokio-native-tls" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" dependencies = [ "native-tls", "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" -dependencies = [ - "rustls", - "rustls-pki-types", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", -] - -[[package]] -name = "toml" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" -dependencies = [ - "indexmap 2.5.0", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tonic" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" -dependencies = [ - "async-stream 0.3.5", - "async-trait", - "axum 0.6.20", - "base64 0.21.7", - "bytes", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.30", - "hyper-timeout 0.4.1", - "percent-encoding", - "pin-project", - "prost 0.12.6", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", "tracing", ] -[[package]] -name = "tonic" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f6ba989e4b2c58ae83d862d3a3e27690b6e3ae630d0deb59f3697f32aa88ad" -dependencies = [ - "async-stream 0.3.5", - "async-trait", - "axum 0.7.5", - "base64 0.22.1", - "bytes", - "h2 0.4.6", - "http 1.1.0", - "http-body 1.0.1", - "http-body-util", - "hyper 1.4.1", - "hyper-timeout 0.5.1", - "hyper-util", - "percent-encoding", - "pin-project", - "prost 0.13.2", - "socket2", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tonic-build" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4ee8877250136bd7e3d2331632810a4df4ea5e004656990d8d66d2f5ee8a67" -dependencies = [ - "prettyplease", - "proc-macro2", - "prost-build", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - [[package]] name = "tower-service" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ - "log", + "cfg-if", "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", - "valuable", ] -[[package]] -name = "tracing-journald" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" -dependencies = [ - "libc", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-log" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-oslog" -version = "0.1.2" -source = "git+https://github.com/Stormshield-robinc/tracing-oslog#c4d21a95e70cdd62b1cea04fc4f8be1c547cad6c" -dependencies = [ - "bindgen 0.64.0", - "cc", - "cfg-if", - "fnv", - "once_cell", - "parking_lot", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log 0.2.0", -] - -[[package]] -name = "trim-in-place" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" - [[package]] name = "try-lock" -version = "0.2.5" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tun" version = "0.1.0" dependencies = [ "anyhow", - "bindgen 0.65.1", - "byteorder", + "bindgen", "fehler", - "futures", - "lazy_static", + "hex-literal", "libc", - "libloading 0.7.4", - "log", - "nix 0.26.4", - "reqwest 0.11.27", - "schemars", - "serde", + "libloading", + "nix", + "platforms", + "reqwest", + "sha2", "socket2", - "ssri", - "tempfile", "tokio", - "tracing", "widestring", - "windows", "zip", ] +[[package]] +name = "tun-async" +version = "0.1.0" +dependencies = [ + "tun", +] + [[package]] name = "typenum" -version = "1.17.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-width" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" -version = "2.5.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "uuid" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" -dependencies = [ - "serde", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "vcpkg" version = "0.2.15" @@ -3374,16 +1250,17 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.5" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "want" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ + "log", "try-lock", ] @@ -3395,35 +1272,34 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", - "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -3433,9 +1309,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3443,59 +1319,49 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.26.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "which" -version = "4.4.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" dependencies = [ "either", - "home", + "libc", "once_cell", - "rustix", ] [[package]] name = "widestring" -version = "1.1.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" [[package]] name = "winapi" @@ -3520,275 +1386,119 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-sys" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-registry" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result", - "windows-strings", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets 0.52.6", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_aarch64_msvc" -version = "0.52.6" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_gnu" -version = "0.52.6" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_i686_msvc" -version = "0.52.6" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_gnu" -version = "0.52.6" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "windows_x86_64_msvc" -version = "0.52.6" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" -dependencies = [ - "memchr", -] +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" [[package]] name = "winreg" -version = "0.50.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "x25519-dalek" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" -dependencies = [ - "curve25519-dalek", - "rand_core", - "serde", - "zeroize", -] - -[[package]] -name = "xxhash-rust" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", + "winapi", ] [[package]] name = "zip" -version = "0.6.6" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080" dependencies = [ "aes", "byteorder", @@ -3825,10 +1535,10 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" +version = "2.0.1+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b" dependencies = [ "cc", - "pkg-config", + "libc", ] diff --git a/Cargo.toml b/Cargo.toml index 362ba2b..8afa305 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,6 @@ [workspace] -members = ["burrow", "tun"] -resolver = "2" -exclude = ["burrow-gtk"] - -[profile.release] -lto = true -panic = "abort" -opt-level = "z" +members = [ + "burrow", + "tun-async", + "tun" +] diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 404179b..0000000 --- a/Dockerfile +++ /dev/null @@ -1,99 +0,0 @@ -FROM docker.io/library/rust:1.79-slim-bookworm AS builder - -ARG TARGETPLATFORM -ARG LLVM_VERSION=16 - -ENV KEYRINGS /etc/apt/keyrings - -RUN set -eux && \ - mkdir -p $KEYRINGS && \ - apt-get update && \ - apt-get install --no-install-recommends -y gpg curl busybox make musl-dev && \ - curl --proto '=https' --tlsv1.2 -sSf https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor --output $KEYRINGS/llvm.gpg && \ - echo "deb [signed-by=$KEYRINGS/llvm.gpg] http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm-$LLVM_VERSION main" > /etc/apt/sources.list.d/llvm.list && \ - apt-get update && \ - apt-get install --no-install-recommends -y clang-$LLVM_VERSION llvm-$LLVM_VERSION lld-$LLVM_VERSION build-essential sqlite3 libsqlite3-dev musl musl-tools musl-dev protobuf-compiler libprotobuf-dev && \ - ln -s clang-$LLVM_VERSION /usr/bin/clang && \ - ln -s clang /usr/bin/clang++ && \ - ln -s lld-$LLVM_VERSION /usr/bin/ld.lld && \ - ln -s clang-$LLVM_VERSION /usr/bin/clang-cl && \ - ln -s llvm-ar-$LLVM_VERSION /usr/bin/llvm-lib && \ - ln -s lld-link-$LLVM_VERSION /usr/bin/lld-link && \ - update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100 && \ - update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100 && \ - apt-get remove -y --auto-remove && \ - rm -rf /var/lib/apt/lists/* - -RUN case $TARGETPLATFORM in \ - "linux/arm64") LLVM_TARGET=aarch64-unknown-linux-musl ;; \ - "linux/amd64") LLVM_TARGET=x86_64-unknown-linux-musl ;; \ - *) exit 1 ;; \ - esac && \ - rustup target add $LLVM_TARGET - -ARG SQLITE_VERSION=3460000 - -RUN case $TARGETPLATFORM in \ - "linux/arm64") LLVM_TARGET=aarch64-unknown-linux-musl MUSL_TARGET=aarch64-linux-musl ;; \ - "linux/amd64") LLVM_TARGET=x86_64-unknown-linux-musl MUSL_TARGET=x86_64-linux-musl ;; \ - *) exit 1 ;; \ - esac && \ - curl --proto '=https' --tlsv1.2 -sSfO https://www.sqlite.org/2024/sqlite-autoconf-$SQLITE_VERSION.tar.gz && \ - tar xf sqlite-autoconf-$SQLITE_VERSION.tar.gz && \ - cd sqlite-autoconf-$SQLITE_VERSION && \ - ./configure --disable-shared --disable-dependency-tracking \ - CC="clang-$LLVM_VERSION -target $LLVM_TARGET" \ - CFLAGS="-I/usr/local/include -I/usr/include/$MUSL_TARGET" \ - LDFLAGS="-L/usr/local/lib -L/usr/lib/$MUSL_TARGET -L/lib/$MUSL_TARGET" && \ - make && \ - make install && \ - cd .. && \ - rm -rf sqlite-autoconf-$SQLITE_VERSION sqlite-autoconf-$SQLITE_VERSION.tar.gz - -ENV CC_x86_64_unknown_linux_musl=clang-$LLVM_VERSION \ - AR_x86_64_unknown_linux_musl=llvm-ar-$LLVM_VERSION \ - CC_aarch64_unknown_linux_musl=clang-$LLVM_VERSION \ - AR_aarch64_unknown_linux_musl=llvm-ar-$LLVM_VERSION \ - CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-L/usr/lib/x86_64-linux-musl -L/lib/x86_64-linux-musl -C linker=rust-lld" \ - CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-L/usr/lib/aarch64-linux-musl -L/lib/aarch64-linux-musl -C linker=rust-lld" \ - SQLITE3_STATIC=1 \ - SQLITE3_INCLUDE_DIR=/usr/local/include \ - SQLITE3_LIB_DIR=/usr/local/lib - -COPY . . - -RUN case $TARGETPLATFORM in \ - "linux/arm64") LLVM_TARGET=aarch64-unknown-linux-musl ;; \ - "linux/amd64") LLVM_TARGET=x86_64-unknown-linux-musl ;; \ - *) exit 1 ;; \ - esac && \ - cargo install --path burrow --target $LLVM_TARGET - -WORKDIR /tmp/rootfs - -RUN set -eux && \ - mkdir -p ./bin ./etc ./tmp ./data && \ - mv /usr/local/cargo/bin/burrow ./bin/burrow && \ - cp /bin/busybox ./bin/busybox && \ - echo 'burrow:x:10001:10001::/tmp:/bin/busybox' > ./etc/passwd && \ - echo 'burrow:x:10001:' > ./etc/group && \ - chown -R 10001:10001 ./tmp ./data && \ - chmod 0777 ./tmp - -FROM scratch as runtime -LABEL \ - # https://github.com/opencontainers/image-spec/blob/master/annotations.md - org.opencontainers.image.title="burrow" \ - org.opencontainers.image.description="Burrow is an open source tool for burrowing through firewalls, built by teenagers at Hack Club." \ - org.opencontainers.image.url="https://github.com/hackclub/burrow" \ - org.opencontainers.image.source="https://github.com/hackclub/burrow" \ - org.opencontainers.image.vendor="hackclub" \ - org.opencontainers.image.licenses="GPL-3.0" - -USER 10001:10001 -COPY --from=builder /tmp/rootfs / -WORKDIR /data - -EXPOSE 8080 - -CMD ["/bin/burrow", "auth-server"] diff --git a/Makefile b/Makefile deleted file mode 100644 index 6563ab1..0000000 --- a/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -tun := $(shell ifconfig -l | sed 's/ /\n/g' | grep utun | tail -n 1) -cargo_console := RUST_BACKTRACE=1 RUST_LOG=debug RUSTFLAGS='--cfg tokio_unstable' cargo run --all-features -cargo_norm := RUST_BACKTRACE=1 RUST_LOG=debug cargo run - -check: - @cargo check - -build: - @cargo run build - -daemon-console: - @$(cargo_console) daemon - -daemon: - @$(cargo_norm) daemon - -start: - @$(cargo_norm) start - -stop: - @$(cargo_norm) stop - -status: - @$(cargo_norm) server-status - -tunnel-config: - @$(cargo_norm) tunnel-config - -test-dns: - @sudo route delete 8.8.8.8 - @sudo route add 8.8.8.8 -interface $(tun) - @dig @8.8.8.8 hackclub.com - -test-https: - @sudo route delete 193.183.0.162 - @sudo route add 193.183.0.162 -interface $(tun) - @curl -vv https://search.marginalia.nu - -v4_target := 146.190.62.39 -test-http: - @sudo route delete ${v4_target} - @sudo route add ${v4_target} -interface $(tun) - @curl -vv ${v4_target}:80 - -test-ipv4: - @sudo route delete ${v4_target} - @sudo route add ${v4_target} -interface $(tun) - @ping ${v4_target} - -v6_target := 2001:4860:4860::8888 -test-ipv6: - @sudo route delete ${v6_target} - @sudo route -n add -inet6 ${v6_target} -interface $(tun) - @echo preparing - @sudo ping6 -v ${v6_target} diff --git a/README.md b/README.md index 89914d0..9a89463 100644 --- a/README.md +++ b/README.md @@ -2,41 +2,8 @@ ![License](https://img.shields.io/github/license/hackclub/burrow) ![Apple Build Status](https://img.shields.io/github/actions/workflow/status/hackclub/burrow/build-apple.yml?branch=main&label=macos%2C%20ios&logo=Apple) ![Crate Build Status](https://img.shields.io/github/actions/workflow/status/hackclub/burrow/build-rust.yml?branch=main&label=crate&logo=Rust) -Burrow is an open source tool for burrowing through firewalls, built by teenagers at [Hack Club](https://hackclub.com/). +Burrow is a tool for burrowing through firewalls, built by teenagers at [Hack Club](https://hackclub.com/). -`burrow` provides a simple command-line tool to open virtual interfaces and direct traffic through them. +At its core, `burrow` is a command line utility written in Rust that can open virtual interfaces and direct traffic through them. -## Contributing - -Burrow is fully open source, you can fork the repo and start contributing easily. For more information and in-depth discussions, visit the `#burrow` channel on the [Hack Club Slack](https://hackclub.com/slack/), here you can ask for help and talk with other people interested in burrow! Checkout [GETTING_STARTED.md](./docs/GETTING_STARTED.md) for build instructions and [GTK_APP.md](./docs/GTK_APP.md) for the Linux app. - -The project structure is divided in the following folders: - -``` -Apple/ # Xcode project for burrow on macOS and iOS -burrow/ # Higher-level API library for tun and tun-async -burrow-gtk/ # GTK project for burrow on Linux -tun/ # Low-level interface to OS networking - src/ - tokio/ # Async/Tokio code - unix/ # macOS and Linux code - windows/ # Windows networking code -``` - -## Installation - -To start burrowing, download the latest release build in the release section. - -## Hack Club - -Hack Club is a global community of high-school hackers from all around the world! Start your own Hack Club, attend an upcoming hackathon or join our online community at [hackclub.com](https://hackclub.com/). - -## License - -Burrow is open source and licensed under the [GNU General Public License v3.0](./LICENSE.md) - -## Contributors - - - - +You can use it directly from the command line, or you can use it wrapped inside of an app. Currently, there are apps for iOS and macOS that you can use to start the tunnel. diff --git a/Tools/version.sh b/Tools/version.sh deleted file mode 100755 index fcb3f00..0000000 --- a/Tools/version.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -export PATH="$PATH:/opt/homebrew/bin:/usr/local/bin:/etc/profiles/per-user/$USER/bin" - -set -euo pipefail - -cd "$(dirname "${BASH_SOURCE[0]}")"/.. - -TAG_PREFIX="builds/" - -CURRENT_BUILD=$(git tag --points-at HEAD | tail -n 1) -LATEST_BUILD="$TAG_PREFIX$(git tag -l "builds/[0-9]*" | cut -d'/' -f 2 | sort -n | tail -n 1)" - -CURRENT_BUILD_NUMBER=${CURRENT_BUILD#$TAG_PREFIX} -LATEST_BUILD_NUMBER=${LATEST_BUILD#$TAG_PREFIX} -if [[ -z $LATEST_BUILD_NUMBER ]]; then - LATEST_BUILD_NUMBER="0" -fi - -if [[ ! -z $LATEST_BUILD && $(git merge-base --is-ancestor $LATEST_BUILD HEAD) -ne 0 ]]; then - echo "error: HEAD is not descended from build $LATEST_BUILD_NUMBER" >&2 - exit 1 -fi - -BUILD_NUMBER=$LATEST_BUILD_NUMBER - -if [[ $# -gt 0 && "$1" == "increment" ]]; then - NEW_BUILD_NUMBER=$((LATEST_BUILD_NUMBER + 1)) - NEW_TAG="$TAG_PREFIX$NEW_BUILD_NUMBER" - BUILD_NUMBER=$NEW_BUILD_NUMBER - - git tag $NEW_TAG - git push --quiet origin $NEW_TAG - gh release create "$NEW_TAG" -t "Build $BUILD_NUMBER" --verify-tag --generate-notes >/dev/null -fi - -if [[ -z $(grep $BUILD_NUMBER Apple/Configuration/Version.xcconfig 2>/dev/null) ]]; then - echo "CURRENT_PROJECT_VERSION = $BUILD_NUMBER" > Apple/Configuration/Version.xcconfig - git update-index --assume-unchanged Apple/Configuration/Version.xcconfig -fi - -if [[ $# -gt 0 && "$1" == "status" ]]; then - if [[ $CURRENT_BUILD_NUMBER -eq $LATEST_BUILD_NUMBER ]]; then - echo "clean" - else - echo "dirty" - fi - exit 0 -fi - -echo $BUILD_NUMBER diff --git a/burrow-gtk/.cargo/config.toml b/burrow-gtk/.cargo/config.toml deleted file mode 100644 index 87e5dd7..0000000 --- a/burrow-gtk/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.'cfg(unix)'] -runner = "sh -c" diff --git a/burrow-gtk/.gitignore b/burrow-gtk/.gitignore deleted file mode 100644 index caeec17..0000000 --- a/burrow-gtk/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.flatpak-builder diff --git a/burrow-gtk/Cargo.lock b/burrow-gtk/Cargo.lock deleted file mode 100644 index 6721318..0000000 --- a/burrow-gtk/Cargo.lock +++ /dev/null @@ -1,3342 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "anstream" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" - -[[package]] -name = "anstyle-parse" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - -[[package]] -name = "anyhow" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" - -[[package]] -name = "async-channel" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" -dependencies = [ - "concurrent-queue", - "event-listener", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-trait" -version = "0.1.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bindgen" -version = "0.64.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 1.0.109", - "which", -] - -[[package]] -name = "bindgen" -version = "0.65.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.48", - "which", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "burrow" -version = "0.1.0" -dependencies = [ - "aead", - "anyhow", - "async-channel", - "base64", - "blake2", - "caps", - "chacha20poly1305", - "clap", - "console", - "fehler", - "futures", - "hmac", - "ip_network", - "ip_network_table", - "libsystemd", - "log", - "nix 0.27.1", - "once_cell", - "parking_lot", - "rand", - "rand_core", - "ring", - "schemars", - "serde", - "serde_json", - "tokio", - "tracing", - "tracing-journald", - "tracing-log 0.1.4", - "tracing-oslog", - "tracing-subscriber", - "tun", - "x25519-dalek", -] - -[[package]] -name = "burrow-gtk" -version = "0.1.0" -dependencies = [ - "anyhow", - "burrow", - "gettext-rs", - "glib-build-tools", - "relm4", - "tokio", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" - -[[package]] -name = "bzip2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" -dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "cairo-rs" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3603c4028a5e368d09b51c8b624b9a46edcd7c3778284077a6125af73c9f0a" -dependencies = [ - "bitflags 1.3.2", - "cairo-sys-rs", - "glib", - "libc", - "once_cell", - "thiserror", -] - -[[package]] -name = "cairo-sys-rs" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "691d0c66b1fb4881be80a760cb8fe76ea97218312f9dfe2c9cc0f496ca279cb1" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - -[[package]] -name = "caps" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190baaad529bcfbde9e1a19022c42781bdb6ff9de25721abdb8fd98c0807730b" -dependencies = [ - "libc", - "thiserror", -] - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "jobserver", - "libc", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-expr" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6100bc57b6209840798d95cb2775684849d332f7bd788db2a8c8caf7ef82a41a" -dependencies = [ - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", - "zeroize", -] - -[[package]] -name = "clang-sys" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" -dependencies = [ - "glob", - "libc", - "libloading 0.8.1", -] - -[[package]] -name = "clap" -version = "4.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "concurrent-queue" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "console" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.52.0", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "rand_core", - "typenum", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "fiat-crypto", - "platforms", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "dyn-clone" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "event-listener" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "fehler" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5729fe49ba028cd550747b6e62cd3d841beccab5390aa398538c31a2d983635" -dependencies = [ - "fehler-macros", -] - -[[package]] -name = "fehler-macros" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb5acb1045ebbfa222e2c50679e392a71dd77030b78fb0189f2d9c5974400f9" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" - -[[package]] -name = "field-offset" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" -dependencies = [ - "memoffset 0.9.0", - "rustc_version", -] - -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "pin-project", - "spin", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fragile" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "gdk-pixbuf" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "695d6bc846438c5708b07007537b9274d883373dd30858ca881d7d71b5540717" -dependencies = [ - "bitflags 1.3.2", - "gdk-pixbuf-sys", - "gio", - "glib", - "libc", - "once_cell", -] - -[[package]] -name = "gdk-pixbuf-sys" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9285ec3c113c66d7d0ab5676599176f1f42f4944ca1b581852215bf5694870cb" -dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "gdk4" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3abf96408a26e3eddf881a7f893a1e111767137136e347745e8ea6ed12731ff" -dependencies = [ - "bitflags 1.3.2", - "cairo-rs", - "gdk-pixbuf", - "gdk4-sys", - "gio", - "glib", - "libc", - "pango", -] - -[[package]] -name = "gdk4-sys" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc92aa1608c089c49393d014c38ac0390d01e4841e1fedaa75dbcef77aaed64" -dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "pkg-config", - "system-deps", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gettext-rs" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e49ea8a8fad198aaa1f9655a2524b64b70eb06b2f3ff37da407566c93054f364" -dependencies = [ - "gettext-sys", - "locale_config", -] - -[[package]] -name = "gettext-sys" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c63ce2e00f56a206778276704bbe38564c8695249fdc8f354b4ef71c57c3839d" -dependencies = [ - "cc", - "temp-dir", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "gio" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6973e92937cf98689b6a054a9e56c657ed4ff76de925e36fc331a15f0c5d30a" -dependencies = [ - "bitflags 1.3.2", - "futures-channel", - "futures-core", - "futures-io", - "futures-util", - "gio-sys", - "glib", - "libc", - "once_cell", - "pin-project-lite", - "smallvec", - "thiserror", -] - -[[package]] -name = "gio-sys" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ccf87c30a12c469b6d958950f6a9c09f2be20b7773f7e70d20b867fdf2628c3" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", - "winapi", -] - -[[package]] -name = "glib" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fad45ba8d4d2cea612b432717e834f48031cd8853c8aaf43b2c79fec8d144b" -dependencies = [ - "bitflags 1.3.2", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", - "libc", - "memchr", - "once_cell", - "smallvec", - "thiserror", -] - -[[package]] -name = "glib-build-tools" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3431c56f463443cba9bc3600248bc6d680cb614c2ee1cdd39dab5415bd12ac5c" - -[[package]] -name = "glib-macros" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca5c79337338391f1ab8058d6698125034ce8ef31b72a442437fa6c8580de26" -dependencies = [ - "anyhow", - "heck", - "proc-macro-crate", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "glib-sys" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d80aa6ea7bba0baac79222204aa786a6293078c210abe69ef1336911d4bdc4f0" -dependencies = [ - "libc", - "system-deps", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "gobject-sys" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd34c3317740a6358ec04572c1bcfd3ac0b5b6529275fae255b237b314bb8062" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - -[[package]] -name = "graphene-rs" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def4bb01265b59ed548b05455040d272d989b3012c42d4c1bbd39083cb9b40d9" -dependencies = [ - "glib", - "graphene-sys", - "libc", -] - -[[package]] -name = "graphene-sys" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1856fc817e6a6675e36cea0bd9a3afe296f5d9709d1e2d3182803ac77f0ab21d" -dependencies = [ - "glib-sys", - "libc", - "pkg-config", - "system-deps", -] - -[[package]] -name = "gsk4" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f01ef44fa7cac15e2da9978529383e6bee03e570ba5bf7036b4c10a15cc3a3c" -dependencies = [ - "bitflags 1.3.2", - "cairo-rs", - "gdk4", - "glib", - "graphene-rs", - "gsk4-sys", - "libc", - "pango", -] - -[[package]] -name = "gsk4-sys" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07a84fb4dcf1323d29435aa85e2f5f58bef564342bef06775ec7bd0da1f01b0" -dependencies = [ - "cairo-sys-rs", - "gdk4-sys", - "glib-sys", - "gobject-sys", - "graphene-sys", - "libc", - "pango-sys", - "system-deps", -] - -[[package]] -name = "gtk4" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28a32a04cd75cef14a0983f8b0c669e0fe152a0a7725accdeb594e2c764c88b" -dependencies = [ - "bitflags 1.3.2", - "cairo-rs", - "field-offset", - "futures-channel", - "gdk-pixbuf", - "gdk4", - "gio", - "glib", - "graphene-rs", - "gsk4", - "gtk4-macros", - "gtk4-sys", - "libc", - "once_cell", - "pango", -] - -[[package]] -name = "gtk4-macros" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4d6b61570f76d3ee542d984da443b1cd69b6105264c61afec3abed08c2500f" -dependencies = [ - "anyhow", - "proc-macro-crate", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "gtk4-sys" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f8283f707b07e019e76c7f2934bdd4180c277e08aa93f4c0d8dd07b7a34e22f" -dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gdk4-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "graphene-sys", - "gsk4-sys", - "libc", - "pango-sys", - "system-deps", -] - -[[package]] -name = "h2" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.5", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "ip_network" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" - -[[package]] -name = "ip_network_table" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4099b7cfc5c5e2fe8c5edf3f6f7adf7a714c9cc697534f63a5a5da30397cb2c0" -dependencies = [ - "ip_network", - "ip_network_table-deps-treebitmap", -] - -[[package]] -name = "ip_network_table-deps-treebitmap" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e537132deb99c0eb4b752f0346b6a836200eaaa3516dd7e5514b63930a09e5d" - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "jobserver" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libadwaita" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab9c0843f9f23ff25634df2743690c3a1faffe0a190e60c490878517eb81abf" -dependencies = [ - "bitflags 1.3.2", - "gdk-pixbuf", - "gdk4", - "gio", - "glib", - "gtk4", - "libadwaita-sys", - "libc", - "pango", -] - -[[package]] -name = "libadwaita-sys" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4231cb2499a9f0c4cdfa4885414b33e39901ddcac61150bc0bb4ff8a57ede404" -dependencies = [ - "gdk4-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "gtk4-sys", - "libc", - "pango-sys", - "system-deps", -] - -[[package]] -name = "libc" -version = "0.2.152" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "libloading" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "libsystemd" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c592dc396b464005f78a5853555b9f240bc5378bf5221acc4e129910b2678869" -dependencies = [ - "hmac", - "libc", - "log", - "nix 0.27.1", - "nom", - "once_cell", - "serde", - "sha2", - "thiserror", - "uuid", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "locale_config" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934" -dependencies = [ - "lazy_static", - "objc", - "objc-foundation", - "regex", - "winapi", -] - -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "memchr" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" - -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "miette" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" -dependencies = [ - "miette-derive", - "once_cell", - "thiserror", - "unicode-width", -] - -[[package]] -name = "miette-derive" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom", -] - -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nix" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.7.1", - "pin-utils", -] - -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.4.2", - "cfg-if", - "libc", - "memoffset 0.9.0", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - -[[package]] -name = "objc_id" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" -dependencies = [ - "bitflags 2.4.2", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "pango" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48" -dependencies = [ - "bitflags 1.3.2", - "gio", - "glib", - "libc", - "once_cell", - "pango-sys", -] - -[[package]] -name = "pango-sys" -version = "0.17.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da69f9f3850b0d8990d462f8c709561975e95f689c1cdf0fecdebde78b35195" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "parking" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.48.5", -] - -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest", - "hmac", - "password-hash", - "sha2", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" - -[[package]] -name = "platforms" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "prettyplease" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" -dependencies = [ - "proc-macro2", - "syn 2.0.48", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "regex" -version = "1.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.4", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "relm4" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c16f3fad883034773b7f5af4d7e865532b8f3641e5a8bab2a34561a8d960d81" -dependencies = [ - "async-trait", - "flume", - "fragile", - "futures", - "gtk4", - "libadwaita", - "once_cell", - "relm4-macros", - "tokio", - "tracing", -] - -[[package]] -name = "relm4-macros" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9340e2553c0a184a80a0bfa1dcf73c47f3d48933aa6be90724b202f9fbd24735" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "reqwest" -version = "0.11.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "system-configuration", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "ring" -version = "0.17.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" -dependencies = [ - "cc", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" -dependencies = [ - "bitflags 2.4.2", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "ryu" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" - -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "schemars" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 1.0.109", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" - -[[package]] -name = "serde" -version = "1.0.195" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.195" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "serde_derive_internals" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "serde_json" -version = "1.0.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_spanned" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha-1" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" - -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "ssri" -version = "9.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da7a2b3c2bc9693bcb40870c4e9b5bf0d79f9cb46273321bf855ec513e919082" -dependencies = [ - "base64", - "digest", - "hex", - "miette", - "sha-1", - "sha2", - "thiserror", - "xxhash-rust", -] - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "system-deps" -version = "6.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2d580ff6a20c55dfb86be5f9c238f67835d0e81cbdea8bf5680e0897320331" -dependencies = [ - "cfg-expr", - "heck", - "pkg-config", - "toml", - "version-compare", -] - -[[package]] -name = "target-lexicon" -version = "0.12.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" - -[[package]] -name = "temp-dir" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd16aa9ffe15fe021c6ee3766772132c6e98dfa395a167e16864f61a9cfb71d6" - -[[package]] -name = "tempfile" -version = "3.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "thiserror" -version = "1.0.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "time" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" -dependencies = [ - "deranged", - "powerfmt", - "serde", - "time-core", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.35.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "socket2 0.5.5", - "tokio-macros", - "tracing", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.20.2", -] - -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-journald" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" -dependencies = [ - "libc", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-log" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-oslog" -version = "0.1.2" -source = "git+https://github.com/Stormshield-robinc/tracing-oslog#c4d21a95e70cdd62b1cea04fc4f8be1c547cad6c" -dependencies = [ - "bindgen 0.64.0", - "cc", - "cfg-if", - "fnv", - "once_cell", - "parking_lot", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log 0.2.0", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "tun" -version = "0.1.0" -dependencies = [ - "anyhow", - "bindgen 0.65.1", - "byteorder", - "fehler", - "futures", - "lazy_static", - "libc", - "libloading 0.7.4", - "log", - "nix 0.26.4", - "reqwest", - "schemars", - "serde", - "socket2 0.4.10", - "ssri", - "tempfile", - "tokio", - "tracing", - "widestring", - "windows", - "zip", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "uuid" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" -dependencies = [ - "serde", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version-compare" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.48", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" - -[[package]] -name = "web-sys" -version = "0.3.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "widestring" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" - -[[package]] -name = "winnow" -version = "0.5.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "x25519-dalek" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" -dependencies = [ - "curve25519-dalek", - "rand_core", - "serde", - "zeroize", -] - -[[package]] -name = "xxhash-rust" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53be06678ed9e83edb1745eb72efc0bbcd7b5c3c35711a860906aed827a13d61" - -[[package]] -name = "zeroize" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "aes", - "byteorder", - "bzip2", - "constant_time_eq", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac", - "pbkdf2", - "sha1", - "time", - "zstd", -] - -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/burrow-gtk/Cargo.toml b/burrow-gtk/Cargo.toml deleted file mode 100644 index 21cb52e..0000000 --- a/burrow-gtk/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "burrow-gtk" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0" -relm4 = { version = "0.6", features = ["libadwaita", "gnome_44"]} -burrow = { version = "*", path = "../burrow/" } -tokio = { version = "1.35.0", features = ["time", "sync"] } -gettext-rs = { version = "0.7.0", features = ["gettext-system"] } - -[build-dependencies] -anyhow = "1.0" -glib-build-tools = "0.18.0" diff --git a/burrow-gtk/build-aux/Dockerfile b/burrow-gtk/build-aux/Dockerfile deleted file mode 100644 index 834e450..0000000 --- a/burrow-gtk/build-aux/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM fedora:39 - -ENV DEBIAN_FRONTEND=noninteractive - -RUN set -eux && \ - dnf update -y && \ - dnf install -y clang ninja-build cmake meson gtk4-devel glib2-devel libadwaita-devel desktop-file-utils libappstream-glib util-linux wget fuse fuse-libs file sqlite sqlite-devel protobuf-compiler protobuf-devel - -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal -ENV PATH="/root/.cargo/bin:${PATH}" - -WORKDIR /app -COPY . /app - -ENV SQLITE3_STATIC=1 - -RUN cd /app/burrow-gtk/ && \ - ./build-aux/build_appimage.sh - - diff --git a/burrow-gtk/build-aux/build_appimage.sh b/burrow-gtk/build-aux/build_appimage.sh deleted file mode 100755 index f054cd9..0000000 --- a/burrow-gtk/build-aux/build_appimage.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -set -ex - -BURROW_GTK_ROOT="$(readlink -f $(dirname -- "$(readlink -f -- "$BASH_SOURCE")")/..)" -BURROW_GTK_BUILD="$BURROW_GTK_ROOT/build-appimage" -LINUXDEPLOY_VERSION="${LINUXDEPLOY_VERSION:-"1-alpha-20240109-1"}" -BURROW_BUILD_TYPE="${BURROW_BUILD_TYPE:-"release"}" - -if [ "$BURROW_GTK_ROOT" != $(pwd) ]; then - echo "Make sure to cd into burrow-gtk" - exit 1 -fi - -ARCHITECTURE=$(lscpu | grep Architecture | awk '{print $2}') - -if [ "$ARCHITECTURE" == "x86_64" ]; then - wget "https://github.com/linuxdeploy/linuxdeploy/releases/download/$LINUXDEPLOY_VERSION/linuxdeploy-x86_64.AppImage" -o /dev/null -O /tmp/linuxdeploy - chmod a+x /tmp/linuxdeploy -elif [ "$ARCHITECTURE" == "aarch64" ]; then - wget "https://github.com/linuxdeploy/linuxdeploy/releases/download/$LINUXDEPLOY_VERSION/linuxdeploy-aarch64.AppImage" -o /dev/null -O /tmp/linuxdeploy - chmod a+x /tmp/linuxdeploy -fi - - -CFLAGS="-I/usr/local/include -I/usr/include/$MUSL_TARGET -fPIE" -meson setup $BURROW_GTK_BUILD --bindir bin --prefix /usr --buildtype $BURROW_BUILD_TYPE -meson compile -C $BURROW_GTK_BUILD -DESTDIR=AppDir meson install -C $BURROW_GTK_BUILD -cargo b --$BURROW_BUILD_TYPE --manifest-path=../Cargo.toml -/tmp/linuxdeploy --appimage-extract-and-run --appdir $BURROW_GTK_BUILD/AppDir -e $BURROW_GTK_BUILD/../../target/$BURROW_BUILD_TYPE/burrow --output appimage -mv *.AppImage $BURROW_GTK_BUILD diff --git a/burrow-gtk/build-aux/com.hackclub.burrow.devel.json b/burrow-gtk/build-aux/com.hackclub.burrow.devel.json deleted file mode 100644 index 4a2e5fc..0000000 --- a/burrow-gtk/build-aux/com.hackclub.burrow.devel.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "app-id" : "com.hackclub.burrow-devel", - "runtime" : "org.gnome.Platform", - "runtime-version" : "45", - "sdk" : "org.gnome.Sdk", - "sdk-extensions" : [ - "org.freedesktop.Sdk.Extension.rust-stable" - ], - "command" : "burrow-gtk", - "finish-args" : [ - "--share=network", - "--share=ipc", - "--socket=fallback-x11", - "--device=dri", - "--socket=wayland" - ], - "build-options" : { - "append-path" : "/usr/lib/sdk/rust-stable/bin", - "build-args" : [ - "--share=network" - ], - "env" : { - "RUST_BACKTRACE" : "1", - "RUST_LOG" : "burrow-gtk=debug" - } - }, - "cleanup" : [ - "/include", - "/lib/pkgconfig", - "/man", - "/share/doc", - "/share/gtk-doc", - "/share/man", - "/share/pkgconfig", - "*.la", - "*.a" - ], - "modules" : [ - { - "name" : "burrow-gtk", - "builddir" : true, - "subdir" : "burrow-gtk", - "buildsystem" : "meson", - "config-opts": ["--buildtype=debug"], - "sources" : [ - { - "type": "dir", - "path": "../../" - } - ] - } - ] -} diff --git a/burrow-gtk/build-aux/com.hackclub.burrow.json b/burrow-gtk/build-aux/com.hackclub.burrow.json deleted file mode 100644 index c8b68e5..0000000 --- a/burrow-gtk/build-aux/com.hackclub.burrow.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "app-id" : "com.hackclub.burrow", - "runtime" : "org.gnome.Platform", - "runtime-version" : "45", - "sdk" : "org.gnome.Sdk", - "sdk-extensions" : [ - "org.freedesktop.Sdk.Extension.rust-stable" - ], - "command" : "burrow-gtk", - "finish-args" : [ - "--share=network", - "--share=ipc", - "--socket=fallback-x11", - "--device=dri", - "--socket=wayland" - ], - "build-options" : { - "append-path" : "/usr/lib/sdk/rust-stable/bin", - "build-args" : [ - "--share=network" - ], - "env" : { - "RUST_BACKTRACE" : "1", - "RUST_LOG" : "burrow-gtk=debug" - } - }, - "cleanup" : [ - "/include", - "/lib/pkgconfig", - "/man", - "/share/doc", - "/share/gtk-doc", - "/share/man", - "/share/pkgconfig", - "*.la", - "*.a" - ], - "modules" : [ - { - "name" : "burrow-gtk", - "builddir" : true, - "subdir" : "burrow-gtk", - "buildsystem" : "meson", - "config-opts": ["--buildtype=release"], - "sources" : [ - { - "type": "dir", - "path": "../../" - } - ] - } - ] -} diff --git a/burrow-gtk/build.rs b/burrow-gtk/build.rs deleted file mode 100644 index 4db0175..0000000 --- a/burrow-gtk/build.rs +++ /dev/null @@ -1,16 +0,0 @@ -use anyhow::Result; - -fn main() -> Result<()> { - compile_gresources()?; - - Ok(()) -} - -fn compile_gresources() -> Result<()> { - glib_build_tools::compile_resources( - &["data"], - "data/resources.gresource.xml", - "compiled.gresource", - ); - Ok(()) -} diff --git a/burrow-gtk/data/app.desktop.in.in b/burrow-gtk/data/app.desktop.in.in deleted file mode 100644 index 33b9c5b..0000000 --- a/burrow-gtk/data/app.desktop.in.in +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -Name=@APP_NAME_CAPITALIZED@ -Exec=@APP_NAME@ -Icon=@APP_ID@ -Terminal=false -Type=Application -Categories=GTK;Network -StartupNotify=true diff --git a/burrow-gtk/data/app.gschema.xml.in b/burrow-gtk/data/app.gschema.xml.in deleted file mode 100644 index 0541c6f..0000000 --- a/burrow-gtk/data/app.gschema.xml.in +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/burrow-gtk/data/app.metainfo.xml.in b/burrow-gtk/data/app.metainfo.xml.in deleted file mode 100644 index 8cc2e59..0000000 --- a/burrow-gtk/data/app.metainfo.xml.in +++ /dev/null @@ -1,16 +0,0 @@ - - - @APP_ID@ - CC0 - GPL-3.0-or-later - @APP_NAME_CAPITALIZED@ - @APP_ID@.desktop - - -

No description

-
- - -

No Summary

-
-
diff --git a/burrow-gtk/data/icons/hicolor/scalable/apps/burrow-gtk.svg b/burrow-gtk/data/icons/hicolor/scalable/apps/burrow-gtk.svg deleted file mode 100644 index a74c4df..0000000 --- a/burrow-gtk/data/icons/hicolor/scalable/apps/burrow-gtk.svg +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - application-x-executable - - - - - - - - - - - - - - - - diff --git a/burrow-gtk/data/icons/hicolor/symbolic/apps/burrow-gtk-symbolic.svg b/burrow-gtk/data/icons/hicolor/symbolic/apps/burrow-gtk-symbolic.svg deleted file mode 100644 index 5352e0a..0000000 --- a/burrow-gtk/data/icons/hicolor/symbolic/apps/burrow-gtk-symbolic.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/burrow-gtk/data/meson.build b/burrow-gtk/data/meson.build deleted file mode 100644 index 2c3ffd8..0000000 --- a/burrow-gtk/data/meson.build +++ /dev/null @@ -1,90 +0,0 @@ -# app.desktop.in.in -desktop_conf = configuration_data() -desktop_conf.set('APP_ID', app_id) -desktop_conf.set('APP_NAME', app_name) -desktop_conf.set('APP_NAME_CAPITALIZED', app_name_capitalized) - -desktop_file_in = configure_file( - input: 'app.desktop.in.in', - output: '@BASENAME@', - configuration: desktop_conf, -) - -desktop_file = i18n.merge_file( - input: desktop_file_in, - output: app_id + '.desktop', - type: 'desktop', - po_dir: '../po', - install: true, - install_dir: datadir / 'applications', -) - -if desktop_file_validate.found() - test( - 'validate-desktop', - desktop_file_validate, - args: [desktop_file], - ) -endif - -# app.gschema.xml.in -gschema_conf = configuration_data() -gschema_conf.set('APP_ID', app_id) -gschema_conf.set('APP_NAME', app_name) -gschema_conf.set('APP_IDPATH', app_idpath) -gschema_file = configure_file( - input: 'app.gschema.xml.in', - output: app_id + '.gschema.xml', - configuration: gschema_conf, - install: true, - install_dir: datadir / 'glib-2.0' / 'schemas', -) - -if glib_compile_schemas.found() - test( - 'validate-gschema', - glib_compile_schemas, - args: [ - '--dry-run', - datadir / 'glib-2.0' / 'schemas', - ], - ) -endif - -# app.metainfo.xml.in -appdata_conf = configuration_data() -appdata_conf.set('APP_ID', app_id) -appdata_conf.set('APP_NAME', app_name) -appdata_conf.set('APP_NAME_CAPITALIZED', app_name_capitalized) -appdata_file_in = configure_file( - input: 'app.metainfo.xml.in', - output: '@BASENAME@', - configuration: appdata_conf, -) -appdata_file = i18n.merge_file( - input: appdata_file_in, - output: app_id + '.metainfo.xml', - po_dir: '../po', - install: true, - install_dir: datadir / 'metainfo', -) - -if appstream_util.found() - test( - 'validate-appdata', - appstream_util, - args: ['validate', '--nonet', appdata_file], - ) -endif - -install_data( - 'icons/hicolor/scalable/apps/' + app_name + '.svg', - install_dir: datadir / 'icons' / 'hicolor' / 'scalable' / 'apps', - rename: app_id + '.svg', -) - -install_data( - 'icons/hicolor/symbolic/apps/' + app_name + '-symbolic.svg', - install_dir: datadir / 'icons' / 'hicolor' / 'symbolic' / 'apps', - rename: app_id + '-symbolic.svg', -) diff --git a/burrow-gtk/data/resources.gresource.xml b/burrow-gtk/data/resources.gresource.xml deleted file mode 100644 index 969e77c..0000000 --- a/burrow-gtk/data/resources.gresource.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/burrow-gtk/meson.build b/burrow-gtk/meson.build deleted file mode 100644 index 8c2d5c1..0000000 --- a/burrow-gtk/meson.build +++ /dev/null @@ -1,56 +0,0 @@ -project( - 'burrow-gtk', - ['rust'], - version: '0.0.1', - meson_version: '>= 1.0', -) - -# Find Cargo -cargo_bin = find_program('cargo') -cargo_env = ['CARGO_HOME=' + meson.project_build_root()] -cargo_opt = ['--manifest-path', meson.project_source_root() / 'Cargo.toml'] -cargo_opt += ['--target-dir', meson.project_build_root() / 'target'] - -# Config -prefix = get_option('prefix') -datadir = prefix / get_option('datadir') -localedir = prefix / get_option('localedir') - -app_name = 'burrow-gtk' -app_name_capitalized = 'Burrow' -base_id = 'com.hackclub.burrow' -app_idpath = '/com/hackclub/' + app_name + '/' -if get_option('buildtype') == 'release' - cargo_opt += ['--release'] - rust_target = 'release' - app_id = base_id -else - rust_target = 'debug' - app_id = base_id + '-' + 'devel' -endif - -# Imports -i18n = import('i18n') -gnome = import('gnome') - -# External Dependencies -dependency('gtk4', version: '>= 4.0') -dependency('libadwaita-1', version: '>= 1.2') - -glib_compile_resources = find_program('glib-compile-resources', required: true) -glib_compile_schemas = find_program('glib-compile-schemas', required: true) -desktop_file_validate = find_program('desktop-file-validate', required: false) -appstream_util = find_program('appstream-util', required: false) -fc_cache = find_program('fc-cache', required: false) - -# Our Sources -subdir('po') -subdir('data') -subdir('src') - -# Gnome Post Install -gnome.post_install( - glib_compile_schemas: true, - gtk_update_icon_cache: true, - update_desktop_database: true, -) diff --git a/burrow-gtk/po/LINGUAS b/burrow-gtk/po/LINGUAS deleted file mode 100644 index e69de29..0000000 diff --git a/burrow-gtk/po/POTFILES b/burrow-gtk/po/POTFILES deleted file mode 100644 index 08b570f..0000000 --- a/burrow-gtk/po/POTFILES +++ /dev/null @@ -1 +0,0 @@ -data/app.desktop.in.in diff --git a/burrow-gtk/po/meson.build b/burrow-gtk/po/meson.build deleted file mode 100644 index 597577b..0000000 --- a/burrow-gtk/po/meson.build +++ /dev/null @@ -1 +0,0 @@ -i18n.gettext(app_name, preset: 'glib') diff --git a/burrow-gtk/src/.gitignore b/burrow-gtk/src/.gitignore deleted file mode 100644 index c6bb786..0000000 --- a/burrow-gtk/src/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.rs diff --git a/burrow-gtk/src/components/app.rs b/burrow-gtk/src/components/app.rs deleted file mode 100644 index 62c98c0..0000000 --- a/burrow-gtk/src/components/app.rs +++ /dev/null @@ -1,157 +0,0 @@ -use super::*; -use anyhow::Context; -use std::time::Duration; - -const RECONNECT_POLL_TIME: Duration = Duration::from_secs(5); - -pub struct App { - daemon_client: Arc>>, - settings_screen: Controller, - switch_screen: AsyncController, -} - -#[derive(Debug)] -pub enum AppMsg { - None, - PostInit, -} - -impl App { - pub fn run() { - let app = RelmApp::new(config::ID); - Self::setup_gresources().unwrap(); - Self::setup_i18n().unwrap(); - - app.run_async::(()); - } - - fn setup_i18n() -> Result<()> { - gettextrs::setlocale(gettextrs::LocaleCategory::LcAll, ""); - gettextrs::bindtextdomain(config::GETTEXT_PACKAGE, config::LOCALEDIR)?; - gettextrs::bind_textdomain_codeset(config::GETTEXT_PACKAGE, "UTF-8")?; - gettextrs::textdomain(config::GETTEXT_PACKAGE)?; - Ok(()) - } - - fn setup_gresources() -> Result<()> { - gtk::gio::resources_register_include!("compiled.gresource") - .context("Failed to register and include compiled gresource.") - } -} - -#[relm4::component(pub, async)] -impl AsyncComponent for App { - type Init = (); - type Input = AppMsg; - type Output = (); - type CommandOutput = (); - - view! { - adw::Window { - set_title: Some("Burrow"), - set_default_size: (640, 480), - } - } - - async fn init( - _: Self::Init, - root: Self::Root, - sender: AsyncComponentSender, - ) -> AsyncComponentParts { - let daemon_client = Arc::new(Mutex::new(DaemonClient::new().await.ok())); - - let switch_screen = switch_screen::SwitchScreen::builder() - .launch(switch_screen::SwitchScreenInit { - daemon_client: Arc::clone(&daemon_client), - }) - .forward(sender.input_sender(), |_| AppMsg::None); - - let settings_screen = settings_screen::SettingsScreen::builder() - .launch(settings_screen::SettingsScreenInit { - daemon_client: Arc::clone(&daemon_client), - }) - .forward(sender.input_sender(), |_| AppMsg::None); - - let widgets = view_output!(); - - let view_stack = adw::ViewStack::new(); - view_stack.add_titled(switch_screen.widget(), None, "Switch"); - view_stack.add_titled(settings_screen.widget(), None, "Settings"); - - let view_switcher_bar = adw::ViewSwitcherBar::builder().stack(&view_stack).build(); - view_switcher_bar.set_reveal(true); - - // When libadwaita 1.4 support becomes more avaliable, this approach is more appropriate - // - // let toolbar = adw::ToolbarView::new(); - // toolbar.add_top_bar( - // &adw::HeaderBar::builder() - // .title_widget(>k::Label::new(Some("Burrow"))) - // .build(), - // ); - // toolbar.add_bottom_bar(&view_switcher_bar); - // toolbar.set_content(Some(&view_stack)); - // root.set_content(Some(&toolbar)); - - let content = gtk::Box::new(gtk::Orientation::Vertical, 0); - content.append( - &adw::HeaderBar::builder() - .title_widget(>k::Label::new(Some("Burrow"))) - .build(), - ); - content.append(&view_stack); - content.append(&view_switcher_bar); - - root.set_content(Some(&content)); - - sender.input(AppMsg::PostInit); - - let model = App { - daemon_client, - switch_screen, - settings_screen, - }; - - AsyncComponentParts { model, widgets } - } - - async fn update( - &mut self, - _msg: Self::Input, - _sender: AsyncComponentSender, - _root: &Self::Root, - ) { - loop { - tokio::time::sleep(RECONNECT_POLL_TIME).await; - { - let mut daemon_client = self.daemon_client.lock().await; - let mut disconnected_daemon_client = false; - - if let Some(daemon_client) = daemon_client.as_mut() { - if let Err(_e) = daemon_client.send_command(DaemonCommand::ServerInfo).await { - disconnected_daemon_client = true; - self.switch_screen - .emit(switch_screen::SwitchScreenMsg::DaemonDisconnect); - self.settings_screen - .emit(settings_screen::SettingsScreenMsg::DaemonStateChange) - } - } - - if disconnected_daemon_client || daemon_client.is_none() { - match DaemonClient::new().await { - Ok(new_daemon_client) => { - *daemon_client = Some(new_daemon_client); - self.switch_screen - .emit(switch_screen::SwitchScreenMsg::DaemonReconnect); - self.settings_screen - .emit(settings_screen::SettingsScreenMsg::DaemonStateChange) - } - Err(_e) => { - // TODO: Handle Error - } - } - } - } - } - } -} diff --git a/burrow-gtk/src/components/mod.rs b/burrow-gtk/src/components/mod.rs deleted file mode 100644 index b134809..0000000 --- a/burrow-gtk/src/components/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use super::*; -use adw::prelude::*; -use burrow::{DaemonClient, DaemonCommand, DaemonResponseData}; -use gtk::Align; -use relm4::{ - component::{ - AsyncComponent, AsyncComponentController, AsyncComponentParts, AsyncComponentSender, - AsyncController, - }, - prelude::*, -}; -use std::sync::Arc; -use tokio::sync::Mutex; - -mod app; -mod settings; -mod settings_screen; -mod switch_screen; - -pub use app::*; -pub use settings::{DaemonGroupMsg, DiagGroupMsg}; diff --git a/burrow-gtk/src/components/settings/daemon_group.rs b/burrow-gtk/src/components/settings/daemon_group.rs deleted file mode 100644 index 3817ca6..0000000 --- a/burrow-gtk/src/components/settings/daemon_group.rs +++ /dev/null @@ -1,111 +0,0 @@ -use super::*; -use std::process::Command; - -#[derive(Debug)] -pub struct DaemonGroup { - system_setup: SystemSetup, - daemon_client: Arc>>, - already_running: bool, -} - -pub struct DaemonGroupInit { - pub daemon_client: Arc>>, - pub system_setup: SystemSetup, -} - -#[derive(Debug)] -pub enum DaemonGroupMsg { - LaunchLocal, - DaemonStateChange, -} - -#[relm4::component(pub, async)] -impl AsyncComponent for DaemonGroup { - type Init = DaemonGroupInit; - type Input = DaemonGroupMsg; - type Output = (); - type CommandOutput = (); - - view! { - #[name(group)] - adw::PreferencesGroup { - #[watch] - set_sensitive: - (model.system_setup == SystemSetup::AppImage || model.system_setup == SystemSetup::Other) && - !model.already_running, - set_title: "Local Daemon", - set_description: Some("Run Local Daemon"), - - gtk::Button { - set_label: "Launch", - connect_clicked => DaemonGroupMsg::LaunchLocal - } - } - } - - async fn init( - init: Self::Init, - root: Self::Root, - sender: AsyncComponentSender, - ) -> AsyncComponentParts { - // Should be impossible to panic here - let model = DaemonGroup { - system_setup: init.system_setup, - daemon_client: init.daemon_client.clone(), - already_running: init.daemon_client.lock().await.is_some(), - }; - - let widgets = view_output!(); - - AsyncComponentParts { model, widgets } - } - - async fn update( - &mut self, - msg: Self::Input, - _sender: AsyncComponentSender, - _root: &Self::Root, - ) { - match msg { - DaemonGroupMsg::LaunchLocal => { - let burrow_original_bin = std::env::vars() - .find(|(k, _)| k == "APPDIR") - .map(|(_, v)| v + "/usr/bin/burrow") - .unwrap_or("/usr/bin/burrow".to_owned()); - - let mut burrow_bin = - String::from_utf8(Command::new("mktemp").output().unwrap().stdout).unwrap(); - burrow_bin.pop(); - - let privileged_spawn_script = format!( - r#"TEMP=$(mktemp -p /root) -cp {} $TEMP -chmod +x $TEMP -setcap CAP_NET_BIND_SERVICE,CAP_NET_ADMIN+eip $TEMP -mv $TEMP /tmp/burrow-detached-daemon"#, - burrow_original_bin - ) - .replace('\n', "&&"); - - // TODO: Handle error condition - - Command::new("pkexec") - .arg("sh") - .arg("-c") - .arg(privileged_spawn_script) - .arg(&burrow_bin) - .output() - .unwrap(); - - Command::new("/tmp/burrow-detached-daemon") - .env("RUST_LOG", "debug") - .arg("daemon") - .spawn() - .unwrap(); - } - DaemonGroupMsg::DaemonStateChange => { - self.already_running = self.daemon_client.lock().await.is_some(); - } - } - } -} diff --git a/burrow-gtk/src/components/settings/diag_group.rs b/burrow-gtk/src/components/settings/diag_group.rs deleted file mode 100644 index a15e0ea..0000000 --- a/burrow-gtk/src/components/settings/diag_group.rs +++ /dev/null @@ -1,126 +0,0 @@ -use super::*; - -#[derive(Debug)] -pub struct DiagGroup { - daemon_client: Arc>>, - - system_setup: SystemSetup, - service_installed: StatusTernary, - socket_installed: StatusTernary, - socket_enabled: StatusTernary, - daemon_running: bool, -} - -pub struct DiagGroupInit { - pub daemon_client: Arc>>, - pub system_setup: SystemSetup, -} - -impl DiagGroup { - async fn new(daemon_client: Arc>>) -> Result { - let system_setup = SystemSetup::new(); - let daemon_running = daemon_client.lock().await.is_some(); - - Ok(Self { - service_installed: system_setup.is_service_installed()?, - socket_installed: system_setup.is_socket_installed()?, - socket_enabled: system_setup.is_socket_enabled()?, - daemon_running, - system_setup, - daemon_client, - }) - } -} - -#[derive(Debug)] -pub enum DiagGroupMsg { - Refresh, -} - -#[relm4::component(pub, async)] -impl AsyncComponent for DiagGroup { - type Init = DiagGroupInit; - type Input = DiagGroupMsg; - type Output = (); - type CommandOutput = (); - - view! { - #[name(group)] - adw::PreferencesGroup { - set_title: "Diagnose", - set_description: Some("Diagnose Burrow"), - - adw::ActionRow { - #[watch] - set_title: &format!("System Type: {}", model.system_setup) - }, - adw::ActionRow { - #[watch] - set_title: &format!( - "Service installed: {}", - status_ternary_to_str(model.service_installed) - ) - }, - adw::ActionRow { - #[watch] - set_title: &format!( - "Socket installed: {}", - status_ternary_to_str(model.socket_installed) - ) - }, - adw::ActionRow { - #[watch] - set_title: &format!( - "Socket enabled: {}", - status_ternary_to_str(model.socket_enabled) - ) - }, - adw::ActionRow { - #[watch] - set_title: &format!( - "Daemon running: {}", - if model.daemon_running { "Yes" } else { "No" } - ) - }, - gtk::Button { - set_label: "Refresh", - connect_clicked => DiagGroupMsg::Refresh - } - } - } - - async fn init( - init: Self::Init, - root: Self::Root, - sender: AsyncComponentSender, - ) -> AsyncComponentParts { - // Should be impossible to panic here - let model = DiagGroup::new(init.daemon_client).await.unwrap(); - - let widgets = view_output!(); - - AsyncComponentParts { model, widgets } - } - - async fn update( - &mut self, - msg: Self::Input, - _sender: AsyncComponentSender, - _root: &Self::Root, - ) { - match msg { - DiagGroupMsg::Refresh => { - // Should be impossible to panic here - *self = Self::new(Arc::clone(&self.daemon_client)).await.unwrap(); - } - } - } -} - -fn status_ternary_to_str(status: StatusTernary) -> &'static str { - match status { - StatusTernary::True => "Yes", - StatusTernary::False => "No", - StatusTernary::NA => "N/A", - } -} diff --git a/burrow-gtk/src/components/settings/mod.rs b/burrow-gtk/src/components/settings/mod.rs deleted file mode 100644 index aa87db2..0000000 --- a/burrow-gtk/src/components/settings/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -use super::*; -use diag::{StatusTernary, SystemSetup}; - -mod daemon_group; -mod diag_group; - -pub use daemon_group::{DaemonGroup, DaemonGroupInit, DaemonGroupMsg}; -pub use diag_group::{DiagGroup, DiagGroupInit, DiagGroupMsg}; diff --git a/burrow-gtk/src/components/settings_screen.rs b/burrow-gtk/src/components/settings_screen.rs deleted file mode 100644 index 971f262..0000000 --- a/burrow-gtk/src/components/settings_screen.rs +++ /dev/null @@ -1,71 +0,0 @@ -use super::*; -use diag::SystemSetup; - -pub struct SettingsScreen { - diag_group: AsyncController, - daemon_group: AsyncController, -} - -pub struct SettingsScreenInit { - pub daemon_client: Arc>>, -} - -#[derive(Debug, PartialEq, Eq)] -pub enum SettingsScreenMsg { - DaemonStateChange, -} - -#[relm4::component(pub)] -impl SimpleComponent for SettingsScreen { - type Init = SettingsScreenInit; - type Input = SettingsScreenMsg; - type Output = (); - - view! { - #[name(preferences)] - adw::PreferencesPage {} - } - - fn init( - init: Self::Init, - root: &Self::Root, - sender: ComponentSender, - ) -> ComponentParts { - let system_setup = SystemSetup::new(); - - let diag_group = settings::DiagGroup::builder() - .launch(settings::DiagGroupInit { - system_setup, - daemon_client: Arc::clone(&init.daemon_client), - }) - .forward(sender.input_sender(), |_| { - SettingsScreenMsg::DaemonStateChange - }); - - let daemon_group = settings::DaemonGroup::builder() - .launch(settings::DaemonGroupInit { - system_setup, - daemon_client: Arc::clone(&init.daemon_client), - }) - .forward(sender.input_sender(), |_| { - SettingsScreenMsg::DaemonStateChange - }); - - let widgets = view_output!(); - widgets.preferences.add(diag_group.widget()); - widgets.preferences.add(daemon_group.widget()); - - let model = SettingsScreen { diag_group, daemon_group }; - - ComponentParts { model, widgets } - } - - fn update(&mut self, _: Self::Input, _sender: ComponentSender) { - // Currently, `SettingsScreenMsg` only has one variant, so the if is ambiguous. - // - // if let SettingsScreenMsg::DaemonStateChange = msg { - self.diag_group.emit(DiagGroupMsg::Refresh); - self.daemon_group.emit(DaemonGroupMsg::DaemonStateChange); - // } - } -} diff --git a/burrow-gtk/src/components/switch_screen.rs b/burrow-gtk/src/components/switch_screen.rs deleted file mode 100644 index f660536..0000000 --- a/burrow-gtk/src/components/switch_screen.rs +++ /dev/null @@ -1,158 +0,0 @@ -use super::*; - -pub struct SwitchScreen { - daemon_client: Arc>>, - switch: gtk::Switch, - switch_screen: gtk::Box, - disconnected_banner: adw::Banner, -} - -pub struct SwitchScreenInit { - pub daemon_client: Arc>>, -} - -#[derive(Debug, PartialEq, Eq)] -pub enum SwitchScreenMsg { - DaemonReconnect, - DaemonDisconnect, - Start, - Stop, -} - -#[relm4::component(pub, async)] -impl AsyncComponent for SwitchScreen { - type Init = SwitchScreenInit; - type Input = SwitchScreenMsg; - type Output = (); - type CommandOutput = (); - - view! { - gtk::Box { - set_orientation: gtk::Orientation::Vertical, - set_valign: Align::Fill, - - gtk::Box { - set_orientation: gtk::Orientation::Vertical, - set_spacing: 5, - set_margin_all: 5, - set_valign: Align::Start, - - #[name(setup_banner)] - adw::Banner { - set_title: "Burrow is not running!", - }, - }, - - #[name(switch_screen)] - gtk::Box { - set_orientation: gtk::Orientation::Vertical, - set_spacing: 10, - set_margin_all: 5, - set_valign: Align::Center, - set_vexpand: true, - - gtk::Label { - set_label: "Burrow Switch", - }, - - #[name(switch)] - gtk::Switch { - set_halign: Align::Center, - set_hexpand: false, - set_vexpand: false, - connect_active_notify => move |switch| - sender.input(if switch.is_active() { SwitchScreenMsg::Start } else { SwitchScreenMsg::Stop }) - }, - } - } - } - - async fn init( - init: Self::Init, - root: Self::Root, - sender: AsyncComponentSender, - ) -> AsyncComponentParts { - let mut initial_switch_status = false; - let mut initial_daemon_server_down = false; - - if let Some(daemon_client) = init.daemon_client.lock().await.as_mut() { - if let Ok(res) = daemon_client - .send_command(DaemonCommand::ServerInfo) - .await - .as_ref() - { - initial_switch_status = match res.result.as_ref() { - Ok(DaemonResponseData::None) => false, - Ok(DaemonResponseData::ServerInfo(_)) => true, - _ => false, - }; - } else { - initial_daemon_server_down = true; - } - } else { - initial_daemon_server_down = true; - } - - let widgets = view_output!(); - - widgets.switch.set_active(initial_switch_status); - - if initial_daemon_server_down { - *init.daemon_client.lock().await = None; - widgets.switch.set_active(false); - widgets.switch_screen.set_sensitive(false); - widgets.setup_banner.set_revealed(true); - } - - let model = SwitchScreen { - daemon_client: init.daemon_client, - switch: widgets.switch.clone(), - switch_screen: widgets.switch_screen.clone(), - disconnected_banner: widgets.setup_banner.clone(), - }; - - AsyncComponentParts { model, widgets } - } - - async fn update( - &mut self, - msg: Self::Input, - _: AsyncComponentSender, - _root: &Self::Root, - ) { - let mut disconnected_daemon_client = false; - - if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() { - match msg { - Self::Input::Start => { - if let Err(_e) = daemon_client - .send_command(DaemonCommand::Start(Default::default())) - .await - { - disconnected_daemon_client = true; - } - } - Self::Input::Stop => { - if let Err(_e) = daemon_client.send_command(DaemonCommand::Stop).await { - disconnected_daemon_client = true; - } - } - _ => {} - } - } else { - disconnected_daemon_client = true; - } - - if msg == Self::Input::DaemonReconnect { - self.disconnected_banner.set_revealed(false); - self.switch_screen.set_sensitive(true); - } - - if disconnected_daemon_client || msg == Self::Input::DaemonDisconnect { - *self.daemon_client.lock().await = None; - self.switch.set_active(false); - self.switch_screen.set_sensitive(false); - self.disconnected_banner.set_revealed(true); - } - } -} diff --git a/burrow-gtk/src/config.rs.in b/burrow-gtk/src/config.rs.in deleted file mode 100644 index 7da2f3f..0000000 --- a/burrow-gtk/src/config.rs.in +++ /dev/null @@ -1,8 +0,0 @@ -#[allow(unused)] -pub const ID: &str = @ID@; -#[allow(unused)] -pub const VERSION: &str = @VERSION@; -#[allow(unused)] -pub const LOCALEDIR: &str = @LOCALEDIR@; -#[allow(unused)] -pub const GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@; diff --git a/burrow-gtk/src/diag.rs b/burrow-gtk/src/diag.rs deleted file mode 100644 index ab4757e..0000000 --- a/burrow-gtk/src/diag.rs +++ /dev/null @@ -1,91 +0,0 @@ -use super::*; -use std::{fmt::Display, fs, process::Command}; - -const SYSTEMD_SOCKET_LOC: &str = "/etc/systemd/system/burrow.socket"; -const SYSTEMD_SERVICE_LOC: &str = "/etc/systemd/system/burrow.service"; - -// I don't like this type very much. -#[derive(Debug, Clone, Copy)] -pub enum StatusTernary { - True, - False, - NA, -} - -// Realistically, we may not explicitly "support" non-systemd platforms which would simply this -// code greatly. -// Along with replacing [`StatusTernary`] with good old [`bool`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum SystemSetup { - Systemd, - AppImage, - Other, -} - -impl SystemSetup { - pub fn new() -> Self { - if is_appimage() { - SystemSetup::AppImage - } else if Command::new("systemctl").arg("--version").output().is_ok() { - SystemSetup::Systemd - } else { - SystemSetup::Other - } - } - - pub fn is_service_installed(&self) -> Result { - match self { - SystemSetup::Systemd => Ok(fs::metadata(SYSTEMD_SERVICE_LOC).is_ok().into()), - SystemSetup::AppImage => Ok(StatusTernary::NA), - SystemSetup::Other => Ok(StatusTernary::NA), - } - } - - pub fn is_socket_installed(&self) -> Result { - match self { - SystemSetup::Systemd => Ok(fs::metadata(SYSTEMD_SOCKET_LOC).is_ok().into()), - SystemSetup::AppImage => Ok(StatusTernary::NA), - SystemSetup::Other => Ok(StatusTernary::NA), - } - } - - pub fn is_socket_enabled(&self) -> Result { - match self { - SystemSetup::Systemd => { - let output = Command::new("systemctl") - .arg("is-enabled") - .arg("burrow.socket") - .output()? - .stdout; - let output = String::from_utf8(output)?; - Ok((output == "enabled\n").into()) - } - SystemSetup::AppImage => Ok(StatusTernary::NA), - SystemSetup::Other => Ok(StatusTernary::NA), - } - } -} - -impl From for StatusTernary { - fn from(value: bool) -> Self { - if value { - StatusTernary::True - } else { - StatusTernary::False - } - } -} - -impl Display for SystemSetup { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - SystemSetup::Systemd => "Systemd", - SystemSetup::AppImage => "AppImage", - SystemSetup::Other => "Other", - }) - } -} - -pub fn is_appimage() -> bool { - std::env::vars().any(|(k, _)| k == "APPDIR") -} diff --git a/burrow-gtk/src/main.rs b/burrow-gtk/src/main.rs deleted file mode 100644 index 6f91e2a..0000000 --- a/burrow-gtk/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -use anyhow::Result; - -pub mod components; -mod diag; - -// Generated using meson -mod config; - -fn main() { - components::App::run(); -} diff --git a/burrow-gtk/src/meson.build b/burrow-gtk/src/meson.build deleted file mode 100644 index ed77771..0000000 --- a/burrow-gtk/src/meson.build +++ /dev/null @@ -1,34 +0,0 @@ -# config.rs.in -global_conf = configuration_data() -global_conf.set_quoted('ID', app_id) -global_conf.set_quoted('VERSION', meson.project_version()) -global_conf.set_quoted('LOCALEDIR', localedir) -global_conf.set_quoted('GETTEXT_PACKAGE', app_name) -config = configure_file( - input: 'config.rs.in', - output: 'config.rs', - configuration: global_conf, -) - -run_command( - 'cp', - meson.project_build_root() / 'src' / 'config.rs', - meson.project_source_root() / 'src', - check: true, -) - -# Cargo Build -cargo_build = custom_target( - 'cargo-build', - build_by_default: true, - build_always_stale: true, - output: meson.project_name(), - console: true, - install: true, - install_dir: get_option('bindir'), - command: [ - 'env', cargo_env, - cargo_bin, 'build', - cargo_opt, '&&', 'cp', 'target' / rust_target / meson.project_name(), '@OUTPUT@', - ] - ) diff --git a/burrow-server-compose.yml b/burrow-server-compose.yml deleted file mode 100644 index 4ba31ee..0000000 --- a/burrow-server-compose.yml +++ /dev/null @@ -1,38 +0,0 @@ -version: "2.1" -networks: - wg6: - enable_ipv6: true - ipam: - driver: default - config: - - subnet: "aa:bb:cc:de::/64" -services: - burrow: - image: lscr.io/linuxserver/wireguard:latest - privileged: true - container_name: burrow_server - cap_add: - - NET_ADMIN - - SYS_MODULE - environment: - - PUID=1000 - - PGID=1000 - - TZ=Asia/Calcutta - - SERVERURL=wg.burrow.rs - - SERVERPORT=51820 - - PEERS=10 - - PEERDNS=1.1.1.1 - - INTERNAL_SUBNET=10.13.13.0 - - ALLOWEDIPS=0.0.0.0/0, ::/0 - - PERSISTENTKEEPALIVE_PEERS=all - - LOG_CONFS=true #optional - volumes: - - ./config:/config - - /lib/modules:/lib/modules - ports: - - 51820:51820/udp - sysctls: - - net.ipv4.conf.all.src_valid_mark=1 - - net.ipv6.conf.all.disable_ipv6=0 - - net.ipv6.conf.eth0.proxy_ndp=1 - restart: unless-stopped \ No newline at end of file diff --git a/burrow/Cargo.toml b/burrow/Cargo.toml index d5e56c1..ec16981 100644 --- a/burrow/Cargo.toml +++ b/burrow/Cargo.toml @@ -2,98 +2,9 @@ name = "burrow" version = "0.1.0" edition = "2021" -description = "Burrow is an open source tool for burrowing through firewalls, built by teenagers at Hack Club." -license = "GPL-3.0-or-later" -[lib] -crate-type = ["lib", "staticlib"] +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0" -tokio = { version = "1.37", features = [ - "rt", - "macros", - "sync", - "io-util", - "rt-multi-thread", - "signal", - "time", - "tracing", - "fs", -] } -tun = { version = "0.1", path = "../tun", features = ["serde", "tokio"] } -clap = { version = "4.4", features = ["derive"] } -tracing = "0.1" -tracing-log = "0.1" -tracing-oslog = { git = "https://github.com/Stormshield-robinc/tracing-oslog" } -tracing-subscriber = { version = "0.3", features = ["std", "env-filter"] } -log = "0.4" -serde = { version = "1", features = ["derive"] } -serde_json = "1.0" -blake2 = "0.10" -chacha20poly1305 = "0.10" -rand = "0.8" -rand_core = "0.6" -aead = "0.5" -x25519-dalek = { version = "2.0", features = [ - "reusable_secrets", - "static_secrets", -] } -ring = "0.17" -parking_lot = "0.12" -hmac = "0.12" -base64 = "0.21" -fehler = "1.0" -ip_network_table = "0.2" -ip_network = "0.4" -async-channel = "2.1" -schemars = "0.8" -futures = "0.3.28" -once_cell = "1.19" -console-subscriber = { version = "0.2.0", optional = true } -console = "0.15.8" -axum = "0.7.4" -reqwest = { version = "0.12", default-features = false, features = [ - "json", - "rustls-tls", -] } -rusqlite = { version = "0.31.0", features = ["blob"] } -dotenv = "0.15.0" -tonic = "0.12.0" -prost = "0.13.1" -prost-types = "0.13.1" -tokio-stream = "0.1" -async-stream = "0.2" -tower = "0.4.13" -hyper-util = "0.1.6" -toml = "0.8.15" -rust-ini = "0.21.0" - -[target.'cfg(target_os = "linux")'.dependencies] -caps = "0.5" -libsystemd = "0.7" -tracing-journald = "0.3" - -[target.'cfg(target_vendor = "apple")'.dependencies] -nix = { version = "0.27" } -rusqlite = { version = "0.31.0", features = ["bundled", "blob"] } - -[dev-dependencies] -insta = { version = "1.32", features = ["yaml"] } - -[package.metadata.generate-rpm] -assets = [ - { source = "target/release/burrow", dest = "/usr/bin/burrow", mode = "755" }, - { source = "systemd/burrow.service", dest = "/etc/systemd/system/burrow.service", mode = "644" }, - { source = "systemd/burrow.socket", dest = "/etc/systemd/system/burrow.socket", mode = "644" }, -] -post_install_script = "../package/rpm/post_install" -pre_uninstall_script = "../package/rpm/pre_uninstall" - -[features] -tokio-console = ["dep:console-subscriber"] -bundled = ["rusqlite/bundled"] - - -[build-dependencies] -tonic-build = "0.12.0" +tokio = { version = "1.21", features = ["rt", "macros"] } +tun = { version = "0.1", path = "../tun" } diff --git a/burrow/build.rs b/burrow/build.rs deleted file mode 100644 index 8eea5dc..0000000 --- a/burrow/build.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() -> Result<(), Box> { - tonic_build::compile_protos("../proto/burrow.proto")?; - Ok(()) -} diff --git a/burrow/src/auth/client.rs b/burrow/src/auth/client.rs deleted file mode 100644 index e9721f3..0000000 --- a/burrow/src/auth/client.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::env::var; - -use anyhow::Result; -use reqwest::Url; - -pub async fn login() -> Result<()> { - let state = "vt :P"; - let nonce = "no"; - - let mut url = Url::parse("https://slack.com/openid/connect/authorize")?; - let mut q = url.query_pairs_mut(); - q.append_pair("response_type", "code"); - q.append_pair("scope", "openid profile email"); - q.append_pair("client_id", &var("CLIENT_ID")?); - q.append_pair("state", state); - q.append_pair("team", &var("SLACK_TEAM_ID")?); - q.append_pair("nonce", nonce); - q.append_pair("redirect_uri", "https://burrow.rs/callback"); - drop(q); - - println!("Continue auth in your browser:\n{}", url.as_str()); - - Ok(()) -} diff --git a/burrow/src/auth/mod.rs b/burrow/src/auth/mod.rs deleted file mode 100644 index c07f47e..0000000 --- a/burrow/src/auth/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod client; -pub mod server; diff --git a/burrow/src/auth/server/db.rs b/burrow/src/auth/server/db.rs deleted file mode 100644 index 995e64b..0000000 --- a/burrow/src/auth/server/db.rs +++ /dev/null @@ -1,91 +0,0 @@ -use anyhow::Result; - -use crate::daemon::rpc::grpc_defs::{Network, NetworkType}; - -pub static PATH: &str = "./server.sqlite3"; - -pub fn init_db() -> Result<()> { - let conn = rusqlite::Connection::open(PATH)?; - - conn.execute( - "CREATE TABLE IF NOT EXISTS user ( - id PRIMARY KEY, - created_at TEXT NOT NULL - )", - (), - )?; - - conn.execute( - "CREATE TABLE IF NOT EXISTS user_connection ( - user_id INTEGER REFERENCES user(id) ON DELETE CASCADE, - openid_provider TEXT NOT NULL, - openid_user_id TEXT NOT NULL, - openid_user_name TEXT NOT NULL, - access_token TEXT NOT NULL, - refresh_token TEXT, - PRIMARY KEY (openid_provider, openid_user_id) - )", - (), - )?; - - conn.execute( - "CREATE TABLE IF NOT EXISTS device ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT, - public_key TEXT NOT NULL, - apns_token TEXT UNIQUE, - user_id INT REFERENCES user(id) ON DELETE CASCADE, - created_at TEXT NOT NULL DEFAULT (datetime('now')) CHECK(created_at IS datetime(created_at)), - ipv4 TEXT NOT NULL UNIQUE, - ipv6 TEXT NOT NULL UNIQUE, - access_token TEXT NOT NULL UNIQUE, - refresh_token TEXT NOT NULL UNIQUE, - expires_at TEXT NOT NULL DEFAULT (datetime('now', '+7 days')) CHECK(expires_at IS datetime(expires_at)) - )", - () - ).unwrap(); - - Ok(()) -} - -pub fn store_connection( - openid_user: super::providers::OpenIdUser, - openid_provider: &str, - access_token: &str, - refresh_token: Option<&str>, -) -> Result<()> { - log::debug!("Storing openid user {:#?}", openid_user); - let conn = rusqlite::Connection::open(PATH)?; - - conn.execute( - "INSERT OR IGNORE INTO user (id, created_at) VALUES (?, datetime('now'))", - (&openid_user.sub,), - )?; - conn.execute( - "INSERT INTO user_connection (user_id, openid_provider, openid_user_id, openid_user_name, access_token, refresh_token) VALUES ( - (SELECT id FROM user WHERE id = ?), - ?, - ?, - ?, - ?, - ? - )", - (&openid_user.sub, &openid_provider, &openid_user.sub, &openid_user.name, access_token, refresh_token), - )?; - - Ok(()) -} - -pub fn store_device( - openid_user: super::providers::OpenIdUser, - openid_provider: &str, - access_token: &str, - refresh_token: Option<&str>, -) -> Result<()> { - log::debug!("Storing openid user {:#?}", openid_user); - let conn = rusqlite::Connection::open(PATH)?; - - // TODO - - Ok(()) -} diff --git a/burrow/src/auth/server/mod.rs b/burrow/src/auth/server/mod.rs deleted file mode 100644 index 88b3ff3..0000000 --- a/burrow/src/auth/server/mod.rs +++ /dev/null @@ -1,62 +0,0 @@ -pub mod db; -pub mod providers; - -use anyhow::Result; -use axum::{http::StatusCode, routing::post, Router}; -use providers::slack::auth; -use tokio::signal; - -pub async fn serve() -> Result<()> { - db::init_db()?; - - let app = Router::new() - .route("/slack-auth", post(auth)) - .route("/device/new", post(device_new)); - - let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap(); - log::info!("Starting auth server on port 8080"); - axum::serve(listener, app) - .with_graceful_shutdown(shutdown_signal()) - .await - .unwrap(); - - Ok(()) -} - -async fn device_new() -> StatusCode { - StatusCode::OK -} - -async fn shutdown_signal() { - let ctrl_c = async { - signal::ctrl_c() - .await - .expect("failed to install Ctrl+C handler"); - }; - - #[cfg(unix)] - let terminate = async { - signal::unix::signal(signal::unix::SignalKind::terminate()) - .expect("failed to install signal handler") - .recv() - .await; - }; - - #[cfg(not(unix))] - let terminate = std::future::pending::<()>(); - - tokio::select! { - _ = ctrl_c => {}, - _ = terminate => {}, - } -} - -// mod db { -// use rusqlite::{Connection, Result}; - -// #[derive(Debug)] -// struct User { -// id: i32, -// created_at: String, -// } -// } diff --git a/burrow/src/auth/server/providers/mod.rs b/burrow/src/auth/server/providers/mod.rs deleted file mode 100644 index 36ff0bd..0000000 --- a/burrow/src/auth/server/providers/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub mod slack; -pub use super::db; - -#[derive(serde::Deserialize, Default, Debug)] -pub struct OpenIdUser { - pub sub: String, - pub name: String, -} diff --git a/burrow/src/auth/server/providers/slack.rs b/burrow/src/auth/server/providers/slack.rs deleted file mode 100644 index 581cd1e..0000000 --- a/burrow/src/auth/server/providers/slack.rs +++ /dev/null @@ -1,102 +0,0 @@ -use anyhow::Result; -use axum::{ - extract::Json, - http::StatusCode, - routing::{get, post}, -}; -use reqwest::header::AUTHORIZATION; -use serde::Deserialize; - -use super::db::store_connection; - -#[derive(Deserialize)] -pub struct SlackToken { - slack_token: String, -} -pub async fn auth(Json(payload): Json) -> (StatusCode, String) { - let slack_user = match fetch_slack_user(&payload.slack_token).await { - Ok(user) => user, - Err(e) => { - log::error!("Failed to fetch Slack user: {:?}", e); - return (StatusCode::UNAUTHORIZED, String::new()); - } - }; - - log::info!( - "Slack user {} ({}) logged in.", - slack_user.name, - slack_user.sub - ); - - let conn = match store_connection(slack_user, "slack", &payload.slack_token, None) { - Ok(user) => user, - Err(e) => { - log::error!("Failed to fetch Slack user: {:?}", e); - return (StatusCode::UNAUTHORIZED, String::new()); - } - }; - - (StatusCode::OK, String::new()) -} - -async fn fetch_slack_user(access_token: &str) -> Result { - let client = reqwest::Client::new(); - let res = client - .get("https://slack.com/api/openid.connect.userInfo") - .header(AUTHORIZATION, format!("Bearer {}", access_token)) - .send() - .await? - .json::() - .await?; - - let res_ok = res - .get("ok") - .and_then(|v| v.as_bool()) - .ok_or(anyhow::anyhow!("Slack user object not ok!"))?; - - if !res_ok { - return Err(anyhow::anyhow!("Slack user object not ok!")); - } - - Ok(serde_json::from_value(res)?) -} - -// async fn fetch_save_slack_user_data(query: Query) -> anyhow::Result<()> { -// let client = reqwest::Client::new(); -// log::trace!("Code was {}", &query.code); -// let mut url = Url::parse("https://slack.com/api/openid.connect.token")?; - -// { -// let mut q = url.query_pairs_mut(); -// q.append_pair("client_id", &var("CLIENT_ID")?); -// q.append_pair("client_secret", &var("CLIENT_SECRET")?); -// q.append_pair("code", &query.code); -// q.append_pair("grant_type", "authorization_code"); -// q.append_pair("redirect_uri", "https://burrow.rs/callback"); -// } - -// let data = client -// .post(url) -// .send() -// .await? -// .json::() -// .await?; - -// if !data.ok { -// return Err(anyhow::anyhow!("Slack code exchange response not ok!")); -// } - -// if let Some(access_token) = data.access_token { -// log::trace!("Access token is {access_token}"); -// let user = slack::fetch_slack_user(&access_token) -// .await -// .map_err(|err| anyhow::anyhow!("Failed to fetch Slack user info {:#?}", err))?; - -// db::store_user(user, access_token, String::new()) -// .map_err(|_| anyhow::anyhow!("Failed to store user in db"))?; - -// Ok(()) -// } else { -// Err(anyhow::anyhow!("Access token not found in response")) -// } -// } diff --git a/burrow/src/daemon/apple.rs b/burrow/src/daemon/apple.rs deleted file mode 100644 index c60f131..0000000 --- a/burrow/src/daemon/apple.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::{ - ffi::{c_char, CStr}, - path::PathBuf, - sync::Arc, - thread, -}; - -use once_cell::sync::OnceCell; -use tokio::{ - runtime::{Builder, Handle}, - sync::Notify, -}; -use tracing::error; - -use crate::daemon::daemon_main; - -static BURROW_NOTIFY: OnceCell> = OnceCell::new(); -static BURROW_HANDLE: OnceCell = OnceCell::new(); - -#[no_mangle] -pub unsafe extern "C" fn spawn_in_process(path: *const c_char, db_path: *const c_char) { - crate::tracing::initialize(); - - let notify = BURROW_NOTIFY.get_or_init(|| Arc::new(Notify::new())); - let handle = BURROW_HANDLE.get_or_init(|| { - let path_buf = if path.is_null() { - None - } else { - Some(PathBuf::from(CStr::from_ptr(path).to_str().unwrap())) - }; - let db_path_buf = if db_path.is_null() { - None - } else { - Some(PathBuf::from(CStr::from_ptr(db_path).to_str().unwrap())) - }; - let sender = notify.clone(); - - let (handle_tx, handle_rx) = tokio::sync::oneshot::channel(); - thread::spawn(move || { - let runtime = Builder::new_multi_thread() - .worker_threads(4) - .enable_all() - .thread_name("burrow-worker") - .build() - .unwrap(); - handle_tx.send(runtime.handle().clone()).unwrap(); - runtime.block_on(async { - let result = daemon_main( - path_buf.as_deref(), - db_path_buf.as_deref(), - Some(sender.clone()), - ) - .await; - if let Err(error) = result.as_ref() { - error!("Burrow thread exited: {}", error); - } - result - }) - }); - handle_rx.blocking_recv().unwrap() - }); - - let receiver = notify.clone(); - handle.block_on(async move { receiver.notified().await }); -} diff --git a/burrow/src/daemon/instance.rs b/burrow/src/daemon/instance.rs deleted file mode 100644 index ce96fa5..0000000 --- a/burrow/src/daemon/instance.rs +++ /dev/null @@ -1,256 +0,0 @@ -use std::{ - ops::Deref, - path::{Path, PathBuf}, - sync::Arc, - time::Duration, -}; - -use anyhow::Result; -use rusqlite::Connection; -use tokio::sync::{mpsc, watch, Notify, RwLock}; -use tokio_stream::wrappers::ReceiverStream; -use tonic::{Request, Response, Status as RspStatus}; -use tracing::{debug, info, warn}; -use tun::{tokio::TunInterface, TunOptions}; - -use super::rpc::grpc_defs::{ - networks_server::Networks, - tunnel_server::Tunnel, - Empty, - Network, - NetworkDeleteRequest, - NetworkListResponse, - NetworkReorderRequest, - State as RPCTunnelState, - TunnelConfigurationResponse, - TunnelStatusResponse, -}; -use crate::{ - daemon::rpc::{ - DaemonCommand, - DaemonNotification, - DaemonResponse, - DaemonResponseData, - ServerConfig, - ServerInfo, - }, - database::{ - add_network, - delete_network, - get_connection, - list_networks, - load_interface, - reorder_network, - }, - wireguard::{Config, Interface}, -}; - -#[derive(Debug, Clone)] -enum RunState { - Running, - Idle, -} - -impl RunState { - pub fn to_rpc(&self) -> RPCTunnelState { - match self { - RunState::Running => RPCTunnelState::Running, - RunState::Idle => RPCTunnelState::Stopped, - } - } -} - -#[derive(Clone)] -pub struct DaemonRPCServer { - tun_interface: Arc>>, - wg_interface: Arc>, - config: Arc>, - db_path: Option, - wg_state_chan: (watch::Sender, watch::Receiver), - network_update_chan: (watch::Sender<()>, watch::Receiver<()>), -} - -impl DaemonRPCServer { - pub fn new( - wg_interface: Arc>, - config: Arc>, - db_path: Option<&Path>, - ) -> Result { - Ok(Self { - tun_interface: Arc::new(RwLock::new(None)), - wg_interface, - config, - db_path: db_path.map(|p| p.to_owned()), - wg_state_chan: watch::channel(RunState::Idle), - network_update_chan: watch::channel(()), - }) - } - - pub fn get_connection(&self) -> Result { - get_connection(self.db_path.as_deref()).map_err(proc_err) - } - - async fn set_wg_state(&self, state: RunState) -> Result<(), RspStatus> { - self.wg_state_chan.0.send(state).map_err(proc_err) - } - - async fn get_wg_state(&self) -> RunState { - self.wg_state_chan.1.borrow().to_owned() - } - - async fn notify_network_update(&self) -> Result<(), RspStatus> { - self.network_update_chan.0.send(()).map_err(proc_err) - } -} - -#[tonic::async_trait] -impl Tunnel for DaemonRPCServer { - type TunnelConfigurationStream = ReceiverStream>; - type TunnelStatusStream = ReceiverStream>; - - async fn tunnel_configuration( - &self, - _request: Request, - ) -> Result, RspStatus> { - let (tx, rx) = mpsc::channel(10); - tokio::spawn(async move { - let serv_config = ServerConfig::default(); - tx.send(Ok(TunnelConfigurationResponse { - mtu: serv_config.mtu.unwrap_or(1000), - addresses: serv_config.address, - })) - .await - }); - Ok(Response::new(ReceiverStream::new(rx))) - } - - async fn tunnel_start(&self, _request: Request) -> Result, RspStatus> { - let wg_state = self.get_wg_state().await; - match wg_state { - RunState::Idle => { - let tun_if = TunOptions::new().open()?; - debug!("Setting tun on wg_interface"); - self.tun_interface.write().await.replace(tun_if); - self.wg_interface - .write() - .await - .set_tun_ref(self.tun_interface.clone()) - .await; - debug!("tun set on wg_interface"); - - debug!("Setting tun_interface"); - debug!("tun_interface set: {:?}", self.tun_interface); - - debug!("Cloning wg_interface"); - let tmp_wg = self.wg_interface.clone(); - let run_task = tokio::spawn(async move { - let twlock = tmp_wg.read().await; - twlock.run().await - }); - self.set_wg_state(RunState::Running).await?; - } - - RunState::Running => { - warn!("Got start, but tun interface already up."); - } - } - - return Ok(Response::new(Empty {})); - } - - async fn tunnel_stop(&self, _request: Request) -> Result, RspStatus> { - self.wg_interface.write().await.remove_tun().await; - self.set_wg_state(RunState::Idle).await?; - return Ok(Response::new(Empty {})); - } - - async fn tunnel_status( - &self, - _request: Request, - ) -> Result, RspStatus> { - let (tx, rx) = mpsc::channel(10); - let mut state_rx = self.wg_state_chan.1.clone(); - tokio::spawn(async move { - let cur = state_rx.borrow_and_update().to_owned(); - tx.send(Ok(status_rsp(cur))).await; - loop { - state_rx.changed().await.unwrap(); - let cur = state_rx.borrow().to_owned(); - let res = tx.send(Ok(status_rsp(cur))).await; - if res.is_err() { - eprintln!("Tunnel status channel closed"); - break; - } - } - }); - Ok(Response::new(ReceiverStream::new(rx))) - } -} - -#[tonic::async_trait] -impl Networks for DaemonRPCServer { - type NetworkListStream = ReceiverStream>; - - async fn network_add(&self, request: Request) -> Result, RspStatus> { - let conn = self.get_connection()?; - let network = request.into_inner(); - add_network(&conn, &network).map_err(proc_err)?; - self.notify_network_update().await?; - Ok(Response::new(Empty {})) - } - - async fn network_list( - &self, - _request: Request, - ) -> Result, RspStatus> { - debug!("Mock network_list called"); - let (tx, rx) = mpsc::channel(10); - let conn = self.get_connection()?; - let mut sub = self.network_update_chan.1.clone(); - tokio::spawn(async move { - loop { - let networks = list_networks(&conn) - .map(|res| NetworkListResponse { network: res }) - .map_err(proc_err); - let res = tx.send(networks).await; - if res.is_err() { - eprintln!("Network list channel closed"); - break; - } - sub.changed().await.unwrap(); - } - }); - Ok(Response::new(ReceiverStream::new(rx))) - } - - async fn network_reorder( - &self, - request: Request, - ) -> Result, RspStatus> { - let conn = self.get_connection()?; - reorder_network(&conn, request.into_inner()).map_err(proc_err)?; - self.notify_network_update().await?; - Ok(Response::new(Empty {})) - } - - async fn network_delete( - &self, - request: Request, - ) -> Result, RspStatus> { - let conn = self.get_connection()?; - delete_network(&conn, request.into_inner()).map_err(proc_err)?; - self.notify_network_update().await?; - Ok(Response::new(Empty {})) - } -} - -fn proc_err(err: impl ToString) -> RspStatus { - RspStatus::internal(err.to_string()) -} - -fn status_rsp(state: RunState) -> TunnelStatusResponse { - TunnelStatusResponse { - state: state.to_rpc().into(), - start: None, // TODO: Add timestamp - } -} diff --git a/burrow/src/daemon/mod.rs b/burrow/src/daemon/mod.rs deleted file mode 100644 index f6b973f..0000000 --- a/burrow/src/daemon/mod.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::{path::Path, sync::Arc}; - -pub mod apple; -mod instance; -mod net; -pub mod rpc; - -use anyhow::{Error as AhError, Result}; -use instance::DaemonRPCServer; -pub use net::{get_socket_path, DaemonClient}; -pub use rpc::{DaemonCommand, DaemonResponseData, DaemonStartOptions}; -use tokio::{ - net::UnixListener, - sync::{Notify, RwLock}, -}; -use tokio_stream::wrappers::UnixListenerStream; -use tonic::transport::Server; -use tracing::{error, info}; - -use crate::{ - daemon::rpc::grpc_defs::{networks_server::NetworksServer, tunnel_server::TunnelServer}, - database::{get_connection, load_interface}, - wireguard::Interface, -}; - -pub async fn daemon_main( - socket_path: Option<&Path>, - db_path: Option<&Path>, - notify_ready: Option>, -) -> Result<()> { - if let Some(n) = notify_ready { - n.notify_one() - } - let conn = get_connection(db_path)?; - let config = load_interface(&conn, "1")?; - let burrow_server = DaemonRPCServer::new( - Arc::new(RwLock::new(config.clone().try_into()?)), - Arc::new(RwLock::new(config)), - db_path.clone(), - )?; - let spp = socket_path.clone(); - let tmp = get_socket_path(); - let sock_path = spp.unwrap_or(Path::new(tmp.as_str())); - if sock_path.exists() { - std::fs::remove_file(sock_path)?; - } - let uds = UnixListener::bind(sock_path)?; - let serve_job = tokio::spawn(async move { - let uds_stream = UnixListenerStream::new(uds); - let _srv = Server::builder() - .add_service(TunnelServer::new(burrow_server.clone())) - .add_service(NetworksServer::new(burrow_server)) - .serve_with_incoming(uds_stream) - .await?; - Ok::<(), AhError>(()) - }); - - info!("Starting daemon..."); - - tokio::try_join!(serve_job) - .map(|_| ()) - .map_err(|e| e.into()) -} diff --git a/burrow/src/daemon/net/mod.rs b/burrow/src/daemon/net/mod.rs deleted file mode 100644 index eb45335..0000000 --- a/burrow/src/daemon/net/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -#[cfg(target_family = "unix")] -mod unix; - -#[cfg(target_family = "unix")] -pub use unix::{get_socket_path, DaemonClient, Listener}; - -#[cfg(target_os = "windows")] -mod windows; - -#[cfg(target_os = "windows")] -pub use windows::{DaemonClient, Listener}; diff --git a/burrow/src/daemon/net/unix.rs b/burrow/src/daemon/net/unix.rs deleted file mode 100644 index 975c470..0000000 --- a/burrow/src/daemon/net/unix.rs +++ /dev/null @@ -1,244 +0,0 @@ -#[cfg(target_os = "linux")] -use std::os::fd::{IntoRawFd, RawFd}; -use std::{ffi::OsStr, io, path::Path}; - -use anyhow::{anyhow, Error, Result}; -use fehler::throws; -use tokio::{ - io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, - net::{UnixListener, UnixStream}, -}; -use tracing::{debug, error, info}; - -use crate::daemon::rpc::{ - DaemonCommand, - DaemonMessage, - DaemonNotification, - DaemonRequest, - DaemonResponse, - DaemonResponseData, -}; - -#[cfg(not(target_vendor = "apple"))] -const UNIX_SOCKET_PATH: &str = "/run/burrow.sock"; - -#[cfg(target_vendor = "apple")] -const UNIX_SOCKET_PATH: &str = "burrow.sock"; - -pub fn get_socket_path() -> String { - if std::env::var("BURROW_SOCKET_PATH").is_ok() { - return std::env::var("BURROW_SOCKET_PATH").unwrap(); - } - UNIX_SOCKET_PATH.to_string() -} - -pub struct Listener { - cmd_tx: async_channel::Sender, - rsp_rx: async_channel::Receiver, - sub_chan: async_channel::Receiver, - pub inner: UnixListener, -} - -impl Listener { - #[throws] - pub fn new( - cmd_tx: async_channel::Sender, - rsp_rx: async_channel::Receiver, - sub_chan: async_channel::Receiver, - ) -> Self { - let socket_path = get_socket_path(); - let path = Path::new(OsStr::new(&socket_path)); - Self::new_with_path(cmd_tx, rsp_rx, sub_chan, path)? - } - - #[throws] - #[cfg(target_os = "linux")] - pub fn new_with_path( - cmd_tx: async_channel::Sender, - rsp_rx: async_channel::Receiver, - sub_chan: async_channel::Receiver, - path: &Path, - ) -> Self { - let inner = listener_from_path_or_fd(&path, raw_fd())?; - Self { - cmd_tx, - rsp_rx, - sub_chan, - inner, - } - } - - #[throws] - #[cfg(not(target_os = "linux"))] - pub fn new_with_path( - cmd_tx: async_channel::Sender, - rsp_rx: async_channel::Receiver, - sub_chan: async_channel::Receiver, - path: &Path, - ) -> Self { - let inner = listener_from_path(path)?; - Self { - cmd_tx, - rsp_rx, - inner, - sub_chan, - } - } - - pub async fn run(&self) -> Result<()> { - info!("Waiting for connections..."); - loop { - let (stream, _) = self.inner.accept().await?; - let cmd_tx = self.cmd_tx.clone(); - let rsp_rxc = self.rsp_rx.clone(); - let sub_chan = self.sub_chan.clone(); - tokio::task::spawn(async move { - info!("Got connection: {:?}", stream); - Self::stream(stream, cmd_tx, rsp_rxc, sub_chan).await; - }); - } - } - - async fn stream( - stream: UnixStream, - cmd_tx: async_channel::Sender, - rsp_rxc: async_channel::Receiver, - sub_chan: async_channel::Receiver, - ) { - let mut stream = stream; - let (mut read_stream, mut write_stream) = stream.split(); - let buf_reader = BufReader::new(&mut read_stream); - let mut lines = buf_reader.lines(); - loop { - tokio::select! { - Ok(Some(line)) = lines.next_line() => { - info!("Line: {}", line); - let mut res: DaemonResponse = DaemonResponseData::None.into(); - let req = match serde_json::from_str::(&line) { - Ok(req) => Some(req), - Err(e) => { - res.result = Err(e.to_string()); - error!("Failed to parse request: {}", e); - None - } - }; - - let res = serde_json::to_string(&DaemonMessage::from(res)).unwrap(); - - if let Some(req) = req { - cmd_tx.send(req.command).await.unwrap(); - let res = rsp_rxc.recv().await.unwrap().with_id(req.id); - let mut payload = serde_json::to_string(&DaemonMessage::from(res)).unwrap(); - payload.push('\n'); - info!("Sending response: {}", payload); - write_stream.write_all(payload.as_bytes()).await.unwrap(); - } else { - write_stream.write_all(res.as_bytes()).await.unwrap(); - } - } - Ok(cmd) = sub_chan.recv() => { - info!("Got subscription command: {:?}", cmd); - let msg = DaemonMessage::from(cmd); - let mut payload = serde_json::to_string(&msg).unwrap(); - payload.push('\n'); - write_stream.write_all(payload.as_bytes()).await.unwrap(); - } - } - } - } -} - -#[cfg(target_os = "linux")] -fn raw_fd() -> Option { - if !libsystemd::daemon::booted() { - return None; - } - - match libsystemd::activation::receive_descriptors(false) { - Ok(descriptors) => descriptors.into_iter().map(|d| d.into_raw_fd()).next(), - Err(e) => { - tracing::error!("Failed to receive descriptors: {}", e); - None - } - } -} - -#[throws] -#[cfg(target_os = "linux")] -fn listener_from_path_or_fd(path: &Path, raw_fd: Option) -> UnixListener { - match raw_fd.map(listener_from_fd) { - Some(Ok(listener)) => listener, - _ => listener_from_path(path)?, - } -} - -#[throws] -#[cfg(target_os = "linux")] -fn listener_from_fd(fd: RawFd) -> UnixListener { - use std::os::fd::FromRawFd; - - let listener = unsafe { std::os::unix::net::UnixListener::from_raw_fd(fd) }; - listener.set_nonblocking(true)?; - UnixListener::from_std(listener)? -} - -#[throws] -fn listener_from_path(path: &Path) -> UnixListener { - let error = match UnixListener::bind(path) { - Ok(listener) => return listener, - Err(e) => e, - }; - - match error.kind() { - io::ErrorKind::NotFound => { - if let Some(parent) = path.parent() { - info!("Creating parent directory {:?}", parent); - std::fs::create_dir_all(parent)?; - } - } - io::ErrorKind::AddrInUse => { - info!("Removing existing file"); - match std::fs::remove_file(path) { - Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(()), - stuff => stuff, - }?; - } - _ => error!("Failed to bind to {:?}: {}", path, error), - } - - UnixListener::bind(path)? -} - -#[derive(Debug)] -pub struct DaemonClient { - stream: UnixStream, -} - -impl DaemonClient { - pub async fn new() -> Result { - let socket_path = get_socket_path(); - let path = Path::new(OsStr::new(&socket_path)); - Self::new_with_path(path).await - } - - pub async fn new_with_path(path: &Path) -> Result { - let stream = UnixStream::connect(path).await?; - Ok(Self { stream }) - } - - pub async fn send_command(&mut self, command: DaemonCommand) -> Result { - let mut command = serde_json::to_string(&DaemonRequest { id: 0, command })?; - command.push('\n'); - - self.stream.write_all(command.as_bytes()).await?; - let buf_reader = BufReader::new(&mut self.stream); - let mut lines = buf_reader.lines(); - let response = lines - .next_line() - .await? - .ok_or(anyhow!("Failed to read response"))?; - debug!("Got raw response: {}", response); - let res: DaemonResponse = serde_json::from_str(&response)?; - Ok(res) - } -} diff --git a/burrow/src/daemon/net/windows.rs b/burrow/src/daemon/net/windows.rs deleted file mode 100644 index 5918260..0000000 --- a/burrow/src/daemon/net/windows.rs +++ /dev/null @@ -1,34 +0,0 @@ -use anyhow::Result; -use fehler::throws; - -use super::DaemonCommand; -use crate::daemon::DaemonResponse; - -pub struct Listener; - -impl Listener { - pub fn new_with_path( - cmd_tx: async_channel::Sender, - rsp_rx: async_channel::Receiver, - path: &Path, - ) -> Self { - Self - } - - pub async fn run(&self) -> Result<()> { - Ok(()) - } -} - -#[derive(Debug)] -pub struct DaemonClient; - -impl DaemonClient { - pub async fn new() -> Result { - Ok(Self) - } - - pub async fn send_command(&mut self, command: DaemonCommand) -> Result { - unimplemented!("This platform does not currently support daemon mode.") - } -} diff --git a/burrow/src/daemon/rpc/client.rs b/burrow/src/daemon/rpc/client.rs deleted file mode 100644 index 862e34c..0000000 --- a/burrow/src/daemon/rpc/client.rs +++ /dev/null @@ -1,31 +0,0 @@ -use anyhow::Result; -use hyper_util::rt::TokioIo; -use tokio::net::UnixStream; -use tonic::transport::{Endpoint, Uri}; -use tower::service_fn; - -use super::grpc_defs::{networks_client::NetworksClient, tunnel_client::TunnelClient}; -use crate::daemon::get_socket_path; - -pub struct BurrowClient { - pub networks_client: NetworksClient, - pub tunnel_client: TunnelClient, -} - -impl BurrowClient { - #[cfg(any(target_os = "linux", target_vendor = "apple"))] - pub async fn from_uds() -> Result { - let channel = Endpoint::try_from("http://[::]:50051")? // NOTE: this is a hack(?) - .connect_with_connector(service_fn(|_: Uri| async { - let sock_path = get_socket_path(); - Ok::<_, std::io::Error>(TokioIo::new(UnixStream::connect(sock_path).await?)) - })) - .await?; - let nw_client = NetworksClient::new(channel.clone()); - let tun_client = TunnelClient::new(channel.clone()); - Ok(BurrowClient { - networks_client: nw_client, - tunnel_client: tun_client, - }) - } -} diff --git a/burrow/src/daemon/rpc/grpc_defs.rs b/burrow/src/daemon/rpc/grpc_defs.rs deleted file mode 100644 index f3085ee..0000000 --- a/burrow/src/daemon/rpc/grpc_defs.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub use burrowgrpc::*; - -mod burrowgrpc { - tonic::include_proto!("burrow"); -} diff --git a/burrow/src/daemon/rpc/mod.rs b/burrow/src/daemon/rpc/mod.rs deleted file mode 100644 index 512662c..0000000 --- a/burrow/src/daemon/rpc/mod.rs +++ /dev/null @@ -1,43 +0,0 @@ -pub mod client; -pub mod grpc_defs; -pub mod notification; -pub mod request; -pub mod response; - -pub use client::BurrowClient; -pub use notification::DaemonNotification; -pub use request::{DaemonCommand, DaemonRequest, DaemonStartOptions}; -pub use response::{DaemonResponse, DaemonResponseData, ServerConfig, ServerInfo}; -use serde::{Deserialize, Serialize}; - -/// The `Message` object contains either a `DaemonRequest` or a `DaemonResponse` to be serialized / deserialized -/// for our IPC communication. Our IPC protocol is based on jsonrpc (https://www.jsonrpc.org/specification#overview), -/// but deviates from it in a few ways: -/// - We differentiate Notifications from Requests explicitly. -/// - We have a "type" field to differentiate between a request, a response, and a notification. -/// - The params field may receive any json value(such as a string), not just an object or an array. -#[derive(Serialize, Deserialize)] -#[serde(tag = "type")] -pub enum DaemonMessage { - Request(DaemonRequest), - Response(DaemonResponse), - Notification(DaemonNotification), -} - -impl From for DaemonMessage { - fn from(request: DaemonRequest) -> Self { - DaemonMessage::Request(request) - } -} - -impl From for DaemonMessage { - fn from(response: DaemonResponse) -> Self { - DaemonMessage::Response(response) - } -} - -impl From for DaemonMessage { - fn from(notification: DaemonNotification) -> Self { - DaemonMessage::Notification(notification) - } -} diff --git a/burrow/src/daemon/rpc/notification.rs b/burrow/src/daemon/rpc/notification.rs deleted file mode 100644 index 135b0e4..0000000 --- a/burrow/src/daemon/rpc/notification.rs +++ /dev/null @@ -1,11 +0,0 @@ -use rpc::ServerConfig; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::daemon::rpc; - -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "method", content = "params")] -pub enum DaemonNotification { - ConfigChange(ServerConfig), -} diff --git a/burrow/src/daemon/rpc/request.rs b/burrow/src/daemon/rpc/request.rs deleted file mode 100644 index e9480aa..0000000 --- a/burrow/src/daemon/rpc/request.rs +++ /dev/null @@ -1,42 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use tun::TunOptions; - -#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] -#[serde(tag="method", content="params")] -pub enum DaemonCommand { - Start(DaemonStartOptions), - ServerInfo, - ServerConfig, - Stop, - ReloadConfig(String), -} - -#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)] -pub struct DaemonStartOptions { - pub tun: TunOptions, -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct DaemonRequest { - pub id: u64, - #[serde(flatten)] - pub command: DaemonCommand, -} - -#[test] -fn test_daemoncommand_serialization() { - insta::assert_snapshot!(serde_json::to_string(&DaemonCommand::Start( - DaemonStartOptions::default() - )) - .unwrap()); - insta::assert_snapshot!( - serde_json::to_string(&DaemonCommand::Start(DaemonStartOptions { - tun: TunOptions { ..TunOptions::default() } - })) - .unwrap() - ); - insta::assert_snapshot!(serde_json::to_string(&DaemonCommand::ServerInfo).unwrap()); - insta::assert_snapshot!(serde_json::to_string(&DaemonCommand::Stop).unwrap()); - insta::assert_snapshot!(serde_json::to_string(&DaemonCommand::ServerConfig).unwrap()) -} diff --git a/burrow/src/daemon/rpc/response.rs b/burrow/src/daemon/rpc/response.rs deleted file mode 100644 index 61c9c50..0000000 --- a/burrow/src/daemon/rpc/response.rs +++ /dev/null @@ -1,128 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use tun::TunInterface; - -use crate::wireguard::Config; - -#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema)] -pub struct DaemonResponse { - // Error types can't be serialized, so this is the second best option. - pub result: Result, - pub id: u64, -} - -impl DaemonResponse { - pub fn new(result: Result) -> Self { - Self { - result: result.map_err(|e| e.to_string()), - id: 0, - } - } -} - -impl From for DaemonResponse { - fn from(val: DaemonResponseData) -> Self { - DaemonResponse::new(Ok::(val)) - } -} - -impl DaemonResponse { - pub fn with_id(self, id: u64) -> Self { - Self { id, ..self } - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] -pub struct ServerInfo { - pub name: Option, - pub ip: Option, - pub mtu: Option, -} - -impl TryFrom<&TunInterface> for ServerInfo { - type Error = anyhow::Error; - - #[cfg(any(target_os = "linux", target_vendor = "apple"))] - fn try_from(server: &TunInterface) -> anyhow::Result { - Ok(ServerInfo { - name: server.name().ok(), - ip: server.ipv4_addr().ok().map(|ip| ip.to_string()), - mtu: server.mtu().ok(), - }) - } - - #[cfg(not(any(target_os = "linux", target_vendor = "apple")))] - fn try_from(server: &TunInterface) -> anyhow::Result { - Err(anyhow!("Not implemented in this platform")) - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] -pub struct ServerConfig { - pub address: Vec, - pub name: Option, - pub mtu: Option, -} - -impl TryFrom<&Config> for ServerConfig { - type Error = anyhow::Error; - - fn try_from(config: &Config) -> anyhow::Result { - Ok(ServerConfig { - address: config.interface.address.clone(), - name: None, - mtu: config.interface.mtu.map(|mtu| mtu as i32), - }) - } -} - -impl Default for ServerConfig { - fn default() -> Self { - Self { - address: vec!["10.13.13.2".to_string()], // Dummy remote address - name: None, - mtu: None, - } - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] -#[serde(tag = "type")] -pub enum DaemonResponseData { - ServerInfo(ServerInfo), - ServerConfig(ServerConfig), - None, -} - -#[test] -fn test_response_serialization() -> anyhow::Result<()> { - insta::assert_snapshot!(serde_json::to_string(&DaemonResponse::new(Ok::< - DaemonResponseData, - String, - >( - DaemonResponseData::None - )))?); - insta::assert_snapshot!(serde_json::to_string(&DaemonResponse::new(Ok::< - DaemonResponseData, - String, - >( - DaemonResponseData::ServerInfo(ServerInfo { - name: Some("burrow".to_string()), - ip: None, - mtu: Some(1500) - }) - )))?); - insta::assert_snapshot!(serde_json::to_string(&DaemonResponse::new(Err::< - DaemonResponseData, - String, - >( - "error".to_string() - )))?); - insta::assert_snapshot!(serde_json::to_string(&DaemonResponse::new(Ok::< - DaemonResponseData, - String, - >( - DaemonResponseData::ServerConfig(ServerConfig::default()) - )))?); - Ok(()) -} diff --git a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-2.snap b/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-2.snap deleted file mode 100644 index 01ec8a7..0000000 --- a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-2.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/rpc/request.rs -expression: "serde_json::to_string(&DaemonCommand::Start(DaemonStartOptions {\n tun: TunOptions { ..TunOptions::default() },\n })).unwrap()" ---- -{"method":"Start","params":{"tun":{"name":null,"no_pi":false,"tun_excl":false,"tun_retrieve":false,"address":[]}}} diff --git a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-3.snap b/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-3.snap deleted file mode 100644 index a6a0466..0000000 --- a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-3.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/rpc/request.rs -expression: "serde_json::to_string(&DaemonCommand::ServerInfo).unwrap()" ---- -{"method":"ServerInfo"} diff --git a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-4.snap b/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-4.snap deleted file mode 100644 index f930051..0000000 --- a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-4.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/rpc/request.rs -expression: "serde_json::to_string(&DaemonCommand::Stop).unwrap()" ---- -{"method":"Stop"} diff --git a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-5.snap b/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-5.snap deleted file mode 100644 index 89dc42c..0000000 --- a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization-5.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/rpc/request.rs -expression: "serde_json::to_string(&DaemonCommand::ServerConfig).unwrap()" ---- -{"method":"ServerConfig"} diff --git a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization.snap b/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization.snap deleted file mode 100644 index aeca659..0000000 --- a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__request__daemoncommand_serialization.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/rpc/request.rs -expression: "serde_json::to_string(&DaemonCommand::Start(DaemonStartOptions::default())).unwrap()" ---- -{"method":"Start","params":{"tun":{"name":null,"no_pi":false,"tun_excl":false,"tun_retrieve":false,"address":[]}}} diff --git a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization-2.snap b/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization-2.snap deleted file mode 100644 index d7bd712..0000000 --- a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization-2.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/rpc/response.rs -expression: "serde_json::to_string(&DaemonResponse::new(Ok::(DaemonResponseData::ServerInfo(ServerInfo {\n name: Some(\"burrow\".to_string()),\n ip: None,\n mtu: Some(1500),\n }))))?" ---- -{"result":{"Ok":{"type":"ServerInfo","name":"burrow","ip":null,"mtu":1500}},"id":0} diff --git a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization-3.snap b/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization-3.snap deleted file mode 100644 index 30068f3..0000000 --- a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization-3.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/rpc/response.rs -expression: "serde_json::to_string(&DaemonResponse::new(Err::(\"error\".to_string())))?" ---- -{"result":{"Err":"error"},"id":0} diff --git a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization-4.snap b/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization-4.snap deleted file mode 100644 index c40db25..0000000 --- a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization-4.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/rpc/response.rs -expression: "serde_json::to_string(&DaemonResponse::new(Ok::(DaemonResponseData::ServerConfig(ServerConfig::default()))))?" ---- -{"result":{"Ok":{"type":"ServerConfig","address":["10.13.13.2"],"name":null,"mtu":null}},"id":0} diff --git a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization.snap b/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization.snap deleted file mode 100644 index 31bd84b..0000000 --- a/burrow/src/daemon/rpc/snapshots/burrow__daemon__rpc__response__response_serialization.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/rpc/response.rs -expression: "serde_json::to_string(&DaemonResponse::new(Ok::(DaemonResponseData::None)))?" ---- -{"result":{"Ok":{"type":"None"}},"id":0} diff --git a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-2.snap b/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-2.snap deleted file mode 100644 index f78eeaa..0000000 --- a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-2.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/command.rs -expression: "serde_json::to_string(&DaemonCommand::Start(DaemonStartOptions {\n tun: TunOptions { ..TunOptions::default() },\n })).unwrap()" ---- -{"Start":{"tun":{"name":null,"no_pi":false,"tun_excl":false,"tun_retrieve":false,"address":[]}}} diff --git a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-3.snap b/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-3.snap deleted file mode 100644 index 80b9e24..0000000 --- a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-3.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/command.rs -expression: "serde_json::to_string(&DaemonCommand::ServerInfo).unwrap()" ---- -"ServerInfo" diff --git a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-4.snap b/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-4.snap deleted file mode 100644 index 8dc1b8b..0000000 --- a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-4.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/command.rs -expression: "serde_json::to_string(&DaemonCommand::Stop).unwrap()" ---- -"Stop" diff --git a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-5.snap b/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-5.snap deleted file mode 100644 index 9334ece..0000000 --- a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization-5.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/command.rs -expression: "serde_json::to_string(&DaemonCommand::ServerConfig).unwrap()" ---- -"ServerConfig" diff --git a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization.snap b/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization.snap deleted file mode 100644 index eee563d..0000000 --- a/burrow/src/daemon/snapshots/burrow__daemon__command__daemoncommand_serialization.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/command.rs -expression: "serde_json::to_string(&DaemonCommand::Start(DaemonStartOptions::default())).unwrap()" ---- -{"Start":{"tun":{"name":null,"no_pi":false,"tun_excl":false,"tun_retrieve":false,"address":[]}}} diff --git a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-2.snap b/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-2.snap deleted file mode 100644 index 3787cd1..0000000 --- a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-2.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/response.rs -expression: "serde_json::to_string(&DaemonResponse::new(Ok::(DaemonResponseData::ServerInfo(ServerInfo {\n name: Some(\"burrow\".to_string()),\n ip: None,\n mtu: Some(1500),\n }))))?" ---- -{"result":{"Ok":{"ServerInfo":{"name":"burrow","ip":null,"mtu":1500}}},"id":0} diff --git a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-3.snap b/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-3.snap deleted file mode 100644 index 4ef9575..0000000 --- a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-3.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/response.rs -expression: "serde_json::to_string(&DaemonResponse::new(Err::(\"error\".to_string())))?" ---- -{"result":{"Err":"error"},"id":0} diff --git a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-4.snap b/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-4.snap deleted file mode 100644 index 0b9385c..0000000 --- a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization-4.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/response.rs -expression: "serde_json::to_string(&DaemonResponse::new(Ok::(DaemonResponseData::ServerConfig(ServerConfig::default()))))?" ---- -{"result":{"Ok":{"ServerConfig":{"address":["10.13.13.2"],"name":null,"mtu":null}}},"id":0} diff --git a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization.snap b/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization.snap deleted file mode 100644 index 647d01c..0000000 --- a/burrow/src/daemon/snapshots/burrow__daemon__response__response_serialization.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: burrow/src/daemon/response.rs -expression: "serde_json::to_string(&DaemonResponse::new(Ok::(DaemonResponseData::None)))?" ---- -{"result":{"Ok":"None"},"id":0} diff --git a/burrow/src/database.rs b/burrow/src/database.rs deleted file mode 100644 index 9a9aac3..0000000 --- a/burrow/src/database.rs +++ /dev/null @@ -1,216 +0,0 @@ -use std::path::Path; - -use anyhow::Result; -use rusqlite::{params, Connection}; - -use crate::{ - daemon::rpc::grpc_defs::{ - Network as RPCNetwork, - NetworkDeleteRequest, - NetworkReorderRequest, - NetworkType, - }, - wireguard::config::{Config, Interface, Peer}, -}; - -#[cfg(target_vendor = "apple")] -const DB_PATH: &str = "burrow.db"; - -#[cfg(not(target_vendor = "apple"))] -const DB_PATH: &str = "/var/lib/burrow/burrow.db"; - -const CREATE_WG_INTERFACE_TABLE: &str = "CREATE TABLE IF NOT EXISTS wg_interface ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT, - listen_port INTEGER, - mtu INTEGER, - private_key TEXT NOT NULL, - address TEXT NOT NULL, - dns TEXT NOT NULL -)"; - -const CREATE_WG_PEER_TABLE: &str = "CREATE TABLE IF NOT EXISTS wg_peer ( - interface_id INT REFERENCES wg_interface(id) ON UPDATE CASCADE, - endpoint TEXT NOT NULL, - public_key TEXT NOT NULL, - allowed_ips TEXT NOT NULL, - preshared_key TEXT -)"; - -const CREATE_NETWORK_TABLE: &str = "CREATE TABLE IF NOT EXISTS network ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - type TEXT NOT NULL, - payload BLOB, - idx INTEGER, - interface_id INT REFERENCES wg_interface(id) ON UPDATE CASCADE -); -CREATE TRIGGER IF NOT EXISTS increment_network_idx -AFTER INSERT ON network -BEGIN - UPDATE network - SET idx = (SELECT COALESCE(MAX(idx), 0) + 1 FROM network) - WHERE id = NEW.id; -END; -"; - -pub fn initialize_tables(conn: &Connection) -> Result<()> { - conn.execute(CREATE_WG_INTERFACE_TABLE, [])?; - conn.execute(CREATE_WG_PEER_TABLE, [])?; - conn.execute(CREATE_NETWORK_TABLE, [])?; - Ok(()) -} - -pub fn load_interface(conn: &Connection, interface_id: &str) -> Result { - let iface = conn.query_row( - "SELECT private_key, dns, address, listen_port, mtu FROM wg_interface WHERE id = ?", - [&interface_id], - |row| { - let dns_rw: String = row.get(1)?; - let dns = parse_lst(&dns_rw); - let address_rw: String = row.get(2)?; - let address = parse_lst(&address_rw); - Ok(Interface { - private_key: row.get(0)?, - dns, - address, - mtu: row.get(4)?, - listen_port: row.get(3)?, - }) - }, - )?; - let mut peers_stmt = conn.prepare("SELECT public_key, preshared_key, allowed_ips, endpoint FROM wg_peer WHERE interface_id = ?")?; - let peers = peers_stmt - .query_map([&interface_id], |row| { - let preshared_key: Option = row.get(1)?; - let allowed_ips_rw: String = row.get(2)?; - let allowed_ips: Vec = - allowed_ips_rw.split(',').map(|s| s.to_string()).collect(); - Ok(Peer { - public_key: row.get(0)?, - preshared_key, - allowed_ips, - endpoint: row.get(3)?, - persistent_keepalive: None, - name: None, - }) - })? - .collect::>>()?; - Ok(Config { interface: iface, peers }) -} - -pub fn dump_interface(conn: &Connection, config: &Config) -> Result<()> { - let mut stmt = conn.prepare("INSERT INTO wg_interface (private_key, dns, address, listen_port, mtu) VALUES (?, ?, ?, ?, ?)")?; - let cif = &config.interface; - stmt.execute(params![ - cif.private_key, - to_lst(&cif.dns), - to_lst(&cif.address), - cif.listen_port.unwrap_or(51820), - cif.mtu - ])?; - let interface_id = conn.last_insert_rowid(); - let mut stmt = conn.prepare("INSERT INTO wg_peer (interface_id, public_key, preshared_key, allowed_ips, endpoint) VALUES (?, ?, ?, ?, ?)")?; - for peer in &config.peers { - stmt.execute(params![ - &interface_id, - &peer.public_key, - &peer.preshared_key, - &peer.allowed_ips.join(","), - &peer.endpoint - ])?; - } - Ok(()) -} - -pub fn get_connection(path: Option<&Path>) -> Result { - let p = path.unwrap_or_else(|| std::path::Path::new(DB_PATH)); - if !p.exists() { - let conn = Connection::open(p)?; - initialize_tables(&conn)?; - dump_interface(&conn, &Config::default())?; - return Ok(conn); - } - Ok(Connection::open(p)?) -} - -pub fn add_network(conn: &Connection, network: &RPCNetwork) -> Result<()> { - let mut stmt = conn.prepare("INSERT INTO network (id, type, payload) VALUES (?, ?, ?)")?; - stmt.execute(params![ - network.id, - network.r#type().as_str_name(), - &network.payload - ])?; - if network.r#type() == NetworkType::WireGuard { - let payload_str = String::from_utf8(network.payload.clone())?; - let wg_config = Config::from_content_fmt(&payload_str, "ini")?; - dump_interface(conn, &wg_config)?; - } - Ok(()) -} - -pub fn list_networks(conn: &Connection) -> Result> { - let mut stmt = conn.prepare("SELECT id, type, payload FROM network ORDER BY idx")?; - let networks: Vec = stmt - .query_map([], |row| { - println!("row: {:?}", row); - let network_id: i32 = row.get(0)?; - let network_type: String = row.get(1)?; - let network_type = NetworkType::from_str_name(network_type.as_str()) - .ok_or(rusqlite::Error::InvalidQuery)?; - let payload: Vec = row.get(2)?; - Ok(RPCNetwork { - id: network_id, - r#type: network_type.into(), - payload: payload.into(), - }) - })? - .collect::, rusqlite::Error>>()?; - Ok(networks) -} - -pub fn reorder_network(conn: &Connection, req: NetworkReorderRequest) -> Result<()> { - let mut stmt = conn.prepare("UPDATE network SET idx = ? WHERE id = ?")?; - let res = stmt.execute(params![req.index, req.id])?; - if res == 0 { - return Err(anyhow::anyhow!("No such network exists")); - } - Ok(()) -} - -pub fn delete_network(conn: &Connection, req: NetworkDeleteRequest) -> Result<()> { - let mut stmt = conn.prepare("DELETE FROM network WHERE id = ?")?; - let res = stmt.execute(params![req.id])?; - if res == 0 { - return Err(anyhow::anyhow!("No such network exists")); - } - Ok(()) -} - -fn parse_lst(s: &str) -> Vec { - if s.is_empty() { - return vec![]; - } - s.split(',').map(|s| s.to_string()).collect() -} - -fn to_lst(v: &Vec) -> String { - v.iter() - .map(|s| s.to_string()) - .collect::>() - .join(",") -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_db() { - let conn = Connection::open_in_memory().unwrap(); - initialize_tables(&conn).unwrap(); - let config = Config::default(); - dump_interface(&conn, &config).unwrap(); - let loaded = load_interface(&conn, "1").unwrap(); - assert_eq!(config, loaded); - } -} diff --git a/burrow/src/lib.rs b/burrow/src/lib.rs deleted file mode 100644 index 6aae1fb..0000000 --- a/burrow/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -pub mod wireguard; - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -mod daemon; -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -pub mod database; -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -mod auth; -pub(crate) mod tracing; - -#[cfg(target_vendor = "apple")] -pub use daemon::apple::spawn_in_process; -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -pub use daemon::{ - rpc::DaemonResponse, - rpc::ServerInfo, - DaemonClient, - DaemonCommand, - DaemonResponseData, - DaemonStartOptions, -}; diff --git a/burrow/src/main.rs b/burrow/src/main.rs index e87b4c9..3d59fd3 100644 --- a/burrow/src/main.rs +++ b/burrow/src/main.rs @@ -1,296 +1,14 @@ -use anyhow::Result; -use clap::{Args, Parser, Subcommand}; +use tokio::io::Result; +use tun::TunInterface; -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -mod daemon; -pub(crate) mod tracing; -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -mod wireguard; - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -mod auth; - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -use daemon::{DaemonClient, DaemonCommand}; - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -use crate::daemon::DaemonResponseData; - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -pub mod database; - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -use crate::daemon::rpc::{grpc_defs::Empty, BurrowClient}; - -#[derive(Parser)] -#[command(name = "Burrow")] -#[command(author = "Hack Club ")] -#[command(version = "0.1")] -#[command( - about = "Burrow is a tool for burrowing through firewalls, built by teenagers at Hack Club.", - long_about = "Burrow is a 🚀 blazingly fast 🚀 tool designed to penetrate unnecessarily restrictive firewalls, providing teenagers worldwide with secure, less-filtered, and safe access to the internet! -It's being built by teenagers from Hack Club, in public! Check it out: https://github.com/hackclub/burrow -Spotted a bug? Please open an issue! https://github.com/hackclub/burrow/issues/new" -)] - -struct Cli { - #[command(subcommand)] - command: Commands, -} - -#[derive(Subcommand)] -enum Commands { - /// Start Burrow - Start(StartArgs), - /// Stop Burrow daemon - Stop, - /// Start Burrow daemon - Daemon(DaemonArgs), - /// Server Info - ServerInfo, - /// Server config - ServerConfig, - /// Reload Config - ReloadConfig(ReloadConfigArgs), - /// Authentication server - AuthServer, - /// Server Status - ServerStatus, - /// Tunnel Config - TunnelConfig, - /// Add Network - NetworkAdd(NetworkAddArgs), - /// List Networks - NetworkList, - /// Reorder Network - NetworkReorder(NetworkReorderArgs), - /// Delete Network - NetworkDelete(NetworkDeleteArgs), -} - -#[derive(Args)] -struct ReloadConfigArgs { - #[clap(long, short)] - interface_id: String, -} - -#[derive(Args)] -struct StartArgs {} - -#[derive(Args)] -struct DaemonArgs {} - -#[derive(Args)] -struct NetworkAddArgs { - id: i32, - network_type: i32, - payload_path: String, -} - -#[derive(Args)] -struct NetworkReorderArgs { - id: i32, - index: i32, -} - -#[derive(Args)] -struct NetworkDeleteArgs { - id: i32, -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_start() -> Result<()> { - let mut client = BurrowClient::from_uds().await?; - let res = client.tunnel_client.tunnel_start(Empty {}).await?; - println!("Got results! {:?}", res); - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_stop() -> Result<()> { - let mut client = BurrowClient::from_uds().await?; - let res = client.tunnel_client.tunnel_stop(Empty {}).await?; - println!("Got results! {:?}", res); - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_serverstatus() -> Result<()> { - let mut client = BurrowClient::from_uds().await?; - let mut res = client - .tunnel_client - .tunnel_status(Empty {}) - .await? - .into_inner(); - if let Some(st) = res.message().await? { - println!("Server Status: {:?}", st); - } else { - println!("Server Status is None"); - } - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_tun_config() -> Result<()> { - let mut client = BurrowClient::from_uds().await?; - let mut res = client - .tunnel_client - .tunnel_configuration(Empty {}) - .await? - .into_inner(); - if let Some(config) = res.message().await? { - println!("Tunnel Config: {:?}", config); - } else { - println!("Tunnel Config is None"); - } - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_network_add(id: i32, network_type: i32, payload_path: &str) -> Result<()> { - use tokio::{fs::File, io::AsyncReadExt}; - - use crate::daemon::rpc::grpc_defs::Network; - - let mut file = File::open(payload_path).await?; - let mut payload = Vec::new(); - file.read_to_end(&mut payload).await?; - - let mut client = BurrowClient::from_uds().await?; - let network = Network { - id, - r#type: network_type, - payload, - }; - let res = client.networks_client.network_add(network).await?; - println!("Network Add Response: {:?}", res); - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_network_list() -> Result<()> { - let mut client = BurrowClient::from_uds().await?; - let mut res = client - .networks_client - .network_list(Empty {}) - .await? - .into_inner(); - while let Some(network_list) = res.message().await? { - println!("Network List: {:?}", network_list); - } - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_network_reorder(id: i32, index: i32) -> Result<()> { - use crate::daemon::rpc::grpc_defs::NetworkReorderRequest; - - let mut client = BurrowClient::from_uds().await?; - let reorder_request = NetworkReorderRequest { id, index }; - let res = client - .networks_client - .network_reorder(reorder_request) - .await?; - println!("Network Reorder Response: {:?}", res); - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_network_delete(id: i32) -> Result<()> { - use crate::daemon::rpc::grpc_defs::NetworkDeleteRequest; - - let mut client = BurrowClient::from_uds().await?; - let delete_request = NetworkDeleteRequest { id }; - let res = client - .networks_client - .network_delete(delete_request) - .await?; - println!("Network Delete Response: {:?}", res); - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -fn handle_unexpected(res: Result) { - match res { - Ok(DaemonResponseData::None) => { - println!("Server not started.") - } - Ok(res) => { - println!("Unexpected Response: {:?}", res) - } - Err(e) => { - println!("Error when retrieving from server: {}", e) - } - } -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_serverinfo() -> Result<()> { - let mut client = DaemonClient::new().await?; - let res = client.send_command(DaemonCommand::ServerInfo).await?; - if let Ok(DaemonResponseData::ServerInfo(si)) = res.result { - println!("Got Result! {:?}", si); - } else { - handle_unexpected(res.result); - } - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_serverconfig() -> Result<()> { - let mut client = DaemonClient::new().await?; - let res = client.send_command(DaemonCommand::ServerConfig).await?; - if let Ok(DaemonResponseData::ServerConfig(cfig)) = res.result { - println!("Got Result! {:?}", cfig); - } else { - handle_unexpected(res.result); - } - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -async fn try_reloadconfig(interface_id: String) -> Result<()> { - let mut client = DaemonClient::new().await?; - let res = client - .send_command(DaemonCommand::ReloadConfig(interface_id)) - .await?; - if let Ok(DaemonResponseData::ServerConfig(cfig)) = res.result { - println!("Got Result! {:?}", cfig); - } else { - handle_unexpected(res.result); - } - Ok(()) -} - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -#[tokio::main] -async fn main() -> Result<()> { - tracing::initialize(); - dotenv::dotenv().ok(); - - let cli = Cli::parse(); - match &cli.command { - Commands::Start(..) => try_start().await?, - Commands::Stop => try_stop().await?, - Commands::Daemon(_) => daemon::daemon_main(None, None, None).await?, - Commands::ServerInfo => try_serverinfo().await?, - Commands::ServerConfig => try_serverconfig().await?, - Commands::ReloadConfig(args) => try_reloadconfig(args.interface_id.clone()).await?, - Commands::AuthServer => crate::auth::server::serve().await?, - Commands::ServerStatus => try_serverstatus().await?, - Commands::TunnelConfig => try_tun_config().await?, - Commands::NetworkAdd(args) => { - try_network_add(args.id, args.network_type, &args.payload_path).await? - } - Commands::NetworkList => try_network_list().await?, - Commands::NetworkReorder(args) => try_network_reorder(args.id, args.index).await?, - Commands::NetworkDelete(args) => try_network_delete(args.id).await?, - } +async fn lol() -> Result<()> { + let iface = TunInterface::new()?; + println!("{:?}", iface.name()); Ok(()) } -#[cfg(not(any(target_os = "linux", target_vendor = "apple")))] -pub fn main() { - eprintln!("This platform is not supported") +#[tokio::main(flavor = "current_thread")] +async fn main() { + lol().await.unwrap(); } diff --git a/burrow/src/tracing.rs b/burrow/src/tracing.rs deleted file mode 100644 index 861b41f..0000000 --- a/burrow/src/tracing.rs +++ /dev/null @@ -1,64 +0,0 @@ -use std::sync::Once; - -use tracing::{error, info}; -use tracing_subscriber::{ - layer::{Layer, SubscriberExt}, - EnvFilter, - Registry, -}; - -static TRACING: Once = Once::new(); - -pub fn initialize() { - TRACING.call_once(|| { - if let Err(e) = tracing_log::LogTracer::init() { - error!("Failed to initialize LogTracer: {}", e); - } - - #[cfg(target_os = "windows")] - let system_log = Some(tracing_subscriber::fmt::layer()); - - #[cfg(target_os = "linux")] - let system_log = match tracing_journald::layer() { - Ok(layer) => Some(layer), - Err(e) => { - if e.kind() != std::io::ErrorKind::NotFound { - error!("Failed to initialize journald: {}", e); - } - None - } - }; - - #[cfg(target_vendor = "apple")] - let system_log = Some(tracing_oslog::OsLogger::new( - "com.hackclub.burrow", - "tracing", - )); - - let stderr = (console::user_attended_stderr() || system_log.is_none()).then(|| { - tracing_subscriber::fmt::layer() - .with_level(true) - .with_writer(std::io::stderr) - .with_line_number(true) - .compact() - .with_filter(EnvFilter::from_default_env()) - }); - - let subscriber = Registry::default().with(stderr).with(system_log); - - #[cfg(feature = "tokio-console")] - let subscriber = subscriber.with( - console_subscriber::spawn().with_filter( - EnvFilter::from_default_env() - .add_directive("tokio=trace".parse().unwrap()) - .add_directive("runtime=trace".parse().unwrap()), - ), - ); - - if let Err(e) = tracing::subscriber::set_global_default(subscriber) { - error!("Failed to initialize logging: {}", e); - } - - info!("Initialized logging") - }); -} diff --git a/burrow/src/wireguard/config.rs b/burrow/src/wireguard/config.rs deleted file mode 100644 index 5766675..0000000 --- a/burrow/src/wireguard/config.rs +++ /dev/null @@ -1,199 +0,0 @@ -use std::{net::ToSocketAddrs, str::FromStr}; - -use anyhow::{anyhow, Error, Result}; -use base64::{engine::general_purpose, Engine}; -use fehler::throws; -use ini::{Ini, Properties}; -use ip_network::IpNetwork; -use serde::{Deserialize, Serialize}; -use x25519_dalek::{PublicKey, StaticSecret}; - -use super::inifield::IniField; -use crate::wireguard::{Interface as WgInterface, Peer as WgPeer}; - -#[throws] -fn parse_key(string: &str) -> [u8; 32] { - let value = general_purpose::STANDARD.decode(string)?; - let mut key = [0u8; 32]; - key.copy_from_slice(&value[..]); - key -} - -#[throws] -fn parse_secret_key(string: &str) -> StaticSecret { - let key = parse_key(string)?; - StaticSecret::from(key) -} - -#[throws] -fn parse_public_key(string: &str) -> PublicKey { - let key = parse_key(string)?; - PublicKey::from(key) -} - -/// A raw version of Peer Config that can be used later to reflect configuration files. -/// This should be later converted to a `WgPeer`. -/// Refers to https://github.com/pirate/wireguard-docs?tab=readme-ov-file#overview -#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] -pub struct Peer { - pub public_key: String, - pub preshared_key: Option, - pub allowed_ips: Vec, - pub endpoint: String, - pub persistent_keepalive: Option, - pub name: Option, -} - -#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] -pub struct Interface { - pub private_key: String, - pub address: Vec, - pub listen_port: Option, - pub dns: Vec, - pub mtu: Option, -} - -#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] -pub struct Config { - #[serde(rename = "Peer")] - pub peers: Vec, - pub interface: Interface, // Support for multiple interfaces? -} - -impl TryFrom for WgInterface { - type Error = anyhow::Error; - - fn try_from(cfig: Config) -> Result { - let sk = parse_secret_key(&cfig.interface.private_key)?; - let wg_peers: Vec = cfig - .peers - .iter() - .map(|p| { - Ok(WgPeer { - private_key: sk.clone(), - public_key: parse_public_key(&p.public_key)?, - endpoint: p - .endpoint - .to_socket_addrs()? - .find(|sock| sock.is_ipv4()) - .ok_or(anyhow!("DNS Lookup Fails!"))?, - preshared_key: match &p.preshared_key { - None => Ok(None), - Some(k) => parse_key(k).map(Some), - }?, - allowed_ips: p - .allowed_ips - .iter() - .map(|ip_addr| { - IpNetwork::from_str(ip_addr) - .map_err(|e| anyhow!("Error parsing IP Network {}: {}", ip_addr, e)) - }) - .collect::>>()?, - }) - }) - .collect::>>()?; - WgInterface::new(wg_peers) - } -} - -impl Default for Config { - fn default() -> Self { - Self { - interface: Interface { - private_key: "OEPVdomeLTxTIBvv3TYsJRge0Hp9NMiY0sIrhT8OWG8=".into(), - address: vec!["10.13.13.2/24".into()], - listen_port: Some(51820), - dns: Default::default(), - mtu: Default::default(), - }, - peers: vec![Peer { - endpoint: "wg.burrow.rs:51820".into(), - allowed_ips: vec!["8.8.8.8/32".into(), "0.0.0.0/0".into()], - public_key: "8GaFjVO6c4luCHG4ONO+1bFG8tO+Zz5/Gy+Geht1USM=".into(), - preshared_key: Some("ha7j4BjD49sIzyF9SNlbueK0AMHghlj6+u0G3bzC698=".into()), - persistent_keepalive: Default::default(), - name: Default::default(), - }], - } - } -} - -fn props_get(props: &Properties, key: &str) -> Result -where - T: TryFrom, -{ - IniField::try_from(props.get(key))?.try_into() -} - -impl TryFrom<&Properties> for Interface { - type Error = anyhow::Error; - - fn try_from(props: &Properties) -> Result { - Ok(Self { - private_key: props_get(props, "PrivateKey")?, - address: props_get(props, "Address")?, - listen_port: props_get(props, "ListenPort")?, - dns: props_get(props, "DNS")?, - mtu: props_get(props, "MTU")?, - }) - } -} - -impl TryFrom<&Properties> for Peer { - type Error = anyhow::Error; - - fn try_from(props: &Properties) -> Result { - Ok(Self { - public_key: props_get(props, "PublicKey")?, - preshared_key: props_get(props, "PresharedKey")?, - allowed_ips: props_get(props, "AllowedIPs")?, - endpoint: props_get(props, "Endpoint")?, - persistent_keepalive: props_get(props, "PersistentKeepalive")?, - name: props_get(props, "Name")?, - }) - } -} - -impl Config { - pub fn from_toml(toml: &str) -> Result { - toml::from_str(toml).map_err(Into::into) - } - - pub fn from_ini(ini: &str) -> Result { - let ini = Ini::load_from_str(ini)?; - let interface = ini - .section(Some("Interface")) - .ok_or(anyhow!("Interface section not found"))?; - let peers = ini.section_all(Some("Peer")); - Ok(Self { - interface: Interface::try_from(interface)?, - peers: peers - .into_iter() - .map(|v| Peer::try_from(v)) - .collect::>>()?, - }) - } - - pub fn from_content_fmt(content: &str, fmt: &str) -> Result { - match fmt { - "toml" => Self::from_toml(content), - "ini" | "conf" => Self::from_ini(content), - _ => Err(anyhow::anyhow!("Unsupported format: {}", fmt)), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn tst_config_toml() { - let cfig = Config::default(); - let toml = toml::to_string(&cfig).unwrap(); - println!("{}", &toml); - insta::assert_snapshot!(toml); - let cfig2: Config = toml::from_str(&toml).unwrap(); - assert_eq!(cfig, cfig2); - } -} diff --git a/burrow/src/wireguard/iface.rs b/burrow/src/wireguard/iface.rs deleted file mode 100755 index 321801b..0000000 --- a/burrow/src/wireguard/iface.rs +++ /dev/null @@ -1,232 +0,0 @@ -use std::{net::IpAddr, ops::Deref, sync::Arc}; - -use anyhow::Error; -use fehler::throws; -use futures::future::join_all; -use ip_network_table::IpNetworkTable; -use tokio::sync::{Notify, RwLock}; -use tracing::{debug, error}; -use tun::tokio::TunInterface; - -use super::{noise::Tunnel, Peer, PeerPcb}; - -pub struct IndexedPcbs { - pcbs: Vec>, - allowed_ips: IpNetworkTable, -} - -impl Default for IndexedPcbs { - fn default() -> Self { - Self::new() - } -} - -impl IndexedPcbs { - pub fn new() -> Self { - Self { - pcbs: vec![], - allowed_ips: IpNetworkTable::new(), - } - } - - pub fn insert(&mut self, pcb: PeerPcb) { - let idx: usize = self.pcbs.len(); - for allowed_ip in pcb.allowed_ips.iter() { - self.allowed_ips.insert(*allowed_ip, idx); - } - self.pcbs.insert(idx, Arc::new(pcb)); - } - - pub fn find(&self, addr: IpAddr) -> Option { - let (_, &idx) = self.allowed_ips.longest_match(addr)?; - Some(idx) - } -} - -impl FromIterator for IndexedPcbs { - fn from_iter>(iter: I) -> Self { - iter.into_iter().fold(Self::new(), |mut acc, pcb| { - acc.insert(pcb); - acc - }) - } -} - -enum IfaceStatus { - Running, - Idle, -} - -pub struct Interface { - pub tun: Arc>>, - pub pcbs: Arc, - status: Arc>, - stop_notifier: Arc, -} - -async fn is_running(status: Arc>) -> bool { - let st = status.read().await; - matches!(st.deref(), IfaceStatus::Running) -} - -impl Interface { - #[throws] - pub fn new>(peers: I) -> Self { - let pcbs: IndexedPcbs = peers - .into_iter() - .map(PeerPcb::new) - .collect::>()?; - - let pcbs = Arc::new(pcbs); - Self { - pcbs, - tun: Arc::new(RwLock::new(None)), - status: Arc::new(RwLock::new(IfaceStatus::Idle)), - stop_notifier: Arc::new(Notify::new()), - } - } - - pub async fn set_tun(&self, tun: TunInterface) { - debug!("Setting tun interface"); - self.tun.write().await.replace(tun); - let mut st = self.status.write().await; - *st = IfaceStatus::Running; - } - - pub async fn set_tun_ref(&mut self, tun: Arc>>) { - self.tun = tun; - let mut st = self.status.write().await; - *st = IfaceStatus::Running; - } - - pub fn get_tun(&self) -> Arc>> { - self.tun.clone() - } - - pub async fn remove_tun(&self) { - let mut st = self.status.write().await; - self.stop_notifier.notify_waiters(); - *st = IfaceStatus::Idle; - } - - pub async fn run(&self) -> anyhow::Result<()> { - let pcbs = self.pcbs.clone(); - let tun = self.tun.clone(); - let status = self.status.clone(); - let stop_notifier = self.stop_notifier.clone(); - log::info!("Starting interface"); - - let outgoing = async move { - while is_running(status.clone()).await { - let mut buf = [0u8; 3000]; - - let src = { - let t = tun.read().await; - let Some(_tun) = t.as_ref() else { - continue; - }; - tokio::select! { - _ = stop_notifier.notified() => continue, - pkg = _tun.recv(&mut buf[..]) => match pkg { - Ok(len) => &buf[..len], - Err(e) => { - error!("Failed to read from interface: {}", e); - continue - } - }, - } - }; - - let dst_addr = match Tunnel::dst_address(src) { - Some(addr) => addr, - None => { - debug!("No destination found"); - continue; - } - }; - - debug!("Routing packet to {}", dst_addr); - - let Some(idx) = pcbs.find(dst_addr) else { - continue - }; - - debug!("Found peer:{}", idx); - - match pcbs.pcbs[idx].send(src).await { - Ok(..) => { - let addr = pcbs.pcbs[idx].endpoint; - debug!("Sent packet to peer {}", addr); - } - Err(e) => { - log::error!("Failed to send packet {}", e); - continue; - } - }; - } - }; - - let mut tsks = vec![]; - let tun = self.tun.clone(); - let outgoing = tokio::task::spawn(outgoing); - tsks.push(outgoing); - debug!("preparing to spawn read tasks"); - - { - let pcbs = &self.pcbs; - for i in 0..pcbs.pcbs.len() { - debug!("spawning read task for peer {}", i); - let pcb = pcbs.pcbs[i].clone(); - let tun = tun.clone(); - let main_tsk = async move { - if let Err(e) = pcb.open_if_closed().await { - log::error!("failed to open pcb: {}", e); - return; - } - let r2 = pcb.run(tun).await; - if let Err(e) = r2 { - log::error!("failed to run pcb: {}", e); - } else { - debug!("pcb ran successfully"); - } - }; - - let pcb = pcbs.pcbs[i].clone(); - let status = self.status.clone(); - let update_timers_tsk = async move { - let mut buf = [0u8; 65535]; - while is_running(status.clone()).await { - tokio::time::sleep(tokio::time::Duration::from_millis(250)).await; - match pcb.update_timers(&mut buf).await { - Ok(..) => (), - Err(e) => { - error!("Failed to update timers: {}", e); - return; - } - } - } - }; - - let pcb = pcbs.pcbs[i].clone(); - let status = self.status.clone(); - let reset_rate_limiter_tsk = async move { - while is_running(status.clone()).await { - tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - pcb.reset_rate_limiter().await; - } - }; - tsks.extend(vec![ - tokio::spawn(main_tsk), - tokio::spawn(update_timers_tsk), - tokio::spawn(reset_rate_limiter_tsk), - ]); - debug!("task made.."); - } - debug!("spawned read tasks"); - } - debug!("preparing to join.."); - join_all(tsks).await; - debug!("joined!"); - Ok(()) - } -} diff --git a/burrow/src/wireguard/inifield.rs b/burrow/src/wireguard/inifield.rs deleted file mode 100644 index 946868d..0000000 --- a/burrow/src/wireguard/inifield.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::str::FromStr; - -use anyhow::{Error, Result}; - -pub struct IniField(String); - -impl FromStr for IniField { - type Err = Error; - - fn from_str(s: &str) -> Result { - Ok(Self(s.to_string())) - } -} - -impl TryFrom for Vec { - type Error = Error; - - fn try_from(field: IniField) -> Result { - Ok(field.0.split(',').map(|s| s.trim().to_string()).collect()) - } -} - -impl TryFrom for u32 { - type Error = Error; - - fn try_from(value: IniField) -> Result { - value.0.parse().map_err(Error::from) - } -} - -impl TryFrom for Option { - type Error = Error; - - fn try_from(value: IniField) -> Result { - if value.0.is_empty() { - Ok(None) - } else { - value.0.parse().map(Some).map_err(Error::from) - } - } -} - -impl TryFrom for String { - type Error = Error; - - fn try_from(value: IniField) -> Result { - Ok(value.0) - } -} - -impl TryFrom for Option { - type Error = Error; - - fn try_from(value: IniField) -> Result { - if value.0.is_empty() { - Ok(None) - } else { - Ok(Some(value.0)) - } - } -} - -impl TryFrom> for IniField -where - T: ToString, -{ - type Error = Error; - - fn try_from(value: Option) -> Result { - Ok(match value { - Some(v) => Self(v.to_string()), - None => Self(String::new()), - }) - } -} - -impl IniField { - fn new(value: &str) -> Self { - Self(value.to_string()) - } -} diff --git a/burrow/src/wireguard/mod.rs b/burrow/src/wireguard/mod.rs deleted file mode 100755 index cfb4585..0000000 --- a/burrow/src/wireguard/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub mod config; -mod iface; -mod inifield; -mod noise; -mod pcb; -mod peer; - -pub use config::Config; -pub use iface::Interface; -pub use pcb::PeerPcb; -pub use peer::Peer; diff --git a/burrow/src/wireguard/noise/errors.rs b/burrow/src/wireguard/noise/errors.rs deleted file mode 100755 index e196635..0000000 --- a/burrow/src/wireguard/noise/errors.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2019 Cloudflare, Inc. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -#[derive(Debug)] -pub enum WireGuardError { - DestinationBufferTooSmall, - UnexpectedPacket, - WrongIndex, - WrongKey, - InvalidTai64nTimestamp, - WrongTai64nTimestamp, - InvalidMac, - InvalidAeadTag, - InvalidCounter, - DuplicateCounter, - InvalidPacket, - NoCurrentSession, - ConnectionExpired, - UnderLoad, -} diff --git a/burrow/src/wireguard/noise/handshake.rs b/burrow/src/wireguard/noise/handshake.rs deleted file mode 100755 index 2ec0c6a..0000000 --- a/burrow/src/wireguard/noise/handshake.rs +++ /dev/null @@ -1,900 +0,0 @@ -// Copyright (c) 2019 Cloudflare, Inc. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -use std::{ - convert::TryInto, - time::{Duration, Instant, SystemTime}, -}; - -use aead::{Aead, Payload}; -use blake2::{ - digest::{FixedOutput, KeyInit}, - Blake2s256, - Blake2sMac, - Digest, -}; -use chacha20poly1305::XChaCha20Poly1305; -use rand_core::OsRng; -use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305}; - -use super::{ - errors::WireGuardError, - session::Session, - x25519, - HandshakeInit, - HandshakeResponse, - PacketCookieReply, -}; - -pub(crate) const LABEL_MAC1: &[u8; 8] = b"mac1----"; -pub(crate) const LABEL_COOKIE: &[u8; 8] = b"cookie--"; -const KEY_LEN: usize = 32; -const TIMESTAMP_LEN: usize = 12; - -// initiator.chaining_key = HASH(CONSTRUCTION) -const INITIAL_CHAIN_KEY: [u8; KEY_LEN] = [ - 96, 226, 109, 174, 243, 39, 239, 192, 46, 195, 53, 226, 160, 37, 210, 208, 22, 235, 66, 6, 248, - 114, 119, 245, 45, 56, 209, 152, 139, 120, 205, 54, -]; - -// initiator.chaining_hash = HASH(initiator.chaining_key || IDENTIFIER) -const INITIAL_CHAIN_HASH: [u8; KEY_LEN] = [ - 34, 17, 179, 97, 8, 26, 197, 102, 105, 18, 67, 219, 69, 138, 213, 50, 45, 156, 108, 102, 34, - 147, 232, 183, 14, 225, 156, 101, 186, 7, 158, 243, -]; - -#[inline] -pub(crate) fn b2s_hash(data1: &[u8], data2: &[u8]) -> [u8; 32] { - let mut hash = Blake2s256::new(); - hash.update(data1); - hash.update(data2); - hash.finalize().into() -} - -#[inline] -/// RFC 2401 HMAC+Blake2s, not to be confused with *keyed* Blake2s -pub(crate) fn b2s_hmac(key: &[u8], data1: &[u8]) -> [u8; 32] { - use blake2::digest::Update; - type HmacBlake2s = hmac::SimpleHmac; - let mut hmac = HmacBlake2s::new_from_slice(key).unwrap(); - hmac.update(data1); - hmac.finalize_fixed().into() -} - -#[inline] -/// Like b2s_hmac, but chain data1 and data2 together -pub(crate) fn b2s_hmac2(key: &[u8], data1: &[u8], data2: &[u8]) -> [u8; 32] { - use blake2::digest::Update; - type HmacBlake2s = hmac::SimpleHmac; - let mut hmac = HmacBlake2s::new_from_slice(key).unwrap(); - hmac.update(data1); - hmac.update(data2); - hmac.finalize_fixed().into() -} - -#[inline] -pub(crate) fn b2s_keyed_mac_16(key: &[u8], data1: &[u8]) -> [u8; 16] { - let mut hmac = Blake2sMac::new_from_slice(key).unwrap(); - blake2::digest::Update::update(&mut hmac, data1); - hmac.finalize_fixed().into() -} - -#[inline] -pub(crate) fn b2s_keyed_mac_16_2(key: &[u8], data1: &[u8], data2: &[u8]) -> [u8; 16] { - let mut hmac = Blake2sMac::new_from_slice(key).unwrap(); - blake2::digest::Update::update(&mut hmac, data1); - blake2::digest::Update::update(&mut hmac, data2); - hmac.finalize_fixed().into() -} - -pub(crate) fn b2s_mac_24(key: &[u8], data1: &[u8]) -> [u8; 24] { - let mut hmac = Blake2sMac::new_from_slice(key).unwrap(); - blake2::digest::Update::update(&mut hmac, data1); - hmac.finalize_fixed().into() -} - -#[inline] -/// This wrapper involves an extra copy and MAY BE SLOWER -fn aead_chacha20_seal(ciphertext: &mut [u8], key: &[u8], counter: u64, data: &[u8], aad: &[u8]) { - let mut nonce: [u8; 12] = [0; 12]; - nonce[4..12].copy_from_slice(&counter.to_le_bytes()); - - aead_chacha20_seal_inner(ciphertext, key, nonce, data, aad) -} - -#[inline] -fn aead_chacha20_seal_inner( - ciphertext: &mut [u8], - key: &[u8], - nonce: [u8; 12], - data: &[u8], - aad: &[u8], -) { - let key = LessSafeKey::new(UnboundKey::new(&CHACHA20_POLY1305, key).unwrap()); - - ciphertext[..data.len()].copy_from_slice(data); - - let tag = key - .seal_in_place_separate_tag( - Nonce::assume_unique_for_key(nonce), - Aad::from(aad), - &mut ciphertext[..data.len()], - ) - .unwrap(); - - ciphertext[data.len()..].copy_from_slice(tag.as_ref()); -} - -#[inline] -/// This wrapper involves an extra copy and MAY BE SLOWER -fn aead_chacha20_open( - buffer: &mut [u8], - key: &[u8], - counter: u64, - data: &[u8], - aad: &[u8], -) -> Result<(), WireGuardError> { - let mut nonce: [u8; 12] = [0; 12]; - nonce[4..].copy_from_slice(&counter.to_le_bytes()); - aead_chacha20_open_inner(buffer, key, nonce, data, aad) - .map_err(|_| WireGuardError::InvalidAeadTag)?; - Ok(()) -} - -#[inline] -fn aead_chacha20_open_inner( - buffer: &mut [u8], - key: &[u8], - nonce: [u8; 12], - data: &[u8], - aad: &[u8], -) -> Result<(), ring::error::Unspecified> { - let key = LessSafeKey::new(UnboundKey::new(&CHACHA20_POLY1305, key).unwrap()); - - let mut inner_buffer = data.to_owned(); - - let plaintext = key.open_in_place( - Nonce::assume_unique_for_key(nonce), - Aad::from(aad), - &mut inner_buffer, - )?; - - buffer.copy_from_slice(plaintext); - - Ok(()) -} - -#[derive(Debug)] -/// This struct represents a 12 byte [Tai64N](https://cr.yp.to/libtai/tai64.html) timestamp -struct Tai64N { - secs: u64, - nano: u32, -} - -#[derive(Debug)] -/// This struct computes a [Tai64N](https://cr.yp.to/libtai/tai64.html) timestamp from current system time -struct TimeStamper { - duration_at_start: Duration, - instant_at_start: Instant, -} - -impl TimeStamper { - /// Create a new TimeStamper - pub fn new() -> TimeStamper { - TimeStamper { - duration_at_start: SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap(), - instant_at_start: Instant::now(), - } - } - - /// Take time reading and generate a 12 byte timestamp - pub fn stamp(&self) -> [u8; 12] { - const TAI64_BASE: u64 = (1u64 << 62) + 37; - let mut ext_stamp = [0u8; 12]; - let stamp = Instant::now().duration_since(self.instant_at_start) + self.duration_at_start; - ext_stamp[0..8].copy_from_slice(&(stamp.as_secs() + TAI64_BASE).to_be_bytes()); - ext_stamp[8..12].copy_from_slice(&stamp.subsec_nanos().to_be_bytes()); - ext_stamp - } -} - -impl Tai64N { - /// A zeroed out timestamp - fn zero() -> Tai64N { - Tai64N { secs: 0, nano: 0 } - } - - /// Parse a timestamp from a 12 byte u8 slice - fn parse(buf: &[u8; 12]) -> Result { - if buf.len() < 12 { - return Err(WireGuardError::InvalidTai64nTimestamp) - } - - let (sec_bytes, nano_bytes) = buf.split_at(std::mem::size_of::()); - let secs = u64::from_be_bytes(sec_bytes.try_into().unwrap()); - let nano = u32::from_be_bytes(nano_bytes.try_into().unwrap()); - - // WireGuard does not actually expect tai64n timestamp, just monotonically - // increasing one if secs < (1u64 << 62) || secs >= (1u64 << 63) { - // return Err(WireGuardError::InvalidTai64nTimestamp); - //}; - // if nano >= 1_000_000_000 { - // return Err(WireGuardError::InvalidTai64nTimestamp); - //} - - Ok(Tai64N { secs, nano }) - } - - /// Check if this timestamp represents a time that is chronologically after - /// the time represented by the other timestamp - pub fn after(&self, other: &Tai64N) -> bool { - (self.secs > other.secs) || ((self.secs == other.secs) && (self.nano > other.nano)) - } -} - -/// Parameters used by the noise protocol -struct NoiseParams { - /// Our static public key - static_public: x25519::PublicKey, - /// Our static private key - static_private: x25519::StaticSecret, - /// Static public key of the other party - peer_static_public: x25519::PublicKey, - /// A shared key = DH(static_private, peer_static_public) - static_shared: x25519::SharedSecret, - /// A pre-computation of HASH("mac1----", peer_static_public) for this peer - sending_mac1_key: [u8; KEY_LEN], - /// An optional preshared key - preshared_key: Option<[u8; KEY_LEN]>, -} - -impl std::fmt::Debug for NoiseParams { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("NoiseParams") - .field("static_public", &self.static_public) - .field("static_private", &"") - .field("peer_static_public", &self.peer_static_public) - .field("static_shared", &"") - .field("sending_mac1_key", &self.sending_mac1_key) - .field("preshared_key", &self.preshared_key) - .finish() - } -} - -struct HandshakeInitSentState { - local_index: u32, - hash: [u8; KEY_LEN], - chaining_key: [u8; KEY_LEN], - ephemeral_private: x25519::ReusableSecret, - time_sent: Instant, -} - -impl std::fmt::Debug for HandshakeInitSentState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("HandshakeInitSentState") - .field("local_index", &self.local_index) - .field("hash", &self.hash) - .field("chaining_key", &self.chaining_key) - .field("ephemeral_private", &"") - .field("time_sent", &self.time_sent) - .finish() - } -} - -#[derive(Debug)] -enum HandshakeState { - /// No handshake in process - None, - /// We initiated the handshake - InitSent(HandshakeInitSentState), - /// Handshake initiated by peer - InitReceived { - hash: [u8; KEY_LEN], - chaining_key: [u8; KEY_LEN], - peer_ephemeral_public: x25519::PublicKey, - peer_index: u32, - }, - /// Handshake was established too long ago (implies no handshake is in - /// progress) - Expired, -} - -#[derive(Debug)] -pub struct Handshake { - params: NoiseParams, - /// Index of the next session - next_index: u32, - /// Allow to have two outgoing handshakes in flight, because sometimes we - /// may receive a delayed response to a handshake with bad networks - previous: HandshakeState, - /// Current handshake state - state: HandshakeState, - cookies: Cookies, - /// The timestamp of the last handshake we received - last_handshake_timestamp: Tai64N, - // TODO: make TimeStamper a singleton - stamper: TimeStamper, - pub(super) last_rtt: Option, -} - -#[derive(Default, Debug)] -struct Cookies { - last_mac1: Option<[u8; 16]>, - index: u32, - write_cookie: Option<[u8; 16]>, -} - -#[derive(Debug)] -pub struct HalfHandshake { - pub peer_index: u32, - pub peer_static_public: [u8; 32], -} - -pub fn parse_handshake_anon( - static_private: &x25519::StaticSecret, - static_public: &x25519::PublicKey, - packet: &HandshakeInit, -) -> Result { - let peer_index = packet.sender_idx; - // initiator.chaining_key = HASH(CONSTRUCTION) - let mut chaining_key = INITIAL_CHAIN_KEY; - // initiator.hash = HASH(HASH(initiator.chaining_key || IDENTIFIER) || - // responder.static_public) - let mut hash = INITIAL_CHAIN_HASH; - hash = b2s_hash(&hash, static_public.as_bytes()); - // msg.unencrypted_ephemeral = DH_PUBKEY(initiator.ephemeral_private) - let peer_ephemeral_public = x25519::PublicKey::from(*packet.unencrypted_ephemeral); - // initiator.hash = HASH(initiator.hash || msg.unencrypted_ephemeral) - hash = b2s_hash(&hash, peer_ephemeral_public.as_bytes()); - // temp = HMAC(initiator.chaining_key, msg.unencrypted_ephemeral) - // initiator.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac( - &b2s_hmac(&chaining_key, peer_ephemeral_public.as_bytes()), - &[0x01], - ); - // temp = HMAC(initiator.chaining_key, DH(initiator.ephemeral_private, - // responder.static_public)) - let ephemeral_shared = static_private.diffie_hellman(&peer_ephemeral_public); - let temp = b2s_hmac(&chaining_key, &ephemeral_shared.to_bytes()); - // initiator.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // key = HMAC(temp, initiator.chaining_key || 0x2) - let key = b2s_hmac2(&temp, &chaining_key, &[0x02]); - - let mut peer_static_public = [0u8; KEY_LEN]; - // msg.encrypted_static = AEAD(key, 0, initiator.static_public, initiator.hash) - aead_chacha20_open( - &mut peer_static_public, - &key, - 0, - packet.encrypted_static, - &hash, - )?; - - Ok(HalfHandshake { peer_index, peer_static_public }) -} - -impl NoiseParams { - /// New noise params struct from our secret key, peers public key, and - /// optional preshared key - fn new( - static_private: x25519::StaticSecret, - static_public: x25519::PublicKey, - peer_static_public: x25519::PublicKey, - preshared_key: Option<[u8; 32]>, - ) -> Result { - let static_shared = static_private.diffie_hellman(&peer_static_public); - - let initial_sending_mac_key = b2s_hash(LABEL_MAC1, peer_static_public.as_bytes()); - - Ok(NoiseParams { - static_public, - static_private, - peer_static_public, - static_shared, - sending_mac1_key: initial_sending_mac_key, - preshared_key, - }) - } - - /// Set a new private key - fn set_static_private( - &mut self, - static_private: x25519::StaticSecret, - static_public: x25519::PublicKey, - ) -> Result<(), WireGuardError> { - // Check that the public key indeed matches the private key - let check_key = x25519::PublicKey::from(&static_private); - assert_eq!(check_key.as_bytes(), static_public.as_bytes()); - - self.static_private = static_private; - self.static_public = static_public; - - self.static_shared = self.static_private.diffie_hellman(&self.peer_static_public); - Ok(()) - } -} - -impl Handshake { - pub(crate) fn new( - static_private: x25519::StaticSecret, - static_public: x25519::PublicKey, - peer_static_public: x25519::PublicKey, - global_idx: u32, - preshared_key: Option<[u8; 32]>, - ) -> Result { - let params = NoiseParams::new( - static_private, - static_public, - peer_static_public, - preshared_key, - )?; - - Ok(Handshake { - params, - next_index: global_idx, - previous: HandshakeState::None, - state: HandshakeState::None, - last_handshake_timestamp: Tai64N::zero(), - stamper: TimeStamper::new(), - cookies: Default::default(), - last_rtt: None, - }) - } - - pub(crate) fn is_in_progress(&self) -> bool { - !matches!(self.state, HandshakeState::None | HandshakeState::Expired) - } - - pub(crate) fn timer(&self) -> Option { - match self.state { - HandshakeState::InitSent(HandshakeInitSentState { time_sent, .. }) => Some(time_sent), - _ => None, - } - } - - pub(crate) fn set_expired(&mut self) { - self.previous = HandshakeState::Expired; - self.state = HandshakeState::Expired; - } - - pub(crate) fn is_expired(&self) -> bool { - matches!(self.state, HandshakeState::Expired) - } - - pub(crate) fn has_cookie(&self) -> bool { - self.cookies.write_cookie.is_some() - } - - pub(crate) fn clear_cookie(&mut self) { - self.cookies.write_cookie = None; - } - - // The index used is 24 bits for peer index, allowing for 16M active peers per - // server and 8 bits for cyclic session index - fn inc_index(&mut self) -> u32 { - let index = self.next_index; - let idx8 = index as u8; - self.next_index = (index & !0xff) | u32::from(idx8.wrapping_add(1)); - self.next_index - } - - pub(crate) fn set_static_private( - &mut self, - private_key: x25519::StaticSecret, - public_key: x25519::PublicKey, - ) -> Result<(), WireGuardError> { - self.params.set_static_private(private_key, public_key) - } - - pub(super) fn receive_handshake_initialization<'a>( - &mut self, - packet: HandshakeInit, - dst: &'a mut [u8], - ) -> Result<(&'a mut [u8], Session), WireGuardError> { - // initiator.chaining_key = HASH(CONSTRUCTION) - let mut chaining_key = INITIAL_CHAIN_KEY; - // initiator.hash = HASH(HASH(initiator.chaining_key || IDENTIFIER) || - // responder.static_public) - let mut hash = INITIAL_CHAIN_HASH; - hash = b2s_hash(&hash, self.params.static_public.as_bytes()); - // msg.sender_index = little_endian(initiator.sender_index) - let peer_index = packet.sender_idx; - // msg.unencrypted_ephemeral = DH_PUBKEY(initiator.ephemeral_private) - let peer_ephemeral_public = x25519::PublicKey::from(*packet.unencrypted_ephemeral); - // initiator.hash = HASH(initiator.hash || msg.unencrypted_ephemeral) - hash = b2s_hash(&hash, peer_ephemeral_public.as_bytes()); - // temp = HMAC(initiator.chaining_key, msg.unencrypted_ephemeral) - // initiator.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac( - &b2s_hmac(&chaining_key, peer_ephemeral_public.as_bytes()), - &[0x01], - ); - // temp = HMAC(initiator.chaining_key, DH(initiator.ephemeral_private, - // responder.static_public)) - let ephemeral_shared = self - .params - .static_private - .diffie_hellman(&peer_ephemeral_public); - let temp = b2s_hmac(&chaining_key, &ephemeral_shared.to_bytes()); - // initiator.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // key = HMAC(temp, initiator.chaining_key || 0x2) - let key = b2s_hmac2(&temp, &chaining_key, &[0x02]); - - let mut peer_static_public_decrypted = [0u8; KEY_LEN]; - // msg.encrypted_static = AEAD(key, 0, initiator.static_public, initiator.hash) - aead_chacha20_open( - &mut peer_static_public_decrypted, - &key, - 0, - packet.encrypted_static, - &hash, - )?; - - ring::constant_time::verify_slices_are_equal( - self.params.peer_static_public.as_bytes(), - &peer_static_public_decrypted, - ) - .map_err(|_| WireGuardError::WrongKey)?; - - // initiator.hash = HASH(initiator.hash || msg.encrypted_static) - hash = b2s_hash(&hash, packet.encrypted_static); - // temp = HMAC(initiator.chaining_key, DH(initiator.static_private, - // responder.static_public)) - let temp = b2s_hmac(&chaining_key, self.params.static_shared.as_bytes()); - // initiator.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // key = HMAC(temp, initiator.chaining_key || 0x2) - let key = b2s_hmac2(&temp, &chaining_key, &[0x02]); - // msg.encrypted_timestamp = AEAD(key, 0, TAI64N(), initiator.hash) - let mut timestamp = [0u8; TIMESTAMP_LEN]; - aead_chacha20_open(&mut timestamp, &key, 0, packet.encrypted_timestamp, &hash)?; - - let timestamp = Tai64N::parse(×tamp)?; - if !timestamp.after(&self.last_handshake_timestamp) { - // Possibly a replay - return Err(WireGuardError::WrongTai64nTimestamp) - } - self.last_handshake_timestamp = timestamp; - - // initiator.hash = HASH(initiator.hash || msg.encrypted_timestamp) - hash = b2s_hash(&hash, packet.encrypted_timestamp); - - self.previous = std::mem::replace(&mut self.state, HandshakeState::InitReceived { - chaining_key, - hash, - peer_ephemeral_public, - peer_index, - }); - - self.format_handshake_response(dst) - } - - pub(super) fn receive_handshake_response( - &mut self, - packet: HandshakeResponse, - ) -> Result { - // Check if there is a handshake awaiting a response and return the correct one - let (state, is_previous) = match (&self.state, &self.previous) { - (HandshakeState::InitSent(s), _) if s.local_index == packet.receiver_idx => (s, false), - (_, HandshakeState::InitSent(s)) if s.local_index == packet.receiver_idx => (s, true), - _ => return Err(WireGuardError::UnexpectedPacket), - }; - - let peer_index = packet.sender_idx; - let local_index = state.local_index; - - let unencrypted_ephemeral = x25519::PublicKey::from(*packet.unencrypted_ephemeral); - // msg.unencrypted_ephemeral = DH_PUBKEY(responder.ephemeral_private) - // responder.hash = HASH(responder.hash || msg.unencrypted_ephemeral) - let mut hash = b2s_hash(&state.hash, unencrypted_ephemeral.as_bytes()); - // temp = HMAC(responder.chaining_key, msg.unencrypted_ephemeral) - let temp = b2s_hmac(&state.chaining_key, unencrypted_ephemeral.as_bytes()); - // responder.chaining_key = HMAC(temp, 0x1) - let mut chaining_key = b2s_hmac(&temp, &[0x01]); - // temp = HMAC(responder.chaining_key, DH(responder.ephemeral_private, - // initiator.ephemeral_public)) - let ephemeral_shared = state - .ephemeral_private - .diffie_hellman(&unencrypted_ephemeral); - let temp = b2s_hmac(&chaining_key, &ephemeral_shared.to_bytes()); - // responder.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // temp = HMAC(responder.chaining_key, DH(responder.ephemeral_private, - // initiator.static_public)) - let temp = b2s_hmac( - &chaining_key, - &self - .params - .static_private - .diffie_hellman(&unencrypted_ephemeral) - .to_bytes(), - ); - // responder.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // temp = HMAC(responder.chaining_key, preshared_key) - let temp = b2s_hmac( - &chaining_key, - &self.params.preshared_key.unwrap_or([0u8; 32])[..], - ); - // responder.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // temp2 = HMAC(temp, responder.chaining_key || 0x2) - let temp2 = b2s_hmac2(&temp, &chaining_key, &[0x02]); - // key = HMAC(temp, temp2 || 0x3) - let key = b2s_hmac2(&temp, &temp2, &[0x03]); - // responder.hash = HASH(responder.hash || temp2) - hash = b2s_hash(&hash, &temp2); - // msg.encrypted_nothing = AEAD(key, 0, [empty], responder.hash) - aead_chacha20_open(&mut [], &key, 0, packet.encrypted_nothing, &hash)?; - - // responder.hash = HASH(responder.hash || msg.encrypted_nothing) - // hash = b2s_hash(hash, buf[ENC_NOTHING_OFF..ENC_NOTHING_OFF + - // ENC_NOTHING_SZ]); - - // Derive keys - // temp1 = HMAC(initiator.chaining_key, [empty]) - // temp2 = HMAC(temp1, 0x1) - // temp3 = HMAC(temp1, temp2 || 0x2) - // initiator.sending_key = temp2 - // initiator.receiving_key = temp3 - // initiator.sending_key_counter = 0 - // initiator.receiving_key_counter = 0 - let temp1 = b2s_hmac(&chaining_key, &[]); - let temp2 = b2s_hmac(&temp1, &[0x01]); - let temp3 = b2s_hmac2(&temp1, &temp2, &[0x02]); - - let rtt_time = Instant::now().duration_since(state.time_sent); - self.last_rtt = Some(rtt_time.as_millis() as u32); - - if is_previous { - self.previous = HandshakeState::None; - } else { - self.state = HandshakeState::None; - } - Ok(Session::new(local_index, peer_index, temp3, temp2)) - } - - pub(super) fn receive_cookie_reply( - &mut self, - packet: PacketCookieReply, - ) -> Result<(), WireGuardError> { - let mac1 = match self.cookies.last_mac1 { - Some(mac) => mac, - None => return Err(WireGuardError::UnexpectedPacket), - }; - - let local_index = self.cookies.index; - if packet.receiver_idx != local_index { - return Err(WireGuardError::WrongIndex) - } - // msg.encrypted_cookie = XAEAD(HASH(LABEL_COOKIE || responder.static_public), - // msg.nonce, cookie, last_received_msg.mac1) - let key = b2s_hash(LABEL_COOKIE, self.params.peer_static_public.as_bytes()); // TODO: pre-compute - - let payload = Payload { - aad: &mac1[0..16], - msg: packet.encrypted_cookie, - }; - let plaintext = XChaCha20Poly1305::new_from_slice(&key) - .unwrap() - .decrypt(packet.nonce.into(), payload) - .map_err(|_| WireGuardError::InvalidAeadTag)?; - - let cookie = plaintext - .try_into() - .map_err(|_| WireGuardError::InvalidPacket)?; - self.cookies.write_cookie = Some(cookie); - Ok(()) - } - - // Compute and append mac1 and mac2 to a handshake message - fn append_mac1_and_mac2<'a>( - &mut self, - local_index: u32, - dst: &'a mut [u8], - ) -> Result<&'a mut [u8], WireGuardError> { - let mac1_off = dst.len() - 32; - let mac2_off = dst.len() - 16; - - // msg.mac1 = MAC(HASH(LABEL_MAC1 || responder.static_public), - // msg[0:offsetof(msg.mac1)]) - let msg_mac1 = b2s_keyed_mac_16(&self.params.sending_mac1_key, &dst[..mac1_off]); - - dst[mac1_off..mac2_off].copy_from_slice(&msg_mac1[..]); - - // msg.mac2 = MAC(initiator.last_received_cookie, msg[0:offsetof(msg.mac2)]) - let msg_mac2: [u8; 16] = if let Some(cookie) = self.cookies.write_cookie { - b2s_keyed_mac_16(&cookie, &dst[..mac2_off]) - } else { - [0u8; 16] - }; - - dst[mac2_off..].copy_from_slice(&msg_mac2[..]); - - self.cookies.index = local_index; - self.cookies.last_mac1 = Some(msg_mac1); - Ok(dst) - } - - pub(super) fn format_handshake_initiation<'a>( - &mut self, - dst: &'a mut [u8], - ) -> Result<&'a mut [u8], WireGuardError> { - if dst.len() < super::HANDSHAKE_INIT_SZ { - return Err(WireGuardError::DestinationBufferTooSmall) - } - - let (message_type, rest) = dst.split_at_mut(4); - let (sender_index, rest) = rest.split_at_mut(4); - let (unencrypted_ephemeral, rest) = rest.split_at_mut(32); - let (encrypted_static, rest) = rest.split_at_mut(32 + 16); - let (encrypted_timestamp, _) = rest.split_at_mut(12 + 16); - - let local_index = self.inc_index(); - - // initiator.chaining_key = HASH(CONSTRUCTION) - let mut chaining_key = INITIAL_CHAIN_KEY; - // initiator.hash = HASH(HASH(initiator.chaining_key || IDENTIFIER) || - // responder.static_public) - let mut hash = INITIAL_CHAIN_HASH; - hash = b2s_hash(&hash, self.params.peer_static_public.as_bytes()); - // initiator.ephemeral_private = DH_GENERATE() - let ephemeral_private = x25519::ReusableSecret::random_from_rng(OsRng); - // msg.message_type = 1 - // msg.reserved_zero = { 0, 0, 0 } - message_type.copy_from_slice(&super::HANDSHAKE_INIT.to_le_bytes()); - // msg.sender_index = little_endian(initiator.sender_index) - sender_index.copy_from_slice(&local_index.to_le_bytes()); - // msg.unencrypted_ephemeral = DH_PUBKEY(initiator.ephemeral_private) - unencrypted_ephemeral - .copy_from_slice(x25519::PublicKey::from(&ephemeral_private).as_bytes()); - // initiator.hash = HASH(initiator.hash || msg.unencrypted_ephemeral) - hash = b2s_hash(&hash, unencrypted_ephemeral); - // temp = HMAC(initiator.chaining_key, msg.unencrypted_ephemeral) - // initiator.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&b2s_hmac(&chaining_key, unencrypted_ephemeral), &[0x01]); - // temp = HMAC(initiator.chaining_key, DH(initiator.ephemeral_private, - // responder.static_public)) - let ephemeral_shared = ephemeral_private.diffie_hellman(&self.params.peer_static_public); - let temp = b2s_hmac(&chaining_key, &ephemeral_shared.to_bytes()); - // initiator.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // key = HMAC(temp, initiator.chaining_key || 0x2) - let key = b2s_hmac2(&temp, &chaining_key, &[0x02]); - // msg.encrypted_static = AEAD(key, 0, initiator.static_public, initiator.hash) - aead_chacha20_seal( - encrypted_static, - &key, - 0, - self.params.static_public.as_bytes(), - &hash, - ); - // initiator.hash = HASH(initiator.hash || msg.encrypted_static) - hash = b2s_hash(&hash, encrypted_static); - // temp = HMAC(initiator.chaining_key, DH(initiator.static_private, - // responder.static_public)) - let temp = b2s_hmac(&chaining_key, self.params.static_shared.as_bytes()); - // initiator.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // key = HMAC(temp, initiator.chaining_key || 0x2) - let key = b2s_hmac2(&temp, &chaining_key, &[0x02]); - // msg.encrypted_timestamp = AEAD(key, 0, TAI64N(), initiator.hash) - let timestamp = self.stamper.stamp(); - aead_chacha20_seal(encrypted_timestamp, &key, 0, ×tamp, &hash); - // initiator.hash = HASH(initiator.hash || msg.encrypted_timestamp) - hash = b2s_hash(&hash, encrypted_timestamp); - - let time_now = Instant::now(); - self.previous = std::mem::replace( - &mut self.state, - HandshakeState::InitSent(HandshakeInitSentState { - local_index, - chaining_key, - hash, - ephemeral_private, - time_sent: time_now, - }), - ); - - self.append_mac1_and_mac2(local_index, &mut dst[..super::HANDSHAKE_INIT_SZ]) - } - - fn format_handshake_response<'a>( - &mut self, - dst: &'a mut [u8], - ) -> Result<(&'a mut [u8], Session), WireGuardError> { - if dst.len() < super::HANDSHAKE_RESP_SZ { - return Err(WireGuardError::DestinationBufferTooSmall) - } - - let state = std::mem::replace(&mut self.state, HandshakeState::None); - let (mut chaining_key, mut hash, peer_ephemeral_public, peer_index) = match state { - HandshakeState::InitReceived { - chaining_key, - hash, - peer_ephemeral_public, - peer_index, - } => (chaining_key, hash, peer_ephemeral_public, peer_index), - _ => { - panic!("Unexpected attempt to call send_handshake_response"); - } - }; - - let (message_type, rest) = dst.split_at_mut(4); - let (sender_index, rest) = rest.split_at_mut(4); - let (receiver_index, rest) = rest.split_at_mut(4); - let (unencrypted_ephemeral, rest) = rest.split_at_mut(32); - let (encrypted_nothing, _) = rest.split_at_mut(16); - - // responder.ephemeral_private = DH_GENERATE() - let ephemeral_private = x25519::ReusableSecret::random_from_rng(OsRng); - let local_index = self.inc_index(); - // msg.message_type = 2 - // msg.reserved_zero = { 0, 0, 0 } - message_type.copy_from_slice(&super::HANDSHAKE_RESP.to_le_bytes()); - // msg.sender_index = little_endian(responder.sender_index) - sender_index.copy_from_slice(&local_index.to_le_bytes()); - // msg.receiver_index = little_endian(initiator.sender_index) - receiver_index.copy_from_slice(&peer_index.to_le_bytes()); - // msg.unencrypted_ephemeral = DH_PUBKEY(initiator.ephemeral_private) - unencrypted_ephemeral - .copy_from_slice(x25519::PublicKey::from(&ephemeral_private).as_bytes()); - // responder.hash = HASH(responder.hash || msg.unencrypted_ephemeral) - hash = b2s_hash(&hash, unencrypted_ephemeral); - // temp = HMAC(responder.chaining_key, msg.unencrypted_ephemeral) - let temp = b2s_hmac(&chaining_key, unencrypted_ephemeral); - // responder.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // temp = HMAC(responder.chaining_key, DH(responder.ephemeral_private, - // initiator.ephemeral_public)) - let ephemeral_shared = ephemeral_private.diffie_hellman(&peer_ephemeral_public); - let temp = b2s_hmac(&chaining_key, &ephemeral_shared.to_bytes()); - // responder.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // temp = HMAC(responder.chaining_key, DH(responder.ephemeral_private, - // initiator.static_public)) - let temp = b2s_hmac( - &chaining_key, - &ephemeral_private - .diffie_hellman(&self.params.peer_static_public) - .to_bytes(), - ); - // responder.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // temp = HMAC(responder.chaining_key, preshared_key) - let temp = b2s_hmac( - &chaining_key, - &self.params.preshared_key.unwrap_or([0u8; 32])[..], - ); - // responder.chaining_key = HMAC(temp, 0x1) - chaining_key = b2s_hmac(&temp, &[0x01]); - // temp2 = HMAC(temp, responder.chaining_key || 0x2) - let temp2 = b2s_hmac2(&temp, &chaining_key, &[0x02]); - // key = HMAC(temp, temp2 || 0x3) - let key = b2s_hmac2(&temp, &temp2, &[0x03]); - // responder.hash = HASH(responder.hash || temp2) - hash = b2s_hash(&hash, &temp2); - // msg.encrypted_nothing = AEAD(key, 0, [empty], responder.hash) - aead_chacha20_seal(encrypted_nothing, &key, 0, &[], &hash); - - // Derive keys - // temp1 = HMAC(initiator.chaining_key, [empty]) - // temp2 = HMAC(temp1, 0x1) - // temp3 = HMAC(temp1, temp2 || 0x2) - // initiator.sending_key = temp2 - // initiator.receiving_key = temp3 - // initiator.sending_key_counter = 0 - // initiator.receiving_key_counter = 0 - let temp1 = b2s_hmac(&chaining_key, &[]); - let temp2 = b2s_hmac(&temp1, &[0x01]); - let temp3 = b2s_hmac2(&temp1, &temp2, &[0x02]); - - let dst = self.append_mac1_and_mac2(local_index, &mut dst[..super::HANDSHAKE_RESP_SZ])?; - - Ok((dst, Session::new(local_index, peer_index, temp2, temp3))) - } -} diff --git a/burrow/src/wireguard/noise/mod.rs b/burrow/src/wireguard/noise/mod.rs deleted file mode 100755 index aa06652..0000000 --- a/burrow/src/wireguard/noise/mod.rs +++ /dev/null @@ -1,632 +0,0 @@ -// Copyright (c) 2019 Cloudflare, Inc. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -pub mod errors; -pub mod handshake; -pub mod rate_limiter; - -mod session; -mod timers; - -use std::{ - collections::VecDeque, - convert::{TryFrom, TryInto}, - net::{IpAddr, Ipv4Addr, Ipv6Addr}, - sync::Arc, - time::Duration, -}; - -use errors::WireGuardError; -use handshake::Handshake; -use rate_limiter::RateLimiter; -use timers::{TimerName, Timers}; - -/// The default value to use for rate limiting, when no other rate limiter is -/// defined -const PEER_HANDSHAKE_RATE_LIMIT: u64 = 10; - -const IPV4_MIN_HEADER_SIZE: usize = 20; -const IPV4_LEN_OFF: usize = 2; -const IPV4_SRC_IP_OFF: usize = 12; -const IPV4_DST_IP_OFF: usize = 16; -const IPV4_IP_SZ: usize = 4; - -const IPV6_MIN_HEADER_SIZE: usize = 40; -const IPV6_LEN_OFF: usize = 4; -const IPV6_SRC_IP_OFF: usize = 8; -const IPV6_DST_IP_OFF: usize = 24; -const IPV6_IP_SZ: usize = 16; - -const IP_LEN_SZ: usize = 2; - -const MAX_QUEUE_DEPTH: usize = 256; -/// number of sessions in the ring, better keep a PoT -const N_SESSIONS: usize = 8; - -pub mod x25519 { - pub use x25519_dalek::{PublicKey, ReusableSecret, SharedSecret, StaticSecret}; -} - -#[derive(Debug)] -pub enum TunnResult<'a> { - Done, - Err(WireGuardError), - WriteToNetwork(&'a mut [u8]), - WriteToTunnelV4(&'a mut [u8], Ipv4Addr), - WriteToTunnelV6(&'a mut [u8], Ipv6Addr), -} - -impl<'a> From for TunnResult<'a> { - fn from(err: WireGuardError) -> TunnResult<'a> { - TunnResult::Err(err) - } -} - -/// Tunnel represents a point-to-point WireGuard connection -#[derive(Debug)] -pub struct Tunnel { - /// The handshake currently in progress - handshake: handshake::Handshake, - /// The N_SESSIONS most recent sessions, index is session id modulo - /// N_SESSIONS - sessions: [Option; N_SESSIONS], - /// Index of most recently used session - current: usize, - /// Queue to store blocked packets - packet_queue: VecDeque>, - /// Keeps tabs on the expiring timers - timers: timers::Timers, - tx_bytes: usize, - rx_bytes: usize, - rate_limiter: Arc, -} - -type MessageType = u32; -const HANDSHAKE_INIT: MessageType = 1; -const HANDSHAKE_RESP: MessageType = 2; -const COOKIE_REPLY: MessageType = 3; -const DATA: MessageType = 4; - -const HANDSHAKE_INIT_SZ: usize = 148; -const HANDSHAKE_RESP_SZ: usize = 92; -const COOKIE_REPLY_SZ: usize = 64; -const DATA_OVERHEAD_SZ: usize = 32; - -#[derive(Debug)] -pub struct HandshakeInit<'a> { - sender_idx: u32, - unencrypted_ephemeral: &'a [u8; 32], - encrypted_static: &'a [u8], - encrypted_timestamp: &'a [u8], -} - -#[derive(Debug)] -pub struct HandshakeResponse<'a> { - sender_idx: u32, - pub receiver_idx: u32, - unencrypted_ephemeral: &'a [u8; 32], - encrypted_nothing: &'a [u8], -} - -#[derive(Debug)] -pub struct PacketCookieReply<'a> { - pub receiver_idx: u32, - nonce: &'a [u8], - encrypted_cookie: &'a [u8], -} - -#[derive(Debug)] -pub struct PacketData<'a> { - pub receiver_idx: u32, - counter: u64, - encrypted_encapsulated_packet: &'a [u8], -} - -/// Describes a packet from network -#[derive(Debug)] -pub enum Packet<'a> { - HandshakeInit(HandshakeInit<'a>), - HandshakeResponse(HandshakeResponse<'a>), - CookieReply(PacketCookieReply<'a>), - Data(PacketData<'a>), -} - -impl Tunnel { - #[inline(always)] - pub fn parse_incoming_packet(src: &[u8]) -> Result { - if src.len() < 4 { - return Err(WireGuardError::InvalidPacket) - } - - // Checks the type, as well as the reserved zero fields - let packet_type = u32::from_le_bytes(src[0..4].try_into().unwrap()); - tracing::debug!("packet_type: {}", packet_type); - - Ok(match (packet_type, src.len()) { - (HANDSHAKE_INIT, HANDSHAKE_INIT_SZ) => Packet::HandshakeInit(HandshakeInit { - sender_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()), - unencrypted_ephemeral: <&[u8; 32] as TryFrom<&[u8]>>::try_from(&src[8..40]) - .expect("length already checked above"), - encrypted_static: &src[40..88], - encrypted_timestamp: &src[88..116], - }), - (HANDSHAKE_RESP, HANDSHAKE_RESP_SZ) => Packet::HandshakeResponse(HandshakeResponse { - sender_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()), - receiver_idx: u32::from_le_bytes(src[8..12].try_into().unwrap()), - unencrypted_ephemeral: <&[u8; 32] as TryFrom<&[u8]>>::try_from(&src[12..44]) - .expect("length already checked above"), - encrypted_nothing: &src[44..60], - }), - (COOKIE_REPLY, COOKIE_REPLY_SZ) => Packet::CookieReply(PacketCookieReply { - receiver_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()), - nonce: &src[8..32], - encrypted_cookie: &src[32..64], - }), - (DATA, DATA_OVERHEAD_SZ..=std::usize::MAX) => Packet::Data(PacketData { - receiver_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()), - counter: u64::from_le_bytes(src[8..16].try_into().unwrap()), - encrypted_encapsulated_packet: &src[16..], - }), - _ => return Err(WireGuardError::InvalidPacket), - }) - } - - pub fn is_expired(&self) -> bool { - self.handshake.is_expired() - } - - pub fn dst_address(packet: &[u8]) -> Option { - if packet.is_empty() { - return None - } - - match packet[0] >> 4 { - 4 if packet.len() >= IPV4_MIN_HEADER_SIZE => { - let addr_bytes: [u8; IPV4_IP_SZ] = packet - [IPV4_DST_IP_OFF..IPV4_DST_IP_OFF + IPV4_IP_SZ] - .try_into() - .unwrap(); - Some(IpAddr::from(addr_bytes)) - } - 6 if packet.len() >= IPV6_MIN_HEADER_SIZE => { - let addr_bytes: [u8; IPV6_IP_SZ] = packet - [IPV6_DST_IP_OFF..IPV6_DST_IP_OFF + IPV6_IP_SZ] - .try_into() - .unwrap(); - Some(IpAddr::from(addr_bytes)) - } - _ => None, - } - } - - pub fn src_address(packet: &[u8]) -> Option { - if packet.is_empty() { - return None - } - - match packet[0] >> 4 { - 4 if packet.len() >= IPV4_MIN_HEADER_SIZE => { - let addr_bytes: [u8; IPV4_IP_SZ] = packet - [IPV4_SRC_IP_OFF..IPV4_SRC_IP_OFF + IPV4_IP_SZ] - .try_into() - .unwrap(); - Some(IpAddr::from(addr_bytes)) - } - 6 if packet.len() >= IPV6_MIN_HEADER_SIZE => { - let addr_bytes: [u8; IPV6_IP_SZ] = packet - [IPV6_SRC_IP_OFF..IPV6_SRC_IP_OFF + IPV6_IP_SZ] - .try_into() - .unwrap(); - Some(IpAddr::from(addr_bytes)) - } - _ => None, - } - } - - /// Create a new tunnel using own private key and the peer public key - pub fn new( - static_private: x25519::StaticSecret, - peer_static_public: x25519::PublicKey, - preshared_key: Option<[u8; 32]>, - persistent_keepalive: Option, - index: u32, - rate_limiter: Option>, - ) -> Result { - let static_public = x25519::PublicKey::from(&static_private); - - let tunn = Tunnel { - handshake: Handshake::new( - static_private, - static_public, - peer_static_public, - index << 8, - preshared_key, - ) - .map_err(|_| "Invalid parameters")?, - sessions: Default::default(), - current: Default::default(), - tx_bytes: Default::default(), - rx_bytes: Default::default(), - - packet_queue: VecDeque::new(), - timers: Timers::new(persistent_keepalive, rate_limiter.is_none()), - - rate_limiter: rate_limiter.unwrap_or_else(|| { - Arc::new(RateLimiter::new(&static_public, PEER_HANDSHAKE_RATE_LIMIT)) - }), - }; - - Ok(tunn) - } - - /// Update the private key and clear existing sessions - pub fn set_static_private( - &mut self, - static_private: x25519::StaticSecret, - static_public: x25519::PublicKey, - rate_limiter: Option>, - ) -> Result<(), WireGuardError> { - self.timers.should_reset_rr = rate_limiter.is_none(); - self.rate_limiter = rate_limiter.unwrap_or_else(|| { - Arc::new(RateLimiter::new(&static_public, PEER_HANDSHAKE_RATE_LIMIT)) - }); - self.handshake - .set_static_private(static_private, static_public)?; - for s in &mut self.sessions { - *s = None; - } - Ok(()) - } - - /// Encapsulate a single packet from the tunnel interface. - /// Returns TunnResult. - /// - /// # Panics - /// Panics if dst buffer is too small. - /// Size of dst should be at least src.len() + 32, and no less than 148 - /// bytes. - pub fn encapsulate<'a>(&mut self, src: &[u8], dst: &'a mut [u8]) -> TunnResult<'a> { - let current = self.current; - if let Some(ref session) = self.sessions[current % N_SESSIONS] { - // Send the packet using an established session - let packet = session.format_packet_data(src, dst); - self.timer_tick(TimerName::TimeLastPacketSent); - // Exclude Keepalive packets from timer update. - if !src.is_empty() { - self.timer_tick(TimerName::TimeLastDataPacketSent); - } - self.tx_bytes += src.len(); - return TunnResult::WriteToNetwork(packet) - } - - // If there is no session, queue the packet for future retry - self.queue_packet(src); - // Initiate a new handshake if none is in progress - self.format_handshake_initiation(dst, false) - } - - /// Receives a UDP datagram from the network and parses it. - /// Returns TunnResult. - /// - /// If the result is of type TunnResult::WriteToNetwork, should repeat the - /// call with empty datagram, until TunnResult::Done is returned. If - /// batch processing packets, it is OK to defer until last - /// packet is processed. - pub fn decapsulate<'a>( - &mut self, - src_addr: Option, - datagram: &[u8], - dst: &'a mut [u8], - ) -> TunnResult<'a> { - if datagram.is_empty() { - // Indicates a repeated call - return self.send_queued_packet(dst) - } - - let mut cookie = [0u8; COOKIE_REPLY_SZ]; - let packet = match self - .rate_limiter - .verify_packet(src_addr, datagram, &mut cookie) - { - Ok(packet) => packet, - Err(TunnResult::WriteToNetwork(cookie)) => { - dst[..cookie.len()].copy_from_slice(cookie); - return TunnResult::WriteToNetwork(&mut dst[..cookie.len()]) - } - Err(TunnResult::Err(e)) => return TunnResult::Err(e), - _ => unreachable!(), - }; - - self.handle_verified_packet(packet, dst) - } - - pub fn reset_rate_limiter(&self) { - self.rate_limiter.reset_count(); - } - - pub(crate) fn handle_verified_packet<'a>( - &mut self, - packet: Packet, - dst: &'a mut [u8], - ) -> TunnResult<'a> { - match packet { - Packet::HandshakeInit(p) => self.handle_handshake_init(p, dst), - Packet::HandshakeResponse(p) => self.handle_handshake_response(p, dst), - Packet::CookieReply(p) => self.handle_cookie_reply(p), - Packet::Data(p) => self.handle_data(p, dst), - } - .unwrap_or_else(TunnResult::from) - } - - fn handle_handshake_init<'a>( - &mut self, - p: HandshakeInit, - dst: &'a mut [u8], - ) -> Result, WireGuardError> { - tracing::debug!( - message = "Received handshake_initiation", - remote_idx = p.sender_idx - ); - - let (packet, session) = self.handshake.receive_handshake_initialization(p, dst)?; - - // Store new session in ring buffer - let index = session.local_index(); - self.sessions[index % N_SESSIONS] = Some(session); - - self.timer_tick(TimerName::TimeLastPacketReceived); - self.timer_tick(TimerName::TimeLastPacketSent); - self.timer_tick_session_established(false, index); // New session established, we are not the initiator - - tracing::debug!(message = "Sending handshake_response", local_idx = index); - - Ok(TunnResult::WriteToNetwork(packet)) - } - - fn handle_handshake_response<'a>( - &mut self, - p: HandshakeResponse, - dst: &'a mut [u8], - ) -> Result, WireGuardError> { - tracing::debug!( - message = "Received handshake_response", - local_idx = p.receiver_idx, - remote_idx = p.sender_idx - ); - - let session = self.handshake.receive_handshake_response(p)?; - - let keepalive_packet = session.format_packet_data(&[], dst); - // Store new session in ring buffer - let l_idx = session.local_index(); - let index = l_idx % N_SESSIONS; - self.sessions[index] = Some(session); - - self.timer_tick(TimerName::TimeLastPacketReceived); - self.timer_tick_session_established(true, index); // New session established, we are the initiator - self.set_current_session(l_idx); - - tracing::debug!("Sending keepalive"); - - Ok(TunnResult::WriteToNetwork(keepalive_packet)) // Send a keepalive as - // a response - } - - fn handle_cookie_reply<'a>( - &mut self, - p: PacketCookieReply, - ) -> Result, WireGuardError> { - tracing::debug!( - message = "Received cookie_reply", - local_idx = p.receiver_idx - ); - - self.handshake.receive_cookie_reply(p)?; - self.timer_tick(TimerName::TimeLastPacketReceived); - self.timer_tick(TimerName::TimeCookieReceived); - - tracing::debug!("Did set cookie"); - - Ok(TunnResult::Done) - } - - /// Update the index of the currently used session, if needed - fn set_current_session(&mut self, new_idx: usize) { - let cur_idx = self.current; - if cur_idx == new_idx { - // There is nothing to do, already using this session, this is the common case - return - } - if self.sessions[cur_idx % N_SESSIONS].is_none() - || self.timers.session_timers[new_idx % N_SESSIONS] - >= self.timers.session_timers[cur_idx % N_SESSIONS] - { - self.current = new_idx; - tracing::debug!(message = "New session", session = new_idx); - } - } - - /// Decrypts a data packet, and stores the decapsulated packet in dst. - fn handle_data<'a>( - &mut self, - packet: PacketData, - dst: &'a mut [u8], - ) -> Result, WireGuardError> { - let r_idx = packet.receiver_idx as usize; - let idx = r_idx % N_SESSIONS; - - // Get the (probably) right session - let decapsulated_packet = { - let session = self.sessions[idx].as_ref(); - let session = session.ok_or_else(|| { - tracing::trace!(message = "No current session available", remote_idx = r_idx); - WireGuardError::NoCurrentSession - })?; - session.receive_packet_data(packet, dst)? - }; - - self.set_current_session(r_idx); - - self.timer_tick(TimerName::TimeLastPacketReceived); - - Ok(self.validate_decapsulated_packet(decapsulated_packet)) - } - - /// Formats a new handshake initiation message and store it in dst. If - /// force_resend is true will send a new handshake, even if a handshake - /// is already in progress (for example when a handshake times out) - pub fn format_handshake_initiation<'a>( - &mut self, - dst: &'a mut [u8], - force_resend: bool, - ) -> TunnResult<'a> { - if self.handshake.is_in_progress() && !force_resend { - return TunnResult::Done - } - - if self.handshake.is_expired() { - self.timers.clear(); - } - - let starting_new_handshake = !self.handshake.is_in_progress(); - - match self.handshake.format_handshake_initiation(dst) { - Ok(packet) => { - tracing::debug!("Sending handshake_initiation"); - - if starting_new_handshake { - self.timer_tick(TimerName::TimeLastHandshakeStarted); - } - self.timer_tick(TimerName::TimeLastPacketSent); - TunnResult::WriteToNetwork(packet) - } - Err(e) => TunnResult::Err(e), - } - } - - /// Check if an IP packet is v4 or v6, truncate to the length indicated by - /// the length field Returns the truncated packet and the source IP as - /// TunnResult - fn validate_decapsulated_packet<'a>(&mut self, packet: &'a mut [u8]) -> TunnResult<'a> { - let (computed_len, src_ip_address) = match packet.len() { - 0 => return TunnResult::Done, // This is keepalive, and not an error - _ if packet[0] >> 4 == 4 && packet.len() >= IPV4_MIN_HEADER_SIZE => { - let len_bytes: [u8; IP_LEN_SZ] = packet[IPV4_LEN_OFF..IPV4_LEN_OFF + IP_LEN_SZ] - .try_into() - .unwrap(); - let addr_bytes: [u8; IPV4_IP_SZ] = packet - [IPV4_SRC_IP_OFF..IPV4_SRC_IP_OFF + IPV4_IP_SZ] - .try_into() - .unwrap(); - ( - u16::from_be_bytes(len_bytes) as usize, - IpAddr::from(addr_bytes), - ) - } - _ if packet[0] >> 4 == 6 && packet.len() >= IPV6_MIN_HEADER_SIZE => { - let len_bytes: [u8; IP_LEN_SZ] = packet[IPV6_LEN_OFF..IPV6_LEN_OFF + IP_LEN_SZ] - .try_into() - .unwrap(); - let addr_bytes: [u8; IPV6_IP_SZ] = packet - [IPV6_SRC_IP_OFF..IPV6_SRC_IP_OFF + IPV6_IP_SZ] - .try_into() - .unwrap(); - ( - u16::from_be_bytes(len_bytes) as usize + IPV6_MIN_HEADER_SIZE, - IpAddr::from(addr_bytes), - ) - } - _ => return TunnResult::Err(WireGuardError::InvalidPacket), - }; - - if computed_len > packet.len() { - return TunnResult::Err(WireGuardError::InvalidPacket) - } - - self.timer_tick(TimerName::TimeLastDataPacketReceived); - self.rx_bytes += computed_len; - - match src_ip_address { - IpAddr::V4(addr) => TunnResult::WriteToTunnelV4(&mut packet[..computed_len], addr), - IpAddr::V6(addr) => TunnResult::WriteToTunnelV6(&mut packet[..computed_len], addr), - } - } - - /// Get a packet from the queue, and try to encapsulate it - fn send_queued_packet<'a>(&mut self, dst: &'a mut [u8]) -> TunnResult<'a> { - if let Some(packet) = self.dequeue_packet() { - match self.encapsulate(&packet, dst) { - TunnResult::Err(_) => { - // On error, return packet to the queue - self.requeue_packet(packet); - } - r => return r, - } - } - TunnResult::Done - } - - /// Push packet to the back of the queue - fn queue_packet(&mut self, packet: &[u8]) { - if self.packet_queue.len() < MAX_QUEUE_DEPTH { - // Drop if too many are already in queue - self.packet_queue.push_back(packet.to_vec()); - } - } - - /// Push packet to the front of the queue - fn requeue_packet(&mut self, packet: Vec) { - if self.packet_queue.len() < MAX_QUEUE_DEPTH { - // Drop if too many are already in queue - self.packet_queue.push_front(packet); - } - } - - fn dequeue_packet(&mut self) -> Option> { - self.packet_queue.pop_front() - } - - fn estimate_loss(&self) -> f32 { - let session_idx = self.current; - - let mut weight = 9.0; - let mut cur_avg = 0.0; - let mut total_weight = 0.0; - - for i in 0..N_SESSIONS { - if let Some(ref session) = self.sessions[(session_idx.wrapping_sub(i)) % N_SESSIONS] { - let (expected, received) = session.current_packet_cnt(); - - let loss = if expected == 0 { - 0.0 - } else { - 1.0 - received as f32 / expected as f32 - }; - - cur_avg += loss * weight; - total_weight += weight; - weight /= 3.0; - } - } - - if total_weight == 0.0 { - 0.0 - } else { - cur_avg / total_weight - } - } - - /// Return stats from the tunnel: - /// * Time since last handshake in seconds - /// * Data bytes sent - /// * Data bytes received - pub fn stats(&self) -> (Option, usize, usize, f32, Option) { - let time = self.time_since_last_handshake(); - let tx_bytes = self.tx_bytes; - let rx_bytes = self.rx_bytes; - let loss = self.estimate_loss(); - let rtt = self.handshake.last_rtt; - - (time, tx_bytes, rx_bytes, loss, rtt) - } -} diff --git a/burrow/src/wireguard/noise/rate_limiter.rs b/burrow/src/wireguard/noise/rate_limiter.rs deleted file mode 100755 index ff19efd..0000000 --- a/burrow/src/wireguard/noise/rate_limiter.rs +++ /dev/null @@ -1,212 +0,0 @@ -use std::{ - net::IpAddr, - sync::atomic::{AtomicU64, Ordering}, - time::Instant, -}; - -use aead::{generic_array::GenericArray, AeadInPlace, KeyInit}; -use chacha20poly1305::{Key, XChaCha20Poly1305}; -use parking_lot::Mutex; -use rand_core::{OsRng, RngCore}; -use ring::constant_time::verify_slices_are_equal; - -use super::{ - handshake::{ - b2s_hash, - b2s_keyed_mac_16, - b2s_keyed_mac_16_2, - b2s_mac_24, - LABEL_COOKIE, - LABEL_MAC1, - }, - HandshakeInit, - HandshakeResponse, - Packet, - TunnResult, - Tunnel, - WireGuardError, -}; - -const COOKIE_REFRESH: u64 = 128; // Use 128 and not 120 so the compiler can optimize out the division -const COOKIE_SIZE: usize = 16; -const COOKIE_NONCE_SIZE: usize = 24; - -/// How often should reset count in seconds -const RESET_PERIOD: u64 = 1; - -type Cookie = [u8; COOKIE_SIZE]; - -/// There are two places where WireGuard requires "randomness" for cookies -/// * The 24 byte nonce in the cookie massage - here the only goal is to avoid -/// nonce reuse -/// * A secret value that changes every two minutes -/// Because the main goal of the cookie is simply for a party to prove ownership -/// of an IP address we can relax the randomness definition a bit, in order to -/// avoid locking, because using less resources is the main goal of any DoS -/// prevention mechanism. In order to avoid locking and calls to rand we derive -/// pseudo random values using the AEAD and some counters. -#[derive(Debug)] -pub struct RateLimiter { - /// The key we use to derive the nonce - nonce_key: [u8; 32], - /// The key we use to derive the cookie - secret_key: [u8; 16], - start_time: Instant, - /// A single 64 bit counter (should suffice for many years) - nonce_ctr: AtomicU64, - mac1_key: [u8; 32], - cookie_key: Key, - limit: u64, - /// The counter since last reset - count: AtomicU64, - /// The time last reset was performed on this rate limiter - last_reset: Mutex, -} - -impl RateLimiter { - pub fn new(public_key: &super::x25519::PublicKey, limit: u64) -> Self { - let mut secret_key = [0u8; 16]; - OsRng.fill_bytes(&mut secret_key); - RateLimiter { - nonce_key: Self::rand_bytes(), - secret_key, - start_time: Instant::now(), - nonce_ctr: AtomicU64::new(0), - mac1_key: b2s_hash(LABEL_MAC1, public_key.as_bytes()), - cookie_key: b2s_hash(LABEL_COOKIE, public_key.as_bytes()).into(), - limit, - count: AtomicU64::new(0), - last_reset: Mutex::new(Instant::now()), - } - } - - fn rand_bytes() -> [u8; 32] { - let mut key = [0u8; 32]; - OsRng.fill_bytes(&mut key); - key - } - - /// Reset packet count (ideally should be called with a period of 1 second) - pub fn reset_count(&self) { - // The rate limiter is not very accurate, but at the scale we care about it - // doesn't matter much - let current_time = Instant::now(); - let mut last_reset_time = self.last_reset.lock(); - if current_time.duration_since(*last_reset_time).as_secs() >= RESET_PERIOD { - self.count.store(0, Ordering::SeqCst); - *last_reset_time = current_time; - } - } - - /// Compute the correct cookie value based on the current secret value and - /// the source IP - fn current_cookie(&self, addr: IpAddr) -> Cookie { - let mut addr_bytes = [0u8; 16]; - - match addr { - IpAddr::V4(a) => addr_bytes[..4].copy_from_slice(&a.octets()[..]), - IpAddr::V6(a) => addr_bytes[..].copy_from_slice(&a.octets()[..]), - } - - // The current cookie for a given IP is the - // MAC(responder.changing_secret_every_two_minutes, initiator.ip_address) - // First we derive the secret from the current time, the value of cur_counter - // would change with time. - let cur_counter = Instant::now().duration_since(self.start_time).as_secs() / COOKIE_REFRESH; - - // Next we derive the cookie - b2s_keyed_mac_16_2(&self.secret_key, &cur_counter.to_le_bytes(), &addr_bytes) - } - - fn nonce(&self) -> [u8; COOKIE_NONCE_SIZE] { - let ctr = self.nonce_ctr.fetch_add(1, Ordering::Relaxed); - - b2s_mac_24(&self.nonce_key, &ctr.to_le_bytes()) - } - - fn is_under_load(&self) -> bool { - self.count.fetch_add(1, Ordering::SeqCst) >= self.limit - } - - pub(crate) fn format_cookie_reply<'a>( - &self, - idx: u32, - cookie: Cookie, - mac1: &[u8], - dst: &'a mut [u8], - ) -> Result<&'a mut [u8], WireGuardError> { - if dst.len() < super::COOKIE_REPLY_SZ { - return Err(WireGuardError::DestinationBufferTooSmall) - } - - let (message_type, rest) = dst.split_at_mut(4); - let (receiver_index, rest) = rest.split_at_mut(4); - let (nonce, rest) = rest.split_at_mut(24); - let (encrypted_cookie, _) = rest.split_at_mut(16 + 16); - - // msg.message_type = 3 - // msg.reserved_zero = { 0, 0, 0 } - message_type.copy_from_slice(&super::COOKIE_REPLY.to_le_bytes()); - // msg.receiver_index = little_endian(initiator.sender_index) - receiver_index.copy_from_slice(&idx.to_le_bytes()); - nonce.copy_from_slice(&self.nonce()[..]); - - let cipher = XChaCha20Poly1305::new(&self.cookie_key); - - let iv = GenericArray::from_slice(nonce); - - encrypted_cookie[..16].copy_from_slice(&cookie); - let tag = cipher - .encrypt_in_place_detached(iv, mac1, &mut encrypted_cookie[..16]) - .map_err(|_| WireGuardError::DestinationBufferTooSmall)?; - - encrypted_cookie[16..].copy_from_slice(&tag); - - Ok(&mut dst[..super::COOKIE_REPLY_SZ]) - } - - /// Verify the MAC fields on the datagram, and apply rate limiting if needed - pub fn verify_packet<'a, 'b>( - &self, - src_addr: Option, - src: &'a [u8], - dst: &'b mut [u8], - ) -> Result, TunnResult<'b>> { - let packet = Tunnel::parse_incoming_packet(src)?; - tracing::debug!("packet: {:?}", packet); - - // Verify and rate limit handshake messages only - if let Packet::HandshakeInit(HandshakeInit { sender_idx, .. }) - | Packet::HandshakeResponse(HandshakeResponse { sender_idx, .. }) = packet - { - tracing::debug!("sender_idx: {}", sender_idx); - tracing::debug!("response: {:?}", packet); - let (msg, macs) = src.split_at(src.len() - 32); - let (mac1, mac2) = macs.split_at(16); - - let computed_mac1 = b2s_keyed_mac_16(&self.mac1_key, msg); - verify_slices_are_equal(&computed_mac1[..16], mac1) - .map_err(|_| TunnResult::Err(WireGuardError::InvalidMac))?; - - if self.is_under_load() { - let addr = match src_addr { - None => return Err(TunnResult::Err(WireGuardError::UnderLoad)), - Some(addr) => addr, - }; - - // Only given an address can we validate mac2 - let cookie = self.current_cookie(addr); - let computed_mac2 = b2s_keyed_mac_16_2(&cookie, msg, mac1); - - if verify_slices_are_equal(&computed_mac2[..16], mac2).is_err() { - let cookie_packet = self - .format_cookie_reply(sender_idx, cookie, mac1, dst) - .map_err(TunnResult::Err)?; - return Err(TunnResult::WriteToNetwork(cookie_packet)) - } - } - } - - Ok(packet) - } -} diff --git a/burrow/src/wireguard/noise/session.rs b/burrow/src/wireguard/noise/session.rs deleted file mode 100755 index 8988728..0000000 --- a/burrow/src/wireguard/noise/session.rs +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright (c) 2019 Cloudflare, Inc. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -use std::sync::atomic::{AtomicUsize, Ordering}; - -use parking_lot::Mutex; -use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305}; - -use super::{errors::WireGuardError, PacketData}; - -pub struct Session { - pub(crate) receiving_index: u32, - sending_index: u32, - receiver: LessSafeKey, - sender: LessSafeKey, - sending_key_counter: AtomicUsize, - receiving_key_counter: Mutex, -} - -impl std::fmt::Debug for Session { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( - f, - "Session: {}<- ->{}", - self.receiving_index, self.sending_index - ) - } -} - -/// Where encrypted data resides in a data packet -const DATA_OFFSET: usize = 16; -/// The overhead of the AEAD -const AEAD_SIZE: usize = 16; - -// Receiving buffer constants -const WORD_SIZE: u64 = 64; -const N_WORDS: u64 = 16; // Suffice to reorder 64*16 = 1024 packets; can be increased at will -const N_BITS: u64 = WORD_SIZE * N_WORDS; - -#[derive(Debug, Clone, Default)] -struct ReceivingKeyCounterValidator { - /// In order to avoid replays while allowing for some reordering of the - /// packets, we keep a bitmap of received packets, and the value of the - /// highest counter - next: u64, - /// Used to estimate packet loss - receive_cnt: u64, - bitmap: [u64; N_WORDS as usize], -} - -impl ReceivingKeyCounterValidator { - #[inline(always)] - fn set_bit(&mut self, idx: u64) { - let bit_idx = idx % N_BITS; - let word = (bit_idx / WORD_SIZE) as usize; - let bit = (bit_idx % WORD_SIZE) as usize; - self.bitmap[word] |= 1 << bit; - } - - #[inline(always)] - fn clear_bit(&mut self, idx: u64) { - let bit_idx = idx % N_BITS; - let word = (bit_idx / WORD_SIZE) as usize; - let bit = (bit_idx % WORD_SIZE) as usize; - self.bitmap[word] &= !(1u64 << bit); - } - - /// Clear the word that contains idx - #[inline(always)] - fn clear_word(&mut self, idx: u64) { - let bit_idx = idx % N_BITS; - let word = (bit_idx / WORD_SIZE) as usize; - self.bitmap[word] = 0; - } - - /// Returns true if bit is set, false otherwise - #[inline(always)] - fn check_bit(&self, idx: u64) -> bool { - let bit_idx = idx % N_BITS; - let word = (bit_idx / WORD_SIZE) as usize; - let bit = (bit_idx % WORD_SIZE) as usize; - ((self.bitmap[word] >> bit) & 1) == 1 - } - - /// Returns true if the counter was not yet received, and is not too far - /// back - #[inline(always)] - fn will_accept(&self, counter: u64) -> Result<(), WireGuardError> { - if counter >= self.next { - // As long as the counter is growing no replay took place for sure - return Ok(()) - } - if counter + N_BITS < self.next { - // Drop if too far back - return Err(WireGuardError::InvalidCounter) - } - if !self.check_bit(counter) { - Ok(()) - } else { - Err(WireGuardError::DuplicateCounter) - } - } - - /// Marks the counter as received, and returns true if it is still good (in - /// case during decryption something changed) - #[inline(always)] - fn mark_did_receive(&mut self, counter: u64) -> Result<(), WireGuardError> { - if counter + N_BITS < self.next { - // Drop if too far back - return Err(WireGuardError::InvalidCounter) - } - if counter == self.next { - // Usually the packets arrive in order, in that case we simply mark the bit and - // increment the counter - self.set_bit(counter); - self.next += 1; - return Ok(()) - } - if counter < self.next { - // A packet arrived out of order, check if it is valid, and mark - if self.check_bit(counter) { - return Err(WireGuardError::InvalidCounter) - } - self.set_bit(counter); - return Ok(()) - } - // Packets where dropped, or maybe reordered, skip them and mark unused - if counter - self.next >= N_BITS { - // Too far ahead, clear all the bits - for c in self.bitmap.iter_mut() { - *c = 0; - } - } else { - let mut i = self.next; - while i % WORD_SIZE != 0 && i < counter { - // Clear until i aligned to word size - self.clear_bit(i); - i += 1; - } - while i + WORD_SIZE < counter { - // Clear whole word at a time - self.clear_word(i); - i = (i + WORD_SIZE) & 0u64.wrapping_sub(WORD_SIZE); - } - while i < counter { - // Clear any remaining bits - self.clear_bit(i); - i += 1; - } - } - self.set_bit(counter); - self.next = counter + 1; - Ok(()) - } -} - -impl Session { - pub(super) fn new( - local_index: u32, - peer_index: u32, - receiving_key: [u8; 32], - sending_key: [u8; 32], - ) -> Session { - Session { - receiving_index: local_index, - sending_index: peer_index, - receiver: LessSafeKey::new( - UnboundKey::new(&CHACHA20_POLY1305, &receiving_key).unwrap(), - ), - sender: LessSafeKey::new(UnboundKey::new(&CHACHA20_POLY1305, &sending_key).unwrap()), - sending_key_counter: AtomicUsize::new(0), - receiving_key_counter: Mutex::new(Default::default()), - } - } - - pub(super) fn local_index(&self) -> usize { - self.receiving_index as usize - } - - /// Returns true if receiving counter is good to use - fn receiving_counter_quick_check(&self, counter: u64) -> Result<(), WireGuardError> { - let counter_validator = self.receiving_key_counter.lock(); - counter_validator.will_accept(counter) - } - - /// Returns true if receiving counter is good to use, and marks it as used { - fn receiving_counter_mark(&self, counter: u64) -> Result<(), WireGuardError> { - let mut counter_validator = self.receiving_key_counter.lock(); - let ret = counter_validator.mark_did_receive(counter); - if ret.is_ok() { - counter_validator.receive_cnt += 1; - } - ret - } - - /// src - an IP packet from the interface - /// dst - pre-allocated space to hold the encapsulating UDP packet to send - /// over the network returns the size of the formatted packet - pub(super) fn format_packet_data<'a>(&self, src: &[u8], dst: &'a mut [u8]) -> &'a mut [u8] { - if dst.len() < src.len() + super::DATA_OVERHEAD_SZ { - panic!("The destination buffer is too small"); - } - - let sending_key_counter = self.sending_key_counter.fetch_add(1, Ordering::Relaxed) as u64; - - let (message_type, rest) = dst.split_at_mut(4); - let (receiver_index, rest) = rest.split_at_mut(4); - let (counter, data) = rest.split_at_mut(8); - - message_type.copy_from_slice(&super::DATA.to_le_bytes()); - receiver_index.copy_from_slice(&self.sending_index.to_le_bytes()); - counter.copy_from_slice(&sending_key_counter.to_le_bytes()); - - // TODO: spec requires padding to 16 bytes, but actually works fine without it - let n = { - let mut nonce = [0u8; 12]; - nonce[4..12].copy_from_slice(&sending_key_counter.to_le_bytes()); - data[..src.len()].copy_from_slice(src); - self.sender - .seal_in_place_separate_tag( - Nonce::assume_unique_for_key(nonce), - Aad::from(&[]), - &mut data[..src.len()], - ) - .map(|tag| { - data[src.len()..src.len() + AEAD_SIZE].copy_from_slice(tag.as_ref()); - src.len() + AEAD_SIZE - }) - .unwrap() - }; - - &mut dst[..DATA_OFFSET + n] - } - - /// packet - a data packet we received from the network - /// dst - pre-allocated space to hold the encapsulated IP packet, to send to - /// the interface dst will always take less space than src - /// return the size of the encapsulated packet on success - pub(super) fn receive_packet_data<'a>( - &self, - packet: PacketData, - dst: &'a mut [u8], - ) -> Result<&'a mut [u8], WireGuardError> { - let ct_len = packet.encrypted_encapsulated_packet.len(); - if dst.len() < ct_len { - // This is a very incorrect use of the library, therefore panic and not error - panic!("The destination buffer is too small"); - } - if packet.receiver_idx != self.receiving_index { - return Err(WireGuardError::WrongIndex) - } - // Don't reuse counters, in case this is a replay attack we want to quickly - // check the counter without running expensive decryption - self.receiving_counter_quick_check(packet.counter)?; - - tracing::debug!("TAG C"); - let ret = { - let mut nonce = [0u8; 12]; - nonce[4..12].copy_from_slice(&packet.counter.to_le_bytes()); - dst[..ct_len].copy_from_slice(packet.encrypted_encapsulated_packet); - self.receiver - .open_in_place( - Nonce::assume_unique_for_key(nonce), - Aad::from(&[]), - &mut dst[..ct_len], - ) - .map_err(|_| WireGuardError::InvalidAeadTag)? - }; - - // After decryption is done, check counter again, and mark as received - self.receiving_counter_mark(packet.counter)?; - Ok(ret) - } - - /// Returns the estimated downstream packet loss for this session - pub(super) fn current_packet_cnt(&self) -> (u64, u64) { - let counter_validator = self.receiving_key_counter.lock(); - (counter_validator.next, counter_validator.receive_cnt) - } -} diff --git a/burrow/src/wireguard/noise/timers.rs b/burrow/src/wireguard/noise/timers.rs deleted file mode 100755 index 1d0cf1f..0000000 --- a/burrow/src/wireguard/noise/timers.rs +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (c) 2019 Cloudflare, Inc. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -use std::{ - mem, - ops::{Index, IndexMut}, - time::{Duration, Instant}, -}; - -use super::{errors::WireGuardError, TunnResult, Tunnel}; - -// Some constants, represent time in seconds -// https://www.wireguard.com/papers/wireguard.pdf#page=14 -pub(crate) const REKEY_AFTER_TIME: Duration = Duration::from_secs(120); -const REJECT_AFTER_TIME: Duration = Duration::from_secs(180); -const REKEY_ATTEMPT_TIME: Duration = Duration::from_secs(90); -pub(crate) const REKEY_TIMEOUT: Duration = Duration::from_secs(5); -const KEEPALIVE_TIMEOUT: Duration = Duration::from_secs(10); -const COOKIE_EXPIRATION_TIME: Duration = Duration::from_secs(120); - -#[derive(Debug)] -pub enum TimerName { - /// Current time, updated each call to `update_timers` - TimeCurrent, - /// Time when last handshake was completed - TimeSessionEstablished, - /// Time the last attempt for a new handshake began - TimeLastHandshakeStarted, - /// Time we last received and authenticated a packet - TimeLastPacketReceived, - /// Time we last send a packet - TimeLastPacketSent, - /// Time we last received and authenticated a DATA packet - TimeLastDataPacketReceived, - /// Time we last send a DATA packet - TimeLastDataPacketSent, - /// Time we last received a cookie - TimeCookieReceived, - /// Time we last sent persistent keepalive - TimePersistentKeepalive, - Top, -} - -use self::TimerName::*; - -#[derive(Debug)] -pub struct Timers { - /// Is the owner of the timer the initiator or the responder for the last - /// handshake? - is_initiator: bool, - /// Start time of the tunnel - time_started: Instant, - timers: [Duration; TimerName::Top as usize], - pub(super) session_timers: [Duration; super::N_SESSIONS], - /// Did we receive data without sending anything back? - want_keepalive: bool, - /// Did we send data without hearing back? - want_handshake: bool, - persistent_keepalive: usize, - /// Should this timer call reset rr function (if not a shared rr instance) - pub(super) should_reset_rr: bool, -} - -impl Timers { - pub(super) fn new(persistent_keepalive: Option, reset_rr: bool) -> Timers { - Timers { - is_initiator: false, - time_started: Instant::now(), - timers: Default::default(), - session_timers: Default::default(), - want_keepalive: Default::default(), - want_handshake: Default::default(), - persistent_keepalive: usize::from(persistent_keepalive.unwrap_or(0)), - should_reset_rr: reset_rr, - } - } - - fn is_initiator(&self) -> bool { - self.is_initiator - } - - // We don't really clear the timers, but we set them to the current time to - // so the reference time frame is the same - pub(super) fn clear(&mut self) { - let now = Instant::now().duration_since(self.time_started); - for t in &mut self.timers[..] { - *t = now; - } - self.want_handshake = false; - self.want_keepalive = false; - } -} - -impl Index for Timers { - type Output = Duration; - - fn index(&self, index: TimerName) -> &Duration { - &self.timers[index as usize] - } -} - -impl IndexMut for Timers { - fn index_mut(&mut self, index: TimerName) -> &mut Duration { - &mut self.timers[index as usize] - } -} - -impl Tunnel { - pub(super) fn timer_tick(&mut self, timer_name: TimerName) { - match timer_name { - TimeLastPacketReceived => { - self.timers.want_keepalive = true; - self.timers.want_handshake = false; - } - TimeLastPacketSent => { - self.timers.want_handshake = true; - self.timers.want_keepalive = false; - } - _ => {} - } - - let time = self.timers[TimeCurrent]; - self.timers[timer_name] = time; - } - - pub(super) fn timer_tick_session_established( - &mut self, - is_initiator: bool, - session_idx: usize, - ) { - self.timer_tick(TimeSessionEstablished); - self.timers.session_timers[session_idx % super::N_SESSIONS] = self.timers[TimeCurrent]; - self.timers.is_initiator = is_initiator; - } - - // We don't really clear the timers, but we set them to the current time to - // so the reference time frame is the same - fn clear_all(&mut self) { - for session in &mut self.sessions { - *session = None; - } - - self.packet_queue.clear(); - - self.timers.clear(); - } - - fn update_session_timers(&mut self, time_now: Duration) { - let timers = &mut self.timers; - - for (i, t) in timers.session_timers.iter_mut().enumerate() { - if time_now - *t > REJECT_AFTER_TIME { - if let Some(session) = self.sessions[i].take() { - tracing::debug!( - message = "SESSION_EXPIRED(REJECT_AFTER_TIME)", - session = session.receiving_index - ); - } - *t = time_now; - } - } - } - - pub fn update_timers<'a>(&mut self, dst: &'a mut [u8]) -> TunnResult<'a> { - let mut handshake_initiation_required = false; - let mut keepalive_required = false; - - let time = Instant::now(); - - if self.timers.should_reset_rr { - self.rate_limiter.reset_count(); - } - - // All the times are counted from tunnel initiation, for efficiency our timers - // are rounded to a second, as there is no real benefit to having highly - // accurate timers. - let now = time.duration_since(self.timers.time_started); - self.timers[TimeCurrent] = now; - - self.update_session_timers(now); - - // Load timers only once: - let session_established = self.timers[TimeSessionEstablished]; - let handshake_started = self.timers[TimeLastHandshakeStarted]; - let aut_packet_received = self.timers[TimeLastPacketReceived]; - let aut_packet_sent = self.timers[TimeLastPacketSent]; - let data_packet_received = self.timers[TimeLastDataPacketReceived]; - let data_packet_sent = self.timers[TimeLastDataPacketSent]; - let persistent_keepalive = self.timers.persistent_keepalive; - - { - if self.handshake.is_expired() { - return TunnResult::Err(WireGuardError::ConnectionExpired) - } - - // Clear cookie after COOKIE_EXPIRATION_TIME - if self.handshake.has_cookie() - && now - self.timers[TimeCookieReceived] >= COOKIE_EXPIRATION_TIME - { - self.handshake.clear_cookie(); - } - - // All ephemeral private keys and symmetric session keys are zeroed out after - // (REJECT_AFTER_TIME * 3) ms if no new keys have been exchanged. - if now - session_established >= REJECT_AFTER_TIME * 3 { - tracing::error!("CONNECTION_EXPIRED(REJECT_AFTER_TIME * 3)"); - self.handshake.set_expired(); - self.clear_all(); - return TunnResult::Err(WireGuardError::ConnectionExpired) - } - - if let Some(time_init_sent) = self.handshake.timer() { - // Handshake Initiation Retransmission - if now - handshake_started >= REKEY_ATTEMPT_TIME { - // After REKEY_ATTEMPT_TIME ms of trying to initiate a new handshake, - // the retries give up and cease, and clear all existing packets queued - // up to be sent. If a packet is explicitly queued up to be sent, then - // this timer is reset. - tracing::error!("CONNECTION_EXPIRED(REKEY_ATTEMPT_TIME)"); - self.handshake.set_expired(); - self.clear_all(); - return TunnResult::Err(WireGuardError::ConnectionExpired) - } - - if time_init_sent.elapsed() >= REKEY_TIMEOUT { - // We avoid using `time` here, because it can be earlier than `time_init_sent`. - // Once `checked_duration_since` is stable we can use that. - // A handshake initiation is retried after REKEY_TIMEOUT + jitter ms, - // if a response has not been received, where jitter is some random - // value between 0 and 333 ms. - tracing::warn!("HANDSHAKE(REKEY_TIMEOUT)"); - handshake_initiation_required = true; - } - } else { - if self.timers.is_initiator() { - // After sending a packet, if the sender was the original initiator - // of the handshake and if the current session key is REKEY_AFTER_TIME - // ms old, we initiate a new handshake. If the sender was the original - // responder of the handshake, it does not re-initiate a new handshake - // after REKEY_AFTER_TIME ms like the original initiator does. - if session_established < data_packet_sent - && now - session_established >= REKEY_AFTER_TIME - { - tracing::debug!("HANDSHAKE(REKEY_AFTER_TIME (on send))"); - handshake_initiation_required = true; - } - - // After receiving a packet, if the receiver was the original initiator - // of the handshake and if the current session key is REJECT_AFTER_TIME - // - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT ms old, we initiate a new - // handshake. - if session_established < data_packet_received - && now - session_established - >= REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT - { - tracing::warn!( - "HANDSHAKE(REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - \ - REKEY_TIMEOUT \ - (on receive))" - ); - handshake_initiation_required = true; - } - } - - // If we have sent a packet to a given peer but have not received a - // packet after from that peer for (KEEPALIVE + REKEY_TIMEOUT) ms, - // we initiate a new handshake. - if data_packet_sent > aut_packet_received - && now - aut_packet_received >= KEEPALIVE_TIMEOUT + REKEY_TIMEOUT - && mem::replace(&mut self.timers.want_handshake, false) - { - tracing::warn!("HANDSHAKE(KEEPALIVE + REKEY_TIMEOUT)"); - handshake_initiation_required = true; - } - - if !handshake_initiation_required { - // If a packet has been received from a given peer, but we have not sent one - // back to the given peer in KEEPALIVE ms, we send an empty - // packet. - if data_packet_received > aut_packet_sent - && now - aut_packet_sent >= KEEPALIVE_TIMEOUT - && mem::replace(&mut self.timers.want_keepalive, false) - { - tracing::debug!("KEEPALIVE(KEEPALIVE_TIMEOUT)"); - keepalive_required = true; - } - - // Persistent KEEPALIVE - if persistent_keepalive > 0 - && (now - self.timers[TimePersistentKeepalive] - >= Duration::from_secs(persistent_keepalive as _)) - { - tracing::debug!("KEEPALIVE(PERSISTENT_KEEPALIVE)"); - self.timer_tick(TimePersistentKeepalive); - keepalive_required = true; - } - } - } - } - - if handshake_initiation_required { - return self.format_handshake_initiation(dst, true) - } - - if keepalive_required { - return self.encapsulate(&[], dst) - } - - TunnResult::Done - } - - pub fn time_since_last_handshake(&self) -> Option { - let current_session = self.current; - if self.sessions[current_session % super::N_SESSIONS].is_some() { - let duration_since_tun_start = Instant::now().duration_since(self.timers.time_started); - let duration_since_session_established = self.timers[TimeSessionEstablished]; - - Some(duration_since_tun_start - duration_since_session_established) - } else { - None - } - } - - pub fn persistent_keepalive(&self) -> Option { - let keepalive = self.timers.persistent_keepalive; - - if keepalive > 0 { - Some(keepalive as u16) - } else { - None - } - } -} diff --git a/burrow/src/wireguard/pcb.rs b/burrow/src/wireguard/pcb.rs deleted file mode 100755 index 974d84e..0000000 --- a/burrow/src/wireguard/pcb.rs +++ /dev/null @@ -1,173 +0,0 @@ -use std::{net::SocketAddr, sync::Arc}; - -use anyhow::{Error, Result}; -use fehler::throws; -use ip_network::IpNetwork; -use rand::random; -use tokio::{net::UdpSocket, sync::RwLock, task::JoinHandle}; -use tun::tokio::TunInterface; - -use super::{ - noise::{TunnResult, Tunnel}, - Peer, -}; -use crate::wireguard::noise::errors::WireGuardError; - -#[derive(Debug)] -pub struct PeerPcb { - pub endpoint: SocketAddr, - pub allowed_ips: Vec, - pub handle: RwLock>>, - socket: RwLock>, - tunnel: RwLock, -} - -impl PeerPcb { - #[throws] - pub fn new(peer: Peer) -> Self { - let tunnel = RwLock::new( - Tunnel::new( - peer.private_key, - peer.public_key, - peer.preshared_key, - None, - 1, - None, - ) - .map_err(|s| anyhow::anyhow!("{}", s))?, - ); - Self { - endpoint: peer.endpoint, - allowed_ips: peer.allowed_ips, - handle: RwLock::new(None), - socket: RwLock::new(None), - tunnel, - } - } - - pub async fn open_if_closed(&self) -> Result<(), Error> { - if self.socket.read().await.is_none() { - let socket = UdpSocket::bind("0.0.0.0:0").await?; - socket.connect(self.endpoint).await?; - self.socket.write().await.replace(socket); - } - Ok(()) - } - - pub async fn run(&self, tun_interface: Arc>>) -> Result<(), Error> { - tracing::debug!("starting read loop for pcb... for {:?}", &self); - let rid: i32 = random(); - let mut buf: [u8; 3000] = [0u8; 3000]; - tracing::debug!("start read loop {}", rid); - loop { - tracing::debug!("{}: waiting for packet", rid); - let guard = self.socket.read().await; - let Some(socket) = guard.as_ref() else { - self.open_if_closed().await?; - continue - }; - let mut res_buf = [0; 1500]; - // tracing::debug!("{} : waiting for readability on {:?}", rid, socket); - let len = match socket.recv(&mut res_buf).await { - Ok(l) => l, - Err(e) => { - log::error!("{}: error reading from socket: {:?}", rid, e); - continue - } - }; - let mut res_dat = &res_buf[..len]; - tracing::debug!("{}: Decapsulating {} bytes", rid, len); - tracing::debug!("{:?}", &res_dat); - loop { - match self - .tunnel - .write() - .await - .decapsulate(None, res_dat, &mut buf[..]) - { - TunnResult::Done => break, - TunnResult::Err(e) => { - tracing::error!(message = "Decapsulate error", error = ?e); - break - } - TunnResult::WriteToNetwork(packet) => { - tracing::debug!("WriteToNetwork: {:?}", packet); - self.open_if_closed().await?; - self.socket - .read() - .await - .as_ref() - .unwrap() - .send(packet) - .await?; - tracing::debug!("WriteToNetwork done"); - res_dat = &[]; - continue - } - TunnResult::WriteToTunnelV4(packet, addr) => { - tracing::debug!("WriteToTunnelV4: {:?}, {:?}", packet, addr); - tun_interface.read().await.as_ref().ok_or(anyhow::anyhow!("tun interface does not exist"))?.send(packet).await?; - break - } - TunnResult::WriteToTunnelV6(packet, addr) => { - tracing::debug!("WriteToTunnelV6: {:?}, {:?}", packet, addr); - tun_interface.read().await.as_ref().ok_or(anyhow::anyhow!("tun interface does not exist"))?.send(packet).await?; - break - } - } - } - } - } - - pub async fn send(&self, src: &[u8]) -> Result<(), Error> { - tracing::debug!("Sending packet: {:?}", src); - let mut dst_buf = [0u8; 3000]; - match self.tunnel.write().await.encapsulate(src, &mut dst_buf[..]) { - TunnResult::Done => { - tracing::debug!("Encapsulate done"); - } - TunnResult::Err(e) => { - tracing::error!(message = "Encapsulate error", error = ?e) - } - TunnResult::WriteToNetwork(packet) => { - self.open_if_closed().await?; - let handle = self.socket.read().await; - let Some(socket) = handle.as_ref() else { - tracing::error!("No socket for peer"); - return Ok(()) - }; - tracing::debug!("Our Encapsulated packet: {:?}", packet); - socket.send(packet).await?; - } - _ => panic!("Unexpected result from encapsulate"), - }; - Ok(()) - } - - pub async fn update_timers(&self, dst: &mut [u8]) -> Result<(), Error> { - match self.tunnel.write().await.update_timers(dst) { - TunnResult::Done => {} - TunnResult::Err(WireGuardError::ConnectionExpired) => {} - TunnResult::Err(e) => { - tracing::error!(message = "Update timers error", error = ?e) - } - TunnResult::WriteToNetwork(packet) => { - tracing::debug!("Sending Packet for timer update: {:?}", packet); - self.open_if_closed().await?; - let handle = self.socket.read().await; - let Some(socket) = handle.as_ref() else { - tracing::error!("No socket for peer"); - return Ok(()) - }; - socket.send(packet).await?; - tracing::debug!("Sent Packet for timer update"); - } - _ => panic!("Unexpected result from update_timers"), - }; - Ok(()) - } - - pub async fn reset_rate_limiter(&self) { - self.tunnel.read().await.reset_rate_limiter(); - } -} diff --git a/burrow/src/wireguard/peer.rs b/burrow/src/wireguard/peer.rs deleted file mode 100755 index 131b0d4..0000000 --- a/burrow/src/wireguard/peer.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::{fmt, net::SocketAddr}; - -use ip_network::IpNetwork; -use x25519_dalek::{PublicKey, StaticSecret}; - -pub struct Peer { - pub endpoint: SocketAddr, - pub private_key: StaticSecret, - pub public_key: PublicKey, - pub allowed_ips: Vec, - pub preshared_key: Option<[u8; 32]>, -} - -impl fmt::Debug for Peer { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Peer") - .field("endpoint", &self.endpoint) - .field("public_key", &self.public_key) - .field("allowed_ips", &self.allowed_ips) - .finish() - } -} diff --git a/burrow/src/wireguard/snapshots/burrow__wireguard__config__tests__tst_config_toml.snap b/burrow/src/wireguard/snapshots/burrow__wireguard__config__tests__tst_config_toml.snap deleted file mode 100644 index 3800647..0000000 --- a/burrow/src/wireguard/snapshots/burrow__wireguard__config__tests__tst_config_toml.snap +++ /dev/null @@ -1,16 +0,0 @@ ---- -source: burrow/src/wireguard/config.rs -expression: toml ---- -[[Peer]] -public_key = "8GaFjVO6c4luCHG4ONO+1bFG8tO+Zz5/Gy+Geht1USM=" -preshared_key = "ha7j4BjD49sIzyF9SNlbueK0AMHghlj6+u0G3bzC698=" -allowed_ips = ["8.8.8.8/32", "0.0.0.0/0"] -endpoint = "wg.burrow.rs:51820" - -[interface] -private_key = "OEPVdomeLTxTIBvv3TYsJRge0Hp9NMiY0sIrhT8OWG8=" -address = ["10.13.13.2/24"] -listen_port = 51820 -dns = [] - diff --git a/burrow/tmp/conrd.conf b/burrow/tmp/conrd.conf deleted file mode 100644 index 52572d1..0000000 --- a/burrow/tmp/conrd.conf +++ /dev/null @@ -1,8 +0,0 @@ -[Interface] -PrivateKey = gAaK0KFGOpxY7geGo59XXDufcxeoSNXXNC12mCQmlVs= -Address = 10.1.11.2/32 -DNS = 10.1.11.1 -[Peer] -PublicKey = Ab6V2mgPHiCXaAZfQrNts8ha8RkEzC49VnmMQfe5Yg4= -AllowedIPs = 10.1.11.1/32,10.1.11.2/32,0.0.0.0/0 -Endpoint = 172.251.163.175:51820 \ No newline at end of file diff --git a/docs/GETTING_STARTED.md b/docs/GETTING_STARTED.md deleted file mode 100644 index 764c219..0000000 --- a/docs/GETTING_STARTED.md +++ /dev/null @@ -1,130 +0,0 @@ -# Getting Started - -## Dependencies - -Before you can start working on Burrow, you'll need to install some dependencies. They are different for each platform: - -
- Linux - -1. Install **rustup** using the instructions on the [website](https://rustup.rs/): - -```bash -$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` - -2. Install **Visual Studio Code** from the [website](https://code.visualstudio.com/#alt-downloads), [Snap Store](https://snapcraft.io/code), or your package manager of choice. -
- -
- macOS - -1. Install **rustup** using the instructions on the [website](https://rustup.rs/): - -```bash -$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` - -2. Download and install **Visual Studio Code** from the [website](https://code.visualstudio.com/#alt-downloads), or by using brew: - -``` -brew install --cask visual-studio-code -``` - -3. Download and Install **Xcode** from the [App Store](https://apps.apple.com/us/app/xcode/id497799835) or the [Apple Developer](https://developer.apple.com/downloads) website. - -4. Make sure the _"current"_ version of Xcode matches the one you are using: - -``` -$ xcode-select -p -``` - -If the output is not the version of Xcode you just installed, run the following command to switch to the new version: - -``` -$ sudo xcode-select -s {PATH_TO_XCODE} -``` - -
- -
- Windows - -1. Download **Visual Studio** community edition from the [website](https://visualstudio.microsoft.com/vs/). Install the components for "Desktop Development with C++" - -2. Install [**Visual Studio Code**](https://apps.microsoft.com/store/detail/visual-studio-code/XP9KHM4BK9FZ7Q), [**PowerShell**](https://apps.microsoft.com/store/detail/powershell/9MZ1SNWT0N5D) and [**Windows Terminal**](https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701) from the Microsoft Store - -3. Open Windows Terminal and use [winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/) to install **git**, **LLVM** and **rustup**: - -```posh -winget install Git.Git -winget install LLVM.LLVM -winget install Rustlang.Rustup -``` - -4. Install Rust using rustup: - -```posh -rustup toolchain install stable-msvc -``` - -
- -## Building - -1. Clone the repository: - -``` -git clone git@github.com:hackclub/burrow.git -``` - -2. Open the `burrow` folder in Visual Studio Code: - -``` -code burrow -``` - -3. Install the Visual Studio Code extensions [**rust-analyzer**](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) and [**CodeLLDB**](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb). You should get a suggestion to do this automatically: - - - -4. Compile burrow in Visual Studio Code by selecting `Terminal -> Run Build Task` - -## Running - -
- Command Line - -You can run burrow on the command line with cargo: - -``` -cargo run -``` - -Cargo will ask for your password because burrow needs permission in order to create a tunnel. - -
- -
- Visual Studio Code - -You can debug the Rust program inside of Visual Studio using the **Run and Debug** tab. - -**_This does not work fully yet_**. Visual Studio Code does not have a way to debug programs with administrative privileges. - -
- -
- iOS or macOS - -You can run the Burrow app on iOS or macOS using **Xcode**. - -You will need to be logged in with your Apple ID, and it should be a part of **The Hack Foundation** team: - - - -If your Apple ID is not a part of The Hack Foundation team, ask the Slack channel for assistance. - -You should now be able to run the app by opening `Apple/Burrow.xcodeproj` in Xcode, selecting the **App** scheme and clicking **Run**. - -
diff --git a/docs/GTK_APP.md b/docs/GTK_APP.md deleted file mode 100644 index ef73d2b..0000000 --- a/docs/GTK_APP.md +++ /dev/null @@ -1,170 +0,0 @@ -# Linux GTK App Getting Started - -Currently, the GTK App can be built as a binary or as an AppImage. -Note that the flatpak version can compile but will not run properly! - -## Dependencies - -### Install Build Dependencies - -
- Debian - - > Note: Burrow currently cannot compile on Debian Stable (Bookworm) due to its outdated dependencies - - 1. Install build dependencies - - ``` - sudo apt install -y clang meson cmake pkg-config libgtk-4-dev libadwaita-1-dev gettext desktop-file-utils - ``` - - 2. Install flatpak builder (Optional) - - ``` - sudo apt install -y flatpak-builder - ``` - - 3. Install AppImage build tools (Optional) - - ``` - sudo apt install -y wget fuse file - ``` - -
- -
- Fedora - - 1. Install build dependencies - - ``` - sudo dnf install -y clang ninja-build cmake meson gtk4-devel glib2-devel libadwaita-devel desktop-file-utils libappstream-glib - ``` - - 2. Install flatpak builder (Optional) - - ``` - sudo dnf install -y flatpak-builder - ``` - - 3. Install AppImage build tools (Optional) - - ``` - sudo dnf install -y util-linux wget fuse fuse-libs file - ``` - -
- -
- Void Linux (glibc) - - 1. Install build dependencies - - ``` - sudo xbps-install -Sy gcc clang meson cmake pkg-config gtk4-devel gettext desktop-file-utils gtk4-update-icon-cache appstream-glib - ``` - - 2. Install flatpak builder (Optional) - - ``` - sudo xbps-install -Sy flatpak-builder - ``` - - 3. Install AppImage build tools (Optional) - - ``` - sudo xbps-install -Sy wget fuse file - ``` - -
- -### Flatpak Build Dependencies (Optional) - -``` -flatpak install --user \ - org.gnome.Platform/x86_64/45 \ - org.freedesktop.Sdk.Extension.rust-stable/x86_64/23.08 -``` - -## Building - -
- General - - 1. Enter the `burrow-gtk` - - ```bash - cd burrow-gtk - ``` - - 2. Perform the meson build - ``` - meson setup build - meson compile -C build - ``` - -
- -
- Flatpak - - 1. Compile and install the flatpak - - ``` - flatpak-builder - --user --install --force-clean --disable-rofiles-fuse \ - flatpak_debug/ \ - burrow-gtk/build-aux/com.hackclub.burrow.devel.json - ``` - -
- -
- AppImage - - 1. Enter the `burrow-gtk` - - ```bash - cd burrow-gtk - ``` - - 2. Compile the AppImage - - ``` - ./build-aux/build_appimage.sh - ``` - -
- - -## Running - -
- General - - The compiled binary can be found in `build/src/burrow-gtk`. - - ``` - ./build/src/burrow-gtk - ``` -
- -
- Flatpak - - ``` - flatpak run com.hackclub.burrow-devel - ``` - -
- -
- AppImage - - The compiled binary can be found in `build-appimage/Burrow-*.AppImage`. - - ``` - ./build-appimage/Burrow-*.AppImage - ``` - -
diff --git a/docs/extensions.png b/docs/extensions.png deleted file mode 100644 index ad94ee4..0000000 Binary files a/docs/extensions.png and /dev/null differ diff --git a/docs/xcode.png b/docs/xcode.png deleted file mode 100644 index 469ada3..0000000 Binary files a/docs/xcode.png and /dev/null differ diff --git a/package/rpm/post_install b/package/rpm/post_install deleted file mode 100644 index 751c190..0000000 --- a/package/rpm/post_install +++ /dev/null @@ -1,2 +0,0 @@ -systemctl daemon-reload -systemctl enable burrow diff --git a/package/rpm/pre_uninstall b/package/rpm/pre_uninstall deleted file mode 100644 index e0fef26..0000000 --- a/package/rpm/pre_uninstall +++ /dev/null @@ -1,3 +0,0 @@ -systemctl disable burrow.service > /dev/null 2>&1 -systemctl stop burrow.service > /dev/null 2>&1 -systemctl daemon-reload diff --git a/proto/burrow.proto b/proto/burrow.proto deleted file mode 100644 index 2355b8d..0000000 --- a/proto/burrow.proto +++ /dev/null @@ -1,72 +0,0 @@ -syntax = "proto3"; -package burrow; - -import "google/protobuf/timestamp.proto"; - -service Tunnel { - rpc TunnelConfiguration (Empty) returns (stream TunnelConfigurationResponse); - rpc TunnelStart (Empty) returns (Empty); - rpc TunnelStop (Empty) returns (Empty); - rpc TunnelStatus (Empty) returns (stream TunnelStatusResponse); -} - -service Networks { - rpc NetworkAdd (Network) returns (Empty); - rpc NetworkList (Empty) returns (stream NetworkListResponse); - rpc NetworkReorder (NetworkReorderRequest) returns (Empty); - rpc NetworkDelete (NetworkDeleteRequest) returns (Empty); -} - -message NetworkReorderRequest { - int32 id = 1; - int32 index = 2; -} - -message WireGuardPeer { - string endpoint = 1; - repeated string subnet = 2; -} - -message WireGuardNetwork { - string address = 1; - string dns = 2; - repeated WireGuardPeer peer = 3; -} - -message NetworkDeleteRequest { - int32 id = 1; -} - -message Network { - int32 id = 1; - NetworkType type = 2; - bytes payload = 3; -} - -enum NetworkType { - WireGuard = 0; - HackClub = 1; -} - -message NetworkListResponse { - repeated Network network = 1; -} - -message Empty { - -} - -enum State { - Stopped = 0; - Running = 1; -} - -message TunnelStatusResponse { - State state = 1; - optional google.protobuf.Timestamp start = 2; -} - -message TunnelConfigurationResponse { - repeated string addresses = 1; - int32 mtu = 2; -} diff --git a/server_patch.txt b/server_patch.txt deleted file mode 100644 index de8e14c..0000000 --- a/server_patch.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Add this to ~/server/wg0.conf upon regeneration - -PostUp = iptables -A FORWARD -i %i -j ACCEPT - -PostUp = iptables -A FORWARD -o %i -j ACCEPT - -PostUp = iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE - -PostUp = ip6tables -A FORWARD -i %i -j ACCEPT - -PostUp = ip6tables -A FORWARD -o %i -j ACCEPT - -PostDown = iptables -D FORWARD -i %i -j ACCEPT - -PostDown = iptables -D FORWARD -o %i -j ACCEPT - -PostDown = iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE - -PostDown = ip6tables -D FORWARD -i %i -j ACCEPT - -PostDown = ip6tables -D FORWARD -o %i -j ACCEPT \ No newline at end of file diff --git a/site/.eslintrc.json b/site/.eslintrc.json deleted file mode 100644 index bffb357..0000000 --- a/site/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "next/core-web-vitals" -} diff --git a/site/.gitignore b/site/.gitignore deleted file mode 100644 index 71b863e..0000000 --- a/site/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/node_modules -/out/ - -/.next/ -next-env.d.ts diff --git a/site/.prettierignore b/site/.prettierignore deleted file mode 100644 index fcac576..0000000 --- a/site/.prettierignore +++ /dev/null @@ -1,6 +0,0 @@ -# Ignore artifacts: -build -coverage - -# Ignore all HTML files: -**/*.html \ No newline at end of file diff --git a/site/assets/Bold.woff2 b/site/assets/Bold.woff2 deleted file mode 100644 index 8c00084..0000000 Binary files a/site/assets/Bold.woff2 and /dev/null differ diff --git a/site/assets/Italic.woff2 b/site/assets/Italic.woff2 deleted file mode 100644 index 056909c..0000000 Binary files a/site/assets/Italic.woff2 and /dev/null differ diff --git a/site/assets/Regular.woff2 b/site/assets/Regular.woff2 deleted file mode 100644 index d7c3d52..0000000 Binary files a/site/assets/Regular.woff2 and /dev/null differ diff --git a/site/bun.lockb b/site/bun.lockb deleted file mode 100755 index ea2d137..0000000 Binary files a/site/bun.lockb and /dev/null differ diff --git a/site/layout/layout.tsx b/site/layout/layout.tsx deleted file mode 100644 index 28ff24d..0000000 --- a/site/layout/layout.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Space_Mono, Poppins } from "next/font/google"; -import localFont from "next/font/local"; - -const space_mono = Space_Mono({ - weight: ["400", "700"], - subsets: ["latin"], - display: "swap", - variable: "--font-space-mono", -}); - -const poppins = Poppins({ - weight: ["400", "500", "600", "700", "800", "900"], - subsets: ["latin"], - display: "swap", - variable: "--font-poppins", -}); - -const phantomSans = localFont({ - src: [ - { - path: "../assets/Regular.woff2", - weight: "400", - style: "normal", - }, - { - path: "../assets/Italic.woff2", - weight: "400", - style: "italic", - }, - { - path: "../assets/Bold.woff2", - weight: "700", - style: "normal", - }, - ], - variable: "--font-phantom-sans", -}); - -export default function Layout({ children }: { children: React.ReactNode }) { - return ( -
- {children} -
- ); -} diff --git a/site/next.config.js b/site/next.config.js deleted file mode 100644 index afbb70f..0000000 --- a/site/next.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - headers() { - return [ - { - source: "/.well-known/apple-app-site-association", - headers: [{ key: "Content-Type", value: "application/json" }], - } - ]; - } -}; - -module.exports = nextConfig; diff --git a/site/package.json b/site/package.json deleted file mode 100644 index 4fcacc8..0000000 --- a/site/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "burrow", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@fortawesome/fontawesome-free": "^6.4.2", - "@fortawesome/fontawesome-svg-core": "^6.4.2", - "@fortawesome/free-brands-svg-icons": "^6.4.2", - "@fortawesome/free-solid-svg-icons": "^6.4.2", - "@fortawesome/react-fontawesome": "^0.2.0", - "@headlessui/react": "^1.7.17", - "@headlessui/tailwindcss": "^0.2.0", - "@types/node": "20.5.8", - "@types/react": "18.2.21", - "@types/react-dom": "18.2.7", - "autoprefixer": "10.4.15", - "eslint": "8.48.0", - "eslint-config-next": "13.4.19", - "next": "13.4.19", - "postcss": "8.4.29", - "react": "18.2.0", - "react-dom": "18.2.0", - "tailwindcss": "3.3.3", - "typescript": "5.2.2" - }, - "devDependencies": { - "prettier": "^3.0.3", - "prettier-plugin-tailwindcss": "^0.5.4" - } -} diff --git a/site/pages/_app.tsx b/site/pages/_app.tsx deleted file mode 100644 index c0572f6..0000000 --- a/site/pages/_app.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import Layout from "@/layout/layout"; -import type { AppProps } from "next/app"; -import { config } from "@fortawesome/fontawesome-svg-core"; -import "@fortawesome/fontawesome-svg-core/styles.css"; -config.autoAddCss = false; -import "static/globals.css"; - -export default function App({ Component, pageProps }: AppProps) { - return ( - - - - ); -} diff --git a/site/pages/_document.tsx b/site/pages/_document.tsx deleted file mode 100644 index ce4b5e1..0000000 --- a/site/pages/_document.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Html, Head, Main, NextScript } from "next/document"; - -export default function Document() { - return ( - - - -
- - - - ); -} diff --git a/site/pages/index.tsx b/site/pages/index.tsx deleted file mode 100644 index 73fbc33..0000000 --- a/site/pages/index.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import { faGithub } from "@fortawesome/free-brands-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import Head from "next/head"; -import { - faChevronDown, - faChevronUp, - faUpRightFromSquare, -} from "@fortawesome/free-solid-svg-icons"; -import { Menu, Transition } from "@headlessui/react"; -import { useState, useRef, useEffect } from "react"; -export default function Page() { - const [chevron, setChevron] = useState(false); - const menuButtonRef = useRef(null); - const toggleDropdown = () => { - setChevron(!chevron); - }; - const handleClickOutside = (event: MouseEvent) => { - if ( - menuButtonRef.current && - !menuButtonRef.current.contains(event.target as Node) - ) { - setChevron(false); - } - }; - useEffect(() => { - document.addEventListener("click", handleClickOutside); - - return () => { - document.removeEventListener("click", handleClickOutside); - }; - }, []); - return ( - <> - - Burrow - - - -
-
-

- Burrow Through{" "} - Firewalls -

-
-

- Burrow is an open source tool for burrowing through firewalls, - built by teenagers at{" "} - - - Hack Club. - - {" "} - - burrow - {" "} - is a Rust-based VPN for getting around restrictive Internet - censors. -

-
-
-
- -
- toggleDropdown()} - ref={menuButtonRef} - className="w-50 h-12 rounded-2xl bg-hackClubRed px-3 font-SpaceMono hover:scale-105 md:h-12 md:w-auto md:rounded-3xl md:text-xl 2xl:h-16 2xl:text-2xl " - > - Install for Linux - {chevron ? ( - - ) : ( - - )} - -
- - -
- - {({ active }) => ( - - Install for Windows - - )} - - - - Install for MacOS - - -
-
-
-
- - - -
- -
- {/* Footer */} - {/* */} -
-
- - ); -} diff --git a/site/postcss.config.js b/site/postcss.config.js deleted file mode 100644 index 12a703d..0000000 --- a/site/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/site/prettier.config.js b/site/prettier.config.js deleted file mode 100644 index d573118..0000000 --- a/site/prettier.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - plugins: ["prettier-plugin-tailwindcss"], -}; diff --git a/site/public/.well-known/apple-app-site-association b/site/public/.well-known/apple-app-site-association deleted file mode 100644 index 63262fb..0000000 --- a/site/public/.well-known/apple-app-site-association +++ /dev/null @@ -1,21 +0,0 @@ -{ - "applinks": { - "details": [ - { - "appIDs": [ - "P6PV2R9443.com.hackclub.burrow" - ], - "components": [ - { - "/": "/callback/*" - } - ] - } - ] - }, - "webcredentials": { - "apps": [ - "P6PV2R9443.com.hackclub.burrow" - ] - } -} diff --git a/site/public/hackclub.svg b/site/public/hackclub.svg deleted file mode 100644 index 38c2a68..0000000 --- a/site/public/hackclub.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/site/static/globals.css b/site/static/globals.css deleted file mode 100644 index b5c61c9..0000000 --- a/site/static/globals.css +++ /dev/null @@ -1,3 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; diff --git a/site/tailwind.config.ts b/site/tailwind.config.ts deleted file mode 100644 index 3df6f5a..0000000 --- a/site/tailwind.config.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { Config } from "tailwindcss"; - -const config: Config = { - content: [ - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./components/**/*.{js,ts,jsx,tsx,mdx}", - "./app/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - extend: { - colors: { - backgroundBlack: "#17171D", - hackClubRed: "#EC3750", - hackClubBlueShade: "#32323D", - hackClubBlue: "#338EDA", - burrowStroke: "#595959", - burrowHover: "#3D3D3D", - }, - fontFamily: { - SpaceMono: ["var(--font-space-mono)"], - Poppins: ["var(--font-poppins)"], - PhantomSans: ["var(--font-phantom-sans)"], - }, - }, - }, - plugins: [require("@headlessui/tailwindcss")({ prefix: "ui" })], -}; -export default config; diff --git a/site/tsconfig.json b/site/tsconfig.json deleted file mode 100644 index c714696..0000000 --- a/site/tsconfig.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "plugins": [ - { - "name": "next" - } - ], - "paths": { - "@/*": ["./*"] - } - }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] -} diff --git a/systemd/burrow.service b/systemd/burrow.service deleted file mode 100644 index 8d35355..0000000 --- a/systemd/burrow.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Burrow -After=burrow.socket - -[Service] -ExecStart=/usr/bin/burrow daemon - -[Install] -WantedBy=multi-user.target diff --git a/systemd/burrow.socket b/systemd/burrow.socket deleted file mode 100644 index c5da49d..0000000 --- a/systemd/burrow.socket +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=Burrow Socket - -[Socket] -ListenStream=/run/burrow.sock - -[Install] -WantedBy=sockets.target diff --git a/tun-async/Cargo.toml b/tun-async/Cargo.toml new file mode 100644 index 0000000..e011ca4 --- /dev/null +++ b/tun-async/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "tun-async" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tun = { version = "0.1", path = "../tun" } diff --git a/tun-async/src/lib.rs b/tun-async/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/tun-async/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/tun/Cargo.toml b/tun/Cargo.toml index 1b07833..f203870 100644 --- a/tun/Cargo.toml +++ b/tun/Cargo.toml @@ -6,35 +6,20 @@ edition = "2021" [dependencies] libc = "0.2" fehler = "1.0" -nix = { version = "0.26", features = ["ioctl"] } -socket2 = "0.5" -tokio = { version = "1.37", default-features = false, optional = true } -byteorder = "1.4" -tracing = "0.1" -log = "0.4" -serde = { version = "1", features = ["derive"], optional = true } -schemars = { version = "0.8", optional = true } - -futures = { version = "0.3.28", optional = true } - -[features] -serde = ["dep:serde", "dep:schemars"] -tokio = ["tokio/net", "dep:tokio", "dep:futures"] +nix = { version = "0.25", features = ["ioctl"] } +socket2 = "0.4" +tokio = { version = "1.21", features = [] } [target.'cfg(windows)'.dependencies] -lazy_static = "1.4" libloading = "0.7" -tempfile = "3.5" widestring = "1.0" -windows = { version = "0.48", features = [ - "Win32_Foundation", - "Win32_NetworkManagement_IpHelper", -] } [target.'cfg(windows)'.build-dependencies] anyhow = "1.0" -bindgen = "0.65" -reqwest = { version = "0.11" } -ssri = { version = "9.0", default-features = false } -tokio = { version = "1.28", features = ["rt", "macros"] } +bindgen = "0.61" +hex-literal = "0.3" +platforms = "3.0" +reqwest = { version = "0.11", features = ["native-tls"] } +sha2 = "0.10" +tokio = { version = "1.21", features = ["rt"] } zip = { version = "0.6", features = ["deflate"] } diff --git a/tun/build.rs b/tun/build.rs index 8da8a40..6ad98c3 100644 --- a/tun/build.rs +++ b/tun/build.rs @@ -1,98 +1,40 @@ -#[cfg(not(windows))] -fn main() { - println!("cargo:rerun-if-changed=build.rs"); -} - #[cfg(windows)] #[tokio::main(flavor = "current_thread")] async fn main() -> anyhow::Result<()> { - let out_dir = std::env::var("OUT_DIR")?; - let path = std::path::PathBuf::from(out_dir); - generate(&path).await?; + use std::io::{Cursor, Read}; - println!("cargo:rerun-if-changed=build.rs"); - Ok(()) -} + let buf = reqwest::get("https://www.wintun.net/builds/wintun-0.14.1.zip") + .await? + .bytes() + .await?; + assert_content_hash( + &buf, + hex_literal::hex!("07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51"), + ); + let mut archive = zip::ZipArchive::new(Cursor::new(buf))?; -#[cfg(windows)] -async fn generate(out_dir: &std::path::Path) -> anyhow::Result<()> { - use std::{fs::File, io::Write}; - - use anyhow::Context; - - let bindings_path = out_dir.join("wintun.rs"); - let binary_path = out_dir.join("wintun.dll"); - println!("cargo:rerun-if-changed={}", bindings_path.to_str().unwrap()); - println!("cargo:rerun-if-changed={}", binary_path.to_str().unwrap()); - - if let (Ok(..), Ok(..)) = (File::open(&bindings_path), File::open(&binary_path)) { - return Ok(()) - }; - - let archive = download(out_dir) - .await - .context("Failed to download wintun")?; - - let (bindings, binary) = parse(archive).context("Failed to parse wintun archive")?; - - bindings - .write_to_file(bindings_path) - .context("Failed to write bindings")?; - - let mut file = std::fs::OpenOptions::new() - .write(true) - .create(true) - .open(binary_path) - .context("Failed to write binary")?; - file.write_all(&binary)?; - - Ok(()) -} - -#[cfg(windows)] -async fn download(directory: &std::path::Path) -> anyhow::Result { - use std::{io::Write, str::FromStr}; - - let path = directory.join(WINTUN_FILENAME); - let mut file = match std::fs::OpenOptions::new().read(true).open(&path) { - Ok(existing) => return Ok(existing), - Err(_e) => std::fs::OpenOptions::new() - .read(true) - .write(true) - .create(true) - .open(path)?, - }; - - let mut url = reqwest::Url::from_str("https://www.wintun.net/builds")?; - url.path_segments_mut().unwrap().push(WINTUN_FILENAME); - - let body = reqwest::get(url).await?.bytes().await?; - - ssri::IntegrityChecker::new(WINTUN_INTEGRITY.parse()?) - .chain(&body) - .result()?; - - file.set_len(0)?; - file.write_all(&body)?; - - Ok(file) -} - -#[cfg(windows)] -fn parse(file: std::fs::File) -> anyhow::Result<(bindgen::Bindings, Vec)> { - use std::io::Read; - - use anyhow::Context; - - let reader = std::io::BufReader::new(file); - let mut archive = zip::ZipArchive::new(reader)?; + let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR")?); let mut header = String::new(); archive .by_name("wintun/include/wintun.h")? .read_to_string(&mut header)?; - header.push_str(WINTUN_BINDINGS_PREAMBLE); - + header.push_str( + "WINTUN_CLOSE_ADAPTER_FUNC WintunCloseAdapter; + WINTUN_OPEN_ADAPTER_FUNC WintunOpenAdapter; + WINTUN_GET_ADAPTER_LUID_FUNC WintunGetAdapterLUID; + WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC WintunGetRunningDriverVersion; + WINTUN_DELETE_DRIVER_FUNC WintunDeleteDriver; + WINTUN_SET_LOGGER_FUNC WintunSetLogger; + WINTUN_START_SESSION_FUNC WintunStartSession; + WINTUN_END_SESSION_FUNC WintunEndSession; + WINTUN_CREATE_ADAPTER_FUNC WintunCreateAdapter; + WINTUN_GET_READ_WAIT_EVENT_FUNC WintunGetReadWaitEvent; + WINTUN_RECEIVE_PACKET_FUNC WintunReceivePacket; + WINTUN_RELEASE_RECEIVE_PACKET_FUNC WintunReleaseReceivePacket; + WINTUN_ALLOCATE_SEND_PACKET_FUNC WintunAllocateSendPacket; + WINTUN_SEND_PACKET_FUNC WintunSendPacket;", + ); let bindings = bindgen::Builder::default() .header_contents("wintun.h", &header) .allowlist_function("Wintun.*") @@ -100,47 +42,38 @@ fn parse(file: std::fs::File) -> anyhow::Result<(bindgen::Bindings, Vec)> { .dynamic_library_name("wintun") .dynamic_link_require_all(true) .generate() - .context("Failed to generate bindings from wintun archive") .unwrap(); + bindings.write_to_file(out_dir.join("wintun.rs"))?; - let mut binary = Vec::new(); - let target = std::env::var("TARGET")?; - let arch = match target.split('-').next() { - Some("i686") => "x86", - Some("x86_64") => "amd64", - Some("aarch64") => "arm64", - Some("thumbv7a") => "arm", - Some(a) => panic!("{} is not a supported architecture", a), - None => unreachable!(), + let mut library = Vec::new(); + let platform = platforms::Platform::find(&std::env::var("TARGET")?).unwrap(); + let arch = match platform.target_arch { + platforms::target::Arch::Arm => "arm", + platforms::Arch::AArch64 => "arm64", + platforms::Arch::X86 => "x86", + platforms::Arch::X86_64 => "amd64", + arch => panic!("{} is not a supported architecture", arch), }; archive .by_name(&format!("wintun/bin/{}/wintun.dll", arch))? - .read_to_end(&mut binary) - .context("Failed to read binary from wintun archive")?; + .read_to_end(&mut library)?; + std::fs::write(out_dir.join("wintun.dll"), library)?; - Ok((bindings, binary)) + println!("cargo:rerun-if-changed=build.rs"); + + Ok(()) +} + +#[cfg(not(windows))] +fn main() { + println!("cargo:rerun-if-changed=build.rs"); } #[cfg(windows)] -const WINTUN_FILENAME: &str = "wintun-0.14.1.zip"; +fn assert_content_hash(content: &[u8], hash: [u8; 32]) { + use sha2::digest::Update; + use sha2::Digest; -#[cfg(windows)] -const WINTUN_INTEGRITY: &str = "sha256-B8JWGF1u42UuCfpVwLZz4mJLVl4CxLkJHHnKfS8k71E="; - -#[cfg(windows)] -const WINTUN_BINDINGS_PREAMBLE: &str = r#" -WINTUN_CLOSE_ADAPTER_FUNC WintunCloseAdapter; -WINTUN_OPEN_ADAPTER_FUNC WintunOpenAdapter; -WINTUN_GET_ADAPTER_LUID_FUNC WintunGetAdapterLUID; -WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC WintunGetRunningDriverVersion; -WINTUN_DELETE_DRIVER_FUNC WintunDeleteDriver; -WINTUN_SET_LOGGER_FUNC WintunSetLogger; -WINTUN_START_SESSION_FUNC WintunStartSession; -WINTUN_END_SESSION_FUNC WintunEndSession; -WINTUN_CREATE_ADAPTER_FUNC WintunCreateAdapter; -WINTUN_GET_READ_WAIT_EVENT_FUNC WintunGetReadWaitEvent; -WINTUN_RECEIVE_PACKET_FUNC WintunReceivePacket; -WINTUN_RELEASE_RECEIVE_PACKET_FUNC WintunReleaseReceivePacket; -WINTUN_ALLOCATE_SEND_PACKET_FUNC WintunAllocateSendPacket; -WINTUN_SEND_PACKET_FUNC WintunSendPacket; -"#; + let computed = sha2::Sha256::new().chain(content).finalize(); + assert_eq!(computed.as_slice(), &hash[..]); +} diff --git a/tun/src/lib.rs b/tun/src/lib.rs index a1ca636..7e86059 100644 --- a/tun/src/lib.rs +++ b/tun/src/lib.rs @@ -1,18 +1,9 @@ -#![deny(missing_debug_implementations)] - #[cfg(target_os = "windows")] #[path = "windows/mod.rs"] -mod os_imp; +mod imp; #[cfg(any(target_os = "linux", target_vendor = "apple"))] #[path = "unix/mod.rs"] -pub(crate) mod os_imp; +pub(crate) mod imp; -mod options; - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -#[cfg(feature = "tokio")] -pub mod tokio; - -pub use options::TunOptions; -pub use os_imp::{TunInterface, TunQueue}; +pub use imp::{TunInterface, TunQueue}; diff --git a/tun/src/options.rs b/tun/src/options.rs deleted file mode 100644 index e21bf5f..0000000 --- a/tun/src/options.rs +++ /dev/null @@ -1,59 +0,0 @@ -use std::io::Error; - -use fehler::throws; - -#[cfg(any(target_os = "linux", target_vendor = "apple"))] -#[cfg(feature = "tokio")] -use super::tokio::TunInterface; - -#[derive(Debug, Clone, Default)] -#[cfg_attr( - feature = "serde", - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema) -)] -pub struct TunOptions { - /// (Windows + Linux) Name the tun interface. - pub name: Option, - /// (Linux) Don't include packet information. - pub no_pi: bool, - /// (Linux) Avoid opening an existing persistant device. - pub tun_excl: bool, - /// (Apple) Retrieve the tun interface - pub tun_retrieve: bool, - /// (Linux) The IP address of the tun interface. - pub address: Vec, -} - -impl TunOptions { - pub fn new() -> Self { - Self::default() - } - - pub fn name(mut self, name: &str) -> Self { - self.name = Some(name.to_owned()); - self - } - - pub fn no_pi(mut self, enable: bool) -> Self { - self.no_pi = enable; - self - } - - pub fn tun_excl(mut self, enable: bool) -> Self { - self.tun_excl = enable; - self - } - - pub fn address(mut self, address: Vec) -> Self { - self.address = address.iter().map(|x| x.to_string()).collect(); - self - } - - #[cfg(any(target_os = "linux", target_vendor = "apple"))] - #[cfg(feature = "tokio")] - #[throws] - pub fn open(self) -> TunInterface { - let ti = super::TunInterface::new_with_options(self)?; - TunInterface::new(ti)? - } -} diff --git a/tun/src/queue.rs b/tun/src/queue.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tun/src/queue.rs @@ -0,0 +1 @@ + diff --git a/tun/src/tokio/mod.rs b/tun/src/tokio/mod.rs deleted file mode 100644 index bd27109..0000000 --- a/tun/src/tokio/mod.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::io; - -use tokio::io::unix::AsyncFd; -use tracing::instrument; - -#[derive(Debug)] -pub struct TunInterface { - pub inner: AsyncFd, -} - -impl TunInterface { - #[instrument] - pub fn new(mut tun: crate::TunInterface) -> io::Result { - tun.set_nonblocking(true)?; - Ok(Self { inner: AsyncFd::new(tun)? }) - } - - #[instrument] - pub async fn send(&self, buf: &[u8]) -> io::Result { - loop { - let mut guard = self.inner.writable().await?; - match guard.try_io(|inner| inner.get_ref().send(buf)) { - Ok(result) => return result, - Err(_would_block) => continue, - } - } - } - - pub async fn recv(&self, buf: &mut [u8]) -> io::Result { - loop { - let mut guard = self.inner.readable().await?; - match guard.try_io(|inner| inner.get_ref().recv(buf)) { - Ok(result) => return result, - Err(_would_block) => { - tracing::debug!("WouldBlock"); - continue - } - } - } - } -} diff --git a/tun/src/unix/apple/kern_control.rs b/tun/src/unix/apple/kern_control.rs index 6075233..abc1e04 100644 --- a/tun/src/unix/apple/kern_control.rs +++ b/tun/src/unix/apple/kern_control.rs @@ -1,6 +1,7 @@ -use std::{io::Error, mem::size_of, os::unix::io::AsRawFd}; - use fehler::throws; +use std::io::Error; +use std::mem::size_of; +use std::os::unix::io::AsRawFd; use super::sys; @@ -15,16 +16,19 @@ pub trait SysControlSocket { impl SysControlSocket for socket2::Socket { #[throws] fn resolve(&self, name: &str, index: u32) -> socket2::SockAddr { - let mut info = sys::ctl_info { ctl_id: 0, ctl_name: [0; 96] }; + let mut info = sys::ctl_info { + ctl_id: 0, + ctl_name: [0; 96], + }; info.ctl_name[..name.len()].copy_from_slice(name.as_bytes()); unsafe { sys::resolve_ctl_info(self.as_raw_fd(), &mut info as *mut sys::ctl_info)? }; let (_, addr) = unsafe { - socket2::SockAddr::try_init(|addr_storage, len| { + socket2::SockAddr::init(|addr_storage, len| { *len = size_of::() as u32; - let addr: &mut sys::sockaddr_ctl = &mut *addr_storage.cast(); + let mut addr: &mut sys::sockaddr_ctl = &mut *addr_storage.cast(); addr.sc_len = *len as u8; addr.sc_family = sys::AF_SYSTEM as u8; addr.ss_sysaddr = sys::AF_SYS_CONTROL as u16; diff --git a/tun/src/unix/apple/mod.rs b/tun/src/unix/apple/mod.rs index 74e93eb..178ec6a 100644 --- a/tun/src/unix/apple/mod.rs +++ b/tun/src/unix/apple/mod.rs @@ -1,24 +1,17 @@ -use std::{ - io::{Error, IoSlice}, - mem, - net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4}, - os::fd::{AsRawFd, FromRawFd, RawFd}, -}; - -use byteorder::{ByteOrder, NetworkEndian}; use fehler::throws; -use libc::{c_char, iovec, writev, AF_INET, AF_INET6}; -use socket2::{Domain, SockAddr, Socket, Type}; -use tracing::{self, instrument}; +use libc::c_char; +use std::net::Ipv4Addr; +use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; +use std::io::Error; -pub mod kern_control; -pub mod sys; +mod sys; +mod kern_control; +pub use super::queue::TunQueue; + +use super::ifname_to_string; use kern_control::SysControlSocket; -use super::{ifname_to_string, string_to_ifname}; -use crate::TunOptions; - #[derive(Debug)] pub struct TunInterface { pub(crate) socket: socket2::Socket, @@ -26,63 +19,11 @@ pub struct TunInterface { impl TunInterface { #[throws] - #[instrument] pub fn new() -> TunInterface { - Self::new_with_options(TunOptions::new())? + TunInterface::connect(0)? } #[throws] - #[instrument] - pub fn new_with_options(options: TunOptions) -> TunInterface { - let ti = if options.tun_retrieve { - TunInterface::retrieve().ok_or(Error::new( - std::io::ErrorKind::NotFound, - "No tun interface found", - ))? - } else { - TunInterface::connect(0)? - }; - ti.configure(options)?; - ti - } - - pub fn retrieve() -> Option { - (3..100) - .filter_map(|fd| unsafe { - let peer_addr = socket2::SockAddr::try_init(|storage, len| { - *len = mem::size_of::() as u32; - libc::getpeername(fd, storage as *mut _, len); - Ok(()) - }) - .map(|(_, addr)| (fd, addr)); - peer_addr.ok() - }) - .filter(|(_fd, addr)| { - let ctl_addr = unsafe { &*(addr.as_ptr() as *const libc::sockaddr_ctl) }; - addr.family() == libc::AF_SYSTEM as u8 - && ctl_addr.ss_sysaddr == libc::AF_SYS_CONTROL as u16 - }) - .map(|(fd, _)| { - let socket = unsafe { socket2::Socket::from_raw_fd(fd) }; - TunInterface { socket } - }) - .next() - } - - #[throws] - fn configure(&self, options: TunOptions) { - for addr in options.address { - if let Ok(addr) = addr.parse::() { - match addr { - IpAddr::V4(addr) => self.set_ipv4_addr(addr)?, - IpAddr::V6(addr) => self.set_ipv6_addr(addr)?, - } - } - } - } - - #[throws] - #[instrument] fn connect(index: u32) -> TunInterface { use socket2::{Domain, Protocol, Socket, Type}; @@ -98,7 +39,6 @@ impl TunInterface { } #[throws] - #[instrument] pub fn name(&self) -> String { let mut buf = [0 as c_char; sys::IFNAMSIZ]; let mut len = buf.len() as sys::socklen_t; @@ -113,140 +53,24 @@ impl TunInterface { } #[throws] - #[instrument] - fn ifreq(&self) -> sys::ifreq { - let mut iff: sys::ifreq = unsafe { mem::zeroed() }; - iff.ifr_name = string_to_ifname(&self.name()?); - iff + pub fn set_ipv4_addr(&self, _addr: Ipv4Addr) { + todo!() } #[throws] - #[instrument] - fn in6_ifreq(&self) -> sys::in6_ifreq { - let mut iff: sys::in6_ifreq = unsafe { mem::zeroed() }; - iff.ifr_name = string_to_ifname(&self.name()?); - iff - } - - #[throws] - #[instrument] - pub fn set_ipv4_addr(&self, addr: Ipv4Addr) { - let addr = SockAddr::from(SocketAddrV4::new(addr, 0)); - let mut iff = self.ifreq()?; - iff.ifr_ifru.ifru_addr = unsafe { *addr.as_ptr() }; - self.perform(|fd| unsafe { sys::if_set_addr(fd, &iff) })?; - tracing::info!("ipv4_addr_set: {:?} (fd: {:?})", addr, self.as_raw_fd()) - } - - #[throws] - #[instrument] pub fn ipv4_addr(&self) -> Ipv4Addr { - let mut iff = self.ifreq()?; - self.perform(|fd| unsafe { sys::if_get_addr(fd, &mut iff) })?; - let addr = unsafe { *(&iff.ifr_ifru.ifru_addr as *const _ as *const sys::sockaddr_in) }; - Ipv4Addr::from(u32::from_be(addr.sin_addr.s_addr)) - } - - #[throws] - pub fn set_ipv6_addr(&self, _addr: Ipv6Addr) { - // let addr = SockAddr::from(SocketAddrV6::new(addr, 0, 0, 0)); - // println!("addr: {:?}", addr); - // let mut iff = self.in6_ifreq()?; - // let sto = addr.as_storage(); - // let ifadddr_ptr: *const sockaddr_in6 = addr_of!(sto).cast(); - // iff.ifr_ifru.ifru_addr = unsafe { *ifadddr_ptr }; - // println!("ifru addr set"); - // println!("{:?}", sys::SIOCSIFADDR_IN6); - // self.perform6(|fd| unsafe { sys::if_set_addr6(fd, &iff) })?; - // tracing::info!("ipv6_addr_set"); - tracing::warn!("Setting IPV6 address on MacOS CLI mode is not supported yet."); - } - - #[throws] - fn perform(&self, perform: impl FnOnce(RawFd) -> Result) -> R { - let span = tracing::info_span!("perform", fd = self.as_raw_fd()); - let _enter = span.enter(); - - let socket = Socket::new(Domain::IPV4, Type::DGRAM, None)?; - perform(socket.as_raw_fd())? - } - - #[throws] - fn perform6(&self, perform: impl FnOnce(RawFd) -> Result) -> R { - let span = tracing::info_span!("perform6", fd = self.as_raw_fd()); - let _enter = span.enter(); - - let socket = Socket::new(Domain::IPV6, Type::DGRAM, None)?; - perform(socket.as_raw_fd())? - } - - #[throws] - #[instrument] - pub fn mtu(&self) -> i32 { - let mut iff = self.ifreq()?; - self.perform(|fd| unsafe { sys::if_get_mtu(fd, &mut iff) })?; - let mtu = unsafe { iff.ifr_ifru.ifru_mtu }; - - mtu - } - - #[throws] - #[instrument] - pub fn set_mtu(&self, mtu: i32) { - let mut iff = self.ifreq()?; - iff.ifr_ifru.ifru_mtu = mtu; - self.perform(|fd| unsafe { sys::if_set_mtu(fd, &iff) })?; - tracing::info!("mtu_set: {:?} (fd: {:?})", mtu, self.as_raw_fd()) - } - - #[throws] - #[instrument] - pub fn netmask(&self) -> Ipv4Addr { - let mut iff = self.ifreq()?; - self.perform(|fd| unsafe { sys::if_get_netmask(fd, &mut iff) })?; - - let netmask = - unsafe { *(&iff.ifr_ifru.ifru_netmask as *const _ as *const sys::sockaddr_in) }; - - Ipv4Addr::from(u32::from_be(netmask.sin_addr.s_addr)) - } - - #[throws] - #[instrument] - pub fn set_netmask(&self, addr: Ipv4Addr) { - let addr = SockAddr::from(SocketAddrV4::new(addr, 0)); - let mut iff = self.ifreq()?; - iff.ifr_ifru.ifru_netmask = unsafe { *addr.as_ptr() }; - self.perform(|fd| unsafe { sys::if_set_netmask(fd, &iff) })?; - tracing::info!( - "netmask_set: {:?} (fd: {:?})", - unsafe { iff.ifr_ifru.ifru_netmask }, - self.as_raw_fd() - ) - } - - #[throws] - #[instrument] - pub fn send(&self, buf: &[u8]) -> usize { - use std::io::ErrorKind; - let proto = match buf[0] >> 4 { - 6 => Ok(AF_INET6), - 4 => Ok(AF_INET), - _ => Err(Error::new(ErrorKind::InvalidInput, "Invalid IP version")), - }?; - let mut pbuf = [0; 4]; - NetworkEndian::write_i32(&mut pbuf, proto); - - let bufs = [IoSlice::new(&pbuf), IoSlice::new(buf)]; - let bytes_written: isize = unsafe { - writev( - self.as_raw_fd(), - bufs.as_ptr() as *const iovec, - bufs.len() as i32, - ) - }; - bytes_written - .try_into() - .map_err(|_| Error::new(ErrorKind::Other, "Conversion error"))? + todo!() + } +} + +impl AsRawFd for TunInterface { + fn as_raw_fd(&self) -> RawFd { + self.socket.as_raw_fd() + } +} + +impl IntoRawFd for TunInterface { + fn into_raw_fd(self) -> RawFd { + self.socket.into_raw_fd() } } diff --git a/tun/src/unix/apple/sys.rs b/tun/src/unix/apple/sys.rs index d48d6ee..ff909ed 100644 --- a/tun/src/unix/apple/sys.rs +++ b/tun/src/unix/apple/sys.rs @@ -1,203 +1,35 @@ -use std::mem; - -use libc::{c_char, c_int, c_short, c_uint, c_ulong, sockaddr, sockaddr_in6, time_t}; -pub use libc::{ - c_void, - sockaddr_ctl, - sockaddr_in, - socklen_t, - AF_SYSTEM, - AF_SYS_CONTROL, - IFNAMSIZ, - SYSPROTO_CONTROL, -}; -use nix::{ - ioctl_read_bad, - ioctl_readwrite, - ioctl_write_ptr_bad, - request_code_readwrite, - request_code_write, -}; +pub use libc::{c_void, socklen_t, SYSPROTO_CONTROL, IFNAMSIZ, sockaddr_ctl, AF_SYSTEM, AF_SYS_CONTROL}; +use nix::ioctl_readwrite; pub const UTUN_CONTROL_NAME: &str = "com.apple.net.utun_control"; pub const UTUN_OPT_IFNAME: libc::c_int = 2; pub const MAX_KCTL_NAME: usize = 96; -pub const SCOPE6_ID_MAX: usize = 16; -#[repr(C)] -#[derive(Copy, Clone, Debug)] + #[repr(C)] pub struct ctl_info { pub ctl_id: u32, pub ctl_name: [u8; MAX_KCTL_NAME], } #[repr(C)] -#[derive(Copy, Clone, Debug)] -pub struct ifkpi { - pub ifk_module_id: c_uint, - pub ifk_type: c_uint, - pub ifk_ptr: *mut c_void, -} +pub struct ifreq {} -#[repr(C)] -#[derive(Copy, Clone, Debug)] -pub struct ifdevmtu { - pub ifdm_current: c_int, - pub ifdm_min: c_int, - pub ifdm_max: c_int, -} - -#[repr(C)] -pub union ifr_ifru { - pub ifru_addr: sockaddr, - pub ifru_dstaddr: sockaddr, - pub ifru_broadaddr: sockaddr, - pub ifru_netmask: sockaddr, - pub ifru_flags: c_short, - pub ifru_metric: c_int, - pub ifru_mtu: c_int, - pub ifru_phys: c_int, - pub ifru_media: c_int, - pub ifru_intval: c_int, - pub ifru_data: *mut c_char, - pub ifru_devmtu: ifdevmtu, - pub ifru_kpi: ifkpi, - pub ifru_wake_flags: u32, - pub ifru_route_refcnt: u32, - pub ifru_cap: [c_int; 2], - pub ifru_functional_type: u32, -} - -#[repr(C)] -pub struct ifreq { - pub ifr_name: [c_char; IFNAMSIZ], - pub ifr_ifru: ifr_ifru, -} - -#[repr(C)] -#[derive(Copy, Clone, Debug)] -pub struct in6_addrlifetime{ - pub ia6t_expire: time_t, - pub ia6t_preferred: time_t, - pub ia6t_vltime: u32, - pub ia6t_pltime: u32, -} - -#[repr(C)] -#[derive(Copy, Clone, Debug)] -pub struct in6_ifstat { - pub ifs6_in_receive: u64, - pub ifs6_in_hdrerr: u64, - pub ifs6_in_toobig: u64, - pub ifs6_in_noroute: u64, - pub ifs6_in_addrerr: u64, - pub ifs6_in_protounknown: u64, - pub ifs6_in_truncated: u64, - pub ifs6_in_discard: u64, - pub ifs6_in_deliver: u64, - pub ifs6_out_forward: u64, - pub ifs6_out_request: u64, - pub ifs6_out_discard: u64, - pub ifs6_out_fragok: u64, - pub ifs6_out_fragfail: u64, - pub ifs6_out_fragcreat: u64, - pub ifs6_reass_reqd: u64, - pub ifs6_reass_ok: u64, - pub ifs6_atmfrag_rcvd: u64, - pub ifs6_reass_fail: u64, - pub ifs6_in_mcast: u64, - pub ifs6_out_mcast: u64, - pub ifs6_cantfoward_icmp6: u64, - pub ifs6_addr_expiry_cnt: u64, - pub ifs6_pfx_expiry_cnt: u64, - pub ifs6_defrtr_expiry_cnt: u64, -} - -#[repr(C)] -#[derive(Copy, Clone, Debug)] -pub struct icmp6_ifstat { - pub ifs6_in_msg: u64, - pub ifs6_in_error: u64, - pub ifs6_in_dstunreach: u64, - pub ifs6_in_adminprohib: u64, - pub ifs6_in_timeexceed: u64, - pub ifs6_in_paramprob: u64, - pub ifs6_in_pkttoobig: u64, - pub ifs6_in_echo: u64, - pub ifs6_in_echoreply: u64, - pub ifs6_in_routersolicit: u64, - pub ifs6_in_routeradvert: u64, - pub ifs6_in_neighborsolicit: u64, - pub ifs6_in_neighboradvert: u64, - pub ifs6_in_redirect: u64, - pub ifs6_in_mldquery: u64, - pub ifs6_in_mldreport: u64, - pub ifs6_in_mlddone: u64, - pub ifs6_out_msg: u64, - pub ifs6_out_error: u64, - pub ifs6_out_dstunreach: u64, - pub ifs6_out_adminprohib: u64, - pub ifs6_out_timeexceed: u64, - pub ifs6_out_paramprob: u64, - pub ifs6_out_pkttoobig: u64, - pub ifs6_out_echo: u64, - pub ifs6_out_echoreply: u64, - pub ifs6_out_routersolicit: u64, - pub ifs6_out_routeradvert: u64, - pub ifs6_out_neighborsolicit: u64, - pub ifs6_out_neighboradvert: u64, - pub ifs6_out_redirect: u64, - pub ifs6_out_mldquery: u64, - pub ifs6_out_mldreport: u64, - pub ifs6_out_mlddone: u64, -} - -#[repr(C)] -pub union ifr_ifru6 { - pub ifru_addr: sockaddr_in6, - pub ifru_dstaddr: sockaddr_in6, - pub ifru_flags: c_int, - pub ifru_flags6: c_int, - pub ifru_metric: c_int, - pub ifru_intval: c_int, - pub ifru_data: *mut c_char, - pub ifru_lifetime: in6_addrlifetime, // ifru_lifetime - pub ifru_stat: in6_ifstat, - pub ifru_icmp6stat: icmp6_ifstat, - pub ifru_scope_id: [u32; SCOPE6_ID_MAX] -} - -#[repr(C)] -pub struct in6_ifreq { - pub ifr_name: [c_char; IFNAMSIZ], - pub ifr_ifru: ifr_ifru6, -} - -pub const SIOCSIFADDR: c_ulong = request_code_write!(b'i', 12, mem::size_of::()); -pub const SIOCSIFADDR_IN6: c_ulong = request_code_write!(b'i', 12, mem::size_of::()); -pub const SIOCGIFMTU: c_ulong = request_code_readwrite!(b'i', 51, mem::size_of::()); -pub const SIOCSIFMTU: c_ulong = request_code_write!(b'i', 52, mem::size_of::()); -pub const SIOCGIFNETMASK: c_ulong = request_code_readwrite!(b'i', 37, mem::size_of::()); -pub const SIOCSIFNETMASK: c_ulong = request_code_write!(b'i', 22, mem::size_of::()); +ioctl_readwrite!(resolve_ctl_info, b'N', 3, ctl_info); +/// Copied from https://github.com/rust-lang/socket2/blob/61314a231f73964b3db969ef72c0e9479df320f3/src/sys/unix.rs#L168-L178 +/// getsockopt is not exposed by socket2 #[macro_export] macro_rules! syscall { - ($call: ident ( $($arg: expr),* $(,)* ) ) => {{ - match unsafe { ::libc::$call($($arg, )*) } { - -1 => Err(::std::io::Error::last_os_error()), - res => Ok(res), + ($fn: ident ( $($arg: expr),* $(,)* ) ) => {{ + #[allow(unused_unsafe)] + let res = unsafe { libc::$fn($($arg, )*) }; + if res == -1 { + Err(std::io::Error::last_os_error()) + } else { + Ok(res) } }}; } pub use syscall; - -ioctl_readwrite!(resolve_ctl_info, b'N', 3, ctl_info); -ioctl_read_bad!(if_get_addr, libc::SIOCGIFADDR, ifreq); -ioctl_read_bad!(if_get_mtu, SIOCGIFMTU, ifreq); -ioctl_read_bad!(if_get_netmask, SIOCGIFNETMASK, ifreq); -ioctl_write_ptr_bad!(if_set_addr, SIOCSIFADDR, ifreq); -ioctl_write_ptr_bad!(if_set_addr6, SIOCSIFADDR_IN6, in6_ifreq); -ioctl_write_ptr_bad!(if_set_mtu, SIOCSIFMTU, ifreq); -ioctl_write_ptr_bad!(if_set_netmask, SIOCSIFNETMASK, ifreq); diff --git a/tun/src/unix/linux/mod.rs b/tun/src/unix/linux/mod.rs index 60d6341..cc80f97 100644 --- a/tun/src/unix/linux/mod.rs +++ b/tun/src/unix/linux/mod.rs @@ -1,21 +1,14 @@ -use std::{ - fs::OpenOptions, - io::{Error, Write}, - mem, - net::{Ipv4Addr, Ipv6Addr, SocketAddrV4}, - os::{ - fd::RawFd, - unix::io::{AsRawFd, FromRawFd, IntoRawFd}, - }, -}; - use fehler::throws; -use libc::in6_ifreq; + use socket2::{Domain, SockAddr, Socket, Type}; -use tracing::{info, instrument}; +use std::fs::OpenOptions; +use std::io::Error; +use std::mem; +use std::net::{Ipv4Addr, SocketAddrV4}; +use std::os::fd::RawFd; +use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd}; use super::{ifname_to_string, string_to_ifname}; -use crate::TunOptions; mod sys; @@ -26,36 +19,17 @@ pub struct TunInterface { impl TunInterface { #[throws] - #[instrument] pub fn new() -> TunInterface { - Self::new_with_options(TunOptions::new())? - } - - #[throws] - #[instrument] - pub(crate) fn new_with_options(options: TunOptions) -> TunInterface { let file = OpenOptions::new() .read(true) .write(true) .open("/dev/net/tun")?; - let mut flags = libc::IFF_TUN as i16; - - if options.no_pi { - flags |= libc::IFF_NO_PI as i16; - } - if options.tun_excl { - flags |= libc::IFF_TUN_EXCL as i16; - } - - let name = options - .name - .map(|name| string_to_ifname(&name)) - .unwrap_or([0; libc::IFNAMSIZ]); - let iff = libc::ifreq { - ifr_name: name, - ifr_ifru: libc::__c_anonymous_ifr_ifru { ifru_flags: flags }, + ifr_name: [0; libc::IFNAMSIZ], + ifr_ifru: libc::__c_anonymous_ifr_ifru { + ifru_flags: (libc::IFF_TUN | libc::IFF_TUN_EXCL | libc::IFF_NO_PI) as i16, + }, }; unsafe { sys::tun_set_iff(file.as_raw_fd(), &iff)? }; @@ -64,7 +38,6 @@ impl TunInterface { } #[throws] - #[instrument] pub fn name(&self) -> String { let mut iff = unsafe { mem::zeroed() }; unsafe { sys::tun_get_iff(self.socket.as_raw_fd(), &mut iff)? }; @@ -72,7 +45,6 @@ impl TunInterface { } #[throws] - #[instrument] fn ifreq(&self) -> sys::ifreq { let mut iff: sys::ifreq = unsafe { mem::zeroed() }; iff.ifr_name = string_to_ifname(&self.name()?); @@ -80,15 +52,6 @@ impl TunInterface { } #[throws] - #[instrument] - fn in6_ifreq(&self) -> in6_ifreq { - let mut iff: in6_ifreq = unsafe { mem::zeroed() }; - iff.ifr6_ifindex = self.index()?; - iff - } - - #[throws] - #[instrument] pub fn index(&self) -> i32 { let mut iff = self.ifreq()?; self.perform(|fd| unsafe { sys::if_get_index(fd, &mut iff) })?; @@ -96,17 +59,16 @@ impl TunInterface { } #[throws] - #[instrument] pub fn set_ipv4_addr(&self, addr: Ipv4Addr) { let addr = SockAddr::from(SocketAddrV4::new(addr, 0)); + let mut iff = self.ifreq()?; iff.ifr_ifru.ifru_addr = unsafe { *addr.as_ptr() }; + self.perform(|fd| unsafe { sys::if_set_addr(fd, &iff) })?; - info!("ipv4_addr_set: {:?} (fd: {:?})", addr, self.as_raw_fd()) } #[throws] - #[instrument] pub fn ipv4_addr(&self) -> Ipv4Addr { let mut iff = self.ifreq()?; self.perform(|fd| unsafe { sys::if_get_addr(fd, &mut iff) })?; @@ -114,108 +76,9 @@ impl TunInterface { Ipv4Addr::from(u32::from_be(addr.sin_addr.s_addr)) } - #[throws] - #[instrument] - pub fn set_broadcast_addr(&self, addr: Ipv4Addr) { - let addr = SockAddr::from(SocketAddrV4::new(addr, 0)); - let mut iff = self.ifreq()?; - iff.ifr_ifru.ifru_broadaddr = unsafe { *addr.as_ptr() }; - self.perform(|fd| unsafe { sys::if_set_brdaddr(fd, &iff) })?; - info!( - "broadcast_addr_set: {:?} (fd: {:?})", - addr, - self.as_raw_fd() - ) - } - - #[throws] - #[instrument] - pub fn broadcast_addr(&self) -> Ipv4Addr { - let mut iff = self.ifreq()?; - self.perform(|fd| unsafe { sys::if_get_brdaddr(fd, &mut iff) })?; - let addr = - unsafe { *(&iff.ifr_ifru.ifru_broadaddr as *const _ as *const sys::sockaddr_in) }; - Ipv4Addr::from(u32::from_be(addr.sin_addr.s_addr)) - } - - #[throws] - #[instrument] - pub fn set_ipv6_addr(&self, addr: Ipv6Addr) { - let mut iff = self.in6_ifreq()?; - iff.ifr6_addr.s6_addr = addr.octets(); - self.perform6(|fd| unsafe { sys::if_set_addr6(fd, &iff) })?; - info!("ipv6_addr_set: {:?} (fd: {:?})", addr, self.as_raw_fd()) - } - - #[throws] - #[instrument] - pub fn set_mtu(&self, mtu: i32) { - let mut iff = self.ifreq()?; - iff.ifr_ifru.ifru_mtu = mtu; - self.perform(|fd| unsafe { sys::if_set_mtu(fd, &iff) })?; - info!("mtu_set: {:?} (fd: {:?})", mtu, self.as_raw_fd()) - } - - #[throws] - #[instrument] - pub fn mtu(&self) -> i32 { - let mut iff = self.ifreq()?; - self.perform(|fd| unsafe { sys::if_get_mtu(fd, &mut iff) })?; - let mtu = unsafe { iff.ifr_ifru.ifru_mtu }; - - mtu - } - - #[throws] - #[instrument] - pub fn set_netmask(&self, addr: Ipv4Addr) { - let addr = SockAddr::from(SocketAddrV4::new(addr, 0)); - - let mut iff = self.ifreq()?; - iff.ifr_ifru.ifru_netmask = unsafe { *addr.as_ptr() }; - - self.perform(|fd| unsafe { sys::if_set_netmask(fd, &iff) })?; - - info!( - "netmask_set: {:?} (fd: {:?})", - unsafe { iff.ifr_ifru.ifru_netmask }, - self.as_raw_fd() - ) - } - - #[throws] - #[instrument] - pub fn netmask(&self) -> Ipv4Addr { - let mut iff = self.ifreq()?; - self.perform(|fd| unsafe { sys::if_get_netmask(fd, &mut iff) })?; - - let netmask = - unsafe { *(&iff.ifr_ifru.ifru_netmask as *const _ as *const sys::sockaddr_in) }; - - Ipv4Addr::from(u32::from_be(netmask.sin_addr.s_addr)) - } - #[throws] fn perform(&self, perform: impl FnOnce(RawFd) -> Result) -> R { - let span = tracing::info_span!("perform"); - let _enter = span.enter(); - let socket = Socket::new(Domain::IPV4, Type::DGRAM, None)?; perform(socket.as_raw_fd())? } - - #[throws] - fn perform6(&self, perform: impl FnOnce(RawFd) -> Result) -> R { - let span = tracing::info_span!("perform"); - let _enter = span.enter(); - - let socket = Socket::new(Domain::IPV6, Type::DGRAM, None)?; - perform(socket.as_raw_fd())? - } - - #[throws] - #[instrument] - pub fn send(&self, buf: &[u8]) -> usize { - self.socket.send(buf)? - } } diff --git a/tun/src/unix/linux/sys.rs b/tun/src/unix/linux/sys.rs index e12c8ec..5df22d9 100644 --- a/tun/src/unix/linux/sys.rs +++ b/tun/src/unix/linux/sys.rs @@ -1,7 +1,8 @@ +use nix::{ioctl_read_bad, ioctl_write_ptr_bad, request_code_read, request_code_write}; use std::mem::size_of; -pub use libc::{ifreq, sockaddr, sockaddr_in, sockaddr_in6}; -use nix::{ioctl_read_bad, ioctl_write_ptr_bad, request_code_read, request_code_write}; +pub use libc::ifreq; +pub use libc::sockaddr_in; ioctl_write_ptr_bad!( tun_set_iff, @@ -15,12 +16,4 @@ ioctl_read_bad!( ); ioctl_read_bad!(if_get_index, libc::SIOCGIFINDEX, libc::ifreq); ioctl_read_bad!(if_get_addr, libc::SIOCGIFADDR, libc::ifreq); -ioctl_read_bad!(if_get_brdaddr, libc::SIOCGIFBRDADDR, libc::ifreq); -ioctl_read_bad!(if_get_mtu, libc::SIOCGIFMTU, libc::ifreq); -ioctl_read_bad!(if_get_netmask, libc::SIOCGIFNETMASK, libc::ifreq); - ioctl_write_ptr_bad!(if_set_addr, libc::SIOCSIFADDR, libc::ifreq); -ioctl_write_ptr_bad!(if_set_addr6, libc::SIOCSIFADDR, libc::in6_ifreq); -ioctl_write_ptr_bad!(if_set_brdaddr, libc::SIOCSIFBRDADDR, libc::ifreq); -ioctl_write_ptr_bad!(if_set_mtu, libc::SIOCSIFMTU, libc::ifreq); -ioctl_write_ptr_bad!(if_set_netmask, libc::SIOCSIFNETMASK, libc::ifreq); diff --git a/tun/src/unix/mod.rs b/tun/src/unix/mod.rs index ae0b77a..615e647 100644 --- a/tun/src/unix/mod.rs +++ b/tun/src/unix/mod.rs @@ -1,11 +1,3 @@ -use std::{ - io::Error, - mem::MaybeUninit, - os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd}, -}; - -use tracing::instrument; - mod queue; #[cfg(target_vendor = "apple")] @@ -16,53 +8,9 @@ mod imp; #[path = "linux/mod.rs"] mod imp; -use fehler::throws; pub use imp::TunInterface; pub use queue::TunQueue; -impl AsRawFd for TunInterface { - fn as_raw_fd(&self) -> RawFd { - self.socket.as_raw_fd() - } -} - -impl FromRawFd for TunInterface { - unsafe fn from_raw_fd(fd: RawFd) -> TunInterface { - let socket = socket2::Socket::from_raw_fd(fd); - TunInterface { socket } - } -} - -impl IntoRawFd for TunInterface { - fn into_raw_fd(self) -> RawFd { - self.socket.into_raw_fd() - } -} - -unsafe fn assume_init(buf: &[MaybeUninit]) -> &[u8] { - &*(buf as *const [MaybeUninit] as *const [u8]) -} - -impl TunInterface { - #[throws] - #[instrument] - pub fn recv(&self, buf: &mut [u8]) -> usize { - // Use IoVec to read directly into target buffer - let mut tmp_buf = [MaybeUninit::uninit(); 1500]; - let len = self.socket.recv(&mut tmp_buf)?; - let result_buf = unsafe { assume_init(&tmp_buf[4..len]) }; - buf[..len - 4].copy_from_slice(result_buf); - len - 4 - } - - #[throws] - #[instrument] - pub fn set_nonblocking(&mut self, nb: bool) { - self.socket.set_nonblocking(nb)?; - } -} - -#[instrument] pub fn ifname_to_string(buf: [libc::c_char; libc::IFNAMSIZ]) -> String { // TODO: Switch to `CStr::from_bytes_until_nul` when stabilized unsafe { @@ -73,7 +21,6 @@ pub fn ifname_to_string(buf: [libc::c_char; libc::IFNAMSIZ]) -> String { } } -#[instrument] pub fn string_to_ifname(name: &str) -> [libc::c_char; libc::IFNAMSIZ] { let mut buf = [0 as libc::c_char; libc::IFNAMSIZ]; let len = name.len().min(buf.len()); diff --git a/tun/src/unix/queue.rs b/tun/src/unix/queue.rs index 879dcd5..1288a3b 100644 --- a/tun/src/unix/queue.rs +++ b/tun/src/unix/queue.rs @@ -1,23 +1,21 @@ +use fehler::throws; + use std::{ io::{Error, Read, Write}, mem::MaybeUninit, os::unix::io::{AsRawFd, IntoRawFd, RawFd}, }; -use fehler::throws; -use tracing::instrument; - use crate::TunInterface; -#[derive(Debug)] pub struct TunQueue { socket: socket2::Socket, } impl TunQueue { - #[instrument] - pub fn recv(&self, buf: &mut [MaybeUninit]) -> Result { - self.socket.recv(buf) + #[throws] + pub fn recv(&self, buf: &mut [MaybeUninit]) -> usize { + self.socket.recv(buf)? } } @@ -42,7 +40,9 @@ impl Write for TunQueue { impl From for TunQueue { fn from(interface: TunInterface) -> TunQueue { - TunQueue { socket: interface.socket } + TunQueue { + socket: interface.socket, + } } } diff --git a/tun/src/windows/mod.rs b/tun/src/windows/mod.rs index dadd53f..6c831d1 100644 --- a/tun/src/windows/mod.rs +++ b/tun/src/windows/mod.rs @@ -1,45 +1,28 @@ -use std::{fmt::Debug, io::Error, ptr}; +use std::io::Result; +use std::ptr; +use widestring::{u16cstr, U16CString}; -use fehler::throws; -use widestring::U16CString; -use windows::Win32::Foundation::GetLastError; mod queue; pub use queue::TunQueue; -use super::TunOptions; - pub struct TunInterface { + wintun: sys::wintun, handle: sys::WINTUN_ADAPTER_HANDLE, name: String, } -impl Debug for TunInterface { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("TunInterface") - .field("handle", &"SYS_WINTUN_ADAPTER_HANDLE".to_string()) - .field("name", &self.name) - .finish() - } -} - impl TunInterface { - #[throws] - pub fn new() -> TunInterface { - Self::new_with_options(TunOptions::new())? - } - - #[throws] - pub(crate) fn new_with_options(options: TunOptions) -> TunInterface { - let name_owned = options.name.unwrap_or("Burrow".to_owned()); - let name = U16CString::from_str(&name_owned).unwrap(); - + pub fn new() -> Result { + let name = U16CString::from(u16cstr!("ConradNet")); + let wintun = sys::wintun::default(); let handle = - unsafe { sys::WINTUN.WintunCreateAdapter(name.as_ptr(), name.as_ptr(), ptr::null()) }; - if handle.is_null() { - unsafe { GetLastError() }.ok()? - } - TunInterface { handle, name: name_owned } + unsafe { wintun.WintunCreateAdapter(name.as_ptr(), name.as_ptr(), ptr::null()) }; + Ok(TunInterface { + wintun, + handle, + name: String::from("ConradNet"), + }) } pub fn name(&self) -> String { @@ -49,25 +32,17 @@ impl TunInterface { impl Drop for TunInterface { fn drop(&mut self) { - unsafe { sys::WINTUN.WintunCloseAdapter(self.handle) } + unsafe { self.wintun.WintunCloseAdapter(self.handle) } } } pub(crate) mod sys { - #![allow(clippy::all, dead_code, non_camel_case_types, non_snake_case)] + #![allow(dead_code, non_camel_case_types, non_snake_case)] include!(concat!(env!("OUT_DIR"), "/wintun.rs")); - const WINTUN_BINARY: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/wintun.dll")); - - lazy_static::lazy_static! { - pub static ref WINTUN: wintun = { - use std::io::Write; - - let mut temp_file = tempfile::NamedTempFile::new().unwrap(); - temp_file.write_all(&WINTUN_BINARY).unwrap(); - let (_, path) = temp_file.keep().unwrap(); - - unsafe { wintun::new(&path) }.unwrap() - }; + impl Default for wintun { + fn default() -> Self { + unsafe { wintun::new(format!("{}/wintun.dll", env!("OUT_DIR"))).unwrap() } + } } } diff --git a/tun/src/windows/queue.rs b/tun/src/windows/queue.rs index 8fa9e19..609da89 100644 --- a/tun/src/windows/queue.rs +++ b/tun/src/windows/queue.rs @@ -1,2 +1 @@ -#[derive(Debug)] pub struct TunQueue; diff --git a/tun/tests/configure.rs b/tun/tests/configure.rs index e7e2c6d..29674b6 100644 --- a/tun/tests/configure.rs +++ b/tun/tests/configure.rs @@ -1,7 +1,7 @@ -use std::{io::Error, net::Ipv4Addr}; - use fehler::throws; use tun::TunInterface; +use std::io::Error; +use std::net::Ipv4Addr; #[test] #[throws] @@ -11,22 +11,6 @@ fn test_create() { #[test] #[throws] -#[cfg(not(any(target_os = "windows", target_vendor = "apple")))] -fn test_set_get_broadcast_addr() { - let tun = TunInterface::new()?; - let addr = Ipv4Addr::new(10, 0, 0, 1); - tun.set_ipv4_addr(addr)?; - - let broadcast_addr = Ipv4Addr::new(255, 255, 255, 0); - tun.set_broadcast_addr(broadcast_addr)?; - let result = tun.broadcast_addr()?; - - assert_eq!(broadcast_addr, result); -} - -#[test] -#[throws] -#[cfg(not(target_os = "windows"))] fn test_set_get_ipv4() { let tun = TunInterface::new()?; @@ -35,45 +19,4 @@ fn test_set_get_ipv4() { let result = tun.ipv4_addr()?; assert_eq!(addr, result); -} - -#[test] -#[throws] -#[cfg(not(any(target_os = "windows", target_vendor = "apple")))] -fn test_set_get_ipv6() { - use std::net::Ipv6Addr; - - let tun = TunInterface::new()?; - - let addr = Ipv6Addr::new(1, 1, 1, 1, 1, 1, 1, 1); - tun.set_ipv6_addr(addr)?; - - // let result = tun.ipv6_addr()?; - // assert_eq!(addr, result); -} - -#[test] -#[throws] -#[cfg(not(target_os = "windows"))] -fn test_set_get_mtu() { - let interf = TunInterface::new()?; - - interf.set_mtu(500)?; - - assert_eq!(interf.mtu().unwrap(), 500); -} - -#[test] -#[throws] -#[cfg(not(target_os = "windows"))] -fn test_set_get_netmask() { - let interf = TunInterface::new()?; - - let netmask = Ipv4Addr::new(255, 0, 0, 0); - let addr = Ipv4Addr::new(192, 168, 1, 1); - - interf.set_ipv4_addr(addr)?; - interf.set_netmask(netmask)?; - - assert_eq!(interf.netmask()?, netmask); -} +} \ No newline at end of file diff --git a/tun/tests/packets.rs b/tun/tests/packets.rs deleted file mode 100644 index 80c078b..0000000 --- a/tun/tests/packets.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::{io::Error, net::Ipv4Addr}; -use std::net::Ipv6Addr; - -use fehler::throws; -use tun::TunInterface; - -#[throws] -#[test] -#[ignore = "requires interactivity"] -#[cfg(not(target_os = "windows"))] -fn tst_read() { - // This test is interactive, you need to send a packet to any server through - // 192.168.1.10 EG. `sudo route add 8.8.8.8 192.168.1.10`, - //`dig @8.8.8.8 hackclub.com` - let tun = TunInterface::new()?; - println!("tun name: {:?}", tun.name()?); - tun.set_ipv4_addr(Ipv4Addr::from([192, 168, 1, 10]))?; - println!("tun ip: {:?}", tun.ipv4_addr()?); - println!("Waiting for a packet..."); - let buf = &mut [0u8; 1500]; - let res = tun.recv(buf); - println!("Received!"); - assert!(res.is_ok()); -} - -#[test] -#[throws] -#[ignore = "requires interactivity"] -#[cfg(not(target_os = "windows"))] -fn write_packets() { - let tun = TunInterface::new()?; - let mut buf = [0u8; 1500]; - buf[0] = 6 << 4; - let bytes_written = tun.send(&buf)?; - assert_eq!(bytes_written, 1504); -} - -#[test] -#[throws] -#[ignore = "requires interactivity"] -#[cfg(not(target_os = "windows"))] -fn set_ipv6() { - let tun = TunInterface::new()?; - println!("tun name: {:?}", tun.name()?); - let targ_addr: Ipv6Addr = "::1".parse().unwrap(); - println!("v6 addr: {:?}", targ_addr); - tun.set_ipv6_addr(targ_addr)?; -} \ No newline at end of file diff --git a/tun/tests/tokio.rs b/tun/tests/tokio.rs deleted file mode 100644 index f7cb273..0000000 --- a/tun/tests/tokio.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::net::Ipv4Addr; - -#[tokio::test] -#[cfg(all(feature = "tokio", not(target_os = "windows")))] -async fn test_create() { - let tun = tun::TunInterface::new().unwrap(); - let _ = tun::tokio::TunInterface::new(tun).unwrap(); -} - -#[tokio::test] -#[ignore = "requires interactivity"] -#[cfg(all(feature = "tokio", not(target_os = "windows")))] -async fn test_write() { - let tun = tun::TunInterface::new().unwrap(); - tun.set_ipv4_addr(Ipv4Addr::from([192, 168, 1, 10])) - .unwrap(); - let async_tun = tun::tokio::TunInterface::new(tun).unwrap(); - let mut buf = [0u8; 1500]; - buf[0] = 6 << 4; - let bytes_written = async_tun.send(&buf).await.unwrap(); - assert!(bytes_written > 0); -}