diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 412fb9b..ff1d3d3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,21 +2,28 @@ # Additionally, lint the code before anything else to fail more quickly stages: - lint + - check - build - test - release - dockerify default: - image: "rust:latest" + image: "registry.gitlab.com/fabinfra/rust-builder:latest" tags: - linux - docker + - fabinfra variables: GIT_SUBMODULE_STRATEGY: recursive CARGO_HOME: $CI_PROJECT_DIR/cargo APT_CACHE_DIR: $CI_PROJECT_DIR/apt + FF_USE_FASTZIP: "true" # enable fastzip - a faster zip implementation that also supports level configuration. + ARTIFACT_COMPRESSION_LEVEL: fast # can also be set to fastest, fast, slow and slowest. If just enabling fastzip is not enough try setting this to fastest or fast. + CACHE_COMPRESSION_LEVEL: fastest # same as above, but for caches + TRANSFER_METER_FREQUENCY: 5s # will display transfer progress every 5 seconds for artifacts and remote caches. + # cache dependencies and build environment to speed up setup cache: @@ -26,10 +33,6 @@ cache: - cargo/ - target/ -# install build dependencies -before_script: - - apt-get update -yqq - - apt-get install -o dir::cache::archives="$APT_CACHE_DIR" -yqq --no-install-recommends capnproto build-essential cmake clang libclang-dev jq .lints: stage: lint @@ -41,7 +44,6 @@ before_script: lint:clippy: extends: .lints script: - - rustup component add clippy - cargo clippy -V - echo -e "\e[0Ksection_start:`date +%s`:clippy_output\r\e[0Kcargo clippy output" - cargo clippy -- --no-deps @@ -51,15 +53,14 @@ lint:clippy: lint:fmt: extends: .lints script: - - rustup component add rustfmt - cargo fmt --version - echo -e "\e[0Ksection_start:`date +%s`:rustfmt_output\r\e[0KChanges suggested by rustfmt" - cargo fmt --check -- -v - echo -e "\e[0Ksection_end:`date +%s`:rustfmt_output\r\e[0K" # Check if the code builds on rust stable -stable:build: - stage: build +stable:check: + stage: check only: - main - development @@ -70,9 +71,94 @@ stable:build: - cargo check --verbose - echo -e "\e[0Ksection_end:`date +%s`:build_output\r\e[0K" +# Check if the code builds on rust stable on armv7 +stable:check:armhf: + stage: check + only: + - main + - development + - merge_requests + before_script: + - mkdir -p $CARGO_HOME + - cp cargo-cross-config $CARGO_HOME/config.toml + script: + - rustc +stable --version && cargo --version + - echo -e "\e[0Ksection_start:`date +%s`:build_output\r\e[0KOutput of cargo check with target armv7-unknown-linux-gnueabihf" + - cargo check --verbose --target armv7-unknown-linux-gnueabihf + - echo -e "\e[0Ksection_end:`date +%s`:build_output\r\e[0K" + + # Check if the code builds on rust stable on arm64 +stable:check:arm64: + stage: check + only: + - main + - development + - merge_requests + before_script: + - mkdir -p $CARGO_HOME + - cp cargo-cross-config $CARGO_HOME/config.toml + script: + - rustc +stable --version && cargo --version + - echo -e "\e[0Ksection_start:`date +%s`:build_output\r\e[0KOutput of cargo check with target aarch64-unknown-linux-gnu" + - cargo check --verbose --target aarch64-unknown-linux-gnu + - echo -e "\e[0Ksection_end:`date +%s`:build_output\r\e[0K" + +# Check if the code builds on rust stable +stable:build:amd64: + stage: build + only: + - main + - development + - merge_requests + script: + - rustc +stable --version && cargo --version + - echo -e "\e[0Ksection_start:`date +%s`:build_output\r\e[0KOutput of cargo build with target x86_64-unknown-linux-gnu" + - cargo build --release --target x86_64-unknown-linux-gnu + - echo -e "\e[0Ksection_end:`date +%s`:build_output\r\e[0K" + artifacts: + paths: + - target/x86_64-unknown-linux-gnu/release/bffhd + + +# Check if the code builds on rust stable on armv7 +stable:build:armhf: + stage: build + only: + - main + - development + before_script: + - mkdir -p $CARGO_HOME + - cp cargo-cross-config $CARGO_HOME/config.toml + script: + - rustc +stable --version && cargo --version + - echo -e "\e[0Ksection_start:`date +%s`:build_output\r\e[0KOutput of cargo build with target armv7-unknown-linux-gnueabihf" + - cargo build --release --target armv7-unknown-linux-gnueabihf + - echo -e "\e[0Ksection_end:`date +%s`:build_output\r\e[0K" + artifacts: + paths: + - target/armv7-unknown-linux-gnueabihf/release/bffhd + + # Check if the code builds on rust stable on arm64 +stable:build:arm64: + stage: build + only: + - main + - development + before_script: + - mkdir -p $CARGO_HOME + - cp cargo-cross-config $CARGO_HOME/config.toml + script: + - rustc +stable --version && cargo --version + - echo -e "\e[0Ksection_start:`date +%s`:build_output\r\e[0KOutput of cargo build with target aarch64-unknown-linux-gnu" + - cargo build --release --target aarch64-unknown-linux-gnu + - echo -e "\e[0Ksection_end:`date +%s`:build_output\r\e[0K" + artifacts: + paths: + - target/aarch64-unknown-linux-gnu/release/bffhd + stable:test: stage: build - needs: ["stable:build"] + needs: ["stable:check"] only: - main - development @@ -80,14 +166,12 @@ stable:test: script: - echo -e "\e[0Ksection_start:`date +%s`:build_output\r\e[0KOutput of cargo test --no-run" - cargo test --verbose --no-run --workspace - - echo -e "\e[0Ksection_end:`date +%s`:build_output\r\e[0K" - - cargo install --root $CARGO_HOME cargo2junit .tests: stage: test needs: ["stable:test"] script: - - cargo test --workspace $TEST_TARGET -- -Z unstable-options --format json --report-time | $CARGO_HOME/bin/cargo2junit > report.xml + - cargo test --workspace $TEST_TARGET -- -Z unstable-options --format json --report-time | cargo2junit > report.xml artifacts: when: always reports: @@ -114,6 +198,23 @@ unit test 3:3: TEST_TARGET: "--examples" extends: .tests +upload_binaries: + stage: release + image: curlimages/curl:latest + before_script: [] + cache: [] + dependencies: + - stable:build:amd64 + - stable:build:armhf + - stable:build:arm64 + script: + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file target/aarch64-unknown-linux-gnu/release/bffhd "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/bffhd/${CI_COMMIT_TAG}/bffhd_${VERSION}_linux_arm64"' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file target/x86_64-unknown-linux-gnu/release/bffhd "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/bffhd/${CI_COMMIT_TAG}/bffhd_${VERSION}_linux_amd64"' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file target/armv7-unknown-linux-gnueabihf/release/bffhd "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/bffhd/${VERSION}/bffhd_${VERSION}_linux_arm"' + rules: + - if: $CI_COMMIT_TAG =~ "release/.*" + when: never + - if: $CI_COMMIT_BRANCH == "main" release_prepare: stage: release @@ -144,32 +245,106 @@ release_job: name: "BFFH $VERSION" description: "GitLab CI auto-created release" tag_name: "release/$VERSION" + assets: + links: + - name: 'bffhd AMD64' + url: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/bffhd/${VERSION}/bffhd_${VERSION}_linux_amd64" + - name: 'bffhd ARMv7' + url: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/bffhd/${VERSION}/bffhd_${VERSION}_linux_arm" + - name: 'bffhd ARM64' + url: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/bffhd/${VERSION}/bffhd_${VERSION}_linux_arm64" build:docker-releases: stage: dockerify - image: - name: gcr.io/kaniko-project/executor:v1.6.0-debug - entrypoint: [""] + image: jdrouet/docker-with-buildx:latest + dependencies: + - stable:build:amd64 + - stable:build:armhf + - stable:build:arm64 + tags: + - linux + - docker + - fabinfra + variables: + DOCKER_HOST: tcp://docker:2375/ + DOCKER_DRIVER: overlay2 + DOCKER_TLS_CERTDIR: "" + TRIVY_NO_PROGRESS: "true" + TRIVY_CACHE_DIR: ".trivycache/" + services: + - docker:dind before_script: - - '' + - export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') + - echo $TRIVY_VERSION + - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf - script: - - mkdir -p /kaniko/.docker - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --force --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG + - docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" + - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + - docker buildx create --name cibuilder --driver docker-container --use + - docker buildx ls + - docker buildx inspect --bootstrap + - docker buildx build --platform linux/arm/v7,linux/arm64,linux/amd64 -t $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG . + - docker buildx build --load --platform linux/amd64 -t $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG . + # Build report + - ./trivy image --exit-code 0 --format template --template "@contrib/gitlab.tpl" -o gl-container-scanning-report.json $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG + # Print report + - ./trivy image --exit-code 0 --severity HIGH $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG + # Fail on severe vulnerabilities + - ./trivy image --exit-code 1 --severity CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG + - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG + cache: + paths: + - .trivycache/ + artifacts: + reports: + container_scanning: gl-container-scanning-report.json rules: - if: $CI_COMMIT_TAG =~ "release/.*" when: never build:docker-development: stage: dockerify - image: - name: gcr.io/kaniko-project/executor:v1.6.0-debug - entrypoint: [""] + image: jdrouet/docker-with-buildx:latest + dependencies: + - stable:build:amd64 + - stable:build:armhf + - stable:build:arm64 + tags: + - linux + - docker + - fabinfra + variables: + DOCKER_HOST: tcp://docker:2375/ + DOCKER_DRIVER: overlay2 + DOCKER_TLS_CERTDIR: "" + TRIVY_NO_PROGRESS: "true" + TRIVY_CACHE_DIR: ".trivycache/" + services: + - docker:dind before_script: - - '' + - export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') + - echo $TRIVY_VERSION + - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf - script: - - mkdir -p /kaniko/.docker - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --force --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:dev-latest + - docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" + - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + - docker buildx create --name cibuilder --driver docker-container --use + - docker buildx ls + - docker buildx inspect --bootstrap + - docker buildx build --platform linux/arm/v7,linux/arm64,linux/amd64 -t $CI_REGISTRY_IMAGE:development . + - docker buildx build --load --platform linux/amd64 -t $CI_REGISTRY_IMAGE:development . + # Build report + - ./trivy image --exit-code 0 --format template --template "@contrib/gitlab.tpl" -o gl-container-scanning-report.json $CI_REGISTRY_IMAGE:development + # Print report + - ./trivy image --exit-code 0 --severity HIGH $CI_REGISTRY_IMAGE:development + # Fail on severe vulnerabilities + - ./trivy image --exit-code 1 --severity CRITICAL $CI_REGISTRY_IMAGE:development + - docker push $CI_REGISTRY_IMAGE:development + cache: + paths: + - .trivycache/ + artifacts: + reports: + container_scanning: gl-container-scanning-report.json only: - development diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ef7f37..72d088b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ A changelog following the [keepachangelog.com/en/1.0.0](https://keepachangelog.c * errors in actors are now logged as errors ([#84](https://gitlab.com/fabinfra/fabaccess/bffh/-/issues/84)) +## 0.4.3 -- 2025-02-11 + +* Adds binary version of FabFire authenitcation protocol +* Adds commands to dump and restore the full database as a TOML text file (`--dump-db` and `--load-db`) +* allows compilation with current stable Rust (1.84) + - Attention: The database format still relies on Rust data layout, so when updating the compiler, the database must be transfered as TOML dump. + Therefore, the `rust-toolchain.toml` file pinning `rustc` to version `1.66` is still in place. +* resolves a crash (use after free) when disconnecting a client. +* resolves some compiler warnings + +## 0.4.2 -- TODO + ## 0.4.1 -- 2022-04-24 * Initial full implementation of the FabAccess 0.3 API, "Spigots of Berlin". diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9836afd..9eea7d6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,7 +56,7 @@ But before you open an issue in this repo for a feature request, please first ch ## Contributing Code -To help develop Diflouroborane you will need a Rust toolchain. I heavily recommend installing +To help develop Difluoroborane you will need a Rust toolchain. I heavily recommend installing [rustup](https://rustup.rs) even if your distribution provides a recent enough rustc, simply because it allows to easily switch compilers between several versions of both stable and nightly. It also allows you to download the respective stdlib crate, giving you the option of an offline reference. diff --git a/Cargo.lock b/Cargo.lock index cc70b38..2ba05ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,30 +4,40 @@ version = 3 [[package]] name = "abnf" -version = "0.6.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47feb9fbcef700639ef28e04ca2a87eab8161a01a075ee227b15c90143805462" +checksum = "33741baa462d86e43fdec5e8ffca7c6ac82847ad06cbfb382c1bdbf527de9e6b" dependencies = [ - "nom 5.1.2", + "abnf-core", + "nom", +] + +[[package]] +name = "abnf-core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c44e09c43ae1c368fb91a03a566472d0087c26cf7e1b9e8e289c14ede681dd7d" +dependencies = [ + "nom", ] [[package]] name = "abnf_to_pest" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372baaa5d3a422d8816b513bcdb2c120078c8614f7ecbcc3baf34a1634bbbe2e" +checksum = "939d59666dd9a7964a3a5312b9d24c9c107630752ee64f2dd5038189a23fe331" dependencies = [ "abnf", "indexmap", - "itertools 0.9.0", + "itertools 0.10.5", "pretty", ] [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ "gimli", ] @@ -47,7 +57,7 @@ dependencies = [ "cfg-if", "cipher", "cpufeatures", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -63,13 +73,22 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "annotate-snippets" version = "0.9.1" @@ -79,20 +98,11 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" -version = "1.0.58" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" [[package]] name = "api" @@ -123,9 +133,9 @@ checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "async-channel" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" dependencies = [ "concurrent-queue", "event-listener", @@ -147,23 +157,23 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" dependencies = [ + "async-lock", "async-task", "concurrent-queue", "fastrand", "futures-lite", - "once_cell", "slab", ] [[package]] name = "async-global-executor" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5262ed948da60dd8956c6c5aca4d4163593dddb7b32d73267c93dab7b2e98940" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" dependencies = [ "async-channel", "async-executor", @@ -171,45 +181,47 @@ dependencies = [ "async-lock", "blocking", "futures-lite", - "num_cpus", "once_cell", ] [[package]] name = "async-io" -version = "1.7.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5e18f61464ae81cde0a23e713ae8fd299580c54d697a35820cfd0625b8b0e07" +checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" dependencies = [ + "async-lock", + "autocfg", "concurrent-queue", "futures-lite", "libc", "log", - "once_cell", "parking", "polling", "slab", "socket2", "waker-fn", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "async-lock" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" +checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" dependencies = [ "event-listener", + "futures-lite", ] [[package]] name = "async-net" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5373304df79b9b4395068fb080369ec7178608827306ce4d081cba51cac551df" +checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" dependencies = [ "async-io", + "autocfg", "blocking", "futures-lite", ] @@ -225,19 +237,20 @@ dependencies = [ [[package]] name = "async-process" -version = "1.4.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2c06e30a24e8c78a3987d07f0930edf76ef35e027e7bdb063fccafdad1f60c" +checksum = "6381ead98388605d0d9ff86371043b5aa922a3905824244de40dc263a14fcba4" dependencies = [ "async-io", + "async-lock", + "autocfg", "blocking", "cfg-if", "event-listener", "futures-lite", "libc", - "once_cell", "signal-hook", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -284,31 +297,31 @@ checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "async-task" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.56" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" +checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "atomic-waker" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" +checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" [[package]] name = "atty" @@ -316,7 +329,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -329,9 +342,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.5.9" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d590cacd53140ff87cc2e192eb22fc3dc23c5b3f93b0d4f020677f98e8c629" +checksum = "acee9fd5073ab6b045a275b3e709c163dd36c90685219cb21804a147b58dba43" dependencies = [ "async-trait", "axum-core", @@ -341,7 +354,7 @@ dependencies = [ "http", "http-body", "hyper", - "itoa 1.0.2", + "itoa 1.0.5", "matchit", "memchr", "mime", @@ -358,9 +371,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.2.6" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4d047478b986f14a13edad31a009e2e05cb241f9805d0d75e4cba4e129ad4d" +checksum = "37e5939e02c56fecd5c017c37df4238c0a839fa76b7f97acdd7efb804fd181cc" dependencies = [ "async-trait", "bytes", @@ -368,13 +381,15 @@ dependencies = [ "http", "http-body", "mime", + "tower-layer", + "tower-service", ] [[package]] name = "backtrace" -version = "0.3.65" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", @@ -387,9 +402,24 @@ dependencies = [ [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "basic-toml" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e819b667739967cd44d308b8c7b71305d8bb0729ac44a248aa08f33d01950b4" +dependencies = [ + "serde", +] [[package]] name = "bitfield" @@ -414,25 +444,22 @@ dependencies = [ "constant_time_eq", ] -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding 0.1.5", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.5", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", ] [[package]] @@ -441,19 +468,10 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" dependencies = [ - "block-padding 0.2.1", + "block-padding", "cipher", ] -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - [[package]] name = "block-padding" version = "0.2.1" @@ -462,16 +480,16 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "blocking" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" +checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8" dependencies = [ "async-channel", + "async-lock", "async-task", "atomic-waker", "fastrand", "futures-lite", - "once_cell", ] [[package]] @@ -488,21 +506,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "bytecheck" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a31f923c2db9513e4298b72df143e6e655a759b3d6a0966df18f81223fff54f" +checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -510,13 +522,13 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb17c862a905d912174daa27ae002326fff56dc8b8ada50a0a5f0976cb174f0" +checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -527,27 +539,21 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cache-padded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "capnp" -version = "0.14.6" +version = "0.14.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21d5d7da973146f1720672faa44f1523cc8f923636190ca1a931c7bc8834de68" +checksum = "2dca085c2c7d9d65ad749d450b19b551efaa8e3476a439bdca07aca8533097f3" [[package]] name = "capnp-futures" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a15248c8facb189a3c5fee74fbf1ff3adc134261d27da663b89c7d19ebaf983" +checksum = "9821801cc6f199a9d9c3c793504e800c797b536d2befddaffb15144e40a6e63a" dependencies = [ "capnp", "futures", @@ -566,27 +572,24 @@ dependencies = [ [[package]] name = "capnpc" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ed9b80f792ac01a8b328ccbc509c2bd756fb5dec18af0163e7963dde23c0b5" +checksum = "bdc9f1dc84666d4ff007b1a16c8f97db80764a624625979be05d869bcff43aaa" dependencies = [ "capnp", ] [[package]] name = "cast" -version = "0.2.7" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" -dependencies = [ - "rustc_version", -] +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" dependencies = [ "jobserver", ] @@ -599,15 +602,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", "num-traits", "serde", "time", + "wasm-bindgen", "winapi", ] @@ -617,7 +622,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array 0.14.5", + "generic-array", ] [[package]] @@ -633,9 +638,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.6" +version = "3.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" dependencies = [ "atty", "bitflags", @@ -644,25 +649,35 @@ dependencies = [ "once_cell", "strsim", "termcolor", - "textwrap 0.15.0", + "textwrap 0.16.0", ] [[package]] name = "clap_lex" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] [[package]] -name = "concurrent-queue" -version = "1.2.2" +name = "codespan-reporting" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ - "cache-padded", + "termcolor", + "unicode-width", +] + +[[package]] +name = "concurrent-queue" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" +dependencies = [ + "crossbeam-utils", ] [[package]] @@ -704,18 +719,18 @@ dependencies = [ [[package]] name = "const_format" -version = "0.2.25" +version = "0.2.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2906f2480cdc015e998deac388331a0f1c1cd88744948c749513020c83c370bc" +checksum = "7309d9b4d3d2c0641e018d449232f2e28f1b22933c137f157d3dbc14228b8c0e" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.22" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef196d5d972878a48da7decb7686eded338b4858fbabeed513d63a7c98b2b82d" +checksum = "d897f47bf7270cf70d370f8f98c1abb6d2d4cf60a6845d30e05bfb90c6568650" dependencies = [ "proc-macro2", "quote", @@ -745,10 +760,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] -name = "cpufeatures" -version = "0.2.2" +name = "core2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] @@ -764,16 +788,16 @@ dependencies = [ [[package]] name = "criterion" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", "cast", "clap 2.34.0", "criterion-plot", "csv", - "itertools 0.10.3", + "itertools 0.10.5", "lazy_static", "num-traits", "oorandom", @@ -790,19 +814,19 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" dependencies = [ "cast", - "itertools 0.10.3", + "itertools 0.10.5", ] [[package]] name = "crossbeam" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" +checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" dependencies = [ "cfg-if", "crossbeam-channel", @@ -814,9 +838,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if", "crossbeam-utils", @@ -824,9 +848,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -835,23 +859,22 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.9" +version = "0.9.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset", - "once_cell", + "memoffset 0.7.1", "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ "cfg-if", "crossbeam-utils", @@ -859,12 +882,21 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.9" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", - "once_cell", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", ] [[package]] @@ -891,12 +923,56 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.22" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn", + "syn 1.0.107", +] + +[[package]] +name = "cxx" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc831ee6a32dd495436e317595e639a587aa9907bef96fe6e6abc290ab6204e9" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94331d54f1b1a8895cd81049f7eaaaef9d05a7dcb4d1fd08bf3ff0806246789d" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 1.0.107", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48dcd35ba14ca9b40d6e4b4b39961f23d835dbb8eed74565ded361d93e1feb8a" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bbeb29798b407ccd82a3324ade1a7286e0d29851475990b612670f6f5124d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", ] [[package]] @@ -907,14 +983,14 @@ checksum = "ac41dd49fb554432020d52c875fc290e110113f864c6b1b525cd62c7e7747a5d" dependencies = [ "byteorder", "cipher", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] name = "desfire" -version = "0.2.0-alpha2" +version = "0.2.0-alpha3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "337f0fcd6ef888be0962aeff547f1b219f4190ea785b5c33328f071e91405411" +checksum = "6ab9ad4e1c8f7f5bdd3b407a1df8745bbf6a90d7a5b7435ca915889d12c40428" dependencies = [ "aes", "block-modes", @@ -946,7 +1022,7 @@ dependencies = [ "quote", "serde", "serde_cbor", - "sha2", + "sha2 0.9.9", "url", ] @@ -958,11 +1034,11 @@ checksum = "f64ba6f41d9b223e2e1d7c97a1145a1aa03e57d65e1c9c2baa29f194caf322c9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] -name = "diflouroborane" +name = "difluoroborane" version = "0.4.2" dependencies = [ "api", @@ -977,7 +1053,7 @@ dependencies = [ "capnp", "capnp-rpc", "chrono", - "clap 3.2.6", + "clap 3.2.23", "console", "desfire", "dirs", @@ -1026,22 +1102,23 @@ dependencies = [ "uuid", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.5", + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.3", + "crypto-common", ] [[package]] @@ -1078,9 +1155,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "either" -version = "1.6.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elsa" @@ -1093,18 +1170,18 @@ dependencies = [ [[package]] name = "erased-serde" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d013529d5574a60caeda29e179e695125448e5de52e3874f7b4c1d7360e18e" +checksum = "e4ca605381c017ec7a5fef5e548f1cfaa419ed0f6df6367339300db74c92aa7d" dependencies = [ "serde", ] [[package]] name = "event-listener" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "executor" @@ -1135,26 +1212,20 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", "miniz_oxide", @@ -1168,19 +1239,18 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] [[package]] name = "futures" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" dependencies = [ "futures-channel", "futures-core", @@ -1193,9 +1263,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" dependencies = [ "futures-core", "futures-sink", @@ -1203,15 +1273,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" dependencies = [ "futures-core", "futures-task", @@ -1220,9 +1290,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" [[package]] name = "futures-lite" @@ -1241,13 +1311,13 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1261,9 +1331,9 @@ dependencies = [ [[package]] name = "futures-rustls" -version = "0.22.1" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01fe9932a224b72b45336d96040aa86386d674a31d0af27d800ea7bc8ca97fe" +checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" dependencies = [ "futures-io", "rustls", @@ -1272,9 +1342,9 @@ dependencies = [ [[package]] name = "futures-signals" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633f5e17d6fb8d3cfa0710087d0cbe708d07cc416ca6c4682ce876aa7839c09d" +checksum = "a3acc659ba666cff13fdf65242d16428f2f11935b688f82e4024ad39667a5132" dependencies = [ "discard", "futures-channel", @@ -1287,21 +1357,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" [[package]] name = "futures-test" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3e9379dbbfb35dd6df79e895d73c0f75558827fe68eb853b858ff417a8ee98" +checksum = "247a763336996e90f355708bf9ae8b78ab5ae8810b9e7bd731cce65fd7fe6d5d" dependencies = [ "futures-core", "futures-executor", @@ -1322,9 +1392,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" dependencies = [ "futures-channel", "futures-core", @@ -1340,18 +1410,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.12.4" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", @@ -1359,9 +1420,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -1370,20 +1431,20 @@ dependencies = [ [[package]] name = "ghost" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76c813ffb63e8fd3df6f1ac3cc1ea392c7612ac2de4d0b44dcbfe03e5c4bf94a" +checksum = "41973d4c45f7a35af8753ba3457cc99d406d863941fd7f52663cff54a5ab99b3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "gimli" -version = "0.26.1" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" [[package]] name = "git2" @@ -1400,15 +1461,15 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "gloo-timers" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" dependencies = [ "futures-channel", "futures-core", @@ -1418,9 +1479,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ "bytes", "fnv", @@ -1443,24 +1504,24 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hashbrown" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", ] [[package]] name = "hdrhistogram" -version = "7.5.0" +version = "7.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31672b7011be2c4f7456c4ddbcb40e7e9a4a9fad8efe49a6ebaf5f307d0109c0" +checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" dependencies = [ - "base64", + "base64 0.13.1", "byteorder", "crossbeam-channel", "flate2", - "nom 7.1.1", + "nom", "num-traits", ] @@ -1473,6 +1534,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" @@ -1490,7 +1560,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa 1.0.2", + "itoa 1.0.5", ] [[package]] @@ -1512,9 +1582,9 @@ checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -1524,9 +1594,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.19" +version = "0.14.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" +checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c" dependencies = [ "bytes", "futures-channel", @@ -1537,7 +1607,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.2", + "itoa 1.0.5", "pin-project-lite", "socket2", "tokio", @@ -1559,21 +1629,44 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.2.3" +name = "iana-time-zone" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -1607,7 +1700,7 @@ checksum = "7e41b53715c6f0c4be49510bb82dee2c1e51c8586d885abe65396e82ed518548" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1633,9 +1726,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -1648,24 +1741,24 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "jobserver" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.58" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] @@ -1685,30 +1778,17 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lexical-core" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" -dependencies = [ - "arrayvec 0.5.2", - "bitflags", - "cfg-if", - "ryu", - "static_assertions", -] - [[package]] name = "libc" -version = "0.2.126" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libgit2-sys" -version = "0.13.4+1.4.2" +version = "0.13.5+1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0fa6563431ede25f5cc7f6d803c6afbc1c5d3ad3d4925d12c882bf2b526f5d1" +checksum = "51e5ea06c26926f1002dd553fded6cfcdc9784c1f60feeb58368b4d9b07b6dba" dependencies = [ "cc", "libc", @@ -1744,23 +1824,32 @@ dependencies = [ ] [[package]] -name = "linkme" -version = "0.2.10" +name = "link-cplusplus" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd4ad156b9934dc21cad96fd17278a7cb6f30a5657a9d976cd7b71d6d49c02c" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "linkme" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "566336154b9e58a4f055f6dd4cbab62c7dc0826ce3c0a04e63b2d2ecd784cdae" dependencies = [ "linkme-impl", ] [[package]] name = "linkme-impl" -version = "0.2.10" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fd9dc7072de7168cbdaba9125e8f742cd3a965aa12bde994b4611a174488d8" +checksum = "edbe595006d355eaf9ae11db92707d4338cd2384d16866131cc1afdbdd35d8d9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -1788,9 +1877,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -1806,12 +1895,6 @@ dependencies = [ "value-bag", ] -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "matchers" version = "0.1.0" @@ -1821,12 +1904,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "matchit" version = "0.5.0" @@ -1848,6 +1925,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "miette" version = "4.7.1" @@ -1863,7 +1949,7 @@ dependencies = [ "supports-hyperlinks", "supports-unicode", "terminal_size", - "textwrap 0.15.0", + "textwrap 0.15.2", "thiserror", "unicode-width", ] @@ -1876,7 +1962,7 @@ checksum = "6b5bc45b761bcf1b5e6e6c4128cd93b84c218721a8d9b894aa0aff4ed180174c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1893,59 +1979,58 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] name = "nix" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" dependencies = [ "bitflags", "cc", "cfg-if", "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] name = "nom" -version = "5.1.2" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" -dependencies = [ - "lexical-core", - "memchr", - "version_check", -] - -[[package]] -name = "nom" -version = "7.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +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-derive" version = "0.3.3" @@ -1954,7 +2039,7 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1978,28 +2063,28 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] [[package]] name = "object" -version = "0.28.4" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.12.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "oorandom" @@ -2007,12 +2092,6 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -2027,15 +2106,21 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "os_str_bytes" -version = "6.1.0" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owo-colors" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "decf7381921fea4dcb2549c5667eda59b3ec297ab7e2b5fc33eac69d2e7da87b" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] name = "parking" @@ -2055,37 +2140,38 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.1.3" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "028accff104c4e513bad663bbcd2ad7cfd5304144404c31ed0a77ac103d00660" dependencies = [ + "thiserror", "ucd-trie", ] [[package]] name = "pest_consume" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb7c2ab7ca422b1f9b9e821c96667dc6675885c8a986cb379f7fac36b229085" +checksum = "79447402d15d18e7142e14c72f2e63fa3d155be1bc5b70b3ccbb610ac55f536b" dependencies = [ "pest", "pest_consume_macros", @@ -2100,14 +2186,14 @@ checksum = "9d8630a7a899cb344ec1c16ba0a6b24240029af34bdc0a21f84e411d7f793f29" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "pest_derive" -version = "2.1.0" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +checksum = "2ac3922aac69a40733080f53c1ce7f91dcf57e1a5f6c52f421fadec7fbdc4b69" dependencies = [ "pest", "pest_generator", @@ -2115,46 +2201,46 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.1.3" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +checksum = "d06646e185566b5961b4058dd107e0a7f56e77c3f484549fb119867773c0f202" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "pest_meta" -version = "2.1.3" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +checksum = "e6f60b2ba541577e2a0c307c8f39d1439108120eb7903adeb6497fa880c59616" dependencies = [ - "maplit", + "once_cell", "pest", - "sha-1", + "sha2 0.10.6", ] [[package]] name = "pin-project" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2171,15 +2257,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "plotters" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" dependencies = [ "num-traits", "plotters-backend", @@ -2190,30 +2276,31 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] [[package]] name = "polling" -version = "2.2.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" +checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" dependencies = [ + "autocfg", "cfg-if", "libc", "log", "wepoll-ffi", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -2224,24 +2311,27 @@ checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "pretty" -version = "0.5.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60c0d9f6fc88ecdd245d90c1920ff76a430ab34303fc778d33b1d0a4c3bf6d3" +checksum = "83f3aa1e3ca87d3b124db7461265ac176b40c277f37e503eaa29c9c75c037846" dependencies = [ + "arrayvec 0.5.2", + "log", "typed-arena", + "unicode-segmentation", ] [[package]] name = "proc-macro2" -version = "1.0.40" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -2263,10 +2353,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" dependencies = [ "anyhow", - "itertools 0.10.3", + "itertools 0.10.5", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2296,14 +2386,14 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "quote" -version = "1.0.20" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -2331,30 +2421,28 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] [[package]] name = "rayon" -version = "1.5.3" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" dependencies = [ - "autocfg", - "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.9.3" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -2364,9 +2452,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -2384,9 +2472,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.6" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "aho-corasick", "memchr", @@ -2404,9 +2492,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "remove_dir_all" @@ -2443,9 +2531,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.38" +version = "0.7.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "517a3034eb2b1499714e9d1e49b2367ad567e07639b69776d35e259d9c27cca6" +checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" dependencies = [ "bytecheck", "hashbrown", @@ -2457,20 +2545,20 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.38" +version = "0.7.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "505c209ee04111a006431abf39696e640838364d67a107c559ababaf6fd8c9dd" +checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "rkyv_dyn" -version = "0.7.38" +version = "0.7.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c7adf3c35f3c1d8aa1f3a573e91d38c0da8110e99f4ff0006def9691025db2" +checksum = "72267bd77a011872e524ce25589e0286daf7f78a5da3a5efc757e1b1597a1178" dependencies = [ "inventory", "lazy_static", @@ -2482,13 +2570,13 @@ dependencies = [ [[package]] name = "rkyv_dyn_derive" -version = "0.7.38" +version = "0.7.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8079a7a86551483b68603bd3712c332e8adfd3a2747a8f51a65cd8b7412b98b" +checksum = "f298184c1603a4e5114ab0147c4a7d47c1b4f7a78720e6211d02aea16cd6c04f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2508,17 +2596,20 @@ checksum = "27a570b78b72542588a1f3ecaa8d109b5332e61465c729e96941adafb81fc6eb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "rsasl" -version = "2.0.0-preview4" -source = "git+https://github.com/dequbed/rsasl.git?rev=0b5012d0#0b5012d0934925aed6eb8463b397c512a2cffbd9" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8b534a23662bb559c5c73213be63ecd6524e774d291f3618c2b04b723d184eb" dependencies = [ - "libc", + "core2", "linkme", + "serde_json", "stringprep", + "thiserror", ] [[package]] @@ -2545,7 +2636,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" dependencies = [ - "base64", + "base64 0.13.1", "blake2b_simd", "constant_time_eq", "crossbeam-utils", @@ -2557,20 +2648,11 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - [[package]] name = "rustls" -version = "0.20.6" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" dependencies = [ "log", "ring", @@ -2585,7 +2667,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.0", + "rustls-pemfile 1.0.2", "schannel", "security-framework", ] @@ -2596,23 +2678,23 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360" dependencies = [ - "base64", + "base64 0.13.1", ] [[package]] name = "rustls-pemfile" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64", + "base64 0.21.0", ] [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "same-file" @@ -2625,12 +2707,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -2639,6 +2720,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" + [[package]] name = "sct" version = "0.7.0" @@ -2653,7 +2740,7 @@ dependencies = [ name = "sdk" version = "0.1.0" dependencies = [ - "diflouroborane", + "difluoroborane", "futures-util", "sdk-proc", ] @@ -2664,7 +2751,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "trybuild", ] @@ -2676,9 +2763,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "security-framework" -version = "2.6.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", "core-foundation", @@ -2689,25 +2776,19 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", ] -[[package]] -name = "semver" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" - [[package]] name = "serde" -version = "1.0.137" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] @@ -2724,13 +2805,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -2748,27 +2829,16 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" dependencies = [ - "itoa 1.0.2", + "itoa 1.0.5", + "memchr", "ryu", "serde", ] -[[package]] -name = "sha-1" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - [[package]] name = "sha2" version = "0.9.9" @@ -2779,7 +2849,18 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", ] [[package]] @@ -2842,15 +2923,18 @@ checksum = "cc47a29ce97772ca5c927f75bac34866b16d64e07f330c3248e2d7226623901b" [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "smawk" @@ -2860,9 +2944,9 @@ checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -2880,20 +2964,15 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "stringprep" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ "unicode-bidi", "unicode-normalization", + "unicode-properties", ] [[package]] @@ -2904,9 +2983,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "supports-color" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4872ced36b91d47bae8a214a683fe54e7078875b399dfa251df346c9b547d1f9" +checksum = "8ba6faf2ca7ee42fdd458f4347ae0a9bd6bcc445ad7cb57ad82b383f18870d6f" dependencies = [ "atty", "is_ci", @@ -2932,9 +3011,20 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.98" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -2943,9 +3033,9 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "tempfile" @@ -2963,9 +3053,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -2991,9 +3081,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" dependencies = [ "smawk", "unicode-linebreak", @@ -3001,23 +3091,29 @@ dependencies = [ ] [[package]] -name = "thiserror" -version = "1.0.31" +name = "textwrap" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -3031,9 +3127,9 @@ dependencies = [ [[package]] name = "time" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", @@ -3061,25 +3157,25 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.19.2" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" +checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" dependencies = [ + "autocfg", "bytes", "libc", "memchr", "mio", - "once_cell", "pin-project-lite", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.42.0", ] [[package]] @@ -3094,13 +3190,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -3116,9 +3212,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" dependencies = [ "futures-core", "pin-project-lite", @@ -3127,9 +3223,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", @@ -3141,9 +3237,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] @@ -3157,7 +3253,7 @@ dependencies = [ "async-stream", "async-trait", "axum", - "base64", + "base64 0.13.1", "bytes", "futures-core", "futures-util", @@ -3202,9 +3298,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" dependencies = [ "bitflags", "bytes", @@ -3221,9 +3317,9 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" [[package]] name = "tower-service" @@ -3233,9 +3329,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.35" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "log", @@ -3246,20 +3342,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "tracing-core" -version = "0.1.27" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", "valuable", @@ -3290,13 +3386,13 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.11" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ - "ansi_term", - "lazy_static", "matchers", + "nu-ansi-term", + "once_cell", "regex", "sharded-slab", "smallvec", @@ -3308,84 +3404,97 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "trybuild" -version = "1.0.63" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "764b9e244b482a9b81bde596aa37aa6f1347bf8007adab25e59f901b32b4e0a0" +checksum = "a44da5a6f2164c8e14d3bbc0657d69c5966af9f5f6930d4f600b1f5c4a673413" dependencies = [ + "basic-toml", "glob", "once_cell", "serde", "serde_derive", "serde_json", "termcolor", - "toml", ] [[package]] name = "typed-arena" -version = "1.7.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" -version = "1.0.1" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-linebreak" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a52dcaab0c48d931f7cc8ef826fa51690a08e1ea55117ef26f89864f532383f" +checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" dependencies = [ + "hashbrown", "regex", ] [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] -name = "unicode-width" -version = "0.1.9" +name = "unicode-properties" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "unicode-xid" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "untrusted" @@ -3395,13 +3504,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -3484,9 +3592,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.81" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3494,24 +3602,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.81" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.31" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" dependencies = [ "cfg-if", "js-sys", @@ -3521,9 +3629,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.81" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3531,28 +3639,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.81" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.81" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "web-sys" -version = "0.3.58" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" dependencies = [ "js-sys", "wasm-bindgen", @@ -3610,43 +3718,81 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ + "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_msvc", "windows_x86_64_gnu", + "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" +name = "windows-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" diff --git a/Cargo.toml b/Cargo.toml index 581c6bf..1812c74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "diflouroborane" +name = "difluoroborane" version = "0.4.2" authors = [ "dequbed " , "Kai Jan Kriegel " @@ -66,7 +66,7 @@ ptr_meta = "0.1" rkyv_typename = "0.7" rkyv_dyn = "0.7" inventory = "0.1" -linkme = "0.2.10" +linkme = "0.3" chrono = { version = "0.4", features = ["serde"] } # Password hashing for internal users @@ -84,7 +84,8 @@ capnp = "0.14" capnp-rpc = "0.14.1" # API Authentication -desfire = "0.2.0-alpha1" +desfire = "0.2.0-alpha3" + hex = { version = "0.4.3", features = ["serde"] } futures-signals = "0.3.22" @@ -112,10 +113,9 @@ rustls-native-certs = "0.6.1" shadow-rs = "0.11" [dependencies.rsasl] -git = "https://github.com/dequbed/rsasl.git" -rev = "0b5012d0" +version = "2.2.0" default_features = false -features = ["unstable_custom_mechanism", "provider", "registry_static", "plain"] +features = ["unstable_custom_mechanism", "provider", "registry_static", "config_builder", "plain"] [dev-dependencies] futures-test = "0.3.16" diff --git a/Dockerfile b/Dockerfile index 2b7b0b9..418c22e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,23 @@ -# Setup build image for multistage build -FROM rust:bullseye as builder -# install build deps -RUN apt-get update && apt-get upgrade -y -RUN apt-get install -yqq --no-install-recommends capnproto +FROM --platform=$BUILDPLATFORM alpine:latest as copy +ARG TARGETPLATFORM +RUN case "$TARGETPLATFORM" in \ + "linux/arm/v7") echo armv7-unknown-linux-gnueabihf > /rust_target.txt ;; \ + "linux/arm/v6") echo arm-unknown-linux-gnueabihf > /rust_target.txt ;; \ + "linux/arm64") echo aarch64-unknown-linux-gnu > /rust_target.txt ;; \ + "linux/amd64") echo x86_64-unknown-linux-gnu > /rust_target.txt ;; \ + *) exit 1 ;; \ +esac WORKDIR /usr/src/bffh COPY . . -RUN cargo build --release - +RUN cp target/$(cat /rust_target.txt)/release/bffhd ./bffhd.bin # Setup deployable image -FROM debian:bullseye-slim -# Install runtime deps -#RUN apt-get update && apt-get upgrade -yqq -COPY --from=builder /usr/src/bffh/target/release/bffhd /usr/local/bin/bffhd -#COPY --from=builder /usr/src/bffh/examples/bffh.dhall /etc/diflouroborane.dhall -# RUN diflouroborane --print-default > /etc/diflouroborane.toml +FROM ubuntu:22.04 +RUN apt-get update && apt-get upgrade -y +RUN apt-get install -yqq --no-install-recommends python3 python3-pip +RUN pip3 install paho-mqtt +COPY --from=copy /usr/src/bffh/bffhd.bin /usr/local/bin/bffhd VOLUME /etc/bffh/ VOLUME /var/lib/bffh/ VOLUME /usr/local/lib/bffh/adapters/ diff --git a/INSTALL.md b/INSTALL.md index 3b667d0..c867d2f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,10 +1,10 @@ # Installation Currently there are no distribution packages available. -However installation is reasonably straight-forward, since Diflouroborane compiles into a single +However installation is reasonably straight-forward, since Difluoroborane compiles into a single mostly static binary with few dependencies. -At the moment only Linux is supported. If you managed to compile Diflouroborane please open an issue +At the moment only Linux is supported. If you managed to compile Difluoroborane please open an issue outlining your steps or add a merge request expanding this part. Thanks! ## Requirements @@ -12,7 +12,7 @@ outlining your steps or add a merge request expanding this part. Thanks! General requirements; scroll down for distribution-specific instructions - GNU SASL (libgsasl). - * If you want to compile Diflouroborane from source you will potentially also need development + * If you want to compile Difluoroborane from source you will potentially also need development headers - capnproto - rustc stable / nightly >= 1.48 @@ -26,11 +26,12 @@ $ pacman -S gsasl rust capnproto ## Compiling from source -Diflouroborane uses Cargo, so compilation boils down to: +Difluoroborane uses Cargo, so compilation boils down to: ```shell $ cargo build --release ``` +https://www.geeksforgeeks.org/how-to-install-rust-on-raspberry-pi/ can show you how to install rust on your Linux computer. The compiled binary can then be found in `./target/release/bffhd` diff --git a/README.md b/README.md index cab0e6a..c9e1ebf 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# FabAccess Diflouroborane +# FabAccess Difluoroborane -Diflouroborane (shorter: BFFH, the chemical formula for Diflouroborane) is the server part of +Difluoroborane (shorter: BFFH, the chemical formula for Difluoroborane) is the server part of FabAccess. -It provides a server-side implementation of the [FabAccess API](/fabinfra/fabaccess/fabaccess-api). +It provides a server-side implementation of the [FabAccess API](https://gitlab.com/fabinfra/fabaccess/fabaccess-api). ## What is this? @@ -13,8 +13,8 @@ to be used for all other things one would like to give exclusive access to even dangerous or expensive to use (think 3D printers, smart lightbulbs, meeting rooms). FabAccess uses a Client/Server architecture with a [Cap'n Proto](https://capnproto.org/) API. You -can find the API schema files over [in their own repository](/fabinfra/fabaccess/fabaccess-api). -The reference client is [Borepin](/fabinfra/fabaccess/borepin), written in C#/Xamarin to be able to +can find the API schema files over [in their own repository](https://gitlab.com/fabinfra/fabaccess/fabaccess-api). +The reference client is [Borepin](https://gitlab.com/fabinfra/fabaccess/borepin), written in C#/Xamarin to be able to be ported to as many platforms as possible. diff --git a/bffhd/actors/mod.rs b/bffhd/actors/mod.rs index d91da4a..bd8facf 100644 --- a/bffhd/actors/mod.rs +++ b/bffhd/actors/mod.rs @@ -12,9 +12,10 @@ use std::future::Future; use std::pin::Pin; -use miette::IntoDiagnostic; +use miette::Diagnostic; use std::task::{Context, Poll}; use std::time::Duration; +use thiserror::Error; use once_cell::sync::Lazy; use rumqttc::ConnectReturnCode::Success; @@ -111,11 +112,33 @@ static ROOT_CERTS: Lazy = Lazy::new(|| { store }); -pub fn load(executor: Executor, config: &Config, resources: ResourcesHandle) -> miette::Result<()> { +#[derive(Debug, Error, Diagnostic)] +pub enum ActorError { + #[error("failed to parse MQTT url")] + UrlParseError( + #[from] + #[source] + url::ParseError, + ), + #[error("MQTT config is invalid")] + InvalidConfig, + #[error("MQTT connection failed")] + ConnectionError( + #[from] + #[source] + rumqttc::ConnectionError, + ), +} + +pub fn load( + executor: Executor, + config: &Config, + resources: ResourcesHandle, +) -> Result<(), ActorError> { let span = tracing::info_span!("loading actors"); let _guard = span; - let mqtt_url = Url::parse(config.mqtt_url.as_str()).into_diagnostic()?; + let mqtt_url = Url::parse(config.mqtt_url.as_str())?; let (transport, default_port) = match mqtt_url.scheme() { "mqtts" | "ssl" => ( rumqttc::Transport::tls_with_config( @@ -132,12 +155,12 @@ pub fn load(executor: Executor, config: &Config, resources: ResourcesHandle) -> scheme => { tracing::error!(%scheme, "MQTT url uses invalid scheme"); - miette::bail!("invalid config"); + return Err(ActorError::InvalidConfig); } }; let host = mqtt_url.host_str().ok_or_else(|| { tracing::error!("MQTT url must contain a hostname"); - miette::miette!("invalid config") + ActorError::InvalidConfig })?; let port = mqtt_url.port().unwrap_or(default_port); @@ -168,7 +191,7 @@ pub fn load(executor: Executor, config: &Config, resources: ResourcesHandle) -> } Err(error) => { tracing::error!(?error, "MQTT connection failed"); - miette::bail!("mqtt connection failed") + return Err(ActorError::ConnectionError(error)); } } diff --git a/bffhd/audit.rs b/bffhd/audit.rs index 0bf135c..d736156 100644 --- a/bffhd/audit.rs +++ b/bffhd/audit.rs @@ -1,8 +1,10 @@ +use miette::Diagnostic; use once_cell::sync::OnceCell; use std::fs::{File, OpenOptions}; use std::io; use std::io::{LineWriter, Write}; use std::sync::Mutex; +use thiserror::Error; use crate::Config; use serde::{Deserialize, Serialize}; @@ -23,8 +25,13 @@ pub struct AuditLogLine<'a> { state: &'a str, } +#[derive(Debug, Error, Diagnostic)] +#[error(transparent)] +#[repr(transparent)] +pub struct Error(#[from] pub io::Error); + impl AuditLog { - pub fn new(config: &Config) -> io::Result<&'static Self> { + pub fn new(config: &Config) -> Result<&'static Self, Error> { AUDIT.get_or_try_init(|| { tracing::debug!(path = %config.auditlog_path.display(), "Initializing audit log"); let fd = OpenOptions::new() diff --git a/bffhd/authentication/fabfire/mod.rs b/bffhd/authentication/fabfire/mod.rs index c34e18a..66e83fa 100644 --- a/bffhd/authentication/fabfire/mod.rs +++ b/bffhd/authentication/fabfire/mod.rs @@ -2,43 +2,37 @@ mod server; pub use server::FabFire; use rsasl::mechname::Mechname; -use rsasl::registry::{Mechanism, MECHANISMS}; -use rsasl::session::Side; +use rsasl::registry::{Matches, Mechanism, Named, Side, MECHANISMS}; const MECHNAME: &'static Mechname = &Mechname::const_new_unchecked(b"X-FABFIRE"); #[linkme::distributed_slice(MECHANISMS)] -pub static FABFIRE: Mechanism = Mechanism { - mechanism: MECHNAME, - priority: 300, - // In this situation there's one struct for both sides, however you can just as well use - // different types than then have different `impl Authentication` instead of checking a value - // in self. - client: None, - server: Some(FabFire::new_server), - first: Side::Client, -}; +pub static FABFIRE: Mechanism = Mechanism::build( + MECHNAME, + 300, + None, + Some(FabFire::new_server), + Side::Client, + |_| Some(Matches::::name()), + |_| true, +); + +struct Select; +impl Named for Select { + fn mech() -> &'static Mechanism { + &FABFIRE + } +} diff --git a/bffhd/authentication/fabfire_bin/server.rs b/bffhd/authentication/fabfire_bin/server.rs new file mode 100644 index 0000000..5cc7c73 --- /dev/null +++ b/bffhd/authentication/fabfire_bin/server.rs @@ -0,0 +1,532 @@ +use desfire::desfire::desfire::MAX_BYTES_PER_TRANSACTION; +use desfire::desfire::Desfire; +use desfire::error::Error as DesfireError; +use desfire::iso7816_4::apduresponse::APDUResponse; +use rsasl::mechanism::{ + Authentication, Demand, DemandReply, MechanismData, MechanismError, MechanismErrorKind, + Provider, State, ThisProvider, +}; +use rsasl::prelude::{MessageSent, SASLConfig, SASLError, SessionError}; +use rsasl::property::AuthId; +use serde::{Deserialize, Serialize}; +use std::convert::TryFrom; +use std::fmt::{Debug, Display, Formatter}; +use std::io::Write; + +use crate::authentication::fabfire::FabFireCardKey; +use crate::CONFIG; + +enum FabFireError { + ParseError, + SerializationError, + DeserializationError(serde_json::Error), + CardError(DesfireError), + InvalidMagic(String), + InvalidToken(String), + InvalidURN(String), + InvalidCredentials(String), + Session(SessionError), +} + +impl Debug for FabFireError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + FabFireError::ParseError => write!(f, "ParseError"), + FabFireError::SerializationError => write!(f, "SerializationError"), + FabFireError::DeserializationError(e) => write!(f, "DeserializationError: {}", e), + FabFireError::CardError(err) => write!(f, "CardError: {}", err), + FabFireError::InvalidMagic(magic) => write!(f, "InvalidMagic: {}", magic), + FabFireError::InvalidToken(token) => write!(f, "InvalidToken: {}", token), + FabFireError::InvalidURN(urn) => write!(f, "InvalidURN: {}", urn), + FabFireError::InvalidCredentials(credentials) => { + write!(f, "InvalidCredentials: {}", credentials) + } + FabFireError::Session(err) => write!(f, "Session: {}", err), + } + } +} + +impl Display for FabFireError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + FabFireError::ParseError => write!(f, "ParseError"), + FabFireError::SerializationError => write!(f, "SerializationError"), + FabFireError::DeserializationError(e) => write!(f, "DeserializationError: {}", e), + FabFireError::CardError(err) => write!(f, "CardError: {}", err), + FabFireError::InvalidMagic(magic) => write!(f, "InvalidMagic: {}", magic), + FabFireError::InvalidToken(token) => write!(f, "InvalidToken: {}", token), + FabFireError::InvalidURN(urn) => write!(f, "InvalidURN: {}", urn), + FabFireError::InvalidCredentials(credentials) => { + write!(f, "InvalidCredentials: {}", credentials) + } + FabFireError::Session(err) => write!(f, "Session: {}", err), + } + } +} + +impl std::error::Error for FabFireError {} + +impl MechanismError for FabFireError { + fn kind(&self) -> MechanismErrorKind { + match self { + FabFireError::ParseError => MechanismErrorKind::Parse, + FabFireError::SerializationError => MechanismErrorKind::Protocol, + FabFireError::DeserializationError(_) => MechanismErrorKind::Parse, + FabFireError::CardError(_) => MechanismErrorKind::Protocol, + FabFireError::InvalidMagic(_) => MechanismErrorKind::Protocol, + FabFireError::InvalidToken(_) => MechanismErrorKind::Protocol, + FabFireError::InvalidURN(_) => MechanismErrorKind::Protocol, + FabFireError::InvalidCredentials(_) => MechanismErrorKind::Protocol, + FabFireError::Session(_) => MechanismErrorKind::Protocol, + } + } +} + +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct CardInfo { + #[serde(rename = "UID", with = "hex")] + uid: [u8; 7], + key_old: Option>, + key_new: Option>, +} + +struct KeyInfo { + authid: String, + key_id: u8, + key: Box<[u8]>, +} + +struct AuthInfo { + rnd_a: Vec, + rnd_b: Vec, + iv: Vec, +} + +enum Step { + New, + SelectApp, + VerifyMagic, + GetURN, + GetToken, + Authenticate1, + Authenticate2, +} + +pub struct FabFire { + step: Step, + card_info: Option, + key_info: Option, + auth_info: Option, + app_id: u32, + local_urn: String, + desfire: Desfire, +} + +const MAGIC: &'static str = "FABACCESS\0DESFIRE\01.0\0"; + +impl FabFire { + pub fn new_server(_sasl: &SASLConfig) -> Result, SASLError> { + let space = if let Some(space) = CONFIG.get().map(|c| c.spacename.as_str()) { + space + } else { + tracing::error!("No space configured"); + "generic" + }; + + Ok(Box::new(Self { + step: Step::New, + card_info: None, + key_info: None, + auth_info: None, + app_id: 0x464142, + local_urn: format!("urn:fabaccess:lab:{space}"), + desfire: Desfire { + card: None, + session_key: None, + cbc_iv: None, + }, + })) + } +} + +impl Authentication for FabFire { + fn step( + &mut self, + session: &mut MechanismData<'_, '_>, + input: Option<&[u8]>, + writer: &mut dyn Write, + ) -> Result { + match self.step { + Step::New => { + tracing::trace!("Step: New"); + //receive card info (especially card UID) from reader + return match input { + None => Err(SessionError::InputDataRequired), + Some(_) => { + //select application + return match self.desfire.select_application_cmd(self.app_id) { + Ok(buf) => match Vec::::try_from(buf) { + Ok(data) => { + self.step = Step::SelectApp; + writer + .write_all(&data) + .map_err(|e| SessionError::Io { source: e })?; + Ok(State::Running) + } + Err(e) => { + tracing::error!( + "Failed to convert APDUCommand to Vec: {:?}", + e + ); + return Err(FabFireError::SerializationError.into()); + } + }, + Err(e) => { + tracing::error!("Failed to generate APDUCommand: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + }; + } + }; + } + Step::SelectApp => { + tracing::trace!("Step: SelectApp"); + // check that we successfully selected the application + + let apdu_response = match input { + Some(data) => APDUResponse::new(data), + None => return Err(SessionError::InputDataRequired), + }; + + apdu_response + .check() + .map_err(|e| FabFireError::CardError(e))?; + + // request the contents of the file containing the magic string + const MAGIC_FILE_ID: u8 = 0x01; + + return match self + .desfire + .read_data_chunk_cmd(MAGIC_FILE_ID, 0, MAGIC.len()) + { + Ok(buf) => match Vec::::try_from(buf) { + Ok(data) => { + self.step = Step::VerifyMagic; + writer + .write_all(&data) + .map_err(|e| SessionError::Io { source: e })?; + Ok(State::Running) + } + Err(e) => { + tracing::error!("Failed to convert APDUCommand to Vec: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + }, + Err(e) => { + tracing::error!("Failed to generate APDUCommand: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + }; + } + Step::VerifyMagic => { + tracing::trace!("Step: VerifyMagic"); + // verify the magic string to determine that we have a valid fabfire card + let apdu_response = match input { + Some(data) => APDUResponse::new(data), + None => return Err(SessionError::InputDataRequired), + }; + + match apdu_response.check() { + Ok(_) => { + match apdu_response.body { + Some(data) => { + if std::str::from_utf8(data.as_slice()) != Ok(MAGIC) { + tracing::error!("Invalid magic string"); + return Err(FabFireError::ParseError.into()); + } + } + None => { + tracing::error!("No data returned from card"); + return Err(FabFireError::ParseError.into()); + } + }; + } + Err(e) => { + tracing::error!("Got invalid APDUResponse: {:?}", e); + return Err(FabFireError::ParseError.into()); + } + } + + // request the contents of the file containing the URN + const URN_FILE_ID: u8 = 0x02; + + return match self.desfire.read_data_chunk_cmd( + URN_FILE_ID, + 0, + self.local_urn.as_bytes().len(), + ) { + // TODO: support urn longer than 47 Bytes + Ok(buf) => match Vec::::try_from(buf) { + Ok(data) => { + self.step = Step::GetURN; + writer + .write_all(&data) + .map_err(|e| SessionError::Io { source: e })?; + Ok(State::Running) + } + Err(e) => { + tracing::error!("Failed to convert APDUCommand to Vec: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + }, + Err(e) => { + tracing::error!("Failed to generate APDUCommand: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + }; + } + Step::GetURN => { + tracing::trace!("Step: GetURN"); + // parse the urn and match it to our local urn + let apdu_response = match input { + Some(data) => APDUResponse::new(data), + None => return Err(SessionError::InputDataRequired), + }; + + match apdu_response.check() { + Ok(_) => { + match apdu_response.body { + Some(data) => { + let received_urn = String::from_utf8(data).unwrap(); + if received_urn != self.local_urn { + tracing::error!( + "URN mismatch: {:?} != {:?}", + received_urn, + self.local_urn + ); + return Err(FabFireError::ParseError.into()); + } + } + None => { + tracing::error!("No data returned from card"); + return Err(FabFireError::ParseError.into()); + } + }; + } + Err(e) => { + tracing::error!("Got invalid APDUResponse: {:?}", e); + return Err(FabFireError::ParseError.into()); + } + } + // request the contents of the file containing the URN + const TOKEN_FILE_ID: u8 = 0x03; + + return match self.desfire.read_data_chunk_cmd( + TOKEN_FILE_ID, + 0, + MAX_BYTES_PER_TRANSACTION, + ) { + // TODO: support data longer than 47 Bytes + Ok(buf) => match Vec::::try_from(buf) { + Ok(data) => { + self.step = Step::GetToken; + writer + .write_all(&data) + .map_err(|e| SessionError::Io { source: e })?; + Ok(State::Running) + } + Err(e) => { + tracing::error!("Failed to convert APDUCommand to Vec: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + }, + Err(e) => { + tracing::error!("Failed to generate APDUCommand: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + }; + } + Step::GetToken => { + // println!("Step: GetToken"); + // parse the token and select the appropriate user + let apdu_response = match input { + Some(data) => APDUResponse::new(data), + None => return Err(SessionError::InputDataRequired), + }; + + match apdu_response.check() { + Ok(_) => { + match apdu_response.body { + Some(data) => { + let authid = String::from_utf8(data) + .unwrap() + .trim_matches(char::from(0)) + .to_string(); + let prov = ThisProvider::::with(&authid); + let key = session + .need_with::(&prov, |key| { + Ok(Box::from(key.as_slice())) + })?; + self.key_info = Some(KeyInfo { + authid, + key_id: 0x01, + key, + }); + } + None => { + tracing::error!("No data in response"); + return Err(FabFireError::ParseError.into()); + } + }; + } + Err(e) => { + tracing::error!("Failed to check response: {:?}", e); + return Err(FabFireError::ParseError.into()); + } + } + + return match self + .desfire + .authenticate_iso_aes_challenge_cmd(self.key_info.as_ref().unwrap().key_id) + { + Ok(buf) => match Vec::::try_from(buf) { + Ok(data) => { + self.step = Step::Authenticate1; + writer + .write_all(&data) + .map_err(|e| SessionError::Io { source: e })?; + Ok(State::Running) + } + Err(e) => { + tracing::error!("Failed to convert to Vec: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + }, + Err(e) => { + tracing::error!("Failed to create authenticate command: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + }; + } + Step::Authenticate1 => { + tracing::trace!("Step: Authenticate1"); + let apdu_response = match input { + Some(data) => APDUResponse::new(data), + None => return Err(SessionError::InputDataRequired), + }; + + return match apdu_response.check() { + Ok(_) => { + match apdu_response.body { + Some(data) => { + let rnd_b_enc = data.as_slice(); + + //FIXME: This is ugly, we should find a better way to make the function testable + //TODO: Check if we need a CSPRNG here + let rnd_a: [u8; 16] = rand::random(); + + let (cmd_challenge_response, rnd_b, iv) = self + .desfire + .authenticate_iso_aes_response_cmd( + rnd_b_enc, + &*(self.key_info.as_ref().unwrap().key), + &rnd_a, + ) + .unwrap(); + self.auth_info = Some(AuthInfo { + rnd_a: Vec::::from(rnd_a), + rnd_b, + iv, + }); + match Vec::::try_from(cmd_challenge_response) { + Ok(data) => { + self.step = Step::Authenticate2; + writer + .write_all(&data) + .map_err(|e| SessionError::Io { source: e })?; + Ok(State::Running) + } + Err(e) => { + tracing::error!("Failed to convert to Vec: {:?}", e); + return Err(FabFireError::SerializationError.into()); + } + } + } + None => { + tracing::error!("Got invalid response: {:?}", apdu_response); + Err(FabFireError::ParseError.into()) + } + } + } + Err(e) => { + tracing::error!("Failed to check response: {:?}", e); + Err(FabFireError::ParseError.into()) + } + }; + } + Step::Authenticate2 => { + // println!("Step: Authenticate2"); + let apdu_response = match input { + Some(data) => APDUResponse::new(data), + None => return Err(SessionError::InputDataRequired), + }; + + match apdu_response.check() { + Ok(_) => { + match apdu_response.body { + Some(data) => match self.auth_info.as_ref() { + None => { + return Err(FabFireError::ParseError.into()); + } + Some(auth_info) => { + if self + .desfire + .authenticate_iso_aes_verify( + data.as_slice(), + auth_info.rnd_a.as_slice(), + auth_info.rnd_b.as_slice(), + &*(self.key_info.as_ref().unwrap().key), + auth_info.iv.as_slice(), + ) + .is_ok() + { + struct Prov<'a> { + authid: &'a str, + } + impl<'a> Provider<'a> for Prov<'a> { + fn provide( + &self, + req: &mut Demand<'a>, + ) -> DemandReply<()> + { + req.provide_ref::(self.authid)?.done() + } + } + let prov = Prov { + authid: &self.key_info.as_ref().unwrap().authid, + }; + session.validate(&prov)?; + return Ok(State::Finished(MessageSent::Yes)); + } + } + }, + None => { + tracing::error!("got empty response"); + return Err(FabFireError::ParseError.into()); + } + }; + } + Err(_e) => { + tracing::error!("Got invalid response: {:?}", apdu_response); + return Err( + FabFireError::InvalidCredentials(format!("{}", apdu_response)).into(), + ); + } + } + } + } + + return Ok(State::Finished(MessageSent::No)); + } +} diff --git a/bffhd/authentication/mod.rs b/bffhd/authentication/mod.rs index f486cf1..6c0ea1c 100644 --- a/bffhd/authentication/mod.rs +++ b/bffhd/authentication/mod.rs @@ -1,16 +1,17 @@ use crate::users::Users; -use miette::{Context, IntoDiagnostic}; -use rsasl::error::SessionError; -use rsasl::mechname::Mechname; -use rsasl::property::{AuthId, Password}; -use rsasl::session::{Session, SessionData}; -use rsasl::validate::{validations, Validation}; -use rsasl::{Property, SASL}; +use miette::{IntoDiagnostic, WrapErr}; +use rsasl::callback::{CallbackError, Context, Request, SessionCallback, SessionData}; +use rsasl::mechanism::SessionError; +use rsasl::prelude::{Mechname, SASLConfig, SASLServer, Session, Validation}; +use rsasl::property::{AuthId, AuthzId, Password}; +use rsasl::validate::{Validate, ValidationError}; use std::sync::Arc; use crate::authentication::fabfire::FabFireCardKey; +use crate::users::db::User; mod fabfire; +mod fabfire_bin; struct Callback { users: Users, @@ -22,89 +23,102 @@ impl Callback { Self { users, span } } } -impl rsasl::callback::Callback for Callback { - fn provide_prop( +impl SessionCallback for Callback { + fn callback( &self, - session: &mut rsasl::session::SessionData, - property: Property, + _session_data: &SessionData, + context: &Context, + request: &mut Request, ) -> Result<(), SessionError> { - match property { - fabfire::FABFIRECARDKEY => { - let authcid = session.get_property_or_callback::()?; - let user = self - .users - .get_user(authcid.unwrap().as_ref()) - .ok_or(SessionError::AuthenticationFailure)?; + if let Some(authid) = context.get_ref::() { + request.satisfy_with::(|| { + let user = self.users.get_user(authid).ok_or(CallbackError::NoValue)?; let kv = user .userdata .kv .get("cardkey") - .ok_or(SessionError::AuthenticationFailure)?; - let card_key = <[u8; 16]>::try_from( - hex::decode(kv).map_err(|_| SessionError::AuthenticationFailure)?, - ) - .map_err(|_| SessionError::AuthenticationFailure)?; - session.set_property::(Arc::new(card_key)); - Ok(()) - } - _ => Err(SessionError::NoProperty { property }), + .ok_or(CallbackError::NoValue)?; + let card_key = + <[u8; 16]>::try_from(hex::decode(kv).map_err(|_| CallbackError::NoValue)?) + .map_err(|_| CallbackError::NoValue)?; + Ok(card_key) + })?; } + Ok(()) } fn validate( &self, - session: &mut SessionData, - validation: Validation, - _mechanism: &Mechname, - ) -> Result<(), SessionError> { + session_data: &SessionData, + context: &Context, + validate: &mut Validate<'_>, + ) -> Result<(), ValidationError> { let span = tracing::info_span!(parent: &self.span, "validate"); let _guard = span.enter(); - match validation { - validations::SIMPLE => { - let authnid = session - .get_property::() - .ok_or(SessionError::no_property::())?; - tracing::debug!(authid=%authnid, "SIMPLE validation requested"); + if validate.is::() { + match session_data.mechanism().mechanism.as_str() { + "PLAIN" => { + let authcid = context + .get_ref::() + .ok_or(ValidationError::MissingRequiredProperty)?; + let authzid = context + .get_ref::() + .ok_or(ValidationError::MissingRequiredProperty)?; + let password = context + .get_ref::() + .ok_or(ValidationError::MissingRequiredProperty)?; - if let Some(user) = self.users.get_user(authnid.as_str()) { - let passwd = session - .get_property::() - .ok_or(SessionError::no_property::())?; - - if user - .check_password(passwd.as_bytes()) - .map_err(|_e| SessionError::AuthenticationFailure)? - { + if !authzid.is_empty() { return Ok(()); - } else { - tracing::warn!(authid=%authnid, "AUTH FAILED: bad password"); } - } else { - tracing::warn!(authid=%authnid, "AUTH FAILED: no such user '{}'", authnid); - } - Err(SessionError::AuthenticationFailure) - } - _ => { - tracing::error!(?validation, "Unimplemented validation requested"); - Err(SessionError::no_validate(validation)) + if let Some(user) = self.users.get_user(authcid) { + match user.check_password(password) { + Ok(true) => validate.finalize::(user), + Ok(false) => { + tracing::warn!(authid=%authcid, "AUTH FAILED: bad password"); + } + Err(error) => { + tracing::warn!(authid=%authcid, "Bad DB entry: {}", error); + } + } + } else { + tracing::warn!(authid=%authcid, "AUTH FAILED: no such user"); + } + } + "X-FABFIRE" | "X-FABFIRE-BIN" => { + let authcid = context + .get_ref::() + .ok_or(ValidationError::MissingRequiredProperty)?; + if let Some(user) = self.users.get_user(authcid) { + validate.finalize::(user) + } + } + _ => {} } } + Ok(()) } } +pub struct V; +impl Validation for V { + type Value = User; +} + +#[derive(Clone)] struct Inner { - rsasl: SASL, + rsasl: Arc, } impl Inner { - pub fn new(rsasl: SASL) -> Self { + pub fn new(rsasl: Arc) -> Self { Self { rsasl } } } #[derive(Clone)] pub struct AuthenticationHandle { - inner: Arc, + inner: Inner, } impl AuthenticationHandle { @@ -112,11 +126,13 @@ impl AuthenticationHandle { let span = tracing::debug_span!("authentication"); let _guard = span.enter(); - let mut rsasl = SASL::new(); - rsasl.install_callback(Arc::new(Callback::new(userdb))); + let config = SASLConfig::builder() + .with_defaults() + .with_callback(Callback::new(userdb)) + .unwrap(); - let mechs: Vec<&'static str> = rsasl - .server_mech_list() + let mechs: Vec<&'static str> = SASLServer::::new(config.clone()) + .get_available() .into_iter() .map(|m| m.mechanism.as_str()) .collect(); @@ -124,24 +140,18 @@ impl AuthenticationHandle { tracing::debug!(?mechs, "available mechs"); Self { - inner: Arc::new(Inner::new(rsasl)), + inner: Inner::new(config), } } - pub fn start(&self, mechanism: &Mechname) -> miette::Result { - Ok(self - .inner - .rsasl - .server_start(mechanism) + pub fn start(&self, mechanism: &Mechname) -> miette::Result> { + Ok(SASLServer::new(self.inner.rsasl.clone()) + .start_suggested(mechanism) .into_diagnostic() .wrap_err("Failed to start a SASL authentication with the given mechanism")?) } - pub fn list_available_mechs(&self) -> impl IntoIterator { - self.inner - .rsasl - .server_mech_list() - .into_iter() - .map(|m| m.mechanism) + pub fn sess(&self) -> SASLServer { + SASLServer::new(self.inner.rsasl.clone()) } } diff --git a/bffhd/capnp/authenticationsystem.rs b/bffhd/capnp/authenticationsystem.rs index 56b1530..9b76319 100644 --- a/bffhd/capnp/authenticationsystem.rs +++ b/bffhd/capnp/authenticationsystem.rs @@ -2,13 +2,13 @@ use capnp::capability::Promise; use capnp::Error; use capnp_rpc::pry; use rsasl::mechname::Mechname; -use rsasl::property::AuthId; -use rsasl::session::{Session, Step}; +use rsasl::prelude::State as SaslState; +use rsasl::prelude::{MessageSent, Session}; use std::fmt; use std::fmt::{Formatter, Write}; -use std::io::Cursor; use tracing::Span; +use crate::authentication::V; use crate::capnp::session::APISession; use crate::session::SessionManager; use api::authenticationsystem_capnp::authentication::{ @@ -27,7 +27,7 @@ impl Authentication { pub fn new( parent: &Span, mechanism: &Mechname, /* TODO: this is stored in session as well, get it out of there. */ - session: Session, + session: Session, sessionmanager: SessionManager, ) -> Self { let span = tracing::info_span!( @@ -92,7 +92,7 @@ enum State { InvalidMechanism, Finished, Aborted, - Running(Session, SessionManager), + Running(Session, SessionManager), } impl AuthenticationSystem for Authentication { @@ -113,7 +113,7 @@ impl AuthenticationSystem for Authentication { f.write_char(')') } } - let mut response; + let response; let mut builder = results.get(); if let State::Running(mut session, manager) = @@ -121,36 +121,35 @@ impl AuthenticationSystem for Authentication { { let data: &[u8] = pry!(pry!(params.get()).get_data()); - let mut out = Cursor::new(Vec::new()); + let mut out = Vec::new(); match session.step(Some(data), &mut out) { - Ok(Step::Done(data)) => { + Ok(SaslState::Finished(sent)) => { self.state = State::Finished; - let uid = pry!(session.get_property::().ok_or_else(|| { - tracing::warn!("Authentication didn't provide an authid as required."); - capnp::Error::failed( - "Authentication didn't provide an authid as required".to_string(), - ) - })); - let session = pry!(manager.open(&self.span, uid.as_ref()).ok_or_else(|| { - tracing::warn!(uid = uid.as_str(), "Failed to lookup the given user"); - capnp::Error::failed("Failed to lookup the given user".to_string()) - })); + if let Some(user) = session.validation() { + let session = manager.open(&self.span, user); + response = Response { + union_field: "successful", + }; - response = Response { - union_field: "successful", - }; + let mut builder = builder.init_successful(); + if sent == MessageSent::Yes { + builder.set_additional_data(out.as_slice()); + } - let mut builder = builder.init_successful(); - if data.is_some() { - builder.set_additional_data(out.into_inner().as_slice()); + APISession::build(session, builder) + } else { + let mut builder = builder.init_failed(); + builder.set_code(ErrorCode::InvalidCredentials); + + response = Response { + union_field: "error", + }; } - - APISession::build(session, builder) } - Ok(Step::NeedsMore(_)) => { + Ok(SaslState::Running) => { self.state = State::Running(session, manager); - builder.set_challenge(out.into_inner().as_slice()); + builder.set_challenge(out.as_slice()); response = Response { union_field: "challenge", diff --git a/bffhd/capnp/connection.rs b/bffhd/capnp/connection.rs index 9595ed9..2e96dc6 100644 --- a/bffhd/capnp/connection.rs +++ b/bffhd/capnp/connection.rs @@ -95,9 +95,10 @@ impl bootstrap::Server for BootCap { let builder = result.get(); let mechs: Vec<_> = self .authentication - .list_available_mechs() + .sess() + .get_available() .into_iter() - .map(|m| m.as_str()) + .map(|m| m.mechanism.as_str()) .collect(); let mut mechbuilder = builder.init_mechs(mechs.len() as u32); for (i, m) in mechs.iter().enumerate() { @@ -146,7 +147,7 @@ impl bootstrap::Server for BootCap { tracing::trace!(params.mechanism = mechanism, "method call"); - let mechname = Mechname::new(mechanism.as_bytes()); + let mechname = Mechname::parse(mechanism.as_bytes()); let auth = if let Ok(mechname) = mechname { if let Ok(session) = self.authentication.start(mechname) { Authentication::new(&self.span, mechname, session, self.sessionmanager.clone()) diff --git a/bffhd/capnp/machine.rs b/bffhd/capnp/machine.rs index d05d4f2..7067727 100644 --- a/bffhd/capnp/machine.rs +++ b/bffhd/capnp/machine.rs @@ -211,7 +211,6 @@ impl ManageServer for Machine { mut result: manage::GetMachineInfoExtendedResults, ) -> Promise<(), ::capnp::Error> { let mut builder = result.get(); - let user = User::new_self(self.session.clone()); User::build_optional( &self.session, self.resource.get_current_user(), diff --git a/bffhd/capnp/mod.rs b/bffhd/capnp/mod.rs index 70345f7..55f3140 100644 --- a/bffhd/capnp/mod.rs +++ b/bffhd/capnp/mod.rs @@ -1,13 +1,15 @@ -use async_net::TcpListener; +use miette::Diagnostic; +use thiserror::Error; +use async_net::TcpListener; use capnp_rpc::rpc_twoparty_capnp::Side; use capnp_rpc::twoparty::VatNetwork; use capnp_rpc::RpcSystem; -use executor::prelude::{Executor, GroupId, SupervisionRegistry}; +use executor::prelude::{Executor, SupervisionRegistry}; use futures_rustls::server::TlsStream; use futures_rustls::TlsAcceptor; use futures_util::stream::FuturesUnordered; -use futures_util::{stream, AsyncRead, AsyncWrite, FutureExt, StreamExt}; +use futures_util::{stream, AsyncRead, AsyncWrite, StreamExt}; use std::future::Future; use std::io; @@ -37,6 +39,10 @@ pub struct APIServer { authentication: AuthenticationHandle, } +#[derive(Debug, Error, Diagnostic)] +#[error("Reached Void error, this should not be possible")] +pub enum Error {} + impl APIServer { pub fn new( executor: Executor<'static>, @@ -60,7 +66,7 @@ impl APIServer { acceptor: TlsAcceptor, sessionmanager: SessionManager, authentication: AuthenticationHandle, - ) -> miette::Result { + ) -> Result { let span = tracing::info_span!("binding API listen sockets"); let _guard = span.enter(); diff --git a/bffhd/capnp/permissionsystem.rs b/bffhd/capnp/permissionsystem.rs index 6e8eac3..de5f0aa 100644 --- a/bffhd/capnp/permissionsystem.rs +++ b/bffhd/capnp/permissionsystem.rs @@ -1,4 +1,3 @@ -use crate::authorization::roles::Role; use crate::Roles; use api::permissionsystem_capnp::permission_system::info::{ GetRoleListParams, GetRoleListResults, Server as PermissionSystem, @@ -37,7 +36,7 @@ impl PermissionSystem for Permissions { tracing::trace!("method call"); let roles = self.roles.list().collect::>(); - let mut builder = results.get(); + let builder = results.get(); let mut b = builder.init_role_list(roles.len() as u32); for (i, role) in roles.into_iter().enumerate() { let mut role_builder = b.reborrow().get(i as u32); diff --git a/bffhd/capnp/user.rs b/bffhd/capnp/user.rs index 4333a86..3ef26d9 100644 --- a/bffhd/capnp/user.rs +++ b/bffhd/capnp/user.rs @@ -1,20 +1,38 @@ use crate::authorization::permissions::Permission; use crate::session::SessionHandle; use crate::users::{db, UserRef}; +use crate::CONFIG; use api::general_capnp::optional; -use api::user_capnp::user::{self, admin, info, manage}; +use api::user_capnp::user::card_d_e_s_fire_e_v2::{ + BindParams, BindResults, GenCardTokenParams, GenCardTokenResults, GetMetaInfoParams, + GetMetaInfoResults, GetSpaceInfoParams, GetSpaceInfoResults, GetTokenListParams, + GetTokenListResults, UnbindParams, UnbindResults, +}; +use api::user_capnp::user::{self, admin, card_d_e_s_fire_e_v2, info, manage}; use capnp::capability::Promise; +use capnp::Error; use capnp_rpc::pry; +use std::borrow::Cow; +use std::io::Write; +use uuid::Uuid; + +const TARGET: &str = "bffh::api::user"; #[derive(Clone)] pub struct User { + span: tracing::Span, session: SessionHandle, user: UserRef, } impl User { pub fn new(session: SessionHandle, user: UserRef) -> Self { - Self { session, user } + let span = tracing::info_span!(target: TARGET, "User"); + Self { + span, + session, + user, + } } pub fn new_self(session: SessionHandle) -> Self { @@ -55,6 +73,7 @@ impl User { } if session.has_perm(Permission::new("bffh.users.admin")) { builder.set_admin(capnp_rpc::new_client(client.clone())); + builder.set_card_d_e_s_fire_e_v2(capnp_rpc::new_client(client)); } } } @@ -90,7 +109,7 @@ impl manage::Server for User { if let Some(mut user) = self.session.users.get_user(uid) { if let Ok(true) = user.check_password(old_pw.as_bytes()) { user.set_pw(new_pw.as_bytes()); - self.session.users.put_user(uid, &user); + pry!(self.session.users.put_user(uid, &user)); } } Promise::ok(()) @@ -124,9 +143,9 @@ impl admin::Server for User { // Only update if needed if !target.userdata.roles.iter().any(|r| r.as_str() == rolename) { target.userdata.roles.push(rolename.to_string()); - self.session + pry!(self.session .users - .put_user(self.user.get_username(), &target); + .put_user(self.user.get_username(), &target)); } } @@ -149,9 +168,9 @@ impl admin::Server for User { // Only update if needed if target.userdata.roles.iter().any(|r| r.as_str() == rolename) { target.userdata.roles.retain(|r| r.as_str() != rolename); - self.session + pry!(self.session .users - .put_user(self.user.get_username(), &target); + .put_user(self.user.get_username(), &target)); } } @@ -166,8 +185,218 @@ impl admin::Server for User { let uid = self.user.get_username(); if let Some(mut user) = self.session.users.get_user(uid) { user.set_pw(new_pw.as_bytes()); - self.session.users.put_user(uid, &user); + pry!(self.session.users.put_user(uid, &user)); } Promise::ok(()) } } + +impl card_d_e_s_fire_e_v2::Server for User { + fn get_token_list( + &mut self, + _: GetTokenListParams, + mut results: GetTokenListResults, + ) -> Promise<(), Error> { + let _guard = self.span.enter(); + let _span = tracing::trace_span!(target: TARGET, "get_token_list").entered(); + tracing::trace!("method call"); + + // TODO: This only supports a single token per user + let user = pry!(self + .session + .users + .get_user(self.user.get_username()) + .ok_or_else(|| Error::failed(format!( + "User API object with nonexisting user \"{}\"", + self.user.get_username() + )))); + let tk = user + .userdata + .kv + .get("cardtoken") + .map(|ck| hex::decode(ck).ok()) + .flatten() + .unwrap_or_else(|| { + tracing::debug!(user.id = &user.id, "no tokens stored"); + Vec::new() + }); + if !tk.is_empty() { + let b = results.get(); + let mut lb = b.init_token_list(1); + lb.set(0, &tk[..]); + } + Promise::ok(()) + } + + fn bind(&mut self, params: BindParams, _: BindResults) -> Promise<(), Error> { + let _guard = self.span.enter(); + let _span = tracing::trace_span!(target: TARGET, "bind").entered(); + let params = pry!(params.get()); + let card_key = pry!(params.get_auth_key()); + let token = pry!(params.get_token()); + + let token: Cow<'_, str> = if let Ok(url) = std::str::from_utf8(token) { + Cow::Borrowed(url) + } else { + Cow::Owned(hex::encode(token)) + }; + + tracing::trace!( + params.token = token.as_ref(), + params.auth_key = "", + "method call" + ); + + let card_key = hex::encode(card_key); + + let mut user = pry!(self + .session + .users + .get_user(self.user.get_username()) + .ok_or_else(|| Error::failed(format!( + "User API object with nonexisting user \"{}\"", + self.user.get_username() + )))); + + let prev_token = user.userdata.kv.get("cardtoken"); + let prev_cardk = user.userdata.kv.get("cardkey"); + + match (prev_token, prev_cardk) { + (Some(prev_token), Some(prev_cardk)) + if prev_token.as_str() == &token && prev_cardk.as_str() == card_key.as_str() => + { + tracing::info!( + user.id, token = token.as_ref(), + "new token and card key are identical, skipping no-op" + ); + return Promise::ok(()); + }, + (Some(prev_token), Some(_)) + if prev_token.as_str() == token /* above guard means prev_cardk != card_key */ => + { + tracing::warn!( + token = token.as_ref(), + "trying to overwrite card key for existing token, ignoring!" + ); + return Promise::ok(()); + }, + (Some(prev_token), None) => tracing::warn!( + user.id, prev_token, + "token already set for user but no card key, setting new pair unconditionally!" + ), + (None, Some(_)) => tracing::warn!( + user.id, + "card key already set for user but no token, setting new pair unconditionally!" + ), + (Some(_), Some(_)) | (None, None) => tracing::debug!( + user.id, token = token.as_ref(), + "Adding new card key/token pair" + ), + } + + user.userdata + .kv + .insert("cardtoken".to_string(), token.to_string()); + user.userdata.kv.insert("cardkey".to_string(), card_key); + + pry!(self.session.users.put_user(self.user.get_username(), &user)); + + Promise::ok(()) + } + + fn unbind(&mut self, params: UnbindParams, _: UnbindResults) -> Promise<(), Error> { + let _guard = self.span.enter(); + let _span = tracing::trace_span!(target: TARGET, "unbind").entered(); + + let params = pry!(params.get()); + let token = pry!(params.get_token()); + + let token: Cow<'_, str> = if let Ok(url) = std::str::from_utf8(token) { + Cow::Borrowed(url) + } else { + Cow::Owned(hex::encode(token)) + }; + + tracing::trace!(params.token = token.as_ref(), "method call"); + + let mut user = pry!(self + .session + .users + .get_user(self.user.get_username()) + .ok_or_else(|| Error::failed(format!( + "User API object with nonexisting user \"{}\"", + self.user.get_username() + )))); + if let Some(prev_token) = user.userdata.kv.get("cardtoken") { + if token.as_ref() == prev_token.as_str() { + tracing::debug!( + user.id, + token = token.as_ref(), + "removing card key/token pair" + ); + user.userdata.kv.remove("cardtoken"); + user.userdata.kv.remove("cardkey"); + } + } + + pry!(self.session.users.put_user(self.user.get_username(), &user)); + + Promise::ok(()) + } + + fn gen_card_token( + &mut self, + _: GenCardTokenParams, + mut results: GenCardTokenResults, + ) -> Promise<(), Error> { + let _guard = self.span.enter(); + let _span = tracing::trace_span!(target: TARGET, "gen_card_token").entered(); + tracing::trace!("method call"); + + results.get().set_token(Uuid::new_v4().as_bytes()); + + Promise::ok(()) + } + + fn get_meta_info( + &mut self, + _: GetMetaInfoParams, + mut results: GetMetaInfoResults, + ) -> Promise<(), Error> { + let _guard = self.span.enter(); + let _span = tracing::trace_span!(target: TARGET, "get_meta_info").entered(); + tracing::trace!("method call"); + + results.get().set_bytes(b"FABACCESS\x00DESFIRE\x001.0\x00"); + + Promise::ok(()) + } + + fn get_space_info( + &mut self, + _: GetSpaceInfoParams, + mut results: GetSpaceInfoResults, + ) -> Promise<(), Error> { + let _guard = self.span.enter(); + let _span = tracing::trace_span!(target: TARGET, "get_space_info").entered(); + tracing::trace!("method call"); + + let space = if let Some(space) = CONFIG.get().map(|c| c.spacename.as_str()) { + space + } else { + return Promise::err(Error::failed("No space name configured".to_string())); + }; + + let url = if let Some(url) = CONFIG.get().map(|c| c.instanceurl.as_str()) { + url + } else { + return Promise::err(Error::failed("No instance url configured".to_string())); + }; + + let mut data = Vec::new(); + write!(&mut data, "urn:fabaccess:lab:{space}\x00{url}").unwrap(); + results.get().set_bytes(&data); + + Promise::ok(()) + } +} diff --git a/bffhd/capnp/user_system.rs b/bffhd/capnp/user_system.rs index 2d40a44..6fa699b 100644 --- a/bffhd/capnp/user_system.rs +++ b/bffhd/capnp/user_system.rs @@ -84,13 +84,13 @@ impl manage::Server for Users { "method call" ); - let mut builder = result.get(); + let builder = result.get(); if !username.is_empty() && !password.is_empty() { if self.session.users.get_user(username).is_none() { let user = db::User::new_with_plain_pw(username, password); - self.session.users.put_user(username, &user); - let mut builder = builder.init_successful(); + pry!(self.session.users.put_user(username, &user)); + let builder = builder.init_successful(); User::fill(&self.session, user, builder); } else { let mut builder = builder.init_failed(); diff --git a/bffhd/config/dhall.rs b/bffhd/config/dhall.rs index b933a0b..557cd49 100644 --- a/bffhd/config/dhall.rs +++ b/bffhd/config/dhall.rs @@ -1,8 +1,6 @@ use std::collections::HashMap; use std::default::Default; -use std::error::Error; -use std::fmt::{Debug, Display}; -use std::marker::PhantomData; +use std::fmt::Debug; use std::path::PathBuf; use serde::{Deserialize, Serialize}; @@ -12,7 +10,6 @@ use crate::authorization::roles::Role; use crate::capnp::{Listen, TlsListen}; use crate::logging::LogConfig; -use miette::IntoDiagnostic; use std::path::Path; #[derive(Debug)] @@ -96,6 +93,10 @@ pub struct Config { #[serde(default, skip)] pub logging: LogConfig, + + pub spacename: String, + + pub instanceurl: String, } impl Config { @@ -164,6 +165,8 @@ impl Default for Config { tlskeylog: None, verbosity: 0, logging: LogConfig::default(), + instanceurl: "".into(), + spacename: "".into(), } } } diff --git a/bffhd/config/mod.rs b/bffhd/config/mod.rs index dfce376..fba5f64 100644 --- a/bffhd/config/mod.rs +++ b/bffhd/config/mod.rs @@ -38,13 +38,15 @@ pub fn read(file: impl AsRef) -> Result { if !path.is_file() { return Err(ConfigError::NotAFile(path.to_string_lossy().to_string())); } - let mut config = dhall::read_config_file(file)?; - for (envvar, value) in std::env::vars() { - match envvar.as_str() { - // Do things like this? - // "BFFH_LOG" => config.logging.filter = Some(value), - _ => {} - } - } + let config = dhall::read_config_file(file)?; + // TODO: configuration by environment variables? + // but rather in in a separate function + // for (envvar, value) in std::env::vars() { + // match envvar.as_str() { + // // Do things like this? + // // "BFFH_LOG" => config.logging.filter = Some(value), + // _ => {} + // } + // } Ok(config) } diff --git a/bffhd/db/mod.rs b/bffhd/db/mod.rs index 36a5690..a01cff6 100644 --- a/bffhd/db/mod.rs +++ b/bffhd/db/mod.rs @@ -1,10 +1,13 @@ use thiserror::Error; +// for converting a database error into a failed promise +use capnp; + mod raw; -use miette::{Diagnostic, LabeledSpan, Severity, SourceCode}; +use miette::{Diagnostic, Severity}; pub use raw::RawDB; -use std::fmt::{Debug, Display, Formatter}; +use std::fmt::{Debug, Display}; mod typed; pub use typed::{Adapter, AlignedAdapter, ArchivedValue, DB}; @@ -13,9 +16,9 @@ pub type ErrorO = lmdb::Error; pub type Result = std::result::Result; -#[repr(transparent)] -#[derive(Debug, Error)] +#[derive(Clone, Debug, PartialEq, Eq, Error)] #[error(transparent)] +#[repr(transparent)] pub struct Error(#[from] lmdb::Error); impl Diagnostic for Error { @@ -79,3 +82,9 @@ impl Diagnostic for Error { None } } + +impl From for capnp::Error { + fn from(dberr: Error) -> capnp::Error { + capnp::Error::failed(format!("database error: {}", dberr.to_string())) + } +} diff --git a/bffhd/db/raw.rs b/bffhd/db/raw.rs index 9ec84dd..fc24f40 100644 --- a/bffhd/db/raw.rs +++ b/bffhd/db/raw.rs @@ -1,4 +1,3 @@ -use super::Result; use lmdb::{DatabaseFlags, Environment, RwTransaction, Transaction, WriteFlags}; #[derive(Debug, Clone)] diff --git a/bffhd/error.rs b/bffhd/error.rs index e0af43b..b51385a 100644 --- a/bffhd/error.rs +++ b/bffhd/error.rs @@ -1,4 +1,4 @@ -use miette::{Diagnostic, LabeledSpan, Severity, SourceCode}; +use miette::{Diagnostic, Severity}; use std::error; use std::fmt::{Display, Formatter}; use std::io; diff --git a/bffhd/initiators/dummy.rs b/bffhd/initiators/dummy.rs index 1fd2a3e..2cfd502 100644 --- a/bffhd/initiators/dummy.rs +++ b/bffhd/initiators/dummy.rs @@ -5,14 +5,11 @@ use super::Initiator; use crate::initiators::InitiatorCallbacks; use crate::resources::modules::fabaccess::Status; use crate::session::SessionHandle; -use crate::users::UserRef; use async_io::Timer; use futures_util::future::BoxFuture; use futures_util::ready; -use lmdb::Stat; use std::collections::HashMap; use std::future::Future; -use std::mem; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::{Duration, Instant}; @@ -64,10 +61,7 @@ impl Future for Dummy { match &mut self.state { DummyState::Empty => { tracing::trace!("Dummy initiator is empty, initializing…"); - mem::replace( - &mut self.state, - DummyState::Sleeping(Self::timer(), Some(Status::Free)), - ); + self.state = DummyState::Sleeping(Self::timer(), Some(Status::Free)); } DummyState::Sleeping(timer, next) => { tracing::trace!("Sleep timer exists, polling it."); @@ -78,7 +72,7 @@ impl Future for Dummy { let status = next.take().unwrap(); let f = self.flip(status); - mem::replace(&mut self.state, DummyState::Updating(f)); + self.state = DummyState::Updating(f); } DummyState::Updating(f) => { tracing::trace!("Update future exists, polling it ."); @@ -87,10 +81,7 @@ impl Future for Dummy { tracing::trace!("Update future completed, sleeping!"); - mem::replace( - &mut self.state, - DummyState::Sleeping(Self::timer(), Some(next)), - ); + self.state = DummyState::Sleeping(Self::timer(), Some(next)); } } } diff --git a/bffhd/initiators/mod.rs b/bffhd/initiators/mod.rs index f20ee9d..0b84195 100644 --- a/bffhd/initiators/mod.rs +++ b/bffhd/initiators/mod.rs @@ -3,22 +3,15 @@ use crate::initiators::process::Process; use crate::resources::modules::fabaccess::Status; use crate::session::SessionHandle; use crate::{ - AuthenticationHandle, Config, MachineState, Resource, ResourcesHandle, SessionManager, + AuthenticationHandle, Config, Resource, ResourcesHandle, SessionManager, }; -use async_compat::CompatExt; use executor::prelude::Executor; use futures_util::ready; -use miette::IntoDiagnostic; -use rumqttc::ConnectReturnCode::Success; -use rumqttc::{AsyncClient, ConnectionError, Event, Incoming, MqttOptions}; use std::collections::HashMap; -use std::fmt::Display; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; -use std::time::Duration; use tracing::Span; -use url::Url; mod dummy; mod process; @@ -56,7 +49,7 @@ impl InitiatorCallbacks { } pub fn open_session(&self, uid: &str) -> Option { - self.sessions.open(&self.span, uid) + self.sessions.try_open(&self.span, uid) } } @@ -107,7 +100,7 @@ pub fn load( config: &Config, resources: ResourcesHandle, sessions: SessionManager, - authentication: AuthenticationHandle, + _authentication: AuthenticationHandle, ) -> miette::Result<()> { let span = tracing::info_span!("loading initiators"); let _guard = span.enter(); diff --git a/bffhd/initiators/process.rs b/bffhd/initiators/process.rs index d714ec3..9fae277 100644 --- a/bffhd/initiators/process.rs +++ b/bffhd/initiators/process.rs @@ -1,9 +1,9 @@ use super::Initiator; use super::InitiatorCallbacks; -use crate::resources::state::State; +use crate::resources::modules::fabaccess::Status; use crate::utils::linebuffer::LineBuffer; use async_process::{Child, ChildStderr, ChildStdout, Command, Stdio}; -use futures_lite::{ready, AsyncRead}; +use futures_lite::AsyncRead; use miette::{miette, IntoDiagnostic}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -11,7 +11,6 @@ use std::future::Future; use std::io; use std::pin::Pin; use std::task::{Context, Poll}; -use crate::resources::modules::fabaccess::Status; #[derive(Debug, Serialize, Deserialize)] pub enum InputMessage { @@ -63,7 +62,12 @@ struct ProcessState { impl ProcessState { pub fn new(stdout: ChildStdout, stderr: ChildStderr, child: Child) -> Self { - Self { stdout, stderr, stderr_closed: false, child } + Self { + stdout, + stderr, + stderr_closed: false, + child, + } } fn try_process(&mut self, buffer: &[u8], callbacks: &mut InitiatorCallbacks) -> usize { @@ -100,7 +104,9 @@ impl ProcessState { let InputMessage::SetState(status) = state; callbacks.set_status(status); } - Err(error) => tracing::warn!(%error, "process initiator did not send a valid line"), + Err(error) => { + tracing::warn!(%error, "process initiator did not send a valid line") + } } } } @@ -110,7 +116,7 @@ impl ProcessState { impl Future for Process { type Output = (); - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { if let Process { state: Some(state), buffer, @@ -202,8 +208,8 @@ impl Future for Process { impl Initiator for Process { fn new(params: &HashMap, callbacks: InitiatorCallbacks) -> miette::Result - where - Self: Sized, + where + Self: Sized, { let cmd = params .get("cmd") diff --git a/bffhd/lib.rs b/bffhd/lib.rs index 81dd9ea..6461f26 100644 --- a/bffhd/lib.rs +++ b/bffhd/lib.rs @@ -3,11 +3,14 @@ //#![warn(missing_docs)] //#![warn(missing_crate_level_docs)] -//! Diflouroborane +//! Difluoroborane //! //! This is the capnp component of the FabAccess project. //! The entry point of bffhd can be found in [bin/bffhd/main.rs](../bin/bffhd/main.rs) +use miette::{Diagnostic, IntoDiagnostic}; +use thiserror::Error; + pub mod config; /// Internal Databases build on top of LMDB, a mmap()'ed B-tree DB optimized for reads @@ -44,7 +47,6 @@ mod tls; use std::sync::Arc; use futures_util::{FutureExt, StreamExt}; -use miette::{Context, IntoDiagnostic, Report}; use once_cell::sync::OnceCell; use crate::audit::AuditLog; @@ -65,7 +67,9 @@ use lightproc::recoverable_handle::RecoverableHandle; use signal_hook::consts::signal::*; use tracing::Span; -pub struct Diflouroborane { +use std::collections::HashMap; + +pub struct Difluoroborane { config: Config, executor: Executor<'static>, pub statedb: StateDB, @@ -77,15 +81,72 @@ pub struct Diflouroborane { pub static RESOURCES: OnceCell = OnceCell::new(); +pub static CONFIG: OnceCell = OnceCell::new(); + struct SignalHandlerErr; impl error::Description for SignalHandlerErr { const CODE: &'static str = "signals::new"; } -impl Diflouroborane { +#[derive(Debug, Error, Diagnostic)] +// TODO 0.5: #[non_exhaustive] +pub enum BFFHError { + #[error("DB operation failed")] + DBError( + #[from] + #[source] + db::Error, + ), + #[error("failed to initialize global user store")] + UsersError( + #[from] + #[source] + users::Error, + ), + #[error("failed to initialize state database")] + StateDBError( + #[from] + #[source] + resources::state::db::StateDBError, + ), + #[error("audit log failed")] + AuditLogError( + #[from] + #[source] + audit::Error, + ), + #[error("Failed to initialize signal handler")] + SignalsError(#[source] std::io::Error), + #[error("error in actor subsystem")] + ActorError( + #[from] + #[source] + actors::ActorError, + ), + #[error("failed to initialize TLS config")] + TlsSetup( + #[from] + #[source] + tls::Error, + ), + #[error("API handler failed")] + ApiError( + #[from] + #[source] + capnp::Error, + ), +} + +#[derive(serde::Serialize, serde::Deserialize)] +struct DatabaseDump { + users: HashMap, + state: HashMap, +} + +impl Difluoroborane { pub fn setup() {} - pub fn new(config: Config) -> miette::Result { + pub fn new(config: Config) -> Result { let mut server = logging::init(&config.logging); let span = tracing::info_span!( target: "bffh", @@ -121,9 +182,7 @@ impl Diflouroborane { let users = Users::new(env.clone())?; let roles = Roles::new(config.roles.clone()); - let _audit_log = AuditLog::new(&config) - .into_diagnostic() - .wrap_err("Failed to initialize audit log")?; + let _audit_log = AuditLog::new(&config)?; let resources = ResourcesHandle::new(config.machines.iter().map(|(id, desc)| { Resource::new(Arc::new(resources::Inner::new( @@ -132,7 +191,8 @@ impl Diflouroborane { desc.clone(), ))) })); - RESOURCES.set(resources.clone()); + RESOURCES.set(resources.clone()).unwrap(); + CONFIG.set(config.clone()).unwrap(); Ok(Self { config, @@ -145,10 +205,27 @@ impl Diflouroborane { }) } - pub fn run(&mut self) -> miette::Result<()> { + pub fn dump_db(&mut self, file: &str) -> Result<(), miette::Error> { + let users = self.users.dump_map()?; + let state = self.statedb.dump_map()?; + let dump = DatabaseDump{users, state}; + let data = toml::ser::to_vec(&dump).map_err(|e| miette::Error::msg(format!("Serializing database dump failed: {}", e)))?; + std::fs::write(file, &data).map_err(|e| miette::Error::msg(format!("writing database dump failed: {}", e)))?; + Ok(()) + } + + pub fn load_db(&mut self, file: &str) -> Result<(), miette::Error> { + let data = std::fs::read(file).into_diagnostic()?; + let dump: DatabaseDump = toml::de::from_slice(&data).into_diagnostic()?; + self.users.load_map(&dump.users)?; + self.statedb.load_map(&dump.state)?; + Ok(()) + } + + pub fn run(&mut self) -> Result<(), BFFHError> { let _guard = self.span.enter(); let mut signals = signal_hook_async_std::Signals::new(&[SIGINT, SIGQUIT, SIGTERM]) - .map_err(|ioerr| error::wrap::(ioerr.into()))?; + .map_err(BFFHError::SignalsError)?; let sessionmanager = SessionManager::new(self.users.clone(), self.roles.clone()); let authentication = AuthenticationHandle::new(self.users.clone()); @@ -159,11 +236,12 @@ impl Diflouroborane { self.resources.clone(), sessionmanager.clone(), authentication.clone(), - ); + ).expect("initializing initiators failed"); + // TODO 0.5: error handling. Add variant to BFFHError + actors::load(self.executor.clone(), &self.config, self.resources.clone())?; - let tlsconfig = TlsConfig::new(self.config.tlskeylog.as_ref(), !self.config.is_quiet()) - .into_diagnostic()?; + let tlsconfig = TlsConfig::new(self.config.tlskeylog.as_ref(), !self.config.is_quiet())?; let acceptor = tlsconfig.make_tls_acceptor(&self.config.tlsconfig)?; let apiserver = self.executor.run(APIServer::bind( @@ -179,13 +257,13 @@ impl Diflouroborane { self.executor.spawn(apiserver.handle_until(rx)); let f = async { - let mut sig = None; + let mut sig; while { sig = signals.next().await; sig.is_none() } {} tracing::info!(signal = %sig.unwrap(), "Received signal"); - tx.send(()); + _ = tx.send(()); // ignore result, as an Err means that the executor we want to stop has already stopped }; self.executor.run(f); diff --git a/bffhd/logging.rs b/bffhd/logging.rs index 1fdb2c6..b074ec2 100644 --- a/bffhd/logging.rs +++ b/bffhd/logging.rs @@ -2,16 +2,15 @@ use serde::{Deserialize, Serialize}; use std::path::Path; use tracing_subscriber::fmt::format::Format; use tracing_subscriber::prelude::*; -use tracing_subscriber::reload::Handle; -use tracing_subscriber::{reload, EnvFilter}; +use tracing_subscriber::EnvFilter; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct LogConfig { #[serde(default, skip_serializing_if = "Option::is_none")] /// Log filter string in the tracing format `target[span{field=value}]=level`. /// lvalue is optional and multiple filters can be combined with comma. - /// e.g. `warn,diflouroborane::actors=debug` will only print `WARN` and `ERROR` unless the - /// message is logged in a span below `diflouroborane::actors` (i.e. by an actor task) in + /// e.g. `warn,difluoroborane::actors=debug` will only print `WARN` and `ERROR` unless the + /// message is logged in a span below `difluoroborane::actors` (i.e. by an actor task) in /// which case `DEBUG` and `INFO` will also be printed. pub filter: Option, diff --git a/bffhd/resources/mod.rs b/bffhd/resources/mod.rs index 369efe3..56dccf2 100644 --- a/bffhd/resources/mod.rs +++ b/bffhd/resources/mod.rs @@ -85,10 +85,13 @@ impl Inner { self.db.put(&self.id.as_bytes(), &state).unwrap(); tracing::trace!("Updated DB, sending update signal"); - AUDIT + let res = AUDIT .get() .unwrap() .log(self.id.as_str(), &format!("{}", state)); + if let Err(e) = res { + tracing::error!("Writing to the audit log failed for {} {}: {e}", self.id.as_str(), state); + } self.signal.set(state); tracing::trace!("Sent update signal"); @@ -161,7 +164,7 @@ impl Resource { fn set_state(&self, state: MachineState) { let mut serializer = AllocSerializer::<1024>::default(); - serializer.serialize_value(&state); + serializer.serialize_value(&state).expect("serializing a MachineState shoud be infallible"); let archived = ArchivedValue::new(serializer.into_serializer().into_inner()); self.inner.set_state(archived) } diff --git a/bffhd/resources/modules/fabaccess.rs b/bffhd/resources/modules/fabaccess.rs index b50e9b6..2374d1a 100644 --- a/bffhd/resources/modules/fabaccess.rs +++ b/bffhd/resources/modules/fabaccess.rs @@ -3,7 +3,6 @@ use crate::utils::oid::ObjectIdentifier; use once_cell::sync::Lazy; use rkyv::{Archive, Archived, Deserialize, Infallible}; use std::fmt; -use std::fmt::Write; use std::str::FromStr; //use crate::oidvalue; diff --git a/bffhd/resources/search.rs b/bffhd/resources/search.rs index 97371d7..a82f9e6 100644 --- a/bffhd/resources/search.rs +++ b/bffhd/resources/search.rs @@ -2,6 +2,7 @@ use crate::resources::Resource; use std::collections::HashMap; use std::sync::Arc; +#[derive(Debug)] struct Inner { id: HashMap, } @@ -19,7 +20,7 @@ impl Inner { } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct ResourcesHandle { inner: Arc, } diff --git a/bffhd/resources/state/db.rs b/bffhd/resources/state/db.rs index 3abc0df..d2237aa 100644 --- a/bffhd/resources/state/db.rs +++ b/bffhd/resources/state/db.rs @@ -1,12 +1,12 @@ +use rkyv::ser::Serializer; +use rkyv::ser::serializers::AllocSerializer; use thiserror::Error; use crate::db; use crate::db::{AlignedAdapter, ArchivedValue, RawDB, DB}; use lmdb::{DatabaseFlags, Environment, EnvironmentFlags, Transaction, WriteFlags}; -use miette::{Diagnostic, LabeledSpan, Severity, SourceCode}; -use std::any::TypeId; -use std::error::Error; -use std::fmt::{Debug, Display, Formatter}; +use miette::Diagnostic; +use std::fmt::Debug; use std::{path::Path, sync::Arc}; use crate::resources::state::State; @@ -17,7 +17,7 @@ pub struct StateDB { db: DB>, } -#[derive(Debug, Error, Diagnostic)] +#[derive(Clone, Debug, PartialEq, Eq, Error, Diagnostic)] pub enum StateDBError { #[error("opening the state db environment failed")] #[diagnostic( @@ -54,8 +54,8 @@ impl StateDB { } pub fn open_with_env(env: Arc) -> Result { - let db = unsafe { RawDB::open(&env, Some("state")) }; - let db = db.map_err(|e| StateDBError::Open(e.into()))?; + let db = RawDB::open(&env, Some("state")) + .map_err(|e| StateDBError::Open(e.into()))?; Ok(Self::new(env, db)) } @@ -66,8 +66,8 @@ impl StateDB { pub fn create_with_env(env: Arc) -> Result { let flags = DatabaseFlags::empty(); - let db = unsafe { RawDB::create(&env, Some("state"), flags) }; - let db = db.map_err(|e| StateDBError::Create(e.into()))?; + let db = RawDB::create(&env, Some("state"), flags) + .map_err(|e| StateDBError::Create(e.into()))?; Ok(Self::new(env, db)) } @@ -99,6 +99,30 @@ impl StateDB { self.db.put(&mut txn, key, val, flags)?; Ok(txn.commit()?) } + + pub fn load_map(&self, map: &std::collections::HashMap) -> miette::Result<()> { + use miette::IntoDiagnostic; + let mut txn = self.env.begin_rw_txn().into_diagnostic()?; + let flags = WriteFlags::empty(); + for (key, val) in map { + let mut serializer = AllocSerializer::<1024>::default(); + serializer.serialize_value(val).into_diagnostic()?; + let serialized = ArchivedValue::new(serializer.into_serializer().into_inner()); + self.db.put(&mut txn, &key.as_bytes(), &serialized, flags)?; + } + txn.commit().into_diagnostic()?; + Ok(()) + } + + pub fn dump_map(&self) -> miette::Result> { + let mut map = std::collections::HashMap::new(); + for (key, val) in self.get_all(&self.begin_ro_txn()?)? { + let key_str = core::str::from_utf8(&key).map_err(|_e| miette::Error::msg("state key not UTF8"))?.to_string(); + let val_state: State = rkyv::Deserialize::deserialize(val.as_ref(), &mut rkyv::Infallible).unwrap(); + map.insert(key_str, val_state); + } + Ok(map) + } } #[cfg(test)] diff --git a/bffhd/resources/state/mod.rs b/bffhd/resources/state/mod.rs index 84e3587..efc38c3 100644 --- a/bffhd/resources/state/mod.rs +++ b/bffhd/resources/state/mod.rs @@ -1,5 +1,5 @@ use std::fmt::{Debug, Display, Formatter}; -use std::{fmt, hash::Hasher}; +use std::fmt; use std::ops::Deref; diff --git a/bffhd/resources/state/value.rs b/bffhd/resources/state/value.rs index e87fdde..1a087b0 100644 --- a/bffhd/resources/state/value.rs +++ b/bffhd/resources/state/value.rs @@ -14,8 +14,6 @@ use inventory; use rkyv::ser::{ScratchSpace, Serializer}; -use serde::ser::SerializeMap; - use std::collections::HashMap; use std::ops::Deref; @@ -275,10 +273,6 @@ pub struct ImplDebugInfo { /// [statevalue_register](macro@crate::statevalue_register) macro with your OID as first and type /// as second parameter like so: /// -/// ```no_run -/// struct MyStruct; -/// statevalue_register!(ObjectIdentifier::from_str("1.3.6.1.4.1.48398.612.1.14").unwrap(), MyStruct) -/// ``` pub struct ImplEntry<'a> { id: ImplId<'a>, data: ImplData<'a>, diff --git a/bffhd/session/mod.rs b/bffhd/session/mod.rs index 87eb902..2ac2be7 100644 --- a/bffhd/session/mod.rs +++ b/bffhd/session/mod.rs @@ -1,6 +1,7 @@ use crate::authorization::permissions::Permission; use crate::authorization::roles::Roles; use crate::resources::Resource; +use crate::users::db::User; use crate::users::{db, UserRef}; use crate::Users; use tracing::Span; @@ -16,25 +17,27 @@ impl SessionManager { Self { users, roles } } + pub fn try_open(&self, parent: &Span, uid: impl AsRef) -> Option { + self.users + .get_user(uid.as_ref()) + .map(|user| self.open(parent, user)) + } + // TODO: make infallible - pub fn open(&self, parent: &Span, uid: impl AsRef) -> Option { - let uid = uid.as_ref(); - if let Some(user) = self.users.get_user(uid) { - let span = tracing::info_span!( - target: "bffh::api", - parent: parent, - "session", - uid = uid, - ); - tracing::trace!(parent: &span, uid, ?user, "opening session"); - Some(SessionHandle { - span, - users: self.users.clone(), - roles: self.roles.clone(), - user: UserRef::new(user.id), - }) - } else { - None + pub fn open(&self, parent: &Span, user: User) -> SessionHandle { + let uid = user.id.as_str(); + let span = tracing::info_span!( + target: "bffh::api", + parent: parent, + "session", + uid, + ); + tracing::trace!(parent: &span, uid, ?user, "opening session"); + SessionHandle { + span, + users: self.users.clone(), + roles: self.roles.clone(), + user: UserRef::new(user.id), } } } diff --git a/bffhd/tls.rs b/bffhd/tls.rs index bc327cf..1589406 100644 --- a/bffhd/tls.rs +++ b/bffhd/tls.rs @@ -1,17 +1,19 @@ use std::fs::File; use std::io; use std::io::BufReader; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::sync::Arc; use crate::capnp::TlsListen; use futures_rustls::TlsAcceptor; -use miette::IntoDiagnostic; +use miette::Diagnostic; use rustls::version::{TLS12, TLS13}; use rustls::{Certificate, PrivateKey, ServerConfig, SupportedCipherSuite}; +use thiserror::Error; use tracing::Level; use crate::keylog::KeyLogFile; +use crate::tls::Error::KeyLogOpen; fn lookup_cipher_suite(name: &str) -> Option { match name { @@ -47,8 +49,32 @@ pub struct TlsConfig { keylog: Option>, } +#[derive(Debug, Error, Diagnostic)] +pub enum Error { + #[error("failed to open certificate file at path {0}")] + OpenCertFile(PathBuf, #[source] io::Error), + #[error("failed to open private key file at path {0}")] + OpenKeyFile(PathBuf, #[source] io::Error), + #[error("failed to read system certs")] + SystemCertsFile(#[source] io::Error), + #[error("failed to read from key file")] + ReadKeyFile(#[source] io::Error), + #[error("private key file must contain a single PEM-encoded private key")] + KeyFileFormat, + #[error("invalid TLS version {0}")] + TlsVersion(String), + #[error("Initializing TLS context failed")] + Builder( + #[from] + #[source] + rustls::Error, + ), + #[error("failed to initialize key log")] + KeyLogOpen(#[source] io::Error), +} + impl TlsConfig { - pub fn new(keylogfile: Option>, warn: bool) -> io::Result { + pub fn new(keylogfile: Option>, warn: bool) -> Result { let span = tracing::span!(Level::INFO, "tls"); let _guard = span.enter(); @@ -57,7 +83,11 @@ impl TlsConfig { } if let Some(path) = keylogfile { - let keylog = Some(KeyLogFile::new(path).map(|ok| Arc::new(ok))?); + let keylog = Some( + KeyLogFile::new(path) + .map(|ok| Arc::new(ok)) + .map_err(KeyLogOpen)?, + ); Ok(Self { keylog }) } else { Ok(Self { keylog: None }) @@ -75,27 +105,31 @@ impl TlsConfig { } } - pub fn make_tls_acceptor(&self, config: &TlsListen) -> miette::Result { + pub fn make_tls_acceptor(&self, config: &TlsListen) -> Result { let span = tracing::debug_span!("tls"); let _guard = span.enter(); - tracing::debug!(path = %config.certfile.as_path().display(), "reading certificates"); - let mut certfp = BufReader::new(File::open(config.certfile.as_path()).into_diagnostic()?); + let path = config.certfile.as_path(); + tracing::debug!(path = %path.display(), "reading certificates"); + let mut certfp = + BufReader::new(File::open(path).map_err(|e| Error::OpenCertFile(path.into(), e))?); let certs = rustls_pemfile::certs(&mut certfp) - .into_diagnostic()? + .map_err(Error::SystemCertsFile)? .into_iter() .map(Certificate) .collect(); - tracing::debug!(path = %config.keyfile.as_path().display(), "reading private key"); - let mut keyfp = BufReader::new(File::open(config.keyfile.as_path()).into_diagnostic()?); - let key = match rustls_pemfile::read_one(&mut keyfp).into_diagnostic()? { + let path = config.keyfile.as_path(); + tracing::debug!(path = %path.display(), "reading private key"); + let mut keyfp = + BufReader::new(File::open(path).map_err(|err| Error::OpenKeyFile(path.into(), err))?); + let key = match rustls_pemfile::read_one(&mut keyfp).map_err(Error::ReadKeyFile)? { Some(rustls_pemfile::Item::PKCS8Key(key) | rustls_pemfile::Item::RSAKey(key)) => { PrivateKey(key) } _ => { tracing::error!("private key file invalid"); - miette::bail!("private key file must contain a PEM-encoded private key") + return Err(Error::KeyFileFormat); } }; @@ -104,20 +138,19 @@ impl TlsConfig { .with_safe_default_kx_groups(); let tls_builder = if let Some(ref min) = config.tls_min_version { - match min.as_str() { + let v = min.to_lowercase(); + match v.as_str() { "tls12" => tls_builder.with_protocol_versions(&[&TLS12]), "tls13" => tls_builder.with_protocol_versions(&[&TLS13]), - x => miette::bail!("TLS version {} is invalid", x), + _ => return Err(Error::TlsVersion(v)), } } else { tls_builder.with_safe_default_protocol_versions() - } - .into_diagnostic()?; + }?; let mut tls_config = tls_builder .with_no_client_auth() - .with_single_cert(certs, key) - .into_diagnostic()?; + .with_single_cert(certs, key)?; if let Some(keylog) = &self.keylog { tls_config.key_log = keylog.clone(); diff --git a/bffhd/users/db.rs b/bffhd/users/db.rs index cc13b20..817f45a 100644 --- a/bffhd/users/db.rs +++ b/bffhd/users/db.rs @@ -2,7 +2,6 @@ use lmdb::{DatabaseFlags, Environment, RwTransaction, Transaction, WriteFlags}; use rkyv::Infallible; use std::collections::HashMap; -use miette::{Context, IntoDiagnostic}; use std::sync::Arc; use crate::db; @@ -11,6 +10,8 @@ use rkyv::ser::serializers::AllocSerializer; use rkyv::ser::Serializer; use rkyv::Deserialize; +pub use crate::db::Error; + #[derive( Clone, PartialEq, @@ -34,11 +35,9 @@ fn hash_pw(pw: &[u8]) -> argon2::Result { } impl User { - pub fn check_password(&self, pwd: &[u8]) -> miette::Result { + pub fn check_password(&self, pwd: &[u8]) -> Result { if let Some(ref encoded) = self.userdata.passwd { argon2::verify_encoded(encoded, pwd) - .into_diagnostic() - .wrap_err("Stored password is an invalid string") } else { Ok(false) } @@ -183,8 +182,8 @@ impl UserDB { } pub fn clear_txn(&self, txn: &mut RwTransaction) -> Result<(), db::Error> { - self.db.clear(txn); - Ok(()) + // TODO: why was the result ignored here? + self.db.clear(txn) } pub fn get_all(&self) -> Result, db::Error> { diff --git a/bffhd/users/mod.rs b/bffhd/users/mod.rs index 01360e2..ee4a6c5 100644 --- a/bffhd/users/mod.rs +++ b/bffhd/users/mod.rs @@ -7,10 +7,10 @@ use std::collections::HashMap; use std::fmt::{Display, Formatter}; use std::io::Write; -use clap::ArgMatches; -use miette::{Context, Diagnostic, IntoDiagnostic, SourceOffset, SourceSpan}; +use miette::{Diagnostic, IntoDiagnostic, SourceSpan}; use std::path::Path; use std::sync::Arc; + use thiserror::Error; pub mod db; @@ -69,17 +69,20 @@ pub struct Users { userdb: &'static UserDB, } +#[derive(Clone, Debug, PartialEq, Eq, Error, Diagnostic)] +#[error(transparent)] +#[repr(transparent)] +pub struct Error(#[from] pub db::Error); + impl Users { - pub fn new(env: Arc) -> miette::Result { + pub fn new(env: Arc) -> Result { let span = tracing::debug_span!("users", ?env, "Creating Users handle"); let _guard = span.enter(); - let userdb = USERDB - .get_or_try_init(|| { - tracing::debug!("Global resource not yet initialized, initializing…"); - unsafe { UserDB::create(env) } - }) - .wrap_err("Failed to open userdb")?; + let userdb = USERDB.get_or_try_init(|| { + tracing::debug!("Global resource not yet initialized, initializing…"); + unsafe { UserDB::create(env) } + })?; Ok(Self { userdb }) } @@ -170,6 +173,29 @@ impl Users { Ok(()) } + pub fn load_map(&mut self, dump: &HashMap) -> miette::Result<()> { + let mut txn = unsafe { self.userdb.get_rw_txn() }?; + + self.userdb.clear_txn(&mut txn)?; + + for (uid, data) in dump { + let user = db::User { + id: uid.clone(), + userdata: data.clone(), + }; + + tracing::trace!(%uid, ?user, "Storing user object"); + if let Err(e) = self.userdb.put_txn(&mut txn, uid.as_str(), &user) { + tracing::warn!(error=?e, "failed to add user") + } + } + txn.commit().map_err(crate::db::Error::from)?; + Ok(()) + } + + pub fn dump_map(&self) -> miette::Result> { + return Ok(self.userdb.get_all()?) + } pub fn dump_file(&self, path_str: &str, force: bool) -> miette::Result { let path = Path::new(path_str); let exists = path.exists(); @@ -200,7 +226,7 @@ impl Users { } let mut file = fs::File::create(path).into_diagnostic()?; - let users = self.userdb.get_all()?; + let users = self.dump_map()?; let encoded = toml::ser::to_vec(&users).into_diagnostic()?; file.write_all(&encoded[..]).into_diagnostic()?; diff --git a/bin/bffhd/main.rs b/bin/bffhd/main.rs index fff25b7..a3e64b3 100644 --- a/bin/bffhd/main.rs +++ b/bin/bffhd/main.rs @@ -1,5 +1,5 @@ use clap::{Arg, Command, ValueHint}; -use diflouroborane::{config, Diflouroborane}; +use difluoroborane::{config, Difluoroborane}; use std::str::FromStr; use std::{env, io, io::Write, path::PathBuf}; @@ -15,12 +15,12 @@ fn main() -> miette::Result<()> { FabAccess {apiver}\n\ \t[{build_kind} build built on {build_time}]\n\ \t {rustc_version}\n\t {cargo_version}", - version=diflouroborane::env::PKG_VERSION, + version=difluoroborane::env::PKG_VERSION, apiver="0.3", - rustc_version=diflouroborane::env::RUST_VERSION, - cargo_version=diflouroborane::env::CARGO_VERSION, - build_time=diflouroborane::env::BUILD_TIME_3339, - build_kind=diflouroborane::env::BUILD_RUST_CHANNEL)) + rustc_version=difluoroborane::env::RUST_VERSION, + cargo_version=difluoroborane::env::CARGO_VERSION, + build_time=difluoroborane::env::BUILD_TIME_3339, + build_kind=difluoroborane::env::BUILD_RUST_CHANNEL)) .about(clap::crate_description!()) .arg(Arg::new("config") .help("Path to the config file to use") @@ -57,10 +57,18 @@ fn main() -> miette::Result<()> { .help("Check config for validity") .long("check")) .arg( - Arg::new("dump") + Arg::new("dump-db") .help("Dump all internal databases") - .long("dump") - .conflicts_with("load")) + .long("dump-db") + .alias("dump") + .conflicts_with("dump-users") + .conflicts_with("load-users") + .conflicts_with("load-db") + .takes_value(true) + .value_name("FILE") + .value_hint(ValueHint::AnyPath) + .default_missing_value("bffh-db.toml") + ) .arg( Arg::new("dump-users") .help("Dump the users db to the given file as TOML") @@ -69,18 +77,33 @@ fn main() -> miette::Result<()> { .value_name("FILE") .value_hint(ValueHint::AnyPath) .default_missing_value("users.toml") - .conflicts_with("load")) + .conflicts_with("load-users") + .conflicts_with("load-db") + .conflicts_with("dump-db") + ) .arg( Arg::new("force") .help("force ops that may clobber") .long("force") ) .arg( - Arg::new("load") - .help("Load values into the internal databases") - .long("load") + Arg::new("load-users") + .help("Load users into the internal databases") + .long("load-users") + .alias("load") .takes_value(true) - .conflicts_with("dump")) + .conflicts_with("dump-db") + .conflicts_with("load-db") + .conflicts_with("dump-users") + ) + .arg( + Arg::new("load-db") + .help("Load values into the internal databases") + .long("load-db") + .takes_value(true) + .conflicts_with("dump-db") + .conflicts_with("load-users") + .conflicts_with("dump-users")) .arg(Arg::new("keylog") .help("log TLS keys into PATH. If no path is specified the value of the envvar SSLKEYLOGFILE is used.") .long("tls-key-log") @@ -98,7 +121,7 @@ fn main() -> miette::Result<()> { let configpath = matches .value_of("config") - .unwrap_or("/etc/diflouroborane.dhall"); + .unwrap_or("/etc/difluoroborane.dhall"); // Check for the --print-default option first because we don't need to do anything else in that // case. @@ -137,10 +160,18 @@ fn main() -> miette::Result<()> { let mut config = config::read(&PathBuf::from_str(configpath).unwrap())?; - if matches.is_present("dump") { - return Err(miette::miette!("DB Dumping is currently not implemented, except for the users db, using `--dump-users`")); + if matches.is_present("dump-db") { + let mut bffh = Difluoroborane::new(config)?; + let fname = matches.value_of("dump-db").unwrap(); + bffh.dump_db(fname)?; + return Ok(()); + } else if matches.is_present("load-db") { + let mut bffh = Difluoroborane::new(config)?; + let fname = matches.value_of("load-db").unwrap(); + bffh.load_db(fname)?; + return Ok(()); } else if matches.is_present("dump-users") { - let bffh = Diflouroborane::new(config)?; + let bffh = Difluoroborane::new(config)?; let number = bffh.users.dump_file( matches.value_of("dump-users").unwrap(), @@ -150,12 +181,12 @@ fn main() -> miette::Result<()> { tracing::info!("successfully dumped {} users", number); return Ok(()); - } else if matches.is_present("load") { - let bffh = Diflouroborane::new(config)?; + } else if matches.is_present("load-users") { + let bffh = Difluoroborane::new(config)?; - bffh.users.load_file(matches.value_of("load").unwrap())?; + bffh.users.load_file(matches.value_of("load-users").unwrap())?; - tracing::info!("loaded users from {}", matches.value_of("load").unwrap()); + tracing::info!("loaded users from {}", matches.value_of("load-users").unwrap()); return Ok(()); } else { @@ -179,7 +210,7 @@ fn main() -> miette::Result<()> { } config.logging.format = matches.value_of("log format").unwrap_or("full").to_string(); - let mut bffh = Diflouroborane::new(config)?; + let mut bffh = Difluoroborane::new(config)?; bffh.run()?; } diff --git a/build.rs b/build.rs index 37f84e1..e23aab1 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,4 @@ fn main() { // Extract build-time information using the `shadow-rs` crate - shadow_rs::new(); + shadow_rs::new().unwrap(); } diff --git a/cargo-cross-config b/cargo-cross-config new file mode 100644 index 0000000..ffbdcaa --- /dev/null +++ b/cargo-cross-config @@ -0,0 +1,8 @@ +[target.armv7-unknown-linux-gnueabihf] +linker = "arm-linux-gnueabihf-gcc" + +[target.arm-unknown-linux-gnueabihf] +linker = "arm-linux-gnueabi-gcc" + +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" diff --git a/examples/bffh.dhall b/examples/bffh.dhall index d8cab77..65c5ae1 100644 --- a/examples/bffh.dhall +++ b/examples/bffh.dhall @@ -229,6 +229,9 @@ -- Linking up machines to initiators. Similar to actors a machine can have several initiators assigned but an -- initiator can only be assigned to one machine. -- The below is once again how you have to define *no* initiators. - init_connections = [] : List { machine : Text, initiator : Text } + init_connections = [] : List { machine : Text, initiator : Text }, --init_connections = [{ machine = "Testmachine", initiator = "Initiator" }] + + instanceurl = "https://example.com", + spacename = "examplespace" } diff --git a/examples/docker/integration/docker-compose.yaml b/examples/docker/integration/docker-compose.yaml index 94118a0..38b54f7 100644 --- a/examples/docker/integration/docker-compose.yaml +++ b/examples/docker/integration/docker-compose.yaml @@ -2,7 +2,7 @@ version: "3.8" services: bffh-a: image: registry.gitlab.com/fabinfra/fabaccess/bffh:dev-latest - command: ["sh", "-c", "diflouroborane -c /etc/bffh/bffh.dhall --load=/etc/bffh; diflouroborane -c /etc/bffh/bffh.dhall"] + command: ["sh", "-c", "difluoroborane -c /etc/bffh/bffh.dhall --load=/etc/bffh; difluoroborane -c /etc/bffh/bffh.dhall"] volumes: # generate a sample config.toml by running "docker run registry.gitlab.com/fabinfra/fabaccess/bffh:dev-latest --print-default > examples/config.toml" from the project root. You may have to delete the ipv6 listen section. - "./config_a:/etc/bffh" @@ -12,7 +12,7 @@ services: image: eclipse-mosquitto bffh-b: image: registry.gitlab.com/fabinfra/fabaccess/bffh:dev-latest - command: ["sh", "-c", "diflouroborane -c /etc/bffh/bffh.dhall --load=/etc/bffh; diflouroborane -c /etc/bffh/bffh.dhall"] + command: ["sh", "-c", "difluoroborane -c /etc/bffh/bffh.dhall --load=/etc/bffh; difluoroborane -c /etc/bffh/bffh.dhall"] volumes: # generate a sample config.toml by running "docker run registry.gitlab.com/fabinfra/fabaccess/bffh:dev-latest --print-default > examples/config.toml" from the project root. You may have to delete the ipv6 listen section. - "./config_b:/etc/bffh" @@ -23,4 +23,4 @@ services: test-manager: image: debian - tty: true \ No newline at end of file + tty: true diff --git a/modules/sdk/Cargo.toml b/modules/sdk/Cargo.toml index 33c6d31..7f19865 100644 --- a/modules/sdk/Cargo.toml +++ b/modules/sdk/Cargo.toml @@ -8,4 +8,4 @@ edition = "2021" [dependencies] sdk-proc = { path = "sdk_proc" } futures-util = "0.3" -diflouroborane = { path = "../.." } \ No newline at end of file +difluoroborane = { path = "../.." } diff --git a/runtime/lightproc/examples/proc_panic.rs b/runtime/lightproc/examples/proc_panic.rs index 4fc0c20..3db742e 100644 --- a/runtime/lightproc/examples/proc_panic.rs +++ b/runtime/lightproc/examples/proc_panic.rs @@ -30,7 +30,8 @@ where } let schedule = |t| (QUEUE.deref()).send(t).unwrap(); - let (proc, handle) = LightProc::recoverable(future, schedule); + let span = tracing::trace_span!("runtime.spawn", kind = "local"); + let (proc, handle) = LightProc::recoverable(future, schedule, span, None); let handle = handle.on_panic( |err: Box| match err.downcast::<&'static str>() { diff --git a/runtime/lightproc/examples/proc_run.rs b/runtime/lightproc/examples/proc_run.rs index 483a183..bdeb28f 100644 --- a/runtime/lightproc/examples/proc_run.rs +++ b/runtime/lightproc/examples/proc_run.rs @@ -17,7 +17,8 @@ where let future = async move { fut.await }; let schedule = move |t| sender.send(t).unwrap(); - let (proc, handle) = LightProc::build(future, schedule); + let span = tracing::trace_span!("runtime.spawn", kind = "local"); + let (proc, handle) = LightProc::build(future, schedule, span, None); proc.schedule(); diff --git a/runtime/lightproc/src/lightproc.rs b/runtime/lightproc/src/lightproc.rs index 63af3cd..cc0cf25 100644 --- a/runtime/lightproc/src/lightproc.rs +++ b/runtime/lightproc/src/lightproc.rs @@ -9,6 +9,7 @@ //! # Example Usage //! //! ```rust +//! use tracing::Span; //! use lightproc::prelude::*; //! //! // ... future that does work @@ -23,6 +24,8 @@ //! let panic_recoverable = LightProc::recoverable( //! future, //! schedule_function, +//! Span::current(), +//! None, //! ); //! ``` @@ -60,6 +63,7 @@ impl LightProc { /// # Example /// ```rust /// # use std::any::Any; + /// # use tracing::Span; /// # use lightproc::prelude::*; /// # /// # // ... basic schedule function with no waker logic @@ -72,9 +76,11 @@ impl LightProc { /// let (proc, handle) = LightProc::recoverable( /// future, /// schedule_function, + /// Span::current(), + /// None /// ); - /// let handle = handle.on_panic(|s: &mut EmptyProcState, e: Box| { - /// let reason = e.downcast::(); + /// let handle = handle.on_panic(|e: Box| { + /// let reason = e.downcast::().unwrap(); /// println!("future panicked!: {}", &reason); /// }); /// ``` @@ -110,13 +116,6 @@ impl LightProc { /// # // ... basic schedule function with no waker logic /// # fn schedule_function(proc: LightProc) {;} /// # - /// # // ... process stack with a lifecycle callback - /// # let proc_stack = - /// # ProcStack::default() - /// # .with_after_panic(|s: &mut EmptyProcState| { - /// # println!("After panic started!"); - /// # }); - /// # /// // ... creating a standard process /// let standard = LightProc::build( /// future, diff --git a/runtime/lightproc/src/raw_proc.rs b/runtime/lightproc/src/raw_proc.rs index 1481fb0..1521c35 100644 --- a/runtime/lightproc/src/raw_proc.rs +++ b/runtime/lightproc/src/raw_proc.rs @@ -395,7 +395,7 @@ where unsafe fn tick(ptr: *const ()) { let mut raw = Self::from_ptr(ptr); // Enter the span associated with the process to track execution time if enabled. - let _guard = (&(*raw.pdata).span).enter(); + let guard = (&(*raw.pdata).span).enter(); // Create a context from the raw proc pointer and the vtable inside its pdata. let waker = ManuallyDrop::new(Waker::from_raw(RawWaker::new( @@ -487,6 +487,8 @@ where (*raw.pdata).notify(); } + // the tracing guard is inside the proc, so it must be dropped first + drop(guard); // Drop the proc reference. Self::decrement(ptr); break; diff --git a/runtime/lightproc/src/recoverable_handle.rs b/runtime/lightproc/src/recoverable_handle.rs index eb5bc10..d1be89e 100644 --- a/runtime/lightproc/src/recoverable_handle.rs +++ b/runtime/lightproc/src/recoverable_handle.rs @@ -49,8 +49,7 @@ impl RecoverableHandle { /// /// ```rust /// # use std::any::Any; - /// use lightproc::proc_stack::ProcStack; - /// use lightproc::proc_state::EmptyProcState; + /// # use tracing::Span; /// # use lightproc::prelude::*; /// # /// # // ... future that does work @@ -61,21 +60,16 @@ impl RecoverableHandle { /// # // ... basic schedule function with no waker logic /// # fn schedule_function(proc: LightProc) {;} /// # - /// # // ... process stack with a lifecycle callback - /// # let proc_stack = - /// # ProcStack::default() - /// # .with_after_panic(|s: &mut EmptyProcState| { - /// # println!("After panic started!"); - /// # }); - /// # /// // ... creating a recoverable process /// let (proc, recoverable) = LightProc::recoverable( /// future, /// schedule_function, + /// Span::current(), + /// None /// ); /// /// recoverable - /// .on_return(|_e: Box| { + /// .on_panic(|_e: Box| { /// println!("Inner future panicked"); /// }); /// ``` diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..99c6e11 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.66"