diff --git a/.gitignore b/.gitignore index 22557e38..017b8293 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ /target -/Cargo.lock .vscode *.failed *_failed stalwart.toml +run.sh diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..e5f52e89 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4870 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +dependencies = [ + "aead", + "aes 0.8.2", + "cipher 0.4.4", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes 0.8.2", + "cipher 0.4.4", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "serde", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +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 = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time 0.3.20", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "async-recursion" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body 0.4.5", + "hyper 0.14.26", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body 0.4.5", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "clap", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bindgen" +version = "0.64.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.109", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c70beb79cbb5ce9c4f8e20849978f34225931f665bb49efa6982875a4d5facb3" + +[[package]] +name = "bitpacking" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c7d2ac73c167c06af4a5f37e6e59d84148d57ccbe4480b76f0273eefea82d7" +dependencies = [ + "crunchy", +] + +[[package]] +name = "blake3" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq 0.2.5", + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cedarwood" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d910bedd62c24733263d0bed247460853c9d22e8956bd4cd964302095e04e90" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "serde", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "3.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex", + "indexmap", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "constant_time_eq" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.8.0", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core", + "typenum", +] + +[[package]] +name = "csv" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b015497079b9a9d69c02ad25de6c0a6edef051ea6360a327d0bd05802ef64ad" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher 0.4.4", +] + +[[package]] +name = "cxx" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.15", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "pem-rfc7468 0.6.0", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e58dffcdcc8ee7b22f0c1f71a69243d7c2d9ad87b5a14361f2424a1565c219" +dependencies = [ + "const-oid", + "pem-rfc7468 0.7.0", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "ecdsa" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +dependencies = [ + "der 0.7.5", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki 0.7.2", +] + +[[package]] +name = "ece" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd5463ffecc0677adcd786c4481f73b215714d4757edf2eb37a573c03d00459" +dependencies = [ + "base64 0.13.1", + "byteorder", + "hex", + "hkdf", + "lazy_static", + "once_cell", + "openssl", + "serde", + "sha2", + "thiserror", +] + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +dependencies = [ + "serde", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468 0.7.0", + "pkcs8 0.10.2", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-as-inner" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "farmhash" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f35ce9c8fb9891c75ceadbc330752951a4e369b50af10775955aeb9af3eee34b" + +[[package]] +name = "fast-float" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "libz-sys", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form-data" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0322eefcd026820bbb430b427f0e9b22fc3952f163df23b74a3c5639bae32f0f" +dependencies = [ + "bytes", + "http", + "httparse", + "memchr", + "mime", + "serde", + "thiserror", + "tracing", +] + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "foundationdb" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69adb701525370e5f8958454b46e8459b276d81ce6391edbf84eae32eeddff75" +dependencies = [ + "async-recursion", + "async-trait", + "foundationdb-gen", + "foundationdb-macros", + "foundationdb-sys", + "futures", + "memchr", + "rand", + "static_assertions", + "uuid", +] + +[[package]] +name = "foundationdb-gen" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134e1c986a2bb78904f426d4924a55e8c14162ba764e229501eb6f95c8c37489" +dependencies = [ + "xml-rs", +] + +[[package]] +name = "foundationdb-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2163c7326208be8edc605e10303ec6ae45cf106c12540754a9970bcce0f80cae" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "foundationdb-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb26eee771096794dbee1a2a9defa455443a2c150a810386331aa0d6603d356" +dependencies = [ + "bindgen 0.60.1", +] + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "gethostname" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "199523ba70af2b447640715e8c4bd2b5360313a71d2d69361ae4dd1dc31487dd" +dependencies = [ + "libc", + "windows", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashlink" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +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 = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951dfc2e32ac02d67c90c0d65bd27009a635dc9b381a2cc7d284ab01e3a0150d" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92445bc9cc14bfa0a3ce56817dc3b5bcc227a168781a356b702410789cec0d10" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body 1.0.0-rc.2", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body 0.4.5", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75264b2003a3913f118d35c586e535293b3e22e41f074930762929d071e092" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body 1.0.0-rc.2", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +dependencies = [ + "http", + "hyper 0.14.26", + "rustls 0.20.8", + "tokio", + "tokio-rustls 0.23.4", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper 0.14.26", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[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.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipconfig" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be" +dependencies = [ + "socket2", + "widestring", + "winapi", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "jieba-rs" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37228e06c75842d1097432d94d02f37fe3ebfca9791c2e8fef6e9db17ed128c1" +dependencies = [ + "cedarwood", + "fxhash", + "hashbrown", + "lazy_static", + "phf", + "phf_codegen", + "regex", +] + +[[package]] +name = "jmap" +version = "0.1.0" +dependencies = [ + "aes-gcm", + "aes-gcm-siv", + "async-stream", + "base64 0.21.0", + "bincode", + "ece", + "form-data", + "form_urlencoded", + "futures-util", + "hkdf", + "http-body-util", + "hyper 1.0.0-rc.3", + "jmap_proto", + "mail-builder", + "mail-parser", + "mail-send", + "mime", + "p256", + "reqwest", + "serde", + "serde_json", + "sha2", + "sieve-rs", + "sqlx", + "store", + "tokio", + "tracing", + "utils", +] + +[[package]] +name = "jmap-client" +version = "0.3.0" +dependencies = [ + "ahash 0.8.3", + "async-stream", + "base64 0.13.1", + "chrono", + "futures-util", + "maybe-async 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot", + "reqwest", + "serde", + "serde_json", + "tokio", + "tokio-tungstenite", +] + +[[package]] +name = "jmap_proto" +version = "0.1.0" +dependencies = [ + "ahash 0.8.3", + "fast-float", + "mail-parser", + "serde", + "serde_json", + "store", + "tracing", + "utils", +] + +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libm" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" + +[[package]] +name = "librocksdb-sys" +version = "0.10.0+7.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fe4d5874f5ff2bc616e55e8c6086d478fcda13faf9495768a4aa1c22042d30b" +dependencies = [ + "bindgen 0.64.0", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "lz4-sys", + "zstd-sys", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "lz4-sys" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "mail-auth" +version = "0.3.1" +source = "git+https://github.com/stalwartlabs/mail-auth#e589e5daf8ad12be96c98fa11193fd73afe450f4" +dependencies = [ + "ahash 0.8.3", + "flate2", + "lru-cache", + "mail-builder", + "mail-parser", + "parking_lot", + "quick-xml", + "ring", + "rustls-pemfile", + "serde", + "serde_json", + "trust-dns-resolver", + "zip", +] + +[[package]] +name = "mail-builder" +version = "0.2.5" +source = "git+https://github.com/stalwartlabs/mail-builder#589dc325508c905c6248d13596a82cd1e89e8315" +dependencies = [ + "gethostname", +] + +[[package]] +name = "mail-parser" +version = "0.8.2" +source = "git+https://github.com/stalwartlabs/mail-parser#c7790a89256510f0f09382b73bff6ddcef5f0a5c" +dependencies = [ + "encoding_rs", + "serde", +] + +[[package]] +name = "mail-send" +version = "0.3.3" +source = "git+https://github.com/stalwartlabs/mail-send#f4d58ebf16e0ea6083cfd2d482114ad8ae201c35" +dependencies = [ + "base64 0.20.0", + "gethostname", + "mail-auth", + "mail-builder", + "md5", + "rand", + "rustls 0.21.0", + "smtp-proto", + "tokio", + "tokio-rustls 0.24.0", + "webpki-roots 0.23.0", +] + +[[package]] +name = "mail-server" +version = "0.3.0" +dependencies = [ + "jmap", + "jmap_proto", + "smtp", + "store", + "tokio", + "tracing", + "utils", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "matchit" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" + +[[package]] +name = "maybe-async" +version = "0.2.7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "maybe-async" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.45.0", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", + "static_assertions", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d6c3d7288a106c0a363e4b0e8d308058d56902adefb16f4936f417ffef086e" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry-http" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc79add46364183ece1a4542592ca593e6421c60807232f5b8f7a31703825d" +dependencies = [ + "async-trait", + "bytes", + "http", + "opentelemetry_api", + "reqwest", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c928609d087790fc936a1067bdc310ae702bdf3b090c3f281b713622c8bbde" +dependencies = [ + "async-trait", + "futures", + "futures-util", + "http", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "prost", + "reqwest", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61a2f56df5574508dd86aaca016c917489e589ece4141df1b5e349af8d66c28" +dependencies = [ + "futures", + "futures-util", + "opentelemetry", + "prost", + "tonic", + "tonic-build", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b02e0230abb0ab6636d18e2ba8fa02903ea63772281340ccac18e0af3ec9eeb" +dependencies = [ + "opentelemetry", +] + +[[package]] +name = "opentelemetry_api" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c24f96e21e7acc813c7a8394ee94978929db2bcc46cf6b5014fc612bf7760c22" +dependencies = [ + "fnv", + "futures-channel", + "futures-util", + "indexmap", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca41c4933371b61c2a2f214bf16931499af4ec90543604ec828f7a625c09113" +dependencies = [ + "async-trait", + "crossbeam-channel", + "dashmap", + "fnv", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "percent-encoding", + "rand", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "os_str_bytes" +version = "6.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "windows-sys 0.45.0", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest", + "hmac", + "password-hash", + "sha2", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem-rfc7468" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" +dependencies = [ + "der 0.6.1", + "pkcs8 0.9.0", + "spki 0.6.0", + "zeroize", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.5", + "spki 0.7.2", +] + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "polyval" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "primeorder" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8d3875361e28f7753baefef104386e7aa47642c93023356d97fdef4003bfb5" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "privdrop" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81ed9e5437d82d5f2cde999a21571474c5f09b3d76e33eab94bf0e8e42a4fd96" +dependencies = [ + "libc", + "nix", +] + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-xml" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "reqwest" +version = "0.11.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +dependencies = [ + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body 0.4.5", + "hyper 0.14.26", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.20.8", + "rustls-native-certs", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls 0.23.4", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots 0.22.6", + "winreg", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "retain_mut" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c31b5c4033f8fdde8700e4657be2c497e7288f01515be52168c631e2e4d4086" + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "roaring" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef0fb5e826a8bde011ecae6a8539dd333884335c57ff0f003fbe27c25bbe8f71" +dependencies = [ + "bytemuck", + "byteorder", + "retain_mut", +] + +[[package]] +name = "rocksdb" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "015439787fce1e75d55f279078d33ff14b4af5d93d995e8838ee4631301c8a99" +dependencies = [ + "libc", + "librocksdb-sys", +] + +[[package]] +name = "rsa" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55a77d189da1fee555ad95b7e50e7457d91c0e089ec68ca69ad2989413bbdab4" +dependencies = [ + "byteorder", + "digest", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8 0.9.0", + "rand_core", + "signature", + "subtle", + "zeroize", +] + +[[package]] +name = "rusqlite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" +dependencies = [ + "bitflags 2.1.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rust-stemmers" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustix" +version = "0.37.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79bef90eb6d984c72722595b5b1348ab39275a5e5123faca6863bf07d75a4e0" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07180898a28ed6a7f7ba2311594308f595e3dd2e3c3812fa0a80a47b45f17e5d" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +dependencies = [ + "base64 0.21.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.100.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +dependencies = [ + "base16ct", + "der 0.7.5", + "generic-array", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serial_test" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" +dependencies = [ + "dashmap", + "futures", + "lazy_static", + "log", + "parking_lot", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "sieve-rs" +version = "0.3.0" +source = "git+https://github.com/stalwartlabs/sieve#664a542e07865291f41770bebbe9407d179a5233" +dependencies = [ + "ahash 0.8.3", + "bincode", + "mail-builder", + "mail-parser", + "phf", + "regex", + "serde", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "smtp" +version = "0.1.1" +dependencies = [ + "ahash 0.8.3", + "blake3", + "dashmap", + "form_urlencoded", + "http-body-util", + "hyper 1.0.0-rc.3", + "lru-cache", + "mail-auth", + "mail-builder", + "mail-parser", + "mail-send", + "num_cpus", + "parking_lot", + "privdrop", + "rand", + "rayon", + "regex", + "reqwest", + "rustls 0.21.0", + "rustls-pemfile", + "serde", + "serde_json", + "sha1", + "sha2", + "sieve-rs", + "smtp-proto", + "sqlx", + "tokio", + "tokio-rustls 0.24.0", + "tracing", + "utils", + "webpki-roots 0.23.0", + "x509-parser", +] + +[[package]] +name = "smtp-proto" +version = "0.1.1" +source = "git+https://github.com/stalwartlabs/smtp-proto#72fd0e2da05c2bf45770a58c86833785220d7f19" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.5", +] + +[[package]] +name = "sqlformat" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afd8985c8822235a9ebeedf0bff971462470162759663d3184593c807ab6e898" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c12403de02d88e6808de30eb2153c6997d39cc9511a446b510d5944a3ea6727" +dependencies = [ + "ahash 0.7.6", + "atoi", + "bitflags 1.3.2", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls 0.21.0", + "rustls-pemfile", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", + "webpki-roots 0.23.0", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2be74801a0852ace9d86bc8cc8ac36241e7dc712fea26b8f32bd80ce29c98a10" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ce71dd8afc7ad2aeff001bb6affa7128c9087bbdcab07fa97a7952e8ee3d1da" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c430536df19e8b5b048a9ae19b266aba77f9f3e2255b7195f465d678cb2d0a" +dependencies = [ + "atoi", + "base64 0.21.0", + "bitflags 1.3.2", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210e0a1523b6d46ca73db1c5197a233a8e14787596910ce88ff5d47a00da0241" +dependencies = [ + "atoi", + "base64 0.21.0", + "bitflags 1.3.2", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f446c04b2d2d06b49b905e33c877b282e0f70b1b60a22513eacee8bf56d8afbe" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "tracing", + "url", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "store" +version = "0.1.0" +dependencies = [ + "ahash 0.8.3", + "bitpacking", + "blake3", + "farmhash", + "foundationdb", + "futures", + "jieba-rs", + "lazy_static", + "lru-cache", + "maybe-async 0.2.7", + "parking_lot", + "r2d2", + "rand", + "rayon", + "roaring", + "rocksdb", + "rusqlite", + "rust-stemmers", + "serde", + "siphasher", + "tinysegmenter", + "tokio", + "tracing", + "utils", + "whatlang", + "xxhash-rust", +] + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "tests" +version = "0.1.0" +dependencies = [ + "ahash 0.8.3", + "async-trait", + "base64 0.21.0", + "bytes", + "csv", + "dashmap", + "ece", + "flate2", + "futures", + "http-body-util", + "hyper 1.0.0-rc.3", + "jmap", + "jmap-client", + "jmap_proto", + "mail-auth", + "mail-parser", + "mail-send", + "num_cpus", + "rayon", + "reqwest", + "rustls 0.21.0", + "rustls-pemfile", + "serde", + "serde_json", + "serial_test", + "sieve-rs", + "smtp", + "smtp-proto", + "sqlx", + "store", + "tokio", + "tokio-rustls 0.24.0", + "tracing", + "tracing-subscriber", + "utils", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinysegmenter" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1755695d17d470baf2d937a59ab4e86de3034b056fc8700e21411b0efca36497" +dependencies = [ + "lazy_static", + "maplit", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.45.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.8", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" +dependencies = [ + "rustls 0.21.0", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd" +dependencies = [ + "futures-util", + "log", + "rustls 0.20.8", + "tokio", + "tokio-rustls 0.23.4", + "tungstenite", + "webpki", + "webpki-roots 0.22.6", +] + +[[package]] +name = "tokio-util" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body 0.4.5", + "hyper 0.14.26", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic-build" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" +dependencies = [ + "crossbeam-channel", + "time 0.3.20", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ebb87a95ea13271332df069020513ab70bdb5637ca42d6e492dc3bbbad48de" +dependencies = [ + "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trust-dns-proto" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.2.3", + "ipnet", + "lazy_static", + "rand", + "ring", + "rustls 0.20.8", + "rustls-pemfile", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "tokio-rustls 0.23.4", + "tracing", + "url", + "webpki", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lazy_static", + "lru-cache", + "parking_lot", + "resolv-conf", + "rustls 0.20.8", + "smallvec", + "thiserror", + "tokio", + "tokio-rustls 0.23.4", + "tracing", + "trust-dns-proto", + "webpki-roots 0.22.6", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "tungstenite" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand", + "rustls 0.20.8", + "sha1", + "thiserror", + "url", + "utf-8", + "webpki", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "universal-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna 0.3.0", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utils" +version = "0.1.0" +dependencies = [ + "mail-auth", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "privdrop", + "rustls 0.21.0", + "rustls-pemfile", + "serde", + "smtp-proto", + "tokio", + "tokio-rustls 0.24.0", + "tracing", + "tracing-appender", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "uuid" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "wasm-streams" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "webpki-roots" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa54963694b65584e170cf5dc46aeb4dcaa5584e652ff5f3952e56d66aff0125" +dependencies = [ + "rustls-webpki", +] + +[[package]] +name = "whatlang" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c531a2dc4c462b833788be2c07eef4e621d0e9edbd55bf280cc164c1c1aa043" +dependencies = [ + "hashbrown", + "once_cell", +] + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "whoami" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68" + +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "x509-parser" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab0c2f54ae1d92f4fcb99c0b7ccf0b1e3451cbd395e5f115ccbdbcb18d4f634" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror", + "time 0.3.20", +] + +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + +[[package]] +name = "xxhash-rust" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "735a71d46c4d68d71d4b24d03fdc2b98e38cea81730595801db779c04fe80d70" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" + +[[package]] +name = "zip" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef" +dependencies = [ + "aes 0.7.5", + "byteorder", + "bzip2", + "constant_time_eq 0.1.5", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac", + "pbkdf2", + "sha1", + "time 0.3.20", + "zstd", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.8+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +dependencies = [ + "cc", + "libc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index e6ba5294..17662121 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,8 @@ jmap = { path = "crates/jmap" } jmap_proto = { path = "crates/jmap-proto" } smtp = { path = "crates/smtp" } utils = { path = "crates/utils" } -tests = { path = "tests" } +tokio = { version = "1.23", features = ["full"] } +tracing = "0.1" [workspace] members = [ diff --git a/crates/jmap/src/api/http.rs b/crates/jmap/src/api/http.rs index 1f2a03b7..13788486 100644 --- a/crates/jmap/src/api/http.rs +++ b/crates/jmap/src/api/http.rs @@ -22,10 +22,11 @@ use utils::listener::{ServerInstance, SessionData, SessionManager}; use crate::{ auth::oauth::OAuthMetadata, blob::{DownloadResponse, UploadResponse}, + services::state, JMAP, }; -use super::{session::Session, HtmlResponse, HttpResponse, JsonResponse}; +use super::{session::Session, HtmlResponse, HttpResponse, JmapSessionManager, JsonResponse}; impl JMAP { pub async fn parse_request( @@ -205,7 +206,7 @@ impl JMAP { } } -impl SessionManager for super::SessionManager { +impl SessionManager for JmapSessionManager { fn spawn(&self, session: SessionData) { let jmap = self.inner.clone(); @@ -242,6 +243,13 @@ impl SessionManager for super::SessionManager { } }); } + + fn shutdown(&self) { + let jmap = self.inner.clone(); + tokio::spawn(async move { + let _ = jmap.state_tx.send(state::Event::Stop).await; + }); + } } async fn handle_request( diff --git a/crates/jmap/src/api/mod.rs b/crates/jmap/src/api/mod.rs index 36f9e8fd..af022551 100644 --- a/crates/jmap/src/api/mod.rs +++ b/crates/jmap/src/api/mod.rs @@ -14,13 +14,13 @@ pub mod request; pub mod session; #[derive(Clone)] -pub struct SessionManager { +pub struct JmapSessionManager { pub inner: Arc, } -impl From> for SessionManager { - fn from(inner: Arc) -> Self { - SessionManager { inner } +impl JmapSessionManager { + pub fn new(inner: Arc) -> Self { + Self { inner } } } diff --git a/crates/main/src/main.rs b/crates/main/src/main.rs index f328e4d9..a96dbecb 100644 --- a/crates/main/src/main.rs +++ b/crates/main/src/main.rs @@ -1 +1,59 @@ -fn main() {} +use std::time::Duration; + +use jmap::{api::JmapSessionManager, JMAP}; +use smtp::core::{SmtpAdminSessionManager, SmtpSessionManager, SMTP}; +use utils::{ + config::{Config, ServerProtocol}, + enable_tracing, wait_for_shutdown, UnwrapFailure, +}; + +#[tokio::main] +async fn main() -> std::io::Result<()> { + let config = Config::init(); + let servers = config.parse_servers().failed("Invalid configuration"); + + // Bind ports and drop privileges + servers.bind(&config); + + // Enable tracing + let _tracer = enable_tracing(&config).failed("Failed to enable tracing"); + tracing::info!( + "Starting Stalwart mail server v{}...", + env!("CARGO_PKG_VERSION") + ); + + // Init servers + let smtp = SMTP::init(&config, &servers).await; + let jmap = JMAP::init(&config).await; + + // Spawn servers + let shutdown_tx = servers.spawn(|server, shutdown_rx| { + match &server.protocol { + ServerProtocol::Smtp | ServerProtocol::Lmtp => { + server.spawn(SmtpSessionManager::new(smtp.clone()), shutdown_rx) + } + ServerProtocol::Http => { + server.spawn(SmtpAdminSessionManager::new(smtp.clone()), shutdown_rx) + } + ServerProtocol::Jmap => { + server.spawn(JmapSessionManager::new(jmap.clone()), shutdown_rx) + } + ServerProtocol::Imap => unimplemented!("IMAP is not implemented yet"), + }; + }); + + // Wait for shutdown signal + wait_for_shutdown().await; + tracing::info!( + "Shutting down Stalwart mail server v{}...", + env!("CARGO_PKG_VERSION") + ); + + // Stop services + let _ = shutdown_tx.send(true); + + // Wait for services to finish + tokio::time::sleep(Duration::from_secs(1)).await; + + Ok(()) +} diff --git a/crates/smtp/Cargo.toml b/crates/smtp/Cargo.toml index 2a62ef5a..8d80b1cb 100644 --- a/crates/smtp/Cargo.toml +++ b/crates/smtp/Cargo.toml @@ -32,12 +32,6 @@ sha1 = "0.10" sha2 = "0.10.6" rayon = "1.5" tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["env-filter"] } -tracing-appender = "0.2" -tracing-opentelemetry = "0.18.0" -opentelemetry = { version = "0.18.0", features = ["rt-tokio"] } -opentelemetry-otlp = { version = "0.11.0", features = ["http-proto", "reqwest-client", "reqwest-rustls"] } -opentelemetry-semantic-conventions = { version = "0.10.0" } parking_lot = "0.12" regex = "1.7.0" dashmap = "5.4" diff --git a/crates/smtp/src/config/condition.rs b/crates/smtp/src/config/condition.rs index 999d3729..f798bd50 100644 --- a/crates/smtp/src/config/condition.rs +++ b/crates/smtp/src/config/condition.rs @@ -40,6 +40,7 @@ pub trait ConfigCondition { ctx: &ConfigContext, available_keys: &[EnvelopeKey], ) -> super::Result; + #[cfg(feature = "test_mode")] fn parse_conditions( &self, ctx: &ConfigContext, @@ -381,14 +382,15 @@ mod tests { file.push("rules.toml"); let config = Config::parse(&fs::read_to_string(file).unwrap()).unwrap(); - let mut context = ConfigContext::default(); - let list = Arc::new(Lookup::default()); - context.lookup.insert("test-list".to_string(), list.clone()); - context.servers.push(Server { + let servers = vec![Server { id: "smtp".to_string(), internal_id: 123, ..Default::default() - }); + }]; + let mut context = ConfigContext::new(&servers); + let list = Arc::new(Lookup::default()); + context.lookup.insert("test-list".to_string(), list.clone()); + let mut conditions = config.parse_conditions(&context).unwrap(); let expected_rules = AHashMap::from_iter([ ( diff --git a/crates/smtp/src/config/if_block.rs b/crates/smtp/src/config/if_block.rs index 650fcc92..92fdf98b 100644 --- a/crates/smtp/src/config/if_block.rs +++ b/crates/smtp/src/config/if_block.rs @@ -298,7 +298,7 @@ mod tests { let config = Config::parse(&fs::read_to_string(file).unwrap()).unwrap(); // Create context and add some conditions - let context = ConfigContext::default(); + let context = ConfigContext::new(&[]); let available_keys = vec![ EnvelopeKey::Recipient, EnvelopeKey::RecipientDomain, diff --git a/crates/smtp/src/config/list.rs b/crates/smtp/src/config/list.rs index 4940dfc4..cdc5d0b5 100644 --- a/crates/smtp/src/config/list.rs +++ b/crates/smtp/src/config/list.rs @@ -111,7 +111,7 @@ mod tests { .replace("{LIST2}", list2.as_path().to_str().unwrap()); let config = Config::parse(&toml).unwrap(); - let mut context = ConfigContext::default(); + let mut context = ConfigContext::new(&[]); config.parse_remote_hosts(&mut context).unwrap(); config.parse_lists(&mut context).unwrap(); diff --git a/crates/smtp/src/config/mod.rs b/crates/smtp/src/config/mod.rs index 0c77d9f5..63e9330d 100644 --- a/crates/smtp/src/config/mod.rs +++ b/crates/smtp/src/config/mod.rs @@ -52,7 +52,7 @@ use regex::Regex; use sieve::Sieve; use smtp_proto::MtPriority; use tokio::sync::mpsc; -use utils::config::{Server, ServerProtocol}; +use utils::config::{Rate, Server, ServerProtocol}; use crate::lookup::{self, Lookup, SqlDatabase}; @@ -200,12 +200,6 @@ pub const THROTTLE_REMOTE_IP: u16 = 1 << 7; pub const THROTTLE_LOCAL_IP: u16 = 1 << 8; pub const THROTTLE_HELO_DOMAIN: u16 = 1 << 9; -#[derive(Debug, Default, PartialEq, Eq, Clone)] -pub struct Rate { - pub requests: u64, - pub period: Duration, -} - #[derive(Debug, Clone, PartialEq, Eq)] pub enum IpAddrMask { V4 { addr: Ipv4Addr, mask: u32 }, @@ -527,8 +521,8 @@ pub enum VerifyStrategy { } #[derive(Default)] -pub struct ConfigContext { - pub servers: Vec, +pub struct ConfigContext<'x> { + pub servers: &'x [Server], pub hosts: AHashMap, pub scripts: AHashMap>, pub lookup: AHashMap>, @@ -537,4 +531,13 @@ pub struct ConfigContext { pub sealers: AHashMap>, } +impl<'x> ConfigContext<'x> { + pub fn new(servers: &'x [Server]) -> Self { + Self { + servers, + ..Default::default() + } + } +} + pub type Result = std::result::Result; diff --git a/crates/smtp/src/config/throttle.rs b/crates/smtp/src/config/throttle.rs index 453c8491..81f7f9d5 100644 --- a/crates/smtp/src/config/throttle.rs +++ b/crates/smtp/src/config/throttle.rs @@ -23,7 +23,7 @@ use super::{condition::ConfigCondition, *}; use utils::config::{ - utils::{AsKey, ParseKey, ParseValue}, + utils::{AsKey, ParseValue}, Config, }; @@ -119,36 +119,6 @@ impl ConfigThrottle for Config { } } -impl ParseValue for Rate { - fn parse_value(key: impl AsKey, value: &str) -> super::Result { - if let Some((requests, period)) = value.split_once('/') { - Ok(Rate { - requests: requests - .trim() - .parse::() - .ok() - .and_then(|r| if r > 0 { Some(r) } else { None }) - .ok_or_else(|| { - format!( - "Invalid rate value {:?} for property {:?}.", - value, - key.as_key() - ) - })?, - period: period.parse_key(key)?, - }) - } else if ["false", "none", "unlimited"].contains(&value) { - Ok(Rate::default()) - } else { - Err(format!( - "Invalid rate value {:?} for property {:?}.", - value, - key.as_key() - )) - } - } -} - impl ParseValue for EnvelopeKey { fn parse_value(key: impl AsKey, value: &str) -> super::Result { Ok(match value { @@ -228,7 +198,7 @@ mod tests { ]; let config = Config::parse(&fs::read_to_string(file).unwrap()).unwrap(); - let context = ConfigContext::default(); + let context = ConfigContext::new(&[]); let throttle = config .parse_throttle("throttle", &context, &available_keys, u16::MAX) .unwrap(); diff --git a/crates/smtp/src/core/if_block.rs b/crates/smtp/src/core/if_block.rs index ba95b0c6..2e214f55 100644 --- a/crates/smtp/src/core/if_block.rs +++ b/crates/smtp/src/core/if_block.rs @@ -245,17 +245,19 @@ mod tests { file.push("rules-eval.toml"); let config = Config::parse(&fs::read_to_string(file).unwrap()).unwrap(); - let mut context = ConfigContext::default(); - context.servers.push(Server { - id: "smtp".to_string(), - internal_id: 123, - ..Default::default() - }); - context.servers.push(Server { - id: "smtps".to_string(), - internal_id: 456, - ..Default::default() - }); + let servers = vec![ + Server { + id: "smtp".to_string(), + internal_id: 123, + ..Default::default() + }, + Server { + id: "smtps".to_string(), + internal_id: 456, + ..Default::default() + }, + ]; + let mut context = ConfigContext::new(&servers); config.parse_lists(&mut context).unwrap(); let conditions = config.parse_conditions(&context).unwrap(); diff --git a/crates/smtp/src/core/management.rs b/crates/smtp/src/core/management.rs index e7837fa6..9c7bddb6 100644 --- a/crates/smtp/src/core/management.rs +++ b/crates/smtp/src/core/management.rs @@ -50,7 +50,7 @@ use crate::{ }, }; -use super::{Core, HttpAdminSessionManager}; +use super::{SmtpAdminSessionManager, SMTP}; #[derive(Debug)] pub enum QueueRequest { @@ -155,7 +155,7 @@ pub struct Report { pub size: usize, } -impl SessionManager for HttpAdminSessionManager { +impl SessionManager for SmtpAdminSessionManager { fn spawn(&self, session: utils::listener::SessionData) { let core = self.inner.clone(); tokio::spawn(async move { @@ -179,11 +179,15 @@ impl SessionManager for HttpAdminSessionManager { } }); } + + fn shutdown(&self) { + // No-op + } } async fn handle_request( stream: impl AsyncRead + AsyncWrite + Unpin + 'static, - core: Arc, + core: Arc, remote_addr: IpAddr, _in_flight: InFlight, ) { @@ -223,7 +227,7 @@ async fn handle_request( } } -impl Core { +impl SMTP { async fn parse_request( &self, req: &hyper::Request, diff --git a/crates/smtp/src/core/mod.rs b/crates/smtp/src/core/mod.rs index b85465fb..5f162121 100644 --- a/crates/smtp/src/core/mod.rs +++ b/crates/smtp/src/core/mod.rs @@ -70,27 +70,27 @@ pub mod worker; #[derive(Clone)] pub struct SmtpSessionManager { - pub inner: Arc, + pub inner: Arc, } #[derive(Clone)] -pub struct HttpAdminSessionManager { - pub inner: Arc, +pub struct SmtpAdminSessionManager { + pub inner: Arc, } impl SmtpSessionManager { - pub fn new(inner: Arc) -> Self { + pub fn new(inner: Arc) -> Self { Self { inner } } } -impl HttpAdminSessionManager { - pub fn new(inner: Arc) -> Self { +impl SmtpAdminSessionManager { + pub fn new(inner: Arc) -> Self { Self { inner } } } -pub struct Core { +pub struct SMTP { pub worker_pool: rayon::ThreadPool, pub session: SessionCore, pub queue: QueueCore, @@ -163,7 +163,7 @@ pub enum State { pub struct Session { pub state: State, pub instance: Arc, - pub core: Arc, + pub core: Arc, pub span: Span, pub stream: T, pub data: SessionData, diff --git a/crates/smtp/src/core/scripts.rs b/crates/smtp/src/core/scripts.rs index dfaba78b..dd6b555a 100644 --- a/crates/smtp/src/core/scripts.rs +++ b/crates/smtp/src/core/scripts.rs @@ -43,7 +43,7 @@ use crate::{ queue::{DomainPart, InstantFromTimestamp, Message}, }; -use super::{Core, Session}; +use super::{Session, SMTP}; pub enum ScriptResult { Accept, @@ -113,7 +113,7 @@ impl Session { } } -impl Core { +impl SMTP { fn run_script_blocking( &self, script: Arc, diff --git a/crates/smtp/src/core/throttle.rs b/crates/smtp/src/core/throttle.rs index 98e5cc0e..2b54c041 100644 --- a/crates/smtp/src/core/throttle.rs +++ b/crates/smtp/src/core/throttle.rs @@ -24,6 +24,7 @@ use ::utils::listener::limiter::{ConcurrencyLimiter, RateLimiter}; use dashmap::mapref::entry::Entry; use tokio::io::{AsyncRead, AsyncWrite}; +use utils::config::Rate; use std::{ hash::{BuildHasher, Hash, Hasher}, diff --git a/crates/smtp/src/core/worker.rs b/crates/smtp/src/core/worker.rs index 95463f1b..ca509905 100644 --- a/crates/smtp/src/core/worker.rs +++ b/crates/smtp/src/core/worker.rs @@ -25,9 +25,9 @@ use std::sync::{atomic::Ordering, Arc}; use tokio::sync::oneshot; -use super::Core; +use super::SMTP; -impl Core { +impl SMTP { pub async fn spawn_worker(&self, f: U) -> Option where U: FnOnce() -> V + Send + 'static, @@ -73,7 +73,7 @@ pub trait SpawnCleanup { fn spawn_cleanup(&self); } -impl SpawnCleanup for Arc { +impl SpawnCleanup for Arc { fn spawn_cleanup(&self) { let core = self.clone(); self.worker_pool.spawn(move || { diff --git a/crates/smtp/src/inbound/spawn.rs b/crates/smtp/src/inbound/spawn.rs index 2c71f760..63bef89c 100644 --- a/crates/smtp/src/inbound/spawn.rs +++ b/crates/smtp/src/inbound/spawn.rs @@ -30,8 +30,11 @@ use tokio::{ use tokio_rustls::server::TlsStream; use utils::listener::SessionManager; -use crate::core::{ - scripts::ScriptResult, Session, SessionData, SessionParameters, SmtpSessionManager, State, +use crate::{ + core::{ + scripts::ScriptResult, Session, SessionData, SessionParameters, SmtpSessionManager, State, + }, + queue, reporting, }; use super::IsTls; @@ -65,6 +68,15 @@ impl SessionManager for SmtpSessionManager { } }); } + + fn shutdown(&self) { + // We spawn to avoid using async_trait + let core = self.inner.clone(); + tokio::spawn(async move { + let _ = core.queue.tx.send(queue::Event::Stop).await; + let _ = core.report.tx.send(reporting::Event::Stop).await; + }); + } } impl Session { diff --git a/crates/smtp/src/lib.rs b/crates/smtp/src/lib.rs index acbd2cb1..6fa6b12f 100644 --- a/crates/smtp/src/lib.rs +++ b/crates/smtp/src/lib.rs @@ -21,6 +21,26 @@ * for more details. */ +use crate::core::{ + throttle::ThrottleKeyHasherBuilder, QueueCore, ReportCore, SessionCore, TlsConnectors, SMTP, +}; +use std::sync::Arc; + +use config::{ + auth::ConfigAuth, database::ConfigDatabase, list::ConfigList, queue::ConfigQueue, + remote::ConfigHost, report::ConfigReport, resolver::ConfigResolver, scripts::ConfigSieve, + session::ConfigSession, ConfigContext, +}; +use dashmap::DashMap; +use mail_send::smtp::tls::build_tls_connector; +use queue::manager::SpawnQueue; +use reporting::scheduler::SpawnReport; +use tokio::sync::mpsc; +use utils::{ + config::{Config, Servers}, + UnwrapFailure, +}; + pub mod config; pub mod core; pub mod inbound; @@ -31,35 +51,122 @@ pub mod reporting; pub static USER_AGENT: &str = concat!("StalwartSMTP/", env!("CARGO_PKG_VERSION"),); -pub trait UnwrapFailure { - fn failed(self, action: &str) -> T; -} +impl SMTP { + pub async fn init(config: &Config, servers: &Servers) -> Arc { + // Read configuration parameters + let mut config_ctx = ConfigContext::new(&servers.inner); + config + .parse_remote_hosts(&mut config_ctx) + .failed("Configuration error"); + config + .parse_databases(&mut config_ctx) + .failed("Configuration error"); + config + .parse_lists(&mut config_ctx) + .failed("Configuration error"); + config + .parse_signatures(&mut config_ctx) + .failed("Configuration error"); + let sieve_config = config + .parse_sieve(&mut config_ctx) + .failed("Configuration error"); + let session_config = config + .parse_session_config(&config_ctx) + .failed("Configuration error"); + let queue_config = config + .parse_queue(&config_ctx) + .failed("Configuration error"); + let mail_auth_config = config + .parse_mail_auth(&config_ctx) + .failed("Configuration error"); + let report_config = config + .parse_reports(&config_ctx) + .failed("Configuration error"); -impl UnwrapFailure for Option { - fn failed(self, message: &str) -> T { - match self { - Some(result) => result, - None => { - eprintln!("{message}"); - std::process::exit(1); + // Build core + let (queue_tx, queue_rx) = mpsc::channel(1024); + let (report_tx, report_rx) = mpsc::channel(1024); + let core = Arc::new(SMTP { + worker_pool: rayon::ThreadPoolBuilder::new() + .num_threads( + config + .property::("global.thread-pool") + .failed("Failed to parse thread pool size") + .filter(|v| *v > 0) + .unwrap_or_else(num_cpus::get), + ) + .build() + .unwrap(), + resolvers: config.build_resolvers().failed("Failed to build resolvers"), + session: SessionCore { + config: session_config, + throttle: DashMap::with_capacity_and_hasher_and_shard_amount( + config + .property("global.shared-map.capacity") + .failed("Failed to parse shared map capacity") + .unwrap_or(2), + ThrottleKeyHasherBuilder::default(), + config + .property::("global.shared-map.shard") + .failed("Failed to parse shared map shard amount") + .unwrap_or(32) + .next_power_of_two() as usize, + ), + }, + queue: QueueCore { + config: queue_config, + throttle: DashMap::with_capacity_and_hasher_and_shard_amount( + config + .property("global.shared-map.capacity") + .failed("Failed to parse shared map capacity") + .unwrap_or(2), + ThrottleKeyHasherBuilder::default(), + config + .property::("global.shared-map.shard") + .failed("Failed to parse shared map shard amount") + .unwrap_or(32) + .next_power_of_two() as usize, + ), + id_seq: 0.into(), + quota: DashMap::with_capacity_and_hasher_and_shard_amount( + config + .property("global.shared-map.capacity") + .failed("Failed to parse shared map capacity") + .unwrap_or(2), + ThrottleKeyHasherBuilder::default(), + config + .property::("global.shared-map.shard") + .failed("Failed to parse shared map shard amount") + .unwrap_or(32) + .next_power_of_two() as usize, + ), + tx: queue_tx, + connectors: TlsConnectors { + pki_verify: build_tls_connector(false), + dummy_verify: build_tls_connector(true), + }, + }, + report: ReportCore { + tx: report_tx, + config: report_config, + }, + mail_auth: mail_auth_config, + sieve: sieve_config, + }); + + // Spawn queue manager + queue_rx.spawn(core.clone(), core.queue.read_queue().await); + + // Spawn report manager + report_rx.spawn(core.clone(), core.report.read_reports().await); + + // Spawn remote hosts + for host in config_ctx.hosts.into_values() { + if host.lookup { + host.spawn(config); } } + + core } } - -impl UnwrapFailure for Result { - fn failed(self, message: &str) -> T { - match self { - Ok(result) => result, - Err(err) => { - eprintln!("{message}: {err}"); - std::process::exit(1); - } - } - } -} - -pub fn failed(message: &str) -> ! { - eprintln!("{message}"); - std::process::exit(1); -} diff --git a/crates/smtp/src/old_main.rs b/crates/smtp/src/old_main.rs deleted file mode 100644 index 97d686c1..00000000 --- a/crates/smtp/src/old_main.rs +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright (c) 2023 Stalwart Labs Ltd. - * - * This file is part of the Stalwart SMTP Server. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * in the LICENSE file at the top-level directory of this distribution. - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - * You can be released from the requirements of the AGPLv3 license by - * purchasing a commercial license. Please contact licensing@stalw.art - * for more details. -*/ - -use std::{collections::HashMap, fs, sync::Arc, time::Duration}; - -use dashmap::DashMap; -use mail_send::smtp::tls::build_tls_connector; -use opentelemetry::{ - sdk::{ - trace::{self, Sampler}, - Resource, - }, - KeyValue, -}; -use opentelemetry_otlp::WithExportConfig; -use opentelemetry_semantic_conventions::resource::{SERVICE_NAME, SERVICE_VERSION}; -use stalwart_smtp::{ - config::{Config, ConfigContext, ServerProtocol}, - core::{ - throttle::{ConcurrencyLimiter, ThrottleKeyHasherBuilder}, - Core, QueueCore, ReportCore, SessionCore, TlsConnectors, - }, - failed, - queue::{self, manager::SpawnQueue}, - reporting::{self, scheduler::SpawnReport}, - UnwrapFailure, -}; -use tokio::sync::{mpsc, watch}; -use tracing_appender::non_blocking::WorkerGuard; -use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, EnvFilter}; - -#[tokio::main] -async fn main() -> std::io::Result<()> { - // Read configuration parameters - let config = parse_config(); - let mut config_context = ConfigContext::default(); - config - .parse_servers(&mut config_context) - .failed("Configuration error"); - config - .parse_remote_hosts(&mut config_context) - .failed("Configuration error"); - config - .parse_databases(&mut config_context) - .failed("Configuration error"); - config - .parse_lists(&mut config_context) - .failed("Configuration error"); - config - .parse_signatures(&mut config_context) - .failed("Configuration error"); - let sieve_config = config - .parse_sieve(&mut config_context) - .failed("Configuration error"); - let session_config = config - .parse_session_config(&config_context) - .failed("Configuration error"); - let queue_config = config - .parse_queue(&config_context) - .failed("Configuration error"); - let mail_auth_config = config - .parse_mail_auth(&config_context) - .failed("Configuration error"); - let report_config = config - .parse_reports(&config_context) - .failed("Configuration error"); - - // Build core - let (queue_tx, queue_rx) = mpsc::channel(1024); - let (report_tx, report_rx) = mpsc::channel(1024); - let core = Arc::new(Core { - worker_pool: rayon::ThreadPoolBuilder::new() - .num_threads( - config - .property::("global.thread-pool") - .failed("Failed to parse thread pool size") - .filter(|v| *v > 0) - .unwrap_or_else(num_cpus::get), - ) - .build() - .unwrap(), - resolvers: config.build_resolvers().failed("Failed to build resolvers"), - session: SessionCore { - config: session_config, - throttle: DashMap::with_capacity_and_hasher_and_shard_amount( - config - .property("global.shared-map.capacity") - .failed("Failed to parse shared map capacity") - .unwrap_or(2), - ThrottleKeyHasherBuilder::default(), - config - .property::("global.shared-map.shard") - .failed("Failed to parse shared map shard amount") - .unwrap_or(32) - .next_power_of_two() as usize, - ), - }, - queue: QueueCore { - config: queue_config, - throttle: DashMap::with_capacity_and_hasher_and_shard_amount( - config - .property("global.shared-map.capacity") - .failed("Failed to parse shared map capacity") - .unwrap_or(2), - ThrottleKeyHasherBuilder::default(), - config - .property::("global.shared-map.shard") - .failed("Failed to parse shared map shard amount") - .unwrap_or(32) - .next_power_of_two() as usize, - ), - id_seq: 0.into(), - quota: DashMap::with_capacity_and_hasher_and_shard_amount( - config - .property("global.shared-map.capacity") - .failed("Failed to parse shared map capacity") - .unwrap_or(2), - ThrottleKeyHasherBuilder::default(), - config - .property::("global.shared-map.shard") - .failed("Failed to parse shared map shard amount") - .unwrap_or(32) - .next_power_of_two() as usize, - ), - tx: queue_tx, - connectors: TlsConnectors { - pki_verify: build_tls_connector(false), - dummy_verify: build_tls_connector(true), - }, - }, - report: ReportCore { - tx: report_tx, - config: report_config, - }, - mail_auth: mail_auth_config, - sieve: sieve_config, - }); - - // Bind ports before dropping privileges - for server in &config_context.servers { - for listener in &server.listeners { - listener - .socket - .bind(listener.addr) - .failed(&format!("Failed to bind to {}", listener.addr)); - } - } - - // Drop privileges - #[cfg(not(target_env = "msvc"))] - { - if let Some(run_as_user) = config.value("server.run-as.user") { - let mut pd = privdrop::PrivDrop::default().user(run_as_user); - if let Some(run_as_group) = config.value("server.run-as.group") { - pd = pd.group(run_as_group); - } - pd.apply().failed("Failed to drop privileges"); - } - } - - // Enable tracing - let _tracer = enable_tracing(&config).failed("Failed to enable tracing"); - tracing::info!( - "Starting Stalwart SMTP server v{}...", - env!("CARGO_PKG_VERSION") - ); - - // Spawn queue manager - queue_rx.spawn(core.clone(), core.queue.read_queue().await); - - // Spawn report manager - report_rx.spawn(core.clone(), core.report.read_reports().await); - - // Spawn remote hosts - for host in config_context.hosts.into_values() { - if host.lookup { - host.spawn(&config); - } - } - - // Spawn listeners - let (shutdown_tx, shutdown_rx) = watch::channel(false); - for server in config_context.servers { - match server.protocol { - ServerProtocol::Smtp | ServerProtocol::Lmtp => server - .spawn(core.clone(), shutdown_rx.clone()) - .failed("Failed to start listener"), - ServerProtocol::Http => server - .spawn_management(core.clone(), shutdown_rx.clone()) - .failed("Failed to start management interface"), - ServerProtocol::Imap => { - eprintln!("Invalid protocol 'imap' for listener '{}'.", server.id); - std::process::exit(0); - } - } - } - - // Wait for shutdown signal - #[cfg(not(target_env = "msvc"))] - { - use tokio::signal::unix::{signal, SignalKind}; - - let mut h_term = signal(SignalKind::terminate()).failed("start signal handler"); - let mut h_int = signal(SignalKind::interrupt()).failed("start signal handler"); - - tokio::select! { - _ = h_term.recv() => tracing::debug!("Received SIGTERM."), - _ = h_int.recv() => tracing::debug!("Received SIGINT."), - }; - } - - #[cfg(target_env = "msvc")] - { - match tokio::signal::ctrl_c().await { - Ok(()) => {} - Err(err) => { - eprintln!("Unable to listen for shutdown signal: {}", err); - } - } - } - - // Shutdown the system - tracing::info!( - "Shutting down Stalwart SMTP server v{}...", - env!("CARGO_PKG_VERSION") - ); - - // Stop services - shutdown_tx.send(true).ok(); - core.queue.tx.send(queue::Event::Stop).await.ok(); - core.report.tx.send(reporting::Event::Stop).await.ok(); - - // Wait for services to finish - tokio::time::sleep(Duration::from_secs(1)).await; - - Ok(()) -} - -fn enable_tracing(config: &Config) -> stalwart_smtp::config::Result> { - let level = config.value("global.tracing.level").unwrap_or("info"); - let env_filter = EnvFilter::builder() - .parse(format!("stalwart_smtp={}", level)) - .failed("Failed to log level"); - match config.value("global.tracing.method").unwrap_or_default() { - "log" => { - let path = config.value_require("global.tracing.path")?; - let prefix = config.value_require("global.tracing.prefix")?; - let file_appender = match config.value("global.tracing.rotate").unwrap_or("daily") { - "daily" => tracing_appender::rolling::daily(path, prefix), - "hourly" => tracing_appender::rolling::hourly(path, prefix), - "minutely" => tracing_appender::rolling::minutely(path, prefix), - "never" => tracing_appender::rolling::never(path, prefix), - rotate => { - return Err(format!("Unsupported log rotation strategy {rotate:?}")); - } - }; - - let (non_blocking, guard) = tracing_appender::non_blocking(file_appender); - tracing::subscriber::set_global_default( - tracing_subscriber::FmtSubscriber::builder() - .with_env_filter(env_filter) - .with_writer(non_blocking) - .finish(), - ) - .failed("Failed to set subscriber"); - Ok(guard.into()) - } - "stdout" => { - tracing::subscriber::set_global_default( - tracing_subscriber::FmtSubscriber::builder() - .with_env_filter(env_filter) - .finish(), - ) - .failed("Failed to set subscriber"); - - Ok(None) - } - "otel" | "open-telemetry" => { - let tracer = match config.value_require("global.tracing.transport")? { - "grpc" => { - let mut exporter = opentelemetry_otlp::new_exporter().tonic(); - if let Some(endpoint) = config.value("global.tracing.endpoint") { - exporter = exporter.with_endpoint(endpoint); - } - opentelemetry_otlp::new_pipeline() - .tracing() - .with_exporter(exporter) - } - "http" => { - let mut headers = HashMap::new(); - for (_, value) in config.values("global.tracing.headers") { - if let Some((key, value)) = value.split_once(':') { - headers.insert(key.trim().to_string(), value.trim().to_string()); - } else { - return Err(format!("Invalid open-telemetry header {value:?}")); - } - } - let mut exporter = opentelemetry_otlp::new_exporter() - .http() - .with_endpoint(config.value_require("global.tracing.endpoint")?); - if !headers.is_empty() { - exporter = exporter.with_headers(headers); - } - opentelemetry_otlp::new_pipeline() - .tracing() - .with_exporter(exporter) - } - transport => { - return Err(format!( - "Unsupported open-telemetry transport {transport:?}" - )); - } - } - .with_trace_config( - trace::config() - .with_resource(Resource::new(vec![ - KeyValue::new(SERVICE_NAME, "stalwart-smtp".to_string()), - KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION").to_string()), - ])) - .with_sampler(Sampler::AlwaysOn), - ) - .install_batch(opentelemetry::runtime::Tokio) - .failed("Failed to create tracer"); - - tracing::subscriber::set_global_default( - tracing_subscriber::Registry::default() - .with(tracing_opentelemetry::layer().with_tracer(tracer)) - .with(env_filter), - ) - .failed("Failed to set subscriber"); - - Ok(None) - } - _ => Ok(None), - } -} - -fn parse_config() -> Config { - let mut config_path = None; - let mut found_param = false; - - for arg in std::env::args().skip(1) { - if let Some((key, value)) = arg.split_once('=') { - if key.starts_with("--config") { - config_path = value.trim().to_string().into(); - break; - } else { - failed(&format!("Invalid command line argument: {key}")); - } - } else if found_param { - config_path = arg.into(); - break; - } else if arg.starts_with("--config") { - found_param = true; - } else { - failed(&format!("Invalid command line argument: {arg}")); - } - } - - Config::parse( - &fs::read_to_string(config_path.failed("Missing parameter --config=.")) - .failed("Could not read configuration file"), - ) - .failed("Invalid configuration file") -} diff --git a/crates/smtp/src/outbound/delivery.rs b/crates/smtp/src/outbound/delivery.rs index 3b0ea3e8..b09788e5 100644 --- a/crates/smtp/src/outbound/delivery.rs +++ b/crates/smtp/src/outbound/delivery.rs @@ -37,7 +37,7 @@ use utils::config::ServerProtocol; use crate::{ config::{AggregateFrequency, TlsStrategy}, - core::Core, + core::SMTP, queue::ErrorDetails, reporting::{tls::TlsRptOptions, PolicyType, TlsEvent}, }; @@ -54,7 +54,7 @@ use crate::queue::{ }; impl DeliveryAttempt { - pub async fn try_deliver(mut self, core: Arc, queue: &mut Queue) { + pub async fn try_deliver(mut self, core: Arc, queue: &mut Queue) { // Check that the message still has recipients to be delivered let has_pending_delivery = self.has_pending_delivery(); diff --git a/crates/smtp/src/outbound/lookup.rs b/crates/smtp/src/outbound/lookup.rs index 224405bf..1008492a 100644 --- a/crates/smtp/src/outbound/lookup.rs +++ b/crates/smtp/src/outbound/lookup.rs @@ -27,13 +27,13 @@ use mail_auth::MX; use rand::{seq::SliceRandom, Rng}; use crate::{ - core::{Core, Envelope}, + core::{Envelope, SMTP}, queue::{Error, ErrorDetails, Status}, }; use super::RemoteHost; -impl Core { +impl SMTP { pub(super) async fn resolve_host( &self, remote_host: &RemoteHost<'_>, diff --git a/crates/smtp/src/outbound/mta_sts/lookup.rs b/crates/smtp/src/outbound/mta_sts/lookup.rs index f4dda030..d0aa2258 100644 --- a/crates/smtp/src/outbound/mta_sts/lookup.rs +++ b/crates/smtp/src/outbound/mta_sts/lookup.rs @@ -32,12 +32,12 @@ pub static STS_TEST_POLICY: parking_lot::Mutex> = parking_lot::Mutex::ne use mail_auth::{common::lru::DnsCache, mta_sts::MtaSts, report::tlsrpt::ResultType}; -use crate::core::Core; +use crate::core::SMTP; use super::{Error, Policy}; #[allow(unused_variables)] -impl Core { +impl SMTP { pub async fn lookup_mta_sts_policy<'x>( &self, domain: &str, diff --git a/crates/smtp/src/queue/manager.rs b/crates/smtp/src/queue/manager.rs index 80c2ed46..61120051 100644 --- a/crates/smtp/src/queue/manager.rs +++ b/crates/smtp/src/queue/manager.rs @@ -33,7 +33,7 @@ use tokio::sync::mpsc; use crate::core::{ management::{self}, - Core, QueueCore, + QueueCore, SMTP, }; use super::{ @@ -51,7 +51,7 @@ pub struct Queue { } impl SpawnQueue for mpsc::Receiver { - fn spawn(mut self, core: Arc, mut queue: Queue) { + fn spawn(mut self, core: Arc, mut queue: Queue) { tokio::spawn(async move { loop { let result = tokio::time::timeout(queue.wake_up_time(), self.recv()).await; @@ -557,5 +557,5 @@ impl Default for Queue { } pub trait SpawnQueue { - fn spawn(self, core: Arc, queue: Queue); + fn spawn(self, core: Arc, queue: Queue); } diff --git a/crates/smtp/src/reporting/analysis.rs b/crates/smtp/src/reporting/analysis.rs index b1d47949..50a3f0c2 100644 --- a/crates/smtp/src/reporting/analysis.rs +++ b/crates/smtp/src/reporting/analysis.rs @@ -37,7 +37,7 @@ use mail_auth::{ }; use mail_parser::{DateTime, HeaderValue, Message, MimeHeaders, PartType}; -use crate::core::Core; +use crate::core::SMTP; enum Compression { None, @@ -61,7 +61,7 @@ pub trait AnalyzeReport { fn analyze_report(&self, message: Arc>); } -impl AnalyzeReport for Arc { +impl AnalyzeReport for Arc { fn analyze_report(&self, message: Arc>) { let core = self.clone(); self.worker_pool.spawn(move || { diff --git a/crates/smtp/src/reporting/dkim.rs b/crates/smtp/src/reporting/dkim.rs index a59fccfd..63e8ba5e 100644 --- a/crates/smtp/src/reporting/dkim.rs +++ b/crates/smtp/src/reporting/dkim.rs @@ -25,8 +25,9 @@ use mail_auth::{ common::verify::VerifySignature, AuthenticatedMessage, AuthenticationResults, DkimOutput, }; use tokio::io::{AsyncRead, AsyncWrite}; +use utils::config::Rate; -use crate::{config::Rate, core::Session}; +use crate::core::Session; impl Session { pub async fn send_dkim_report( diff --git a/crates/smtp/src/reporting/dmarc.rs b/crates/smtp/src/reporting/dmarc.rs index 2bea08cb..80f908aa 100644 --- a/crates/smtp/src/reporting/dmarc.rs +++ b/crates/smtp/src/reporting/dmarc.rs @@ -39,7 +39,7 @@ use tokio::{ use crate::{ config::AggregateFrequency, - core::{Core, Session}, + core::{Session, SMTP}, queue::{DomainPart, InstantFromTimestamp, Schedule}, }; @@ -296,7 +296,7 @@ pub trait GenerateDmarcReport { fn generate_dmarc_report(&self, domain: ReportPolicy, path: ReportPath); } -impl GenerateDmarcReport for Arc { +impl GenerateDmarcReport for Arc { fn generate_dmarc_report(&self, domain: ReportPolicy, path: ReportPath) { let core = self.clone(); let handle = Handle::current(); @@ -426,7 +426,7 @@ impl GenerateDmarcReport for Arc { } impl Scheduler { - pub async fn schedule_dmarc(&mut self, event: Box, core: &Core) { + pub async fn schedule_dmarc(&mut self, event: Box, core: &SMTP) { let max_size = core .report .config diff --git a/crates/smtp/src/reporting/mod.rs b/crates/smtp/src/reporting/mod.rs index 75ab301a..f34e5d0e 100644 --- a/crates/smtp/src/reporting/mod.rs +++ b/crates/smtp/src/reporting/mod.rs @@ -37,7 +37,7 @@ use tokio::io::{AsyncRead, AsyncWrite}; use crate::{ config::{AddressMatch, AggregateFrequency, DkimSigner, IfBlock}, - core::{management, Core, Session}, + core::{management, Session, SMTP}, outbound::{dane::Tlsa, mta_sts::Policy}, queue::{DomainPart, Message}, USER_AGENT, @@ -123,7 +123,7 @@ impl Session { } } -impl Core { +impl SMTP { pub async fn send_report( &self, from_addr: &str, diff --git a/crates/smtp/src/reporting/scheduler.rs b/crates/smtp/src/reporting/scheduler.rs index 620e1806..eecfff9e 100644 --- a/crates/smtp/src/reporting/scheduler.rs +++ b/crates/smtp/src/reporting/scheduler.rs @@ -46,7 +46,7 @@ use tokio::{ use crate::{ config::AggregateFrequency, - core::{management::ReportRequest, worker::SpawnCleanup, Core, ReportCore}, + core::{management::ReportRequest, worker::SpawnCleanup, ReportCore, SMTP}, queue::{InstantFromTimestamp, Schedule}, }; @@ -83,7 +83,7 @@ pub struct ReportPolicy { } impl SpawnReport for mpsc::Receiver { - fn spawn(mut self, core: Arc, mut scheduler: Scheduler) { + fn spawn(mut self, core: Arc, mut scheduler: Scheduler) { tokio::spawn(async move { let mut last_cleanup = Instant::now(); @@ -184,7 +184,7 @@ impl SpawnReport for mpsc::Receiver { } } -impl Core { +impl SMTP { pub async fn build_report_path( &self, domain: ReportType<&str, &str>, @@ -645,5 +645,5 @@ impl ToTimestamp for Duration { } pub trait SpawnReport { - fn spawn(self, core: Arc, scheduler: Scheduler); + fn spawn(self, core: Arc, scheduler: Scheduler); } diff --git a/crates/smtp/src/reporting/spf.rs b/crates/smtp/src/reporting/spf.rs index cf062f55..9955901f 100644 --- a/crates/smtp/src/reporting/spf.rs +++ b/crates/smtp/src/reporting/spf.rs @@ -23,8 +23,9 @@ use mail_auth::{report::AuthFailureType, AuthenticationResults, SpfOutput}; use tokio::io::{AsyncRead, AsyncWrite}; +use utils::config::Rate; -use crate::{config::Rate, core::Session}; +use crate::core::Session; impl Session { pub async fn send_spf_report( diff --git a/crates/smtp/src/reporting/tls.rs b/crates/smtp/src/reporting/tls.rs index 248d46f2..00101386 100644 --- a/crates/smtp/src/reporting/tls.rs +++ b/crates/smtp/src/reporting/tls.rs @@ -40,7 +40,7 @@ use tokio::runtime::Handle; use crate::{ config::AggregateFrequency, - core::Core, + core::SMTP, outbound::mta_sts::{Mode, MxPattern}, queue::{InstantFromTimestamp, Schedule}, USER_AGENT, @@ -74,7 +74,7 @@ pub trait GenerateTlsReport { #[cfg(feature = "test_mode")] pub static TLS_HTTP_REPORT: parking_lot::Mutex> = parking_lot::Mutex::new(Vec::new()); -impl GenerateTlsReport for Arc { +impl GenerateTlsReport for Arc { fn generate_tls_report(&self, domain: String, path: ReportPath>>) { let core = self.clone(); let handle = Handle::current(); @@ -277,7 +277,7 @@ impl GenerateTlsReport for Arc { } impl Scheduler { - pub async fn schedule_tls(&mut self, event: Box, core: &Core) { + pub async fn schedule_tls(&mut self, event: Box, core: &SMTP) { let max_size = core .report .config diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index 84826ce0..2bf94c90 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -13,6 +13,15 @@ serde = { version = "1.0", features = ["derive"]} tracing = "0.1" mail-auth = { git = "https://github.com/stalwartlabs/mail-auth" } smtp-proto = { git = "https://github.com/stalwartlabs/smtp-proto" } +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +tracing-appender = "0.2" +tracing-opentelemetry = "0.18.0" +opentelemetry = { version = "0.18.0", features = ["rt-tokio"] } +opentelemetry-otlp = { version = "0.11.0", features = ["http-proto", "reqwest-client", "reqwest-rustls"] } +opentelemetry-semantic-conventions = { version = "0.10.0" } [target.'cfg(unix)'.dependencies] privdrop = "0.5.3" + +[features] +test_mode = [] diff --git a/crates/utils/src/config/listener.rs b/crates/utils/src/config/listener.rs index 0ab247b4..1863065b 100644 --- a/crates/utils/src/config/listener.rs +++ b/crates/utils/src/config/listener.rs @@ -277,14 +277,20 @@ impl Config { .value_or_default(("server.listener", id, "hostname"), "server.hostname") .ok_or("Hostname directive not found.")? .to_string(), - data: if matches!(protocol, ServerProtocol::Smtp | ServerProtocol::Lmtp) { - self.value_or_default(("server.listener", id, "data"), "server.data") + data: match protocol { + ServerProtocol::Smtp | ServerProtocol::Lmtp => self + .value_or_default(("server.listener", id, "greeting"), "server.greeting") .unwrap_or("Stalwart SMTP at your service") - .to_string() - } else { - self.value_or_default(("server.listener", id, "url"), "server.url") + .to_string(), + + ServerProtocol::Jmap => self + .value_or_default(("server.listener", id, "url"), "server.url") .failed(&format!("No 'url' directive found for listener {id:?}")) - .to_string() + .to_string(), + ServerProtocol::Imap | ServerProtocol::Http => self + .value_or_default(("server.listener", id, "url"), "server.url") + .unwrap_or_default() + .to_string(), }, max_connections: self .property_or_default( diff --git a/crates/utils/src/config/mod.rs b/crates/utils/src/config/mod.rs index d30e29c2..accc09b8 100644 --- a/crates/utils/src/config/mod.rs +++ b/crates/utils/src/config/mod.rs @@ -31,6 +31,8 @@ use std::{collections::BTreeMap, fmt::Display, net::SocketAddr, time::Duration}; use rustls::ServerConfig; use tokio::net::TcpSocket; +use crate::{failed, UnwrapFailure}; + #[derive(Debug, Clone, PartialEq, Eq)] pub struct Config { pub keys: BTreeMap, @@ -90,3 +92,36 @@ impl Display for ServerProtocol { } pub type Result = std::result::Result; + +impl Config { + pub fn init() -> Self { + let mut config_path = None; + let mut found_param = false; + + for arg in std::env::args().skip(1) { + if let Some((key, value)) = arg.split_once('=') { + if key.starts_with("--config") { + config_path = value.trim().to_string().into(); + break; + } else { + failed(&format!("Invalid command line argument: {key}")); + } + } else if found_param { + config_path = arg.into(); + break; + } else if arg.starts_with("--config") { + found_param = true; + } else { + failed(&format!("Invalid command line argument: {arg}")); + } + } + + Config::parse( + &std::fs::read_to_string( + config_path.failed("Missing parameter --config=."), + ) + .failed("Could not read configuration file"), + ) + .failed("Invalid configuration file") + } +} diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index 03f2d5f9..dd474451 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -21,11 +21,27 @@ * for more details. */ +use std::collections::HashMap; + +use config::Config; + pub mod codec; pub mod config; pub mod listener; pub mod map; +use opentelemetry::{ + sdk::{ + trace::{self, Sampler}, + Resource, + }, + KeyValue, +}; +use opentelemetry_otlp::WithExportConfig; +use opentelemetry_semantic_conventions::resource::{SERVICE_NAME, SERVICE_VERSION}; +use tracing_appender::non_blocking::WorkerGuard; +use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, EnvFilter}; + pub trait UnwrapFailure { fn failed(self, action: &str) -> T; } @@ -47,8 +63,14 @@ impl UnwrapFailure for Result { match self { Ok(result) => result, Err(err) => { - eprintln!("{message}: {err}"); - std::process::exit(1); + #[cfg(feature = "test_mode")] + panic!("{message}: {err}"); + + #[cfg(not(feature = "test_mode"))] + { + eprintln!("{message}: {err}"); + std::process::exit(1); + } } } } @@ -58,3 +80,127 @@ pub fn failed(message: &str) -> ! { eprintln!("{message}"); std::process::exit(1); } + +pub fn enable_tracing(config: &Config) -> config::Result> { + let level = config.value("global.tracing.level").unwrap_or("info"); + let env_filter = EnvFilter::builder() + .parse(format!("stalwart_smtp={}", level)) + .failed("Failed to log level"); + match config.value("global.tracing.method").unwrap_or_default() { + "log" => { + let path = config.value_require("global.tracing.path")?; + let prefix = config.value_require("global.tracing.prefix")?; + let file_appender = match config.value("global.tracing.rotate").unwrap_or("daily") { + "daily" => tracing_appender::rolling::daily(path, prefix), + "hourly" => tracing_appender::rolling::hourly(path, prefix), + "minutely" => tracing_appender::rolling::minutely(path, prefix), + "never" => tracing_appender::rolling::never(path, prefix), + rotate => { + return Err(format!("Unsupported log rotation strategy {rotate:?}")); + } + }; + + let (non_blocking, guard) = tracing_appender::non_blocking(file_appender); + tracing::subscriber::set_global_default( + tracing_subscriber::FmtSubscriber::builder() + .with_env_filter(env_filter) + .with_writer(non_blocking) + .finish(), + ) + .failed("Failed to set subscriber"); + Ok(guard.into()) + } + "stdout" => { + tracing::subscriber::set_global_default( + tracing_subscriber::FmtSubscriber::builder() + .with_env_filter(env_filter) + .finish(), + ) + .failed("Failed to set subscriber"); + + Ok(None) + } + "otel" | "open-telemetry" => { + let tracer = match config.value_require("global.tracing.transport")? { + "grpc" => { + let mut exporter = opentelemetry_otlp::new_exporter().tonic(); + if let Some(endpoint) = config.value("global.tracing.endpoint") { + exporter = exporter.with_endpoint(endpoint); + } + opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter(exporter) + } + "http" => { + let mut headers = HashMap::new(); + for (_, value) in config.values("global.tracing.headers") { + if let Some((key, value)) = value.split_once(':') { + headers.insert(key.trim().to_string(), value.trim().to_string()); + } else { + return Err(format!("Invalid open-telemetry header {value:?}")); + } + } + let mut exporter = opentelemetry_otlp::new_exporter() + .http() + .with_endpoint(config.value_require("global.tracing.endpoint")?); + if !headers.is_empty() { + exporter = exporter.with_headers(headers); + } + opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter(exporter) + } + transport => { + return Err(format!( + "Unsupported open-telemetry transport {transport:?}" + )); + } + } + .with_trace_config( + trace::config() + .with_resource(Resource::new(vec![ + KeyValue::new(SERVICE_NAME, "stalwart-smtp".to_string()), + KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION").to_string()), + ])) + .with_sampler(Sampler::AlwaysOn), + ) + .install_batch(opentelemetry::runtime::Tokio) + .failed("Failed to create tracer"); + + tracing::subscriber::set_global_default( + tracing_subscriber::Registry::default() + .with(tracing_opentelemetry::layer().with_tracer(tracer)) + .with(env_filter), + ) + .failed("Failed to set subscriber"); + + Ok(None) + } + _ => Ok(None), + } +} + +pub async fn wait_for_shutdown() { + #[cfg(not(target_env = "msvc"))] + { + use tokio::signal::unix::{signal, SignalKind}; + + let mut h_term = signal(SignalKind::terminate()).failed("start signal handler"); + let mut h_int = signal(SignalKind::interrupt()).failed("start signal handler"); + + tokio::select! { + _ = h_term.recv() => tracing::debug!("Received SIGTERM."), + _ = h_int.recv() => tracing::debug!("Received SIGINT."), + }; + } + + #[cfg(target_env = "msvc")] + { + match tokio::signal::ctrl_c().await { + Ok(()) => {} + Err(err) => { + eprintln!("Unable to listen for shutdown signal: {}", err); + } + } + } +} diff --git a/crates/utils/src/listener/listen.rs b/crates/utils/src/listener/listen.rs index 0a63b573..d2452774 100644 --- a/crates/utils/src/listener/listen.rs +++ b/crates/utils/src/listener/listen.rs @@ -103,6 +103,7 @@ impl Server { instance = instance.id, protocol = ?instance.protocol, "Listener shutting down."); + manager.shutdown(); break; } }; @@ -113,11 +114,7 @@ impl Server { } impl Servers { - pub fn spawn( - self, - config: &Config, - spawn: impl Fn(Server, watch::Receiver), - ) -> watch::Sender { + pub fn bind(&self, config: &Config) { // Bind as root for server in &self.inner { for listener in &server.listeners { @@ -139,7 +136,9 @@ impl Servers { pd.apply().failed("Failed to drop privileges"); } } + } + pub fn spawn(self, spawn: impl Fn(Server, watch::Receiver)) -> watch::Sender { // Spawn listeners let (shutdown_tx, shutdown_rx) = watch::channel(false); for server in self.inner { diff --git a/crates/utils/src/listener/mod.rs b/crates/utils/src/listener/mod.rs index 4b72bf3b..453f2b4b 100644 --- a/crates/utils/src/listener/mod.rs +++ b/crates/utils/src/listener/mod.rs @@ -37,4 +37,5 @@ pub struct SessionData { pub trait SessionManager: Sync + Send + 'static + Clone { fn spawn(&self, session: SessionData); + fn shutdown(&self); } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index defc0792..fbd93f65 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" resolver = "2" -[dependencies] +[dev-dependencies] store = { path = "../crates/store", features = ["test_mode"] } jmap = { path = "../crates/jmap", features = ["test_mode"] } jmap_proto = { path = "../crates/jmap-proto" } @@ -13,7 +13,7 @@ smtp-proto = { git = "https://github.com/stalwartlabs/smtp-proto" } mail-send = { git = "https://github.com/stalwartlabs/mail-send" } mail-auth = { git = "https://github.com/stalwartlabs/mail-auth", features = ["test"] } sieve-rs = { git = "https://github.com/stalwartlabs/sieve" } -utils = { path = "../crates/utils" } +utils = { path = "../crates/utils", features = ["test_mode"] } #jmap-client = { git = "https://github.com/stalwartlabs/jmap-client", features = ["websockets", "debug", "async"] } jmap-client = { path = "/home/vagrant/code/jmap-client", features = ["websockets", "debug", "async"] } mail-parser = { git = "https://github.com/stalwartlabs/mail-parser", features = ["full_encoding", "serde_support", "ludicrous_mode"] } diff --git a/tests/src/jmap/mod.rs b/tests/src/jmap/mod.rs index 8fa1f083..c0f79669 100644 --- a/tests/src/jmap/mod.rs +++ b/tests/src/jmap/mod.rs @@ -1,6 +1,6 @@ use std::{sync::Arc, time::Duration}; -use jmap::{api::SessionManager, JMAP}; +use jmap::{api::JmapSessionManager, JMAP}; use jmap_client::client::{Client, Credentials}; use jmap_proto::types::id::Id; use tokio::sync::watch; @@ -147,8 +147,9 @@ async fn init_jmap_tests(delete_if_exists: bool) -> JMAPTest { let servers = settings.parse_servers().unwrap(); // Start JMAP server - let manager = SessionManager::from(JMAP::init(&settings).await); - let shutdown_tx = servers.spawn(&settings, |server, shutdown_rx| { + servers.bind(&settings); + let manager = JmapSessionManager::new(JMAP::init(&settings).await); + let shutdown_tx = servers.spawn(|server, shutdown_rx| { server.spawn(manager.clone(), shutdown_rx); }); diff --git a/tests/src/jmap/push_subscription.rs b/tests/src/jmap/push_subscription.rs index 6c6a8025..c9fbe214 100644 --- a/tests/src/jmap/push_subscription.rs +++ b/tests/src/jmap/push_subscription.rs @@ -80,7 +80,8 @@ pub async fn test(server: Arc, admin_client: &mut Client) { // Start JMAP server let manager = SessionManager::from(push_server.clone()); - let _shutdown_tx = servers.spawn(&settings, |server, shutdown_rx| { + servers.bind(&settings); + let _shutdown_tx = servers.spawn(|server, shutdown_rx| { server.spawn(manager.clone(), shutdown_rx); }); @@ -308,9 +309,7 @@ impl utils::listener::SessionManager for SessionManager { }); } - fn max_concurrent(&self) -> u64 { - 100 - } + fn shutdown(&self) {} } async fn expect_push(event_rx: &mut mpsc::Receiver) -> PushMessage { diff --git a/tests/src/lib.rs b/tests/src/lib.rs index b301b616..c820c0ba 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -1,11 +1,11 @@ use std::path::PathBuf; #[cfg(test)] -//pub mod jmap; -#[cfg(test)] -//pub mod store; +pub mod jmap; #[cfg(test)] pub mod smtp; +#[cfg(test)] +pub mod store; pub fn add_test_certs(config: &str) -> String { let mut cert_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); diff --git a/tests/src/smtp/inbound/auth.rs b/tests/src/smtp/inbound/auth.rs index f61aef60..18c8975c 100644 --- a/tests/src/smtp/inbound/auth.rs +++ b/tests/src/smtp/inbound/auth.rs @@ -32,14 +32,14 @@ use crate::smtp::{ }; use smtp::{ config::ConfigContext, - core::{Core, Session, State}, + core::{Session, State, SMTP}, lookup::Lookup, }; #[tokio::test] async fn auth() { - let mut core = Core::test(); - let mut ctx = ConfigContext::default(); + let mut core = SMTP::test(); + let mut ctx = ConfigContext::new(&[]); ctx.lookup.insert( "plain".to_string(), Arc::new(Lookup::Local(AHashSet::from_iter([ @@ -72,7 +72,7 @@ async fn auth() { core.session.config.extensions.future_release = r"[{if = 'authenticated-as', ne = '', then = '1d'}, {else = false}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); // EHLO should not avertise plain text auth without TLS let mut session = Session::test(core); diff --git a/tests/src/smtp/inbound/basic.rs b/tests/src/smtp/inbound/basic.rs index 50d57542..3c2d8707 100644 --- a/tests/src/smtp/inbound/basic.rs +++ b/tests/src/smtp/inbound/basic.rs @@ -25,11 +25,11 @@ use crate::smtp::{ session::{TestSession, VerifyResponse}, TestConfig, }; -use smtp::core::{Core, Session}; +use smtp::core::{Session, SMTP}; #[tokio::test] async fn basic_commands() { - let mut session = Session::test(Core::test()); + let mut session = Session::test(SMTP::test()); // STARTTLS should be available on clear text connections session.stream.tls = false; diff --git a/tests/src/smtp/inbound/data.rs b/tests/src/smtp/inbound/data.rs index 24730963..6c2f826d 100644 --- a/tests/src/smtp/inbound/data.rs +++ b/tests/src/smtp/inbound/data.rs @@ -28,17 +28,17 @@ use ahash::AHashSet; use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, session::{load_test_message, TestSession, VerifyResponse}, - ParseTestConfig, TestConfig, TestCore, + ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ config::{ConfigContext, IfBlock}, - core::{Core, Session}, + core::{Session, SMTP}, lookup::Lookup, }; #[tokio::test] async fn data() { - let mut core = Core::test(); + let mut core = SMTP::test(); // Create temp dir for queue let mut qr = core.init_test_queue("smtp_data_test"); @@ -59,7 +59,7 @@ async fn data() { let mut config = &mut core.session.config; config.data.add_auth_results = "[{if = 'remote-ip', eq = '10.0.0.3', then = true}, {else = false}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.data.add_date = config.data.add_auth_results.clone(); config.data.add_message_id = config.data.add_auth_results.clone(); config.data.add_received = config.data.add_auth_results.clone(); @@ -68,7 +68,7 @@ async fn data() { config.data.max_received_headers = IfBlock::new(3); config.data.max_messages = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 1}, {else = 100}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); core.queue.config.quota = r"[[queue.quota]] match = {if = 'sender', eq = 'john@doe.org'} @@ -85,7 +85,7 @@ async fn data() { key = ['rcpt'] size = 450 " - .parse_quota(&ConfigContext::default()); + .parse_quota(&ConfigContext::new(&[])); // Test queue message builder let mut session = Session::test(core); diff --git a/tests/src/smtp/inbound/dmarc.rs b/tests/src/smtp/inbound/dmarc.rs index 1f14228a..df6f8951 100644 --- a/tests/src/smtp/inbound/dmarc.rs +++ b/tests/src/smtp/inbound/dmarc.rs @@ -34,22 +34,23 @@ use mail_auth::{ report::DmarcResult, spf::Spf, }; +use utils::config::Rate; use crate::smtp::{ inbound::{sign::TextConfigContext, TestMessage, TestQueueEvent, TestReportingEvent}, session::{TestSession, VerifyResponse}, - ParseTestConfig, TestConfig, TestCore, + ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ - config::{AggregateFrequency, ConfigContext, IfBlock, Rate, VerifyStrategy}, - core::{Core, Session}, + config::{AggregateFrequency, ConfigContext, IfBlock, VerifyStrategy}, + core::{Session, SMTP}, lookup::Lookup, }; #[tokio::test] async fn dmarc() { - let mut core = Core::test(); - let ctx = ConfigContext::default().parse_signatures(); + let mut core = SMTP::test(); + let ctx = ConfigContext::new(&[]).parse_signatures(); // Create temp dir for queue let mut qr = core.init_test_queue("smtp_dmarc_test"); @@ -147,13 +148,13 @@ async fn dmarc() { let mut config = &mut core.mail_auth; config.spf.verify_ehlo = "[{if = 'remote-ip', eq = '10.0.0.2', then = 'strict'}, { else = 'relaxed' }]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.spf.verify_mail_from = config.spf.verify_ehlo.clone(); config.dmarc.verify = IfBlock::new(VerifyStrategy::Strict); config.arc.verify = config.dmarc.verify.clone(); config.dkim.verify = "[{if = 'sender-domain', eq = 'test.net', then = 'relaxed'}, { else = 'strict' }]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); let mut config = &mut core.report.config; config.spf.sign = "['rsa']" diff --git a/tests/src/smtp/inbound/dnsrbl.rs b/tests/src/smtp/inbound/dnsrbl.rs index e66bf7ae..ff10542b 100644 --- a/tests/src/smtp/inbound/dnsrbl.rs +++ b/tests/src/smtp/inbound/dnsrbl.rs @@ -25,10 +25,10 @@ use std::time::{Duration, Instant}; use smtp::{ config::IfBlock, - core::{Core, Session}, + core::{Session, SMTP}, }; -use crate::smtp::{inbound::TestQueueEvent, session::TestSession, TestConfig, TestCore}; +use crate::smtp::{inbound::TestQueueEvent, session::TestSession, TestConfig, TestSMTP}; #[tokio::test] async fn dnsrbl() { @@ -39,7 +39,7 @@ async fn dnsrbl() { ) .unwrap();*/ - let mut core = Core::test(); + let mut core = SMTP::test(); for entry in [ "1.0.0.10.zen.spamhaus.org", "2.0.0.10.b.barracudacentral.org", diff --git a/tests/src/smtp/inbound/ehlo.rs b/tests/src/smtp/inbound/ehlo.rs index c15c0465..d052dec3 100644 --- a/tests/src/smtp/inbound/ehlo.rs +++ b/tests/src/smtp/inbound/ehlo.rs @@ -31,12 +31,12 @@ use crate::smtp::{ }; use smtp::{ config::{ConfigContext, IfBlock}, - core::{Core, Session}, + core::{Session, SMTP}, }; #[tokio::test] async fn ehlo() { - let mut core = Core::test(); + let mut core = SMTP::test(); core.resolvers.dns.txt_add( "mx1.foobar.org", Spf::parse(b"v=spf1 ip4:10.0.0.1 -all").unwrap(), @@ -51,16 +51,16 @@ async fn ehlo() { let mut config = &mut core.session.config; config.data.max_message_size = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 1024}, {else = 2048}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.extensions.future_release = r"[{if = 'remote-ip', eq = '10.0.0.1', then = '1h'}, {else = false}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.extensions.mt_priority = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 'nsep'}, {else = false}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); core.mail_auth.spf.verify_ehlo = r"[{if = 'remote-ip', eq = '10.0.0.2', then = 'strict'}, {else = 'relaxed'}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.ehlo.reject_non_fqdn = IfBlock::new(true); // Reject non-FQDN domains diff --git a/tests/src/smtp/inbound/limits.rs b/tests/src/smtp/inbound/limits.rs index b94985d4..ecfdccd3 100644 --- a/tests/src/smtp/inbound/limits.rs +++ b/tests/src/smtp/inbound/limits.rs @@ -31,26 +31,26 @@ use crate::smtp::{ }; use smtp::{ config::ConfigContext, - core::{Core, Session}, + core::{Session, SMTP}, }; #[tokio::test] async fn limits() { - let mut core = Core::test(); + let mut core = SMTP::test(); let mut config = &mut core.session.config; config.transfer_limit = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 10}, {else = 1024}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.timeout = r"[{if = 'remote-ip', eq = '10.0.0.2', then = '500ms'}, {else = '30m'}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.duration = r"[{if = 'remote-ip', eq = '10.0.0.3', then = '500ms'}, {else = '60m'}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); let (_tx, rx) = watch::channel(true); // Exceed max line length - let mut session = Session::test(core); + let mut session = Session::test_with_shutdown(core, rx); session.data.remote_ip = "10.0.0.1".parse().unwrap(); let mut buf = vec![b'A'; 2049]; session.ingest(&buf).await.unwrap(); diff --git a/tests/src/smtp/inbound/mail.rs b/tests/src/smtp/inbound/mail.rs index e4ac5c70..a01f8e24 100644 --- a/tests/src/smtp/inbound/mail.rs +++ b/tests/src/smtp/inbound/mail.rs @@ -35,12 +35,12 @@ use crate::smtp::{ }; use smtp::{ config::{ConfigContext, IfBlock, VerifyStrategy}, - core::{Core, Session}, + core::{Session, SMTP}, }; #[tokio::test] async fn mail() { - let mut core = Core::test(); + let mut core = SMTP::test(); core.resolvers.dns.txt_add( "foobar.org", Spf::parse(b"v=spf1 ip4:10.0.0.1 -all").unwrap(), @@ -72,32 +72,32 @@ async fn mail() { core.mail_auth.spf.verify_ehlo = IfBlock::new(VerifyStrategy::Relaxed); core.mail_auth.spf.verify_mail_from = r"[{if = 'remote-ip', eq = '10.0.0.2', then = 'strict'}, {else = 'relaxed'}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); core.mail_auth.iprev.verify = r"[{if = 'remote-ip', eq = '10.0.0.2', then = 'strict'}, {else = 'relaxed'}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.extensions.future_release = r"[{if = 'remote-ip', eq = '10.0.0.2', then = '1d'}, {else = false}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.extensions.deliver_by = r"[{if = 'remote-ip', eq = '10.0.0.2', then = '1d'}, {else = false}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.extensions.requiretls = r"[{if = 'remote-ip', eq = '10.0.0.2', then = true}, {else = false}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.extensions.mt_priority = r"[{if = 'remote-ip', eq = '10.0.0.2', then = 'nsep'}, {else = false}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.data.max_message_size = r"[{if = 'remote-ip', eq = '10.0.0.2', then = 2048}, {else = 1024}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.throttle.mail_from = r"[[throttle]] match = {if = 'remote-ip', eq = '10.0.0.1'} key = 'sender' rate = '2/1s' " - .parse_throttle(&ConfigContext::default()); + .parse_throttle(&ConfigContext::new(&[])); // Be rude and do not say EHLO let core = Arc::new(core); diff --git a/tests/src/smtp/inbound/rcpt.rs b/tests/src/smtp/inbound/rcpt.rs index a02256de..ad979369 100644 --- a/tests/src/smtp/inbound/rcpt.rs +++ b/tests/src/smtp/inbound/rcpt.rs @@ -32,13 +32,13 @@ use crate::smtp::{ }; use smtp::{ config::{ConfigContext, IfBlock}, - core::{Core, Session, State}, + core::{Session, State, SMTP}, lookup::Lookup, }; #[tokio::test] async fn rcpt() { - let mut core = Core::test(); + let mut core = SMTP::test(); let list_addresses = Lookup::Local(AHashSet::from_iter([ "jane@foobar.org".to_string(), @@ -54,25 +54,25 @@ async fn rcpt() { config.lookup_addresses = IfBlock::new(Some(Arc::new(list_addresses))); config.max_recipients = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 3}, {else = 5}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.relay = r"[{if = 'remote-ip', eq = '10.0.0.1', then = false}, {else = true}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config_ext.dsn = r"[{if = 'remote-ip', eq = '10.0.0.1', then = false}, {else = true}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.errors_max = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 3}, {else = 100}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.errors_wait = r"[{if = 'remote-ip', eq = '10.0.0.1', then = '5ms'}, {else = '1s'}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); core.session.config.throttle.rcpt_to = r"[[throttle]] match = {if = 'remote-ip', eq = '10.0.0.1'} key = 'sender' rate = '2/1s' " - .parse_throttle(&ConfigContext::default()); + .parse_throttle(&ConfigContext::new(&[])); // RCPT without MAIL FROM let mut session = Session::test(core); diff --git a/tests/src/smtp/inbound/scripts.rs b/tests/src/smtp/inbound/scripts.rs index f67c66b6..09a6ba9b 100644 --- a/tests/src/smtp/inbound/scripts.rs +++ b/tests/src/smtp/inbound/scripts.rs @@ -26,14 +26,14 @@ use std::path::PathBuf; use crate::smtp::{ inbound::{sign::TextConfigContext, TestMessage, TestQueueEvent}, session::{TestSession, VerifyResponse}, - TestConfig, TestCore, + TestConfig, TestSMTP, }; use smtp::{ config::{ database::ConfigDatabase, list::ConfigList, scripts::ConfigSieve, session::ConfigSession, ConfigContext, EnvelopeKey, IfBlock, }, - core::{Core, Session}, + core::{Session, SMTP}, }; use utils::config::Config; @@ -160,9 +160,9 @@ async fn sieve_scripts() { pipe_path.push("pipe"); // Prepare config - let mut core = Core::test(); + let mut core = SMTP::test(); let mut qr = core.init_test_queue("smtp_sieve_test"); - let mut ctx = ConfigContext::default().parse_signatures(); + let mut ctx = ConfigContext::new(&[]).parse_signatures(); let config = Config::parse( &CONFIG .replace("%PATH%", qr._temp_dir.temp_dir.as_path().to_str().unwrap()) diff --git a/tests/src/smtp/inbound/sign.rs b/tests/src/smtp/inbound/sign.rs index 43e24e84..eda2fe2a 100644 --- a/tests/src/smtp/inbound/sign.rs +++ b/tests/src/smtp/inbound/sign.rs @@ -36,11 +36,11 @@ use utils::config::Config; use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, session::{TestSession, VerifyResponse}, - ParseTestConfig, TestConfig, TestCore, + ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ config::{auth::ConfigAuth, ConfigContext, IfBlock, VerifyStrategy}, - core::{Core, Session}, + core::{Session, SMTP}, lookup::Lookup, }; @@ -96,7 +96,7 @@ set-body-length = false #[tokio::test] async fn sign_and_seal() { - let mut core = Core::test(); + let mut core = SMTP::test(); // Create temp dir for queue let mut qr = core.init_test_queue("smtp_sign_test"); @@ -157,7 +157,7 @@ async fn sign_and_seal() { config.data.add_received_spf = IfBlock::new(true); let mut config = &mut core.mail_auth; - let ctx = ConfigContext::default().parse_signatures(); + let ctx = ConfigContext::new(&[]).parse_signatures(); config.spf.verify_ehlo = IfBlock::new(VerifyStrategy::Relaxed); config.spf.verify_mail_from = config.spf.verify_ehlo.clone(); config.dkim.verify = config.spf.verify_ehlo.clone(); @@ -207,11 +207,11 @@ async fn sign_and_seal() { ); } -pub trait TextConfigContext { - fn parse_signatures(self) -> ConfigContext; +pub trait TextConfigContext<'x> { + fn parse_signatures(self) -> ConfigContext<'x>; } -impl TextConfigContext for ConfigContext { +impl<'x> TextConfigContext<'x> for ConfigContext<'x> { fn parse_signatures(mut self) -> Self { Config::parse(SIGNATURES) .unwrap() diff --git a/tests/src/smtp/inbound/throttle.rs b/tests/src/smtp/inbound/throttle.rs index f3935c69..40e69984 100644 --- a/tests/src/smtp/inbound/throttle.rs +++ b/tests/src/smtp/inbound/throttle.rs @@ -26,12 +26,12 @@ use std::time::Duration; use crate::smtp::{session::TestSession, ParseTestConfig, TestConfig}; use smtp::{ config::ConfigContext, - core::{Core, Session, SessionAddress}, + core::{Session, SessionAddress, SMTP}, }; #[tokio::test] async fn throttle_inbound() { - let mut core = Core::test(); + let mut core = SMTP::test(); let mut config = &mut core.session.config; config.throttle.connect = r"[[throttle]] match = {if = 'remote-ip', eq = '10.0.0.1'} @@ -39,17 +39,17 @@ async fn throttle_inbound() { concurrency = 2 rate = '3/1s' " - .parse_throttle(&ConfigContext::default()); + .parse_throttle(&ConfigContext::new(&[])); config.throttle.mail_from = r"[[throttle]] key = 'sender' rate = '2/1s' " - .parse_throttle(&ConfigContext::default()); + .parse_throttle(&ConfigContext::new(&[])); config.throttle.rcpt_to = r"[[throttle]] key = ['remote-ip', 'rcpt'] rate = '2/1s' " - .parse_throttle(&ConfigContext::default()); + .parse_throttle(&ConfigContext::new(&[])); // Test connection concurrency limit let mut session = Session::test(core); diff --git a/tests/src/smtp/inbound/vrfy.rs b/tests/src/smtp/inbound/vrfy.rs index 5df6b7e6..51a18706 100644 --- a/tests/src/smtp/inbound/vrfy.rs +++ b/tests/src/smtp/inbound/vrfy.rs @@ -31,14 +31,14 @@ use crate::smtp::{ }; use smtp::{ config::ConfigContext, - core::{Core, Session}, + core::{Session, SMTP}, lookup::Lookup, }; #[tokio::test] async fn vrfy_expn() { - let mut core = Core::test(); - let mut ctx = ConfigContext::default(); + let mut core = SMTP::test(); + let mut ctx = ConfigContext::new(&[]); ctx.lookup.insert( "vrfy".to_string(), Arc::new(Lookup::Local(AHashSet::from_iter([ diff --git a/tests/src/smtp/lookup/imap.rs b/tests/src/smtp/lookup/imap.rs index d9f330a7..2d42b025 100644 --- a/tests/src/smtp/lookup/imap.rs +++ b/tests/src/smtp/lookup/imap.rs @@ -79,7 +79,7 @@ async fn lookup_imap() { let shutdown = spawn_mock_imap_server(5); // Spawn lookup client - let mut ctx = ConfigContext::default(); + let mut ctx = ConfigContext::new(&[]); let config = Config::parse(REMOTE).unwrap(); config.parse_remote_hosts(&mut ctx).unwrap(); let lookup = ctx.hosts.remove("imap").unwrap().spawn(&config); diff --git a/tests/src/smtp/lookup/smtp.rs b/tests/src/smtp/lookup/smtp.rs index 9c7f5434..2c9f8d26 100644 --- a/tests/src/smtp/lookup/smtp.rs +++ b/tests/src/smtp/lookup/smtp.rs @@ -71,7 +71,7 @@ async fn lookup_smtp() { let shutdown = spawn_mock_lmtp_server(5); // Spawn lookup client - let mut ctx = ConfigContext::default(); + let mut ctx = ConfigContext::new(&[]); let config = Config::parse(REMOTE).unwrap(); config.parse_remote_hosts(&mut ctx).unwrap(); let lookup = ctx.hosts.remove("lmtp").unwrap().spawn(&config); diff --git a/tests/src/smtp/lookup/sql.rs b/tests/src/smtp/lookup/sql.rs index d024c19e..a0a1fa75 100644 --- a/tests/src/smtp/lookup/sql.rs +++ b/tests/src/smtp/lookup/sql.rs @@ -33,7 +33,7 @@ use crate::smtp::{ }; use smtp::{ config::{database::ConfigDatabase, ConfigContext, IfBlock}, - core::{Core, Session}, + core::{Session, SMTP}, lookup::SqlDatabase, }; @@ -69,9 +69,9 @@ async fn lookup_sql() { .unwrap();*/ // Parse settings - let mut core = Core::test(); + let mut core = SMTP::test(); let _temp_dir = make_temp_dir("sql_lookup_test", true); - let mut ctx = ConfigContext::default(); + let mut ctx = ConfigContext::new(&[]); let config = Config::parse(&CONFIG.replace("%PATH%", _temp_dir.temp_dir.as_path().to_str().unwrap())) .unwrap(); diff --git a/tests/src/smtp/lookup/utils.rs b/tests/src/smtp/lookup/utils.rs index 3920917d..27049601 100644 --- a/tests/src/smtp/lookup/utils.rs +++ b/tests/src/smtp/lookup/utils.rs @@ -2,7 +2,7 @@ use std::time::{Duration, Instant}; use mail_auth::{IpLookupStrategy, MX}; -use smtp::{config::IfBlock, core::Core, outbound::RemoteHost}; +use smtp::{config::IfBlock, core::SMTP, outbound::RemoteHost}; use super::ToRemoteHost; @@ -20,7 +20,7 @@ async fn lookup_ip() { "10.0.0.3".parse().unwrap(), "10.0.0.4".parse().unwrap(), ]; - let mut core = Core::test(); + let mut core = SMTP::test(); core.queue.config.source_ip.ipv4 = IfBlock::new(ipv4.clone()); core.queue.config.source_ip.ipv6 = IfBlock::new(ipv6.clone()); core.resolvers.dns.ipv4_add( diff --git a/tests/src/smtp/management/queue.rs b/tests/src/smtp/management/queue.rs index 67952e23..4ec1ed8b 100644 --- a/tests/src/smtp/management/queue.rs +++ b/tests/src/smtp/management/queue.rs @@ -34,11 +34,11 @@ use utils::config::ServerProtocol; use crate::smtp::{ inbound::TestQueueEvent, management::send_manage_request, outbound::start_test_server, - session::TestSession, TestConfig, TestCore, + session::TestSession, TestConfig, TestSMTP, }; use smtp::{ config::IfBlock, - core::{management::Message, Core, Session}, + core::{management::Message, Session, SMTP}, lookup::Lookup, queue::{ manager::{Queue, SpawnQueue}, @@ -57,13 +57,13 @@ async fn manage_queue() { .unwrap();*/ // Start remote test server - let mut core = Core::test(); + let mut core = SMTP::test(); core.session.config.rcpt.relay = IfBlock::new(true); let mut remote_qr = core.init_test_queue("smtp_manage_queue_remote"); let _rx_remote = start_test_server(core.into(), &[ServerProtocol::Smtp]); // Add mock DNS entries - let mut core = Core::test(); + let mut core = SMTP::test(); core.resolvers.dns.mx_add( "foobar.org", vec![MX { diff --git a/tests/src/smtp/management/report.rs b/tests/src/smtp/management/report.rs index 18daf5d3..778f755b 100644 --- a/tests/src/smtp/management/report.rs +++ b/tests/src/smtp/management/report.rs @@ -41,7 +41,7 @@ use crate::smtp::{ }; use smtp::{ config::{AggregateFrequency, IfBlock}, - core::{management::Report, Core}, + core::{management::Report, SMTP}, lookup::Lookup, reporting::{ scheduler::{Scheduler, SpawnReport}, @@ -60,7 +60,7 @@ async fn manage_reports() { .unwrap();*/ // Start reporting service - let mut core = Core::test(); + let mut core = SMTP::test(); let temp_dir = make_temp_dir("smtp_report_management_test", true); let config = &mut core.report.config; config.path = IfBlock::new(temp_dir.temp_dir.clone()); diff --git a/tests/src/smtp/mod.rs b/tests/src/smtp/mod.rs index 71808b86..82f5c825 100644 --- a/tests/src/smtp/mod.rs +++ b/tests/src/smtp/mod.rs @@ -45,8 +45,8 @@ use smtp::{ SessionThrottle, SpfAuthConfig, Throttle, VerifyStrategy, }, core::{ - throttle::ThrottleKeyHasherBuilder, Core, QueueCore, ReportCore, Resolvers, SessionCore, - SieveConfig, SieveCore, TlsConnectors, + throttle::ThrottleKeyHasherBuilder, QueueCore, ReportCore, Resolvers, SessionCore, + SieveConfig, SieveCore, TlsConnectors, SMTP, }, lookup::Lookup, outbound::dane::DnssecResolver, @@ -134,9 +134,9 @@ pub trait TestConfig { fn test() -> Self; } -impl TestConfig for Core { +impl TestConfig for SMTP { fn test() -> Self { - Core { + SMTP { worker_pool: rayon::ThreadPoolBuilder::new() .num_threads(num_cpus::get()) .build() @@ -470,12 +470,12 @@ pub struct ReportReceiver { pub report_rx: mpsc::Receiver, } -pub trait TestCore { +pub trait TestSMTP { fn init_test_queue(&mut self, test_name: &str) -> QueueReceiver; fn init_test_report(&mut self) -> ReportReceiver; } -impl TestCore for Core { +impl TestSMTP for SMTP { fn init_test_queue(&mut self, test_name: &str) -> QueueReceiver { let _temp_dir = make_temp_dir(test_name, true); self.queue.config.path = IfBlock::new(_temp_dir.temp_dir.clone()); diff --git a/tests/src/smtp/outbound/dane.rs b/tests/src/smtp/outbound/dane.rs index 5f9f1a43..58fe0eb5 100644 --- a/tests/src/smtp/outbound/dane.rs +++ b/tests/src/smtp/outbound/dane.rs @@ -38,11 +38,11 @@ use crate::smtp::{ inbound::{TestMessage, TestQueueEvent, TestReportingEvent}, outbound::start_test_server, session::{TestSession, VerifyResponse}, - TestConfig, TestCore, + TestConfig, TestSMTP, }; use smtp::{ config::{AggregateFrequency, IfBlock, RequireOptional}, - core::{Core, Session}, + core::{Session, SMTP}, outbound::dane::{Tlsa, TlsaEntry}, queue::{manager::Queue, DeliveryAttempt}, reporting::PolicyType, @@ -59,13 +59,13 @@ async fn dane_verify() { .unwrap();*/ // Start test server - let mut core = Core::test(); + let mut core = SMTP::test(); core.session.config.rcpt.relay = IfBlock::new(true); let mut remote_qr = core.init_test_queue("smtp_dane_remote"); let _rx = start_test_server(core.into(), &[ServerProtocol::Smtp]); // Add mock DNS entries - let mut core = Core::test(); + let mut core = SMTP::test(); core.resolvers.dns.mx_add( "foobar.org", vec![MX { diff --git a/tests/src/smtp/outbound/extensions.rs b/tests/src/smtp/outbound/extensions.rs index b0995a36..0440b31a 100644 --- a/tests/src/smtp/outbound/extensions.rs +++ b/tests/src/smtp/outbound/extensions.rs @@ -34,11 +34,11 @@ use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, outbound::start_test_server, session::{TestSession, VerifyResponse}, - TestConfig, TestCore, + TestConfig, TestSMTP, }; use smtp::{ config::IfBlock, - core::{Core, Session}, + core::{Session, SMTP}, queue::{manager::Queue, DeliveryAttempt}, }; @@ -53,7 +53,7 @@ async fn extensions() { .unwrap();*/ // Start test server - let mut core = Core::test(); + let mut core = SMTP::test(); core.session.config.rcpt.relay = IfBlock::new(true); core.session.config.data.max_message_size = IfBlock::new(1500); core.session.config.extensions.dsn = IfBlock::new(true); @@ -62,7 +62,7 @@ async fn extensions() { let _rx = start_test_server(core.into(), &[ServerProtocol::Smtp]); // Add mock DNS entries - let mut core = Core::test(); + let mut core = SMTP::test(); core.resolvers.dns.mx_add( "foobar.org", vec![MX { diff --git a/tests/src/smtp/outbound/lmtp.rs b/tests/src/smtp/outbound/lmtp.rs index 865c7d87..c1f2bf42 100644 --- a/tests/src/smtp/outbound/lmtp.rs +++ b/tests/src/smtp/outbound/lmtp.rs @@ -30,11 +30,11 @@ use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, outbound::start_test_server, session::{TestSession, VerifyResponse}, - ParseTestConfig, TestConfig, TestCore, + ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ config::{remote::ConfigHost, ConfigContext, IfBlock}, - core::{Core, Session}, + core::{Session, SMTP}, queue::{manager::Queue, DeliveryAttempt, Event, WorkerResult}, }; use utils::config::{Config, ServerProtocol}; @@ -62,14 +62,14 @@ async fn lmtp_delivery() { .unwrap();*/ // Start test server - let mut core = Core::test(); + let mut core = SMTP::test(); core.session.config.rcpt.relay = IfBlock::new(true); core.session.config.extensions.dsn = IfBlock::new(true); let mut remote_qr = core.init_test_queue("lmtp_delivery_remote"); let _rx = start_test_server(core.into(), &[ServerProtocol::Lmtp]); // Add mock DNS entries - let mut core = Core::test(); + let mut core = SMTP::test(); core.resolvers.dns.ipv4_add( "lmtp.foobar.org", vec!["127.0.0.1".parse().unwrap()], @@ -79,7 +79,7 @@ async fn lmtp_delivery() { // Multiple delivery attempts let mut local_qr = core.init_test_queue("lmtp_delivery_local"); - let mut ctx = ConfigContext::default(); + let mut ctx = ConfigContext::new(&[]); let config = Config::parse(REMOTE).unwrap(); config.parse_remote_hosts(&mut ctx).unwrap(); core.queue.config.next_hop = "[{if = 'rcpt-domain', eq = 'foobar.org', then = 'lmtp'}, diff --git a/tests/src/smtp/outbound/mod.rs b/tests/src/smtp/outbound/mod.rs index 83bace1e..eac2c0c3 100644 --- a/tests/src/smtp/outbound/mod.rs +++ b/tests/src/smtp/outbound/mod.rs @@ -25,7 +25,7 @@ use std::sync::Arc; use tokio::sync::watch; -use ::smtp::core::{Core, HttpAdminSessionManager, SmtpSessionManager}; +use ::smtp::core::{SmtpAdminSessionManager, SmtpSessionManager, SMTP}; use utils::config::{Config, ServerProtocol}; use super::add_test_certs; @@ -68,23 +68,27 @@ cert = 'file://{CERT}' private-key = 'file://{PK}' "; -pub fn start_test_server(core: Arc, protocols: &[ServerProtocol]) -> watch::Sender { +pub fn start_test_server(core: Arc, protocols: &[ServerProtocol]) -> watch::Sender { // Spawn listeners let config = Config::parse(&add_test_certs(SERVER)).unwrap(); - let servers = config.parse_servers().unwrap(); + let mut servers = config.parse_servers().unwrap(); + + // Filter out protocols + servers + .inner + .retain(|server| protocols.contains(&server.protocol)); // Start servers + servers.bind(&config); let smtp_manager = SmtpSessionManager::new(core.clone()); - let smtp_admin_manager = HttpAdminSessionManager::new(core); - servers.spawn(&config, |server, shutdown_rx| { - if protocols.contains(&server.protocol) { - match &server.protocol { - ServerProtocol::Smtp | ServerProtocol::Lmtp => { - server.spawn(smtp_manager.clone(), shutdown_rx) - } - ServerProtocol::Http => server.spawn(smtp_admin_manager.clone(), shutdown_rx), - ServerProtocol::Imap | ServerProtocol::Jmap => unreachable!(), - }; - } + let smtp_admin_manager = SmtpAdminSessionManager::new(core); + servers.spawn(|server, shutdown_rx| { + match &server.protocol { + ServerProtocol::Smtp | ServerProtocol::Lmtp => { + server.spawn(smtp_manager.clone(), shutdown_rx) + } + ServerProtocol::Http => server.spawn(smtp_admin_manager.clone(), shutdown_rx), + ServerProtocol::Imap | ServerProtocol::Jmap => unreachable!(), + }; }) } diff --git a/tests/src/smtp/outbound/mta_sts.rs b/tests/src/smtp/outbound/mta_sts.rs index 030ec3ae..d0bd47aa 100644 --- a/tests/src/smtp/outbound/mta_sts.rs +++ b/tests/src/smtp/outbound/mta_sts.rs @@ -38,11 +38,11 @@ use crate::smtp::{ inbound::{TestMessage, TestQueueEvent, TestReportingEvent}, outbound::start_test_server, session::{TestSession, VerifyResponse}, - TestConfig, TestCore, + TestConfig, TestSMTP, }; use smtp::{ config::{AggregateFrequency, IfBlock, RequireOptional}, - core::{Core, Session}, + core::{Session, SMTP}, outbound::mta_sts::{lookup::STS_TEST_POLICY, Policy}, queue::{manager::Queue, DeliveryAttempt}, reporting::PolicyType, @@ -59,13 +59,13 @@ async fn mta_sts_verify() { .unwrap();*/ // Start test server - let mut core = Core::test(); + let mut core = SMTP::test(); core.session.config.rcpt.relay = IfBlock::new(true); let mut remote_qr = core.init_test_queue("smtp_mta_sts_remote"); let _rx = start_test_server(core.into(), &[ServerProtocol::Smtp]); // Add mock DNS entries - let mut core = Core::test(); + let mut core = SMTP::test(); core.resolvers.dns.mx_add( "foobar.org", vec![MX { diff --git a/tests/src/smtp/outbound/smtp.rs b/tests/src/smtp/outbound/smtp.rs index 7824d3fc..26833cb8 100644 --- a/tests/src/smtp/outbound/smtp.rs +++ b/tests/src/smtp/outbound/smtp.rs @@ -33,11 +33,11 @@ use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, outbound::start_test_server, session::{TestSession, VerifyResponse}, - ParseTestConfig, TestConfig, TestCore, + ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ config::{ConfigContext, IfBlock}, - core::{Core, Session}, + core::{Session, SMTP}, queue::{manager::Queue, DeliveryAttempt, Event, WorkerResult}, }; @@ -52,14 +52,14 @@ async fn smtp_delivery() { .unwrap();*/ // Start test server - let mut core = Core::test(); + let mut core = SMTP::test(); core.session.config.rcpt.relay = IfBlock::new(true); core.session.config.extensions.dsn = IfBlock::new(true); let mut remote_qr = core.init_test_queue("smtp_delivery_remote"); let _rx = start_test_server(core.into(), &[ServerProtocol::Smtp]); // Add mock DNS entries - let mut core = Core::test(); + let mut core = SMTP::test(); core.resolvers.dns.mx_add( "foobar.org", vec![ @@ -112,10 +112,10 @@ async fn smtp_delivery() { config.retry = IfBlock::new(vec![Duration::from_millis(100)]); config.notify = "[{if = 'rcpt-domain', eq = 'foobar.org', then = ['100ms', '200ms']}, {else = ['100ms']}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.expire = "[{if = 'rcpt-domain', eq = 'foobar.org', then = '650ms'}, {else = '750ms'}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); let core = Arc::new(core); let mut queue = Queue::default(); diff --git a/tests/src/smtp/outbound/throttle.rs b/tests/src/smtp/outbound/throttle.rs index d5aaef64..568dfdb7 100644 --- a/tests/src/smtp/outbound/throttle.rs +++ b/tests/src/smtp/outbound/throttle.rs @@ -31,11 +31,11 @@ use mail_auth::MX; use crate::smtp::{ inbound::TestQueueEvent, queue::manager::new_message, session::TestSession, ParseTestConfig, - TestConfig, TestCore, + TestConfig, TestSMTP, }; use smtp::{ config::{ConfigContext, IfBlock}, - core::{Core, Session}, + core::{Session, SMTP}, queue::{manager::Queue, DeliveryAttempt, Message, QueueEnvelope}, }; @@ -83,10 +83,10 @@ async fn throttle_outbound() { // Build test message let mut test_message = new_message(0); test_message.return_path_domain = "foobar.org".to_string(); - let mut core = Core::test(); + let mut core = SMTP::test(); let mut local_qr = core.init_test_queue("smtp_throttle_outbound"); core.session.config.rcpt.relay = IfBlock::new(true); - core.queue.config.throttle = THROTTLE.parse_queue_throttle(&ConfigContext::default()); + core.queue.config.throttle = THROTTLE.parse_queue_throttle(&ConfigContext::new(&[])); core.queue.config.retry = IfBlock::new(vec![Duration::from_secs(86400)]); core.queue.config.notify = IfBlock::new(vec![Duration::from_secs(86400)]); core.queue.config.expire = IfBlock::new(Duration::from_secs(86400)); diff --git a/tests/src/smtp/queue/dsn.rs b/tests/src/smtp/queue/dsn.rs index 32296274..58588a16 100644 --- a/tests/src/smtp/queue/dsn.rs +++ b/tests/src/smtp/queue/dsn.rs @@ -32,11 +32,11 @@ use tokio::{fs::File, io::AsyncReadExt}; use crate::smtp::{ inbound::{sign::TextConfigContext, TestQueueEvent}, - ParseTestConfig, TestConfig, TestCore, + ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ config::ConfigContext, - core::Core, + core::SMTP, queue::{ DeliveryAttempt, Domain, Error, ErrorDetails, HostResponse, Message, Recipient, Schedule, Status, @@ -105,8 +105,8 @@ async fn generate_dsn() { }; // Load config - let mut core = Core::test(); - let ctx = ConfigContext::default().parse_signatures(); + let mut core = SMTP::test(); + let ctx = ConfigContext::new(&[]).parse_signatures(); let mut config = &mut core.queue.config.dsn; config.sign = "['rsa']" .parse_if::>(&ctx) diff --git a/tests/src/smtp/queue/retry.rs b/tests/src/smtp/queue/retry.rs index 2a33d705..07add43d 100644 --- a/tests/src/smtp/queue/retry.rs +++ b/tests/src/smtp/queue/retry.rs @@ -29,11 +29,11 @@ use std::{ use crate::smtp::{ inbound::{TestMessage, TestQueueEvent}, session::{TestSession, VerifyResponse}, - ParseTestConfig, TestConfig, TestCore, + ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ config::{ConfigContext, IfBlock}, - core::{Core, Session}, + core::{Session, SMTP}, queue::{manager::Queue, DeliveryAttempt, Event, WorkerResult}, }; @@ -46,7 +46,7 @@ async fn queue_retry() { ) .unwrap();*/ - let mut core = Core::test(); + let mut core = SMTP::test(); // Create temp dir for queue let mut qr = core.init_test_queue("smtp_queue_retry_test"); @@ -64,10 +64,10 @@ async fn queue_retry() { ]); config.notify = "[{if = 'sender-domain', eq = 'test.org', then = ['150ms', '200ms']}, {else = ['15h', '22h']}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); config.expire = "[{if = 'sender-domain', eq = 'test.org', then = '600ms'}, {else = '1d'}]" - .parse_if(&ConfigContext::default()); + .parse_if(&ConfigContext::new(&[])); // Create test message let core = Arc::new(core); diff --git a/tests/src/smtp/queue/serialize.rs b/tests/src/smtp/queue/serialize.rs index 5f2ba15b..3e9749c4 100644 --- a/tests/src/smtp/queue/serialize.rs +++ b/tests/src/smtp/queue/serialize.rs @@ -29,18 +29,18 @@ use std::{ use smtp_proto::{Response, MAIL_REQUIRETLS, MAIL_SMTPUTF8, RCPT_CONNEG, RCPT_NOTIFY_FAILURE}; use smtp::{ - core::Core, + core::SMTP, queue::{ Domain, Error, ErrorDetails, HostResponse, Message, Recipient, Schedule, Status, RCPT_STATUS_CHANGED, }, }; -use crate::smtp::{inbound::TestQueueEvent, TestConfig, TestCore}; +use crate::smtp::{inbound::TestQueueEvent, TestConfig, TestSMTP}; #[tokio::test] async fn queue_serialize() { - let mut core = Core::test(); + let mut core = SMTP::test(); // Create temp dir for queue let mut qr = core.init_test_queue("smtp_queue_serialize_test"); diff --git a/tests/src/smtp/reporting/analyze.rs b/tests/src/smtp/reporting/analyze.rs index b1614901..5d2ba00e 100644 --- a/tests/src/smtp/reporting/analyze.rs +++ b/tests/src/smtp/reporting/analyze.rs @@ -24,16 +24,16 @@ use std::{fs, sync::Arc, time::Duration}; use crate::smtp::{ - inbound::TestQueueEvent, make_temp_dir, session::TestSession, TestConfig, TestCore, + inbound::TestQueueEvent, make_temp_dir, session::TestSession, TestConfig, TestSMTP, }; use smtp::{ config::{AddressMatch, IfBlock}, - core::{Core, Session}, + core::{Session, SMTP}, }; #[tokio::test] async fn report_analyze() { - let mut core = Core::test(); + let mut core = SMTP::test(); // Create temp dir for queue let mut qr = core.init_test_queue("smtp_analyze_report_test"); diff --git a/tests/src/smtp/reporting/dmarc.rs b/tests/src/smtp/reporting/dmarc.rs index 69d2d3f1..48f295f5 100644 --- a/tests/src/smtp/reporting/dmarc.rs +++ b/tests/src/smtp/reporting/dmarc.rs @@ -37,11 +37,11 @@ use crate::smtp::{ inbound::{sign::TextConfigContext, TestMessage, TestQueueEvent}, make_temp_dir, session::VerifyResponse, - ParseTestConfig, TestConfig, TestCore, + ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ config::{AggregateFrequency, ConfigContext, IfBlock}, - core::Core, + core::SMTP, reporting::{ dmarc::GenerateDmarcReport, scheduler::{ReportType, Scheduler}, @@ -59,8 +59,8 @@ async fn report_dmarc() { .unwrap();*/ // Create scheduler - let mut core = Core::test(); - let ctx = ConfigContext::default().parse_signatures(); + let mut core = SMTP::test(); + let ctx = ConfigContext::new(&[]).parse_signatures(); let temp_dir = make_temp_dir("smtp_report_dmarc_test", true); let config = &mut core.report.config; config.path = IfBlock::new(temp_dir.temp_dir.clone()); diff --git a/tests/src/smtp/reporting/scheduler.rs b/tests/src/smtp/reporting/scheduler.rs index 207c901b..ca19fefb 100644 --- a/tests/src/smtp/reporting/scheduler.rs +++ b/tests/src/smtp/reporting/scheduler.rs @@ -34,7 +34,7 @@ use tokio::fs; use crate::smtp::{make_temp_dir, TestConfig}; use smtp::{ config::{AggregateFrequency, IfBlock}, - core::Core, + core::SMTP, reporting::{ dmarc::DmarcFormat, scheduler::{ReportType, Scheduler}, @@ -52,7 +52,7 @@ async fn report_scheduler() { .unwrap();*/ // Create scheduler - let mut core = Core::test(); + let mut core = SMTP::test(); let temp_dir = make_temp_dir("smtp_report_scheduler_test", true); let config = &mut core.report.config; config.path = IfBlock::new(temp_dir.temp_dir.clone()); diff --git a/tests/src/smtp/reporting/tls.rs b/tests/src/smtp/reporting/tls.rs index 55e33c55..669cc43c 100644 --- a/tests/src/smtp/reporting/tls.rs +++ b/tests/src/smtp/reporting/tls.rs @@ -34,11 +34,11 @@ use crate::smtp::{ inbound::{sign::TextConfigContext, TestMessage, TestQueueEvent}, make_temp_dir, session::VerifyResponse, - ParseTestConfig, TestConfig, TestCore, + ParseTestConfig, TestConfig, TestSMTP, }; use smtp::{ config::{AggregateFrequency, ConfigContext, IfBlock}, - core::Core, + core::SMTP, reporting::{ scheduler::{ReportType, Scheduler}, tls::{GenerateTlsReport, TLS_HTTP_REPORT}, @@ -56,8 +56,8 @@ async fn report_tls() { .unwrap();*/ // Create scheduler - let mut core = Core::test(); - let ctx = ConfigContext::default().parse_signatures(); + let mut core = SMTP::test(); + let ctx = ConfigContext::new(&[]).parse_signatures(); let temp_dir = make_temp_dir("smtp_report_tls_test", true); let config = &mut core.report.config; config.path = IfBlock::new(temp_dir.temp_dir.clone()); diff --git a/tests/src/smtp/session.rs b/tests/src/smtp/session.rs index 1055c5ee..719440fc 100644 --- a/tests/src/smtp/session.rs +++ b/tests/src/smtp/session.rs @@ -29,7 +29,7 @@ use tokio::{ }; use smtp::{ - core::{Core, Session, SessionAddress, SessionData, SessionParameters, State}, + core::{Session, SessionAddress, SessionData, SessionParameters, State, SMTP}, inbound::IsTls, }; use utils::{ @@ -98,7 +98,8 @@ impl Unpin for DummyIo {} #[async_trait::async_trait] pub trait TestSession { - fn test(core: impl Into>) -> Self; + fn test(core: impl Into>) -> Self; + fn test_with_shutdown(core: impl Into>, shutdown_rx: watch::Receiver) -> Self; fn response(&mut self) -> Vec; fn write_rx(&mut self, data: &str); async fn rset(&mut self); @@ -113,10 +114,10 @@ pub trait TestSession { #[async_trait::async_trait] impl TestSession for Session { - fn test(core: impl Into>) -> Self { + fn test_with_shutdown(core: impl Into>, shutdown_rx: watch::Receiver) -> Self { Self { state: State::default(), - instance: Arc::new(ServerInstance::test()), + instance: Arc::new(ServerInstance::test_with_shutdown(shutdown_rx)), core: core.into(), span: tracing::info_span!("test"), stream: DummyIo { @@ -130,6 +131,10 @@ impl TestSession for Session { } } + fn test(core: impl Into>) -> Self { + Self::test_with_shutdown(core, watch::channel(false).1) + } + fn response(&mut self) -> Vec { if !self.stream.tx_buf.is_empty() { let response = std::str::from_utf8(&self.stream.tx_buf) @@ -330,8 +335,12 @@ impl VerifyResponse for Vec { } } -impl TestConfig for ServerInstance { - fn test() -> Self { +pub trait TestServerInstance { + fn test_with_shutdown(shutdown_rx: watch::Receiver) -> Self; +} + +impl TestServerInstance for ServerInstance { + fn test_with_shutdown(shutdown_rx: watch::Receiver) -> Self { Self { id: "smtp".to_string(), listener_id: 1, @@ -341,7 +350,13 @@ impl TestConfig for ServerInstance { tls_acceptor: None, is_tls_implicit: false, limiter: ConcurrencyLimiter::new(100), - shutdown_rx: watch::channel(false).1, + shutdown_rx, } } } + +impl TestConfig for ServerInstance { + fn test() -> Self { + Self::test_with_shutdown(watch::channel(false).1) + } +}