diff --git a/Cargo.lock b/Cargo.lock index d81bd87..fa0e697 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,6 +64,30 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-lc-rs" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +dependencies = [ + "aws-lc-sys", + "untrusted 0.7.1", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "backtrace" version = "0.3.75" @@ -76,7 +100,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -98,6 +122,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + [[package]] name = "bitflags" version = "2.9.1" @@ -137,17 +184,22 @@ dependencies = [ "http-body-util", "hyper", "hyper-util", + "instant-acme", "json", "log", "nanoid", "pretty_env_logger", "ring", + "rustls", + "rustls-pemfile", + "safe-path", "serde", "serde_yaml_bw", "string-builder", - "thiserror", + "thiserror 2.0.12", "tokio", "tokio-postgres", + "tokio-rustls", ] [[package]] @@ -180,9 +232,26 @@ version = "1.2.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" dependencies = [ + "jobserver", + "libc", "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[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.1" @@ -199,6 +268,26 @@ dependencies = [ "inout", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "colour" version = "2.1.0" @@ -208,6 +297,32 @@ dependencies = [ "winapi", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -227,6 +342,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + [[package]] name = "digest" version = "0.10.7" @@ -238,6 +362,18 @@ dependencies = [ "subtle", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "env_logger" version = "0.10.2" @@ -257,6 +393,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -269,6 +415,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures-channel" version = "0.3.31" @@ -362,6 +514,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + [[package]] name = "h2" version = "0.4.10" @@ -402,6 +560,15 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "http" version = "1.3.1" @@ -475,6 +642,24 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "rustls-platform-verifier", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.14" @@ -515,6 +700,32 @@ dependencies = [ "generic-array", ] +[[package]] +name = "instant-acme" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e49a0d5d5b4c21fd218ab511764a9e0c441e2c97b63a8e782ecc3784868b8f9" +dependencies = [ + "async-trait", + "aws-lc-rs", + "base64", + "bytes", + "http", + "http-body", + "http-body-util", + "httpdate", + "hyper", + "hyper-rustls", + "hyper-util", + "rcgen", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", +] + [[package]] name = "is-terminal" version = "0.4.16" @@ -526,12 +737,53 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +dependencies = [ + "getrandom 0.3.3", + "libc", +] + [[package]] name = "js-sys" version = "0.3.77" @@ -548,12 +800,40 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[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.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "lock_api" version = "0.4.13" @@ -586,6 +866,12 @@ version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +[[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.8.9" @@ -615,6 +901,22 @@ dependencies = [ "rand 0.8.5", ] +[[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 = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "object" version = "0.36.7" @@ -630,6 +932,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + [[package]] name = "parking_lot" version = "0.12.4" @@ -650,7 +958,17 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "pem" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +dependencies = [ + "base64", + "serde", ] [[package]] @@ -718,6 +1036,12 @@ dependencies = [ "postgres-protocol", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -737,6 +1061,16 @@ dependencies = [ "log", ] +[[package]] +name = "prettyplease" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.95" @@ -820,6 +1154,19 @@ dependencies = [ "getrandom 0.3.3", ] +[[package]] +name = "rcgen" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0068c5b3cab1d4e271e0bb6539c87563c43411cad90b057b15c79958fbeb41f7" +dependencies = [ + "aws-lc-rs", + "pem", + "rustls-pki-types", + "time", + "yasna", +] + [[package]] name = "redox_syscall" version = "0.5.13" @@ -877,7 +1224,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.16", "libc", - "untrusted", + "untrusted 0.9.0", "windows-sys 0.52.0", ] @@ -887,18 +1234,171 @@ version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls" +version = "0.23.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be59af91596cac372a6942530653ad0c3a246cdd491aaa9dcaee47f88d67d5a0" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.103.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "ryu" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "safe-path" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "980abdd3220aa19b67ca3ea07b173ca36383f18ae48cde696d90c8af39447ffb" +dependencies = [ + "libc", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.219" @@ -919,6 +1419,18 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "serde_yaml_bw" version = "2.1.1" @@ -1030,13 +1542,33 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1050,6 +1582,25 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + [[package]] name = "tinyvec" version = "1.9.0" @@ -1120,6 +1671,16 @@ dependencies = [ "whoami", ] +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.15" @@ -1203,6 +1764,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" @@ -1215,6 +1782,16 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -1312,6 +1889,27 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "whoami" version = "1.6.0" @@ -1354,13 +1952,22 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[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.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1369,7 +1976,22 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[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]] @@ -1378,28 +2000,46 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[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.52.6" @@ -1412,24 +2052,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[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.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[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.52.6" @@ -1445,6 +2109,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + [[package]] name = "zerocopy" version = "0.8.26" diff --git a/Cargo.toml b/Cargo.toml index 229a6f9..03d6bfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,4 +25,9 @@ ansi_colours = "1.2.3" colour = "2.1.0" async-trait = "0.1.88" http = "1.3.1" +instant-acme = "0.8.2" +rustls = "0.23.31" +safe-path = "0.1.0" +rustls-pemfile = "2.2.0" +tokio-rustls = "0.26.2" diff --git a/src/db.rs b/src/db.rs index 3fa8d5d..1666502 100644 --- a/src/db.rs +++ b/src/db.rs @@ -5,6 +5,7 @@ use tokio_postgres::{Client, Row}; const ENDPOINT_TABLE: &str = "endpoints"; const HOSTS_RELATION_TABLE: &str = "hosts"; +const CERTIFICATES_TABLE: &str = "certs"; #[derive(Debug)] pub struct BoxyDatabase { @@ -18,6 +19,86 @@ pub struct Endpoint { pub callback: String, } +pub struct Certificate { + pub hostname: String, + pub cert_data: Vec, + pub key_data: Vec, +} + +impl Certificate { + pub async fn new(hostname: String, cert_data: Vec, key_data: Vec) -> Self { + Self { + hostname, + cert_data, + key_data, + } + } + pub async fn get_by_hostname( + db: &BoxyDatabase, + hostname: String, + ) -> Result> { + let row = db + .client + .query_one( + format!( + "SELECT * FROM {HOSTS_RELATION_TABLE} + WHERE hostname = $1" + ) + .as_str(), + &[&hostname], + ) + .await?; + + Ok(row.into()) + } + pub async fn get_all(db: &BoxyDatabase) -> Result, Box> { + let mut result: Vec = Vec::new(); + + let rows = db + .client + .query(format!("SELECT * FROM {CERTIFICATES_TABLE}").as_str(), &[]) + .await?; + + for row in rows { + result.push(row.into()); + } + + Ok(result) + } +} + +impl Certificate { + pub async fn delete(self, db: &mut BoxyDatabase) -> Result<(), tokio_postgres::Error> { + let tx = db.client.transaction().await?; + + tx.execute( + format!( + "DELETE FROM {CERTIFICATES_TABLE} + WHERE hostname = $1" + ) + .as_str(), + &[&self.hostname], + ) + .await?; + + tx.commit().await?; + + warn!("Removed certificate for host {}", self.hostname); + + Ok(()) + } +} + +impl From for Certificate { + fn from(value: Row) -> Self { + Self { + hostname: value.get("hostname"), + cert_data: value.get("certificate"), + key_data: value.get("key"), + } + } +} + impl Endpoint { pub async fn new(id: Option, address: IpAddr, port: u16, callback: String) -> Self { Self { @@ -119,7 +200,7 @@ impl Endpoint { let id = self.id.unwrap() as i32; tx.execute( - format!("DELETE FROM {ENDPOINT_TABLE} where id = $1").as_str(), + format!("DELETE FROM {ENDPOINT_TABLE} WHERE id = $1").as_str(), &[&id], ) .await?; @@ -205,6 +286,21 @@ impl BoxyDatabase { ) .await?; + c.execute( + format!( + "CREATE TABLE IF NOT EXISTS {CERTIFICATES_TABLE} + ( + hostname text PRIMARY KEY, + certificate bytea, + key bytea + ) + " + ) + .as_str(), + &[], + ) + .await?; + Ok(BoxyDatabase { client: c }) } } diff --git a/src/main.rs b/src/main.rs index b4ddad3..9967716 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod matchers; mod routes; mod server; mod services; +mod tls; use std::{env, process::exit, sync::Arc, time::Duration}; @@ -15,6 +16,7 @@ use log::{debug, error, info}; use matchers::api::ApiMatcher; use server::Server; use services::{controller::ControllerService, matcher::Matcher}; +use tls::{TlsManager, TlsOption}; use tokio::{ sync::Mutex, time::{self}, @@ -70,6 +72,7 @@ async fn main() -> Result<(), Box> { }); info!("Connected to database."); + let database = Box::new(BoxyDatabase::new(client).await.unwrap()); @@ -81,11 +84,11 @@ async fn main() -> Result<(), Box> { database: database_shared.clone(), }; - let api_server = Server::new(api_matcher.service(), (config.api.listen, config.api.port)) + let api_server = Server::new(api_matcher.service(), (config.api.listen, config.api.port), TlsOption::NoTls) .await .unwrap(); - let proxy_server = Server::new(svc, (config.proxy.listen, config.proxy.port)) + let proxy_server = Server::new(svc, (config.proxy.listen, config.proxy.port), TlsOption::Tls(TlsManager.clone)) .await .unwrap(); diff --git a/src/matchers/api.rs b/src/matchers/api.rs index 10ad87c..fe24cab 100644 --- a/src/matchers/api.rs +++ b/src/matchers/api.rs @@ -11,7 +11,7 @@ use tokio::{net::TcpStream, sync::Mutex}; use crate::{ config::{Client, Config}, db::BoxyDatabase, - routes::api::{AddHost, RegisterEndpoint, RemoveHost}, + routes::api::{AddHostToEndpoint, RegisterEndpoint, RemoveHost}, server::{GeneralResponse, custom_resp}, services::matcher::Matcher, }; @@ -119,7 +119,7 @@ impl Matcher for ApiMatcher { fn retrieve(&self) -> Vec + Sync + Send>> { vec![ Arc::new(RegisterEndpoint {}), - Arc::new(AddHost {}), + Arc::new(AddHostToEndpoint {}), Arc::new(RemoveHost {}), ] } diff --git a/src/routes/api.rs b/src/routes/api.rs index 8461fb4..bba2248 100644 --- a/src/routes/api.rs +++ b/src/routes/api.rs @@ -10,10 +10,14 @@ use crate::{ services::matcher::Route, }; -pub struct AddHost {} +pub struct LinkHost {} +pub struct UnlinkHost {} +pub struct GetHostStatus {} +pub struct RegisterEndpoint {} +pub struct DeregisterEndpoint {} #[async_trait] -impl Route for AddHost { +impl Route for LinkHost { fn matcher(&self, _: &ApiMatcher, req: &hyper::Request) -> bool { req.uri().path().starts_with("/endpoint/") && req.method() == Method::POST } @@ -63,8 +67,6 @@ impl Route for AddHost { } } -pub struct RegisterEndpoint {} - #[async_trait] impl Route for RegisterEndpoint { fn matcher(&self, _: &ApiMatcher, req: &hyper::Request) -> bool { @@ -113,10 +115,9 @@ impl Route for RegisterEndpoint { } } -pub struct RemoveHost {} #[async_trait] -impl Route for RemoveHost { +impl Route for DeregisterEndpoint { fn matcher(&self, _: &ApiMatcher, req: &hyper::Request) -> bool { req.uri().path().starts_with("/endpoint/") && req.method() == Method::DELETE } diff --git a/src/server.rs b/src/server.rs index 662bdec..db99e76 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,16 +1,26 @@ -use std::{any::type_name_of_val, error::Error}; +use std::{any::type_name_of_val, collections::HashMap, error::Error, sync::Arc}; use http_body_util::{Either, Full}; use hyper::{ Request, Response, StatusCode, body::{Body, Bytes, Incoming}, + rt::{Read, Write}, server::conn::http1, service::{HttpService, Service}, }; use hyper_util::rt::TokioIo; use json::JsonValue; use log::{error, info}; +use rustls::{ + ConfigBuilder, ServerConfig, + pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}, + server::Acceptor, + sign::SingleCertAndKey, +}; use tokio::net::{TcpListener, TcpStream}; +use tokio_rustls::{LazyConfigAcceptor, StartHandshake}; + +use crate::tls::TlsOption; pub type GeneralResponse = Response; pub type GeneralBody = Either>; @@ -23,6 +33,7 @@ pub fn to_general_response(res: Response) -> GeneralResponse { pub struct Server { listener: TcpListener, service: S, + tls: TlsOption, } pub trait TcpIntercept { @@ -59,7 +70,7 @@ pub async fn json_to_vec(v: JsonValue) -> Option> { impl Server where - S: TcpIntercept, + S: TcpIntercept + Sync, S: Service> + Clone + Send + 'static, S: HttpService + Clone + Send, ::Error: Into>, @@ -67,7 +78,7 @@ where S::ResBody: Send, >::Future: Send, { - pub async fn handle(&self) { + pub async fn handle(&'static self) { info!( "Server started at http://{} for service: {}", self.listener.local_addr().unwrap(), @@ -75,31 +86,76 @@ where ); loop { - let (stream, _) = self.listener.accept().await.unwrap(); + let (tcp_stream, _) = self.listener.accept().await.unwrap(); let mut svc_clone = self.service.clone(); - svc_clone.stream(&stream); - - let io = TokioIo::new(stream); - tokio::task::spawn(async move { - if let Err(err) = http1::Builder::new() - .writev(false) - .serve_connection(io, svc_clone) - .await - { - error!("Error while trying to serve connection: {err}") + svc_clone.stream(&tcp_stream); + + match &self.tls { + TlsOption::NoTls => { + if let Err(err) = http1::Builder::new() + .writev(false) + .serve_connection(TokioIo::new(tcp_stream), svc_clone) + .await + { + error!("Error while trying to serve connection: {err}") + }; + } + TlsOption::Tls(x) => { + let acceptor = LazyConfigAcceptor::new(Acceptor::default(), tcp_stream); + + match acceptor.await { + Ok(y) => { + let mut manager = x.lock().await; + let hello = y.client_hello(); + let hostname = hello.server_name().unwrap(); + + let raw_certificate = + manager.get_certificate(hostname.clone()).await.unwrap(); + + let cert_chain = CertificateDer::pem_slice_iter( + raw_certificate.cert_data.as_slice(), + ) + .map(|cert| cert.unwrap()) + .collect(); + + let key = PrivateKeyDer::from_pem_slice( + raw_certificate.key_data.as_slice(), + ) + .unwrap(); + + let config = ServerConfig::builder() + .with_no_client_auth() + .with_single_cert(cert_chain, key) + .unwrap(); + + let stream = y.into_stream(Arc::new(config)).await.unwrap(); + + if let Err(err) = http1::Builder::new() + .writev(false) + .serve_connection(TokioIo::new(stream), svc_clone) + .await + { + error!("Error while trying to serve connection: {err}") + } + } + Err(e) => error!("Error while initiating handshake: {e}"), + } + } }; }); } } - pub async fn new(service: S, a: (String, u16)) -> Result> { + pub async fn new(service: S, a: (String, u16), tls: TlsOption) -> Result> { Ok(Self { listener: TcpListener::bind(&a).await?, service, + tls, }) } } + /* */ diff --git a/src/tls.rs b/src/tls.rs new file mode 100644 index 0000000..e45f7b1 --- /dev/null +++ b/src/tls.rs @@ -0,0 +1,66 @@ +use std::{collections::HashMap, error::Error, sync::Arc}; + +use rustls::pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}; +use tokio::{ + fs::{self, File}, + sync::Mutex, +}; + +use crate::db::BoxyDatabase; + +pub enum TlsOption { + NoTls, + Tls(Mutex), +} + + +pub struct TlsManager { + pub certs_path: String, + pub certificates: HashMap, + pub database: Arc>, +} + +impl RawCertificate { + pub fn new(cert_data: Vec, key_data: Vec) -> Self { + Self { + cert_data, + key_data, + } + } +} + +impl TlsManager { + pub async fn get_certificate( + &mut self, + hostname: &str, + ) -> Result<&RawCertificate, Box> { + if self.certificates.contains_key(hostname) { + return Ok(self.certificates.get(hostname).unwrap()); + } + + let path_to_pem = + safe_path::scoped_join(self.certs_path.clone(), format!("{hostname}.pem"))?; + let path_to_key = + safe_path::scoped_join(self.certs_path.clone(), format!("{hostname}.key"))?; + + let cert_file = fs::read(path_to_pem).await.unwrap(); + let key_file = fs::read(path_to_key).await.unwrap(); + + self.certificates.insert( + hostname.to_string(), + RawCertificate::new(cert_file, key_file), + ); + + // fucking borrow checker + Ok(self.certificates.get(hostname).unwrap()) + } +} + +impl TlsManager { + pub async fn new(path: String) -> Self { + Self { + certs_path: path, + certificates: HashMap::new(), + } + } +}