diff --git a/.drone.yml b/.drone.yml index 8ab8205..3a41b28 100644 --- a/.drone.yml +++ b/.drone.yml @@ -12,7 +12,7 @@ steps: image: rust:1 commands: - apt-get update -y - - apt-get install -y libzmq3-dev libnftnl-dev libmnl-dev + - apt-get install -y libnftnl-dev libmnl-dev - cargo build --verbose --all - cargo test --verbose --all volumes: @@ -28,7 +28,7 @@ steps: image: rust:1 commands: - apt-get update -y - - apt-get install -y libzmq3-dev libnftnl-dev libmnl-dev + - apt-get install -y libnftnl-dev libmnl-dev - cargo build --release --verbose --all - cd target/release - tar -czvf ipblc-${DRONE_TAG}-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}.tar.gz ipblc @@ -77,7 +77,7 @@ steps: image: rust:1 commands: - apt-get update -y - - apt-get install -y libzmq3-dev libnftnl-dev libmnl-dev + - apt-get install -y libnftnl-dev libmnl-dev - cargo build --verbose --all - cargo test --verbose --all volumes: @@ -93,7 +93,7 @@ steps: image: rust:1 commands: - apt-get update -y - - apt-get install -y libzmq3-dev libnftnl-dev libmnl-dev + - apt-get install -y libnftnl-dev libmnl-dev - cargo build --release --verbose --all - cd target/release - tar -czvf ipblc-${DRONE_TAG}-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}.tar.gz ipblc diff --git a/Cargo.lock b/Cargo.lock index 221e30b..5e9c3eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,13 +4,19 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -22,42 +28,51 @@ dependencies = [ [[package]] name = "anstream" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", + "anstyle-query", "anstyle-wincon", - "concolor-override", - "concolor-query", + "colorchoice", "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "0.3.5" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] [[package]] -name = "anstyle-wincon" -version = "0.2.0" +name = "anstyle-query" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -68,9 +83,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.21.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "bitflags" @@ -79,10 +94,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bumpalo" -version = "3.12.0" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" @@ -95,18 +125,6 @@ name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cfg-expr" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35b255461940a32985c627ce82900867c61db1659764d3675ea81963f72a4c6" -dependencies = [ - "smallvec", -] [[package]] name = "cfg-if" @@ -116,13 +134,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "serde", "time", @@ -132,18 +150,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.1" +version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" +checksum = "2686c4115cb0810d9a984776e197823d08ec94f176549a89a9efded477c456dc" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.2.1" +version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +checksum = "2e53afce1efce6ed1f633cf0e57612fe51db54a1ee4fd8f8503d078fe02d69ae" dependencies = [ "anstream", "anstyle", @@ -154,169 +172,67 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[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 = "concolor-override" +name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] -name = "concolor-query" -version = "0.3.3" +name = "core-foundation" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "windows-sys", + "core-foundation-sys", + "libc", ] [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] -name = "crossbeam" -version = "0.8.2" +name = "cpufeatures" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ - "cfg-if", - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", + "libc", ] [[package]] -name = "crossbeam-channel" -version = "0.5.7" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "cfg-if", - "crossbeam-utils", + "generic-array", + "typenum", ] [[package]] -name = "crossbeam-deque" -version = "0.8.3" +name = "data-encoding" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", + "block-buffer", + "crypto-common", ] -[[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 = "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.13", -] - -[[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.13", -] - -[[package]] -name = "dircpy" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b6622b9d0dc20c70e74ff24c56493278d7d9299ac8729deb923703616e5a7e" -dependencies = [ - "jwalk", - "log", - "walkdir", -] - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - [[package]] name = "encoding_rs" version = "0.8.32" @@ -342,13 +258,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -369,9 +285,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -415,6 +331,27 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "git-version" version = "0.3.5" @@ -439,9 +376,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.16" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ "bytes", "fnv", @@ -462,12 +399,6 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "hermit-abi" version = "0.2.6" @@ -519,9 +450,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.25" +version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ "bytes", "futures-channel", @@ -543,9 +474,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" dependencies = [ "http", "hyper", @@ -556,9 +487,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.54" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -570,19 +501,18 @@ dependencies = [ [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] name = "idna" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -600,13 +530,13 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -626,7 +556,7 @@ dependencies = [ "serde", "serde_json", "tokio", - "zmq", + "tungstenite", ] [[package]] @@ -637,14 +567,14 @@ checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" [[package]] name = "is-terminal" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -653,34 +583,15 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" -[[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" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jwalk" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dbcda57db8b6dc067e589628b7348639014e793d9e8137d8cf215e8b133a0bd" -dependencies = [ - "crossbeam", - "rayon", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -689,30 +600,21 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.140" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" - -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -720,12 +622,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "memchr" @@ -742,15 +641,6 @@ 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" @@ -759,14 +649,13 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mio" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -822,21 +711,11 @@ dependencies = [ "bitflags", "cfg-if", "libc", - "memoffset 0.7.1", + "memoffset", "pin-utils", "static_assertions", ] -[[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-traits" version = "0.2.15" @@ -858,9 +737,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "parking_lot" @@ -874,22 +759,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-targets", ] [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" @@ -905,9 +790,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-error" @@ -941,58 +832,66 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.55" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] [[package]] -name = "rayon" -version = "1.7.0" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "either", - "rayon-core", + "libc", + "rand_chacha", + "rand_core", ] [[package]] -name = "rayon-core" -version = "1.11.0" +name = "rand_chacha" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.7.3" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick", "memchr", @@ -1001,15 +900,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "reqwest" -version = "0.11.16" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64", "bytes", @@ -1061,28 +960,40 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.6" +version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.20.8" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" dependencies = [ "log", "ring", + "rustls-webpki", "sct", - "webpki", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", ] [[package]] @@ -1094,6 +1005,16 @@ dependencies = [ "base64", ] +[[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" @@ -1107,12 +1028,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] -name = "same-file" -version = "1.0.6" +name = "schannel" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "winapi-util", + "windows-sys 0.42.0", ] [[package]] @@ -1121,12 +1042,6 @@ 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" @@ -1138,45 +1053,59 @@ dependencies = [ ] [[package]] -name = "serde" -version = "1.0.159" +name = "security-framework" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +dependencies = [ + "bitflags", + "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.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.18", ] [[package]] name = "serde_json" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" dependencies = [ "itoa", "ryu", "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1189,6 +1118,17 @@ dependencies = [ "serde", ] +[[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 = "signal-hook-registry" version = "1.4.1" @@ -1254,9 +1194,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.13" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -1276,25 +1216,23 @@ dependencies = [ ] [[package]] -name = "system-deps" -version = "6.0.4" +name = "thiserror" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555fc8147af6256f3931a36bb83ad0023240ce9cf2b319dec8236fd1f220b05f" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ - "cfg-expr", - "heck", - "pkg-config", - "toml", - "version-compare", + "thiserror-impl", ] [[package]] -name = "termcolor" -version = "1.2.0" +name = "thiserror-impl" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ - "winapi-util", + "proc-macro2", + "quote", + "syn 2.0.18", ] [[package]] @@ -1325,9 +1263,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.27.0" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", "bytes", @@ -1339,36 +1277,35 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.18", ] [[package]] name = "tokio-rustls" -version = "0.23.4" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls", "tokio", - "webpki", ] [[package]] name = "tokio-util" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -1378,40 +1315,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - [[package]] name = "tower-service" version = "0.3.2" @@ -1431,9 +1334,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] @@ -1444,6 +1347,34 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "tungstenite" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "rustls", + "rustls-native-certs", + "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" @@ -1452,9 +1383,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-normalization" @@ -1465,12 +1396,6 @@ dependencies = [ "tinyvec", ] -[[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" @@ -1485,50 +1410,39 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "version-compare" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "walkdir" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -1546,9 +1460,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1556,24 +1470,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.18", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -1583,9 +1497,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1593,28 +1507,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.18", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -1655,15 +1569,6 @@ 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" @@ -1672,35 +1577,50 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.46.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ "windows-targets", ] [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +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.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "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]] @@ -1709,36 +1629,72 @@ 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" @@ -1746,13 +1702,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] -name = "winnow" -version = "0.4.1" +name = "windows_x86_64_msvc" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" -dependencies = [ - "memchr", -] +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winreg" @@ -1762,35 +1715,3 @@ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ "winapi", ] - -[[package]] -name = "zeromq-src" -version = "0.2.5+4.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53aaa8119f753d047dc5a9dbcc720bf720b466fdf859aaaae8638f3afc1a3564" -dependencies = [ - "cc", - "dircpy", -] - -[[package]] -name = "zmq" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd3091dd571fb84a9b3e5e5c6a807d186c411c812c8618786c3c30e5349234e7" -dependencies = [ - "bitflags", - "libc", - "zmq-sys", -] - -[[package]] -name = "zmq-sys" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8351dc72494b4d7f5652a681c33634063bbad58046c1689e75270908fdc864" -dependencies = [ - "libc", - "system-deps", - "zeromq-src", -] diff --git a/Cargo.toml b/Cargo.toml index 1c1c511..074b9ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,32 +10,22 @@ repository = "https://git.paulbsd.com/paulbsd/ipblc" [dependencies] chrono = { version = "0.4", features = ["serde"] } -clap = { version = "4.0", features = ["string"] } -git-version = "0.3.5" +clap = { version = "4.2", features = ["string"] } +git-version = "0.3" ipnet = "2.7" lazy_static = "1.4" mnl = "0.2" nftnl = "0.6" nix = "0.26" -regex = "1.7" +regex = "1.8" reqwest = { version = "0.11", default-features = false, features = ["json","rustls-tls"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.23", features = ["full"] } -zmq = "0.10" +tokio = { version = "1.28", features = ["full", "sync"] } +tungstenite = { version = "0.19", features = ["handshake","rustls-tls-native-roots"] } -# [target.aarch64-unknown-linux-gnu.dependencies] -# flate2 = { version = "1.0", features = ["cloudflare_zlib"] } - -# [target.aarch64-linux-android.dependencies] -# flate2 = { version = "1.0", features = ["zlib"] } - -# [target.armv7-unknown-linux-gnueabihf.dependencies] -# flate2 = { version = "1.0", features = ["zlib"] } - -# [target.x86_64-unknown-linux-gnu.dependencies] -# flate2 = { version = "1.0", features = ["cloudflare_zlib"] } - -[profile.release] -debug = false -opt-level = 3 \ No newline at end of file +## to optimize binary size (slow compile time) +#[profile.release] +#strip = true +#lto = true +#opt-level = "z" diff --git a/NOTES.md b/NOTES.md new file mode 100644 index 0000000..c05ec58 --- /dev/null +++ b/NOTES.md @@ -0,0 +1,10 @@ +# Notes + +### Date formats + +``` +nginx: 2006-01-02T15:04:05+01:00 +ssh: 2006-01-02T15:04:05.000000+01:00 +openvpn: 2006-01-02 15:04:05 +mail: 2006-01-02T15:04:05.000000+01:00 +``` \ No newline at end of file diff --git a/README.md b/README.md index 1d15cba..6341e20 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,15 @@ cargo build --release ### Usage ``` -USAGE: - ipblc [OPTIONS] +ipblc is a tool that search and send attacking ip addresses to ipbl -OPTIONS: - -d Enable debugging - -h, --help Print help information - -s, --server Sets a ipbl server [default: https://ipbl.paulbsd.com] - -V, --version Print version informatio +Usage: ipblc [OPTIONS] + +Options: + -s, --server Sets a http server [default: https://ipbl.paulbsd.com] + -d Enable debugging + -h, --help Print help information + -V, --version Print version information ``` ### TODO @@ -44,20 +45,19 @@ OPTIONS: - ✅ Handle zeromq data transfer - ✅ Code optimizations (WIP) - ✅ Error handing when fetching config +- ✅ Local bound tcp api socket +- ✅ ZMQ -> Websocket +- ✅ Bug in RwLocks (agent often give up) -### Date formats -``` -nginx: 2006-01-02T15:04:05+01:00 -ssh: 2006-01-02T15:04:05.000000+01:00 -openvpn: 2006-01-02 15:04:05 -mail: 2006-01-02T15:04:05.000000+01:00 -``` +### Notes + +See [here](NOTES.md) ## License ```text -Copyright (c) 2021, 2022 PaulBSD +Copyright (c) 2021, 2022, 2023 PaulBSD All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/old/zmqcom.rs b/old/zmqcom.rs new file mode 100644 index 0000000..90582f5 --- /dev/null +++ b/old/zmqcom.rs @@ -0,0 +1,106 @@ +use crate::config::{Context, ZMQCfg}; +use crate::ip::IpEvent; +use crate::utils::gethostname; + +use std::sync::Arc; +use tokio::sync::mpsc::Sender; +use tokio::sync::RwLock; + +const ZMQPROTO: &str = "tcp"; + +pub async fn zconnect<'a>( + zmqcfg: &ZMQCfg, + zmqtype: zmq::SocketType, +) -> Result { + let zctx = zmq::Context::new(); + let zmqhost = &zmqcfg.hostname; + let zmqport = &zmqcfg.port; + let socket = zctx.socket(zmqtype).unwrap(); + let connectstring = format!("{ZMQPROTO}://{zmqhost}:{zmqport}"); + socket.connect(&connectstring.as_str())?; + Ok(socket) +} + +pub async fn zmqinit(ctx: &Arc>, ipeventtx: &Sender) -> zmq::Socket { + let ctxarc = Arc::clone(&ctx); + + let zmqreqsocket; + let zmqsubsocket; + { + let zmqctx = ctxarc.read().await; + zmqreqsocket = zconnect(&zmqctx.cfg.zmq.get("reqrep").unwrap(), zmq::REQ) + .await + .unwrap(); + zmqsubsocket = zconnect(&zmqctx.cfg.zmq.get("pubsub").unwrap(), zmq::SUB) + .await + .unwrap(); + } + + listenpubsub(&ctx, ipeventtx.clone(), zmqsubsocket).await; + return zmqreqsocket; +} + +async fn listenpubsub(ctx: &Arc>, txpubsub: Sender, socket: zmq::Socket) { + let prefix; + { + let ctx = ctx.read().await; + prefix = format!( + "{sub} ", + sub = ctx.cfg.zmq.get("pubsub").unwrap().subscription + ); + socket + .set_subscribe(ctx.cfg.zmq.get("pubsub").unwrap().subscription.as_bytes()) + .expect("failed setting subscription"); + } + + tokio::spawn(async move { + loop { + let msgs: Option = match socket.recv_string(0) { + Ok(s) => match s { + Ok(ss) => Some(ss), + Err(e) => { + println!("{e:?}"); + None + } + }, + Err(e) => { + println!("{e:?}"); + None + } + }; + match msgs { + Some(ss) => { + let msg = ss.strip_prefix(prefix.as_str()).unwrap(); + let tosend: IpEvent = serde_json::from_str(msg).unwrap(); + if tosend.ipdata.hostname != gethostname(true) + || tosend.msgtype == "init".to_string() + { + txpubsub.send(tosend).await.unwrap(); + } + } + None => {} + }; + } + }); +} + +pub async fn send_to_ipbl_zmq(reqsocket: &zmq::Socket, ip: &IpEvent, _ret: &mut Vec) { + let msg = format!("{val}", val = serde_json::to_string(&ip).unwrap()); + match reqsocket.send(&msg, 0) { + Ok(_) => {} + Err(e) => { + println!("{e:?}") + } + }; + match reqsocket.recv_string(0) { + Ok(o) => match o { + Ok(_) => {} + Err(ee) => { + println!("{ee:?}") + } + }, + Err(e) => { + println!("{e:?}") + } + }; +} diff --git a/scripts/upgrade.sh b/scripts/upgrade.sh new file mode 100755 index 0000000..c516e0a --- /dev/null +++ b/scripts/upgrade.sh @@ -0,0 +1,6 @@ +#!/bin/sh +git pull +cargo b --release +sudo systemctl stop ipblc +sudo cp target/release/ipblc /usr/local/apps/ipblc/ipblc +sudo systemctl start ipblc diff --git a/src/config.rs b/src/config.rs index c351594..3f58aff 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use crate::ip::{BlockIpData, IpData}; +use crate::ip::{BlockIpData, IpData, IpEvent}; use crate::utils::{gethostname, sleep_s}; use chrono::prelude::*; @@ -16,17 +16,16 @@ use std::path::Path; pub const GIT_VERSION: &str = git_version!(); const MASTERSERVER: &str = "ipbl.paulbsd.com"; -const ZMQSUBSCRIPTION: &str = "ipbl"; -const CONFIG_RETRY: u64 = 10; +const WSSUBSCRIPTION: &str = "ipbl"; +const CONFIG_RETRY: u64 = 1; +const WEB_CLIENT_TIMEOUT: i64 = 5; #[derive(Debug, Clone)] pub struct Context { pub blocklist: HashMap, pub cfg: Config, - pub client: Client, pub discovery: Discovery, pub flags: Flags, - pub hostname: String, pub instance: Box, pub sas: HashMap, pub hashwd: HashMap, @@ -49,10 +48,9 @@ pub struct Flags { } impl Context { - pub async fn new<'a>() -> Self { + pub async fn new() -> Self { // Get flags let argp: ArgMatches = Context::argparse(); - //let debug: bool = argp.contains_id("debug"); let debug: bool = argp.get_one::("debug").unwrap().to_owned(); let server: String = argp.get_one::("server").unwrap().to_string(); @@ -60,43 +58,23 @@ impl Context { let mut ctx = Context { cfg: Config::new(), flags: Flags { debug, server }, - hostname: gethostname(true), discovery: Discovery { version: "1.0".to_string(), urls: HashMap::new(), }, - client: Client::builder() - .user_agent(format!( - "{}/{}@{}/{}", - env!("CARGO_PKG_NAME"), - env!("CARGO_PKG_VERSION"), - GIT_VERSION, - gethostname(false) - )) - .build() - .unwrap(), sas: HashMap::new(), instance: Box::new(Inotify::init(InitFlags::empty()).unwrap()), blocklist: HashMap::new(), hashwd: HashMap::new(), }; - loop { - print!("Loading config ... "); - match ctx.load().await { - Ok(_) => { - break; - } - Err(err) => { - println!("error loading config: {err}, retrying in {CONFIG_RETRY} secs"); - sleep_s(CONFIG_RETRY); - } - } - } + print!("Loading config ... "); + ctx.load().await.unwrap(); + ctx } - pub fn argparse<'a>() -> ArgMatches { + pub fn argparse() -> ArgMatches { Command::new(env!("CARGO_PKG_NAME")) .version(format!("{}@{}", env!("CARGO_PKG_VERSION"), GIT_VERSION)) .author(env!("CARGO_PKG_AUTHORS")) @@ -118,9 +96,9 @@ impl Context { .get_matches() } + #[allow(dead_code)] pub async fn discovery(&self) -> Result { - let resp: Result = self - .client + let resp: Result = httpclient() .get(format!("{server}/discovery", server = self.flags.server)) .send() .await; @@ -139,9 +117,30 @@ impl Context { if cfg!(test) { return Ok(()); } - self.discovery = self.discovery().await?; - self.cfg.load(self.to_owned()).await?; + let mut last_in_err = false; + loop { + let res = self.cfg.load(&self.flags.server).await; + match res { + Ok(()) => { + if last_in_err { + println!("loaded config"); + } + break; + } + Err(err) => { + println!("error loading config: {err}, retrying in {CONFIG_RETRY} secs"); + last_in_err = true; + sleep_s(CONFIG_RETRY).await; + } + }; + } + if last_in_err { + println!("creating sas"); + } self.create_sas().await?; + if last_in_err { + println!("created sas"); + } Ok(()) } @@ -156,43 +155,49 @@ impl Context { pub async fn get_blocklist_toblock(&mut self) -> Vec { let mut res: Vec = vec![]; - let now: DateTime = Local::now().trunc_subsecs(0); for (_, block) in self.blocklist.iter_mut() { - let set = self.cfg.sets.get(&block.ipdata.src.to_string()).unwrap(); - if block.tryfail >= set.tryfail { - res.push(block.ipdata.clone()); - if block.tryfail == set.tryfail { - block.starttime = DateTime::from(now); + match self.cfg.sets.get(&block.ipdata.src) { + Some(set) => { + if block.tryfail >= set.tryfail { + res.push(block.ipdata.clone()); + } } + None => {} } } res } - pub async fn update_blocklist(&mut self, ipdata: &mut IpData) -> Option { - match self.cfg.sets.get(&ipdata.src) { + pub async fn update_blocklist(&mut self, ipevent: &IpEvent) -> Option { + match self.cfg.sets.get(&ipevent.ipdata.src) { Some(set) => { - if self.blocklist.contains_key(&ipdata.ip) - && self.hostname == ipdata.hostname - && ipdata.mode == "file".to_string() - { - let mut block = self.blocklist.get_mut(&ipdata.ip).unwrap(); + let starttime = DateTime::parse_from_rfc3339(ipevent.ipdata.date.as_str()) + .unwrap() + .with_timezone(&chrono::Local); + let blocktime = set.blocktime; + if ipevent.mode == "file".to_string() && gethostname(true) == ipevent.hostname { + let block = self + .blocklist + .entry(ipevent.ipdata.ip.to_string()) + .or_insert(BlockIpData { + ipdata: ipevent.ipdata.clone(), + tryfail: 0, + starttime, + blocktime, + }); block.tryfail += 1; - block.blocktime = set.blocktime; + block.blocktime = blocktime; if block.tryfail >= set.tryfail { - return Some(block.ipdata.clone()); + return Some(ipevent.clone()); } } else { - let starttime = DateTime::parse_from_rfc3339(ipdata.date.as_str()) - .unwrap() - .with_timezone(&chrono::Local); self.blocklist - .entry(ipdata.ip.to_string()) + .entry(ipevent.ipdata.ip.to_string()) .or_insert(BlockIpData { - ipdata: ipdata.clone(), - tryfail: 100, + ipdata: ipevent.ipdata.clone(), + tryfail: set.tryfail, starttime, - blocktime: set.blocktime, + blocktime, }); } } @@ -205,8 +210,15 @@ impl Context { let mut removed: Vec = vec![]; let now: DateTime = Local::now().trunc_subsecs(0); // nightly, future use - //let drained: HashMap = ctx.blocklist.drain_filter(|k,v| v.parse_date() < mindate) + // let drained: HashMap = ctx.blocklist.drain_filter(|k,v| v.parse_date() < mindate) for (ip, blocked) in self.blocklist.clone().iter() { + /*match self.cfg.sets.get(&blocked.ipdata.src) { + Some(set) => { + let mut block = self.blocklist.get_mut(ip).unwrap(); + block.blocktime = set.blocktime.clone(); + } + None => {} + }*/ let mindate = now - Duration::minutes(blocked.blocktime); if blocked.starttime < mindate { self.blocklist.remove(&ip.clone()).unwrap(); @@ -273,7 +285,8 @@ pub struct Config { pub sets: HashMap, #[serde(skip_serializing)] pub trustnets: Vec, - pub zmq: HashMap, + pub ws: HashMap, + pub api: String, } impl Config { @@ -323,34 +336,59 @@ impl Config { "172.16.0.0/12".to_string(), "192.168.0.0/16".to_string(), ], - zmq: HashMap::from([("pubsub".to_string(),ZMQ{ + ws: HashMap::from([("pubsub".to_string(),WebSocketCfg{ t: "pubsub".to_string(), - hostname: MASTERSERVER.to_string(), - port: 9999, - subscription: ZMQSUBSCRIPTION.to_string(), - }),("reqrep".to_string(),ZMQ { + endpoint: format!("wss://{}/wsps", MASTERSERVER.to_string()), + subscription: WSSUBSCRIPTION.to_string(), + }),("reqrep".to_string(), WebSocketCfg { t: "reqrep".to_string(), - hostname: MASTERSERVER.to_string(), - port: 9998, - subscription: String::new(), - })]) + endpoint: format!("wss://{}/wsrr", MASTERSERVER.to_string()), + subscription: WSSUBSCRIPTION.to_string(), + })]), + api: String::from("127.0.0.1:8060") } } - pub async fn load(&mut self, ctx: Context) -> Result<(), ReqError> { - self.get_trustnets(&ctx).await?; - self.get_sets(&ctx).await?; - self.get_zmq_config(&ctx).await?; + pub async fn load(&mut self, server: &String) -> Result<(), ReqError> { + self.get_global_config(server).await?; + self.get_trustnets(server).await?; + self.get_sets(server).await?; + self.get_ws_config(server).await?; Ok(()) } - async fn get_trustnets(&mut self, ctx: &Context) -> Result<(), ReqError> { - let resp: Result = ctx - .client - .get(format!( - "{server}/config/trustlist", - server = ctx.flags.server - )) + async fn get_global_config(&mut self, server: &String) -> Result<(), ReqError> { + let resp: Result = + httpclient().get(format!("{server}/config")).send().await; + let req = match resp { + Ok(re) => re, + Err(err) => return Err(err), + }; + let data: HashMap = match req.json::>().await { + Ok(res) => { + let mut out: HashMap = HashMap::new(); + res.into_iter().map(|x| x).for_each(|x| { + out.insert(x.key.to_string(), x); + }); + out + } + Err(err) => return Err(err), + }; + let key = "".to_string(); + self.api = data + .get(&key.to_string()) + .unwrap_or(&GlobalConfig { + key: "api".to_string(), + value: "127.0.0.1:8060".to_string(), + }) + .value + .clone(); + Ok(()) + } + + async fn get_trustnets(&mut self, server: &String) -> Result<(), ReqError> { + let resp: Result = httpclient() + .get(format!("{server}/config/trustlist")) .send() .await; let req = match resp { @@ -365,10 +403,9 @@ impl Config { Ok(()) } - async fn get_sets(&mut self, ctx: &Context) -> Result<(), ReqError> { - let resp: Result = ctx - .client - .get(format!("{server}/config/sets", server = ctx.flags.server)) + async fn get_sets(&mut self, server: &String) -> Result<(), ReqError> { + let resp: Result = httpclient() + .get(format!("{server}/config/sets")) .send() .await; let req = match resp { @@ -385,19 +422,16 @@ impl Config { Ok(()) } - async fn get_zmq_config(&mut self, ctx: &Context) -> Result<(), ReqError> { - let resp: Result = ctx - .client - .get(format!("{server}/config/zmq", server = ctx.flags.server)) - .send() - .await; + async fn get_ws_config(&mut self, server: &String) -> Result<(), ReqError> { + let resp: Result = + httpclient().get(format!("{server}/config/ws")).send().await; let req = match resp { Ok(re) => re, Err(err) => return Err(err), }; - let data: HashMap = match req.json::>().await { + let data: HashMap = match req.json::>().await { Ok(res) => { - let mut out: HashMap = HashMap::new(); + let mut out: HashMap = HashMap::new(); res.into_iter().map(|x| x).for_each(|x| { out.insert(x.t.to_string(), x); }); @@ -405,7 +439,7 @@ impl Config { } Err(err) => return Err(err), }; - self.zmq = data; + self.ws = data; Ok(()) } @@ -421,6 +455,41 @@ impl Config { } trustnets } + + pub fn bootstrap_event(&self) -> IpEvent { + IpEvent { + msgtype: String::from("bootstrap"), + mode: String::from("ws"), + hostname: gethostname(true), + ipdata: IpData { + ip: "".to_string(), + src: "".to_string(), + date: "".to_string(), + hostname: "".to_string(), + }, + } + } +} + +pub fn httpclient() -> Client { + let client = Client::builder() + .user_agent(format!( + "{}/{}@{}/{}", + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION"), + GIT_VERSION, + gethostname(false) + )) + .timeout(Duration::seconds(WEB_CLIENT_TIMEOUT).to_std().unwrap()) + .build() + .unwrap(); + client +} + +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct GlobalConfig { + pub key: String, + pub value: String, } #[derive(Debug, Deserialize, Serialize, Clone)] @@ -434,11 +503,10 @@ pub struct Set { } #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct ZMQ { +pub struct WebSocketCfg { #[serde(rename = "type")] pub t: String, - pub hostname: String, - pub port: i64, + pub endpoint: String, pub subscription: String, } @@ -478,51 +546,71 @@ mod test { ctx.blocklist = HashMap::new(); for _i in 0..10 { - ctx.update_blocklist(&mut IpData { - ip: "1.1.1.1".to_string(), - hostname: "test1".to_string(), - date: now.to_rfc3339().to_string(), - src: "ssh".to_string(), - mode: "file".to_string(), + ctx.update_blocklist(&mut IpEvent { + msgtype: String::from("add"), + mode: String::from("ws"), + hostname: String::from("localhost"), + ipdata: IpData { + ip: "1.1.1.1".to_string(), + hostname: "test1".to_string(), + date: now.to_rfc3339().to_string(), + src: "ssh".to_string(), + }, }) .await; } for _ in 0..10 { - ctx.update_blocklist(&mut IpData { - ip: "1.1.1.2".to_string(), - hostname: "test2".to_string(), - date: now.to_rfc3339().to_string(), - src: "http".to_string(), - mode: "file".to_string(), + ctx.update_blocklist(&mut IpEvent { + msgtype: String::from("add"), + mode: String::from("ws"), + hostname: String::from("localhost"), + ipdata: IpData { + ip: "1.1.1.2".to_string(), + hostname: "test2".to_string(), + date: now.to_rfc3339().to_string(), + src: "http".to_string(), + }, }) .await; } - ctx.update_blocklist(&mut IpData { - ip: "1.1.1.3".to_string(), - hostname: "testgood".to_string(), - date: now.to_rfc3339().to_string(), - src: "http".to_string(), - mode: "file".to_string(), + ctx.update_blocklist(&mut IpEvent { + msgtype: String::from("add"), + mode: String::from("ws"), + hostname: String::from("localhost"), + ipdata: IpData { + ip: "1.1.1.3".to_string(), + hostname: "testgood".to_string(), + date: now.to_rfc3339().to_string(), + src: "http".to_string(), + }, }) .await; - ctx.update_blocklist(&mut IpData { - ip: "1.1.1.4".to_string(), - hostname: "testgood".to_string(), - date: now.to_rfc3339().to_string(), - src: "http".to_string(), - mode: "file".to_string(), + ctx.update_blocklist(&mut IpEvent { + msgtype: String::from("add"), + mode: String::from("ws"), + hostname: String::from("localhost"), + ipdata: IpData { + ip: "1.1.1.4".to_string(), + hostname: "testgood".to_string(), + date: now.to_rfc3339().to_string(), + src: "http".to_string(), + }, }) .await; - ctx.update_blocklist(&mut IpData { - ip: "1.1.1.4".to_string(), - hostname: "testgood".to_string(), - date: now.to_rfc3339().to_string(), - src: "http".to_string(), - mode: "file".to_string(), + ctx.update_blocklist(&mut IpEvent { + msgtype: String::from("add"), + mode: String::from("ws"), + hostname: String::from("localhost"), + ipdata: IpData { + ip: "1.1.1.4".to_string(), + hostname: "testgood".to_string(), + date: now.to_rfc3339().to_string(), + src: "http".to_string(), + }, }) .await; diff --git a/src/fw.rs b/src/fw.rs index 983bf5e..b08f219 100644 --- a/src/fw.rs +++ b/src/fw.rs @@ -1,15 +1,13 @@ use crate::ip::IpData; +use crate::ipblc::PKG_NAME; use nftnl::{nft_expr, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table}; use std::{ffi::CString, io::Error, net::Ipv4Addr}; -pub fn init(tablename: &String) -> (Batch, Table) { +pub fn fwinit() -> (Batch, Table) { let mut batch = Batch::new(); - let table = Table::new( - &CString::new(tablename.as_str()).unwrap(), - ProtoFamily::Ipv4, - ); + let table = Table::new(&CString::new(PKG_NAME).unwrap(), ProtoFamily::Ipv4); batch.add(&table, nftnl::MsgType::Add); batch.add(&table, nftnl::MsgType::Del); @@ -18,18 +16,17 @@ pub fn init(tablename: &String) -> (Batch, Table) { (batch, table) } -pub fn block( - tablename: &String, +pub fn fwblock( ips_add: &Vec, ret: &mut Vec, fwlen: &mut usize, ) -> std::result::Result<(), Error> { // convert chain let ips_add = convert(ips_add); - let (mut batch, table) = init(tablename); + let (mut batch, table) = fwinit(); // build chain - let mut chain = Chain::new(&CString::new(tablename.as_str()).unwrap(), &table); + let mut chain = Chain::new(&CString::new(PKG_NAME).unwrap(), &table); chain.set_hook(nftnl::Hook::In, 1); chain.set_policy(nftnl::Policy::Accept); diff --git a/src/ip.rs b/src/ip.rs index f5f029f..acfe6c3 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -1,4 +1,4 @@ -use crate::config::Context; +use crate::config::httpclient; use crate::utils::gethostname; use chrono::prelude::*; @@ -18,13 +18,20 @@ lazy_static! { static ref R_DATE: Regex = Regex::new(include_str!("regexps/date.txt")).unwrap(); } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct IpEvent { + pub msgtype: String, + pub mode: String, + pub hostname: String, + pub ipdata: IpData, +} + #[derive(Clone, Debug, Serialize, Deserialize, Eq)] pub struct IpData { pub ip: String, pub src: String, pub date: String, pub hostname: String, - pub mode: String, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -60,89 +67,18 @@ impl Display for IpData { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { write!( f, - "ip: {ip}, src: {src}, date: {date}, hostname: {hostname}, mode: {mode}", + "ip: {ip}, src: {src}, date: {date}, hostname: {hostname}", ip = self.ip, src = self.src, date = self.date, hostname = self.hostname, - mode = self.mode, ) } } -pub async fn push_ip(ctx: &Context, ip: &IpData, ret: &mut Vec) -> Result<(), ReqError> { - let result: String; - let mut data: Vec = vec![]; - - data.push(IpData { - ip: ip.ip.to_string(), - src: ip.src.to_string(), - date: ip.date.to_string(), - hostname: ip.hostname.to_string(), - mode: "file".to_string(), - }); - - let resp = ctx - .client - .post(format!("{server}/ips", server = ctx.flags.server)) - .json(&data) - .send() - .await?; - ret.push(format!("status: {status}", status = resp.status())); - - let res = resp.text().await.unwrap(); - - if res.trim().len() > 0 { - result = res.trim().to_string(); - } else { - result = "".to_string(); - } - - ret.push(format!("response: {result}")); - Ok(()) -} - -pub async fn _push_ip_bulk( - ctx: &Context, - ips: &Vec, - ret: &mut Vec, -) -> Result<(), ReqError> { - let result: String; - let mut data: Vec = vec![]; - - for ip in ips { - data.push(IpData { - ip: ip.ip.to_string(), - src: ip.src.to_string(), - date: ip.date.to_string(), - hostname: ip.hostname.to_string(), - mode: "file".to_string(), - }) - } - - let resp = ctx - .client - .post(format!("{server}/ips", server = ctx.flags.server)) - .json(&data) - .send() - .await?; - ret.push(format!("status: {status}", status = resp.status())); - - let res = resp.text().await.unwrap(); - - if res.trim().len() > 0 { - result = res.trim().to_string(); - } else { - result = "".to_string(); - } - - ret.push(format!("response: {result}")); - Ok(()) -} - pub fn filter( lines: Box, - list: &mut Vec, + iplist: &mut Vec, trustnets: &Vec, regex: &Regex, src: &String, @@ -193,12 +129,11 @@ pub fn filter( }; if !is_trusted(&ipaddr, &trustnets) { - list.push(IpData { + iplist.push(IpData { ip: s_ipaddr, src: src.to_owned(), date: s_date.to_rfc3339().to_owned(), hostname: hostname.to_owned(), - mode: "file".to_owned(), }); ips += 1; }; @@ -222,8 +157,15 @@ fn parse_date(input: regex::Captures) -> DateTime { } let date = Local - .ymd(ymd[0] as i32, ymd[1] as u32, ymd[2] as u32) - .and_hms(hms[0] as u32, hms[1] as u32, hms[2] as u32); + .with_ymd_and_hms( + ymd[0] as i32, + ymd[1] as u32, + ymd[2] as u32, + hms[0] as u32, + hms[1] as u32, + hms[2] as u32, + ) + .unwrap(); date } @@ -236,10 +178,9 @@ fn is_trusted(ip: &IpAddr, trustnets: &Vec) -> bool { false } -pub async fn _get_last(ctx: &Context) -> Result, ReqError> { - let resp = ctx - .client - .get(format!("{server}/ips/last", server = ctx.flags.server)) +pub async fn _get_last(server: &String) -> Result, ReqError> { + let resp = httpclient() + .get(format!("{server}/ips/last")) .query(&[("interval", "3 hours")]) .send() .await; diff --git a/src/ipblc.rs b/src/ipblc.rs index 055bc6b..b31d6d8 100644 --- a/src/ipblc.rs +++ b/src/ipblc.rs @@ -1,8 +1,10 @@ use crate::config::{Context, GIT_VERSION}; -use crate::fw::{block, init}; -use crate::ip::{filter, push_ip, IpData}; +use crate::fw::{fwblock, fwinit}; +use crate::ip::{filter, IpData, IpEvent}; +use crate::monitoring::apiserver; use crate::utils::{gethostname, read_lines, sleep_s}; -use crate::zmqcom::zconnect; +use crate::webservice::send_to_ipbl_api; +use crate::websocket::{send_to_ipbl_websocket, websocketpubsub, websocketreqrep}; use chrono::prelude::*; use chrono::prelude::{DateTime, Local}; @@ -11,126 +13,167 @@ use nix::sys::inotify::InotifyEvent; use std::collections::HashMap; use std::sync::Arc; use tokio::sync::mpsc::{channel, Receiver, Sender}; -use tokio::sync::Mutex; +use tokio::sync::RwLock; +pub const PKG_NAME: &str = env!("CARGO_PKG_NAME"); const BL_CHAN_SIZE: usize = 32; -const ZMQ_CHAN_SIZE: usize = 64; +const WS_CHAN_SIZE: usize = 64; +const LOOP_MAX_WAIT: u64 = 5; pub async fn run() { - let ctx = Arc::new(Mutex::new(Context::new().await)); - println!( - "Launching {}, version {}", - env!("CARGO_PKG_NAME"), - format!("{}@{}", env!("CARGO_PKG_VERSION"), GIT_VERSION) - ); - - let (ipdatatx, mut ipdatarx): (Sender, Receiver) = channel(ZMQ_CHAN_SIZE); - - // initialize the firewall table - init(&env!("CARGO_PKG_NAME").to_string()); + let globalctx = Context::new().await; + let ctxarc = Arc::new(RwLock::new(globalctx)); let mut fwlen: usize = 0; - // initialize zeromq sockets - let reqsocket; - let subsocket; - { - let ctxarc = Arc::clone(&ctx); - let zmqctx = ctxarc.lock().await; - reqsocket = zconnect(&zmqctx.cfg.zmq.get("reqrep").unwrap(), zmq::REQ) - .await - .unwrap(); - subsocket = zconnect(&zmqctx.cfg.zmq.get("pubsub").unwrap(), zmq::SUB) - .await - .unwrap(); - } + let pkgversion = format!("{}@{}", env!("CARGO_PKG_VERSION"), GIT_VERSION); - listenpubsub(&ctx, ipdatatx.clone(), subsocket).await; + let mut last_cfg_reload: DateTime = Local::now().trunc_subsecs(0); + println!("Launching {}, version {}", PKG_NAME, pkgversion); + fwinit(); - let mut blrx = watchfiles(&ctx).await; + let ctxapi = Arc::clone(&ctxarc); + apiserver(&ctxapi).await.unwrap(); - let ctxarc = Arc::clone(&ctx); + // initialize sockets + let (ipeventtx, mut ipeventrx): (Sender, Receiver) = channel(WS_CHAN_SIZE); + let ipeventtxarc = Arc::new(RwLock::new(ipeventtx)); + + // init pubsub + let ctxwsps = Arc::clone(&ctxarc); + let ipeventws = Arc::clone(&ipeventtxarc); + websocketpubsub(&ctxwsps, ipeventws).await; + + let ctxwsrr = Arc::clone(&ctxarc); + let mut wssocketrr = websocketreqrep(&ctxwsrr).await; + + // init file watcher + let mut blrx = watchfiles(&ctxarc).await; + + let ctxclone = Arc::clone(&ctxarc); + let ipeventclone = Arc::clone(&ipeventtxarc); tokio::spawn(async move { - compare_files_changes(&ctxarc, &mut blrx, &ipdatatx).await; + compare_files_changes(&ctxclone, &mut blrx, &ipeventclone).await; }); - let mut ip_init = IpData { - ip: "".to_string(), - src: "".to_string(), - date: "".to_string(), - hostname: "".to_string(), - mode: "init".to_string(), - }; - send_to_ipbl_zmq(&reqsocket, &mut ip_init).await; - loop { let mut ret: Vec = Vec::new(); - let begin: DateTime = Local::now().trunc_subsecs(0); - // wait for logs parse and zmq channel receive - let mut received_ip = ipdatarx.recv().await.unwrap(); + let ctxclone = Arc::clone(&ctxarc); - // lock the context mutex - let ctxarc = Arc::clone(&ctx); - let mut ctx = ctxarc.lock().await; + tokio::select! { + ipevent = ipeventrx.recv() => { + let received_ip = ipevent.unwrap(); - if received_ip.ip == "".to_string() && received_ip.mode == "init".to_string() { - for ip_to_send in &mut ctx.get_blocklist_toblock().await { - ip_to_send.mode = "init".to_string(); - send_to_ipbl_zmq(&reqsocket, ip_to_send).await; + let (toblock,server); + { + let mut ctx = ctxclone.write().await; + toblock = ctx.get_blocklist_toblock().await; + server = ctx.flags.server.clone(); + } + + if received_ip.msgtype == "bootstrap".to_string() { + for ip_to_send in toblock { + let ipe = IpEvent{ + msgtype: String::from("init"), + mode: String::from("ws"), + hostname: gethostname(true), + ipdata: ip_to_send, + }; + if !send_to_ipbl_websocket(&mut wssocketrr, &ipe).await { + wssocketrr = websocketreqrep(&ctxwsrr).await; + break; + } + } + continue + } + + // refresh context blocklist + let filtered_ipevent; + { + let mut ctx = ctxarc.write().await; + filtered_ipevent = ctx.update_blocklist(&received_ip).await; + } + + // send ip list to api and ws sockets + if let Some(ipevent) = filtered_ipevent { + if received_ip.msgtype != "init" { + println!("sending {} to api and ws", ipevent.ipdata.ip); + let ipe = IpEvent{ + msgtype: String::from("add"), + mode: String::from("ws"), + hostname: gethostname(true), + ipdata: ipevent.ipdata, + }; + send_to_ipbl_api(&server.clone(), &ipe).await; + let status = send_to_ipbl_websocket(&mut wssocketrr, &ipe).await; + if !status { + wssocketrr = websocketreqrep(&ctxwsrr).await; + continue; + } + } + } } - continue; - } + _val = sleep_s(LOOP_MAX_WAIT) => {} + }; - // refresh context blocklist - let filtered_ip = ctx.update_blocklist(&mut received_ip).await; - ctx.gc_blocklist().await; - - // send ip list to ws and zmq sockets - if let Some(mut ip) = filtered_ip { - send_to_ipbl_ws(&ctx, &mut ip, &mut ret).await; - send_to_ipbl_zmq(&reqsocket, &mut ip).await; - } - - // apply firewall blocking - block( - &env!("CARGO_PKG_NAME").to_string(), - &ctx.get_blocklist_toblock().await, - &mut ret, - &mut fwlen, - ) - .unwrap(); + let ctxclone = Arc::clone(&ctxarc); + handle_fwblock(ctxclone, &mut ret, &mut fwlen).await; // log lines if ret.len() > 0 { println!("{ret}", ret = ret.join(", ")); } - let end: DateTime = Local::now().trunc_subsecs(0); - if (end - begin) > Duration::seconds(5) { - // reload configuration from the server - match ctx.load().await { - Ok(_) => {} - Err(err) => { - println!("error loading config: {err}"); - } - } - } + let ctxclone = Arc::clone(&ctxarc); + handle_cfg_reload(&ctxclone, &mut last_cfg_reload).await; } } -async fn watchfiles(ctx: &Arc>) -> Receiver { +async fn handle_cfg_reload(ctxclone: &Arc>, last_cfg_reload: &mut DateTime) { + let now_cfg_reload = Local::now().trunc_subsecs(0); + if (now_cfg_reload - *last_cfg_reload) > Duration::seconds(LOOP_MAX_WAIT as i64) { + let mut ctx = ctxclone.write().await; + match ctx.load().await { + Ok(_) => { + *last_cfg_reload = Local::now().trunc_subsecs(0); + } + Err(_) => { + println!("error reloading config"); + } + } + }; +} + +async fn handle_fwblock(ctxclone: Arc>, ret: &mut Vec, fwlen: &mut usize) { + let toblock = { + let mut ctx = ctxclone.write().await; + ctx.gc_blocklist().await; + ctx.get_blocklist_toblock().await + }; + + // apply firewall blocking + match fwblock(&toblock, ret, fwlen) { + Ok(_) => {} + Err(err) => { + println!("Err: {err}, unable to push firewall rules, use super user") + } + }; +} + +async fn watchfiles(ctxarc: &Arc>) -> Receiver { let (bltx, blrx): (Sender, Receiver) = channel(BL_CHAN_SIZE); - let ctx = Arc::clone(ctx); + let ctxclone = Arc::clone(ctxarc); tokio::spawn(async move { loop { - let events: Vec; + let events; + let instance; { - let c = ctx.lock().await; - let instance = c.instance.clone(); - drop(c); - events = instance.read_events().unwrap(); + let ctx = ctxclone.read().await; + instance = ctx.instance.clone(); } + events = instance.read_events().unwrap(); + for inevent in events { let date: DateTime = Local::now().trunc_subsecs(0); bltx.send(FileEvent { inevent, date }).await.unwrap(); @@ -153,23 +196,29 @@ async fn get_last_file_size(w: &mut HashMap, path: &str) -> (u64, b } async fn compare_files_changes( - ctx: &Arc>, + ctxarc: &Arc>, inrx: &mut Receiver, - ipdatatx: &Sender, + ipeventtx: &Arc>>, ) { let mut tnets; loop { let modfiles = inrx.recv().await.unwrap(); let mut iplist: Vec = vec![]; - let mut ctx = ctx.lock().await; - tnets = ctx.cfg.build_trustnets(); + let sask; + let sas; + { + let ctx = ctxarc.read().await; + sas = ctx.clone().sas; + sask = sas.keys(); + tnets = ctx.cfg.build_trustnets(); + } match modfiles.inevent.name { Some(name) => { let filename = name.to_str().unwrap(); - for sak in &mut ctx.clone().sas.keys() { - let sa = &mut ctx.sas.get_mut(sak).unwrap(); + for sak in sask { + let sa = sas.get(sak).unwrap(); if modfiles.inevent.wd == sa.wd { let handle: String; if sa.filename.as_str() == "" { @@ -180,8 +229,13 @@ async fn compare_files_changes( continue; } - let (filesize, sizechanged) = - get_last_file_size(&mut sa.watchedfiles, &handle).await; + let (filesize, sizechanged); + { + let mut ctx = ctxarc.write().await; + let sa = ctx.sas.get_mut(sak).unwrap(); + (filesize, sizechanged) = + get_last_file_size(&mut sa.watchedfiles, &handle).await; + } if !sizechanged { continue; @@ -204,7 +258,14 @@ async fn compare_files_changes( } } for ip in iplist { - ipdatatx.send(ip).await.unwrap(); + let ipevent = IpEvent { + msgtype: String::from("add"), + hostname: gethostname(true), + mode: String::from("file"), + ipdata: ip, + }; + let ipetx = ipeventtx.write().await; + ipetx.send(ipevent).await.unwrap(); } } None => {} @@ -222,79 +283,3 @@ impl std::fmt::Debug for FileEvent { write!(f, "{ie:?}", ie = self.inevent) } } - -async fn send_to_ipbl_zmq(reqsocket: &zmq::Socket, ip: &mut IpData) { - let msg = format!("{val}", val = serde_json::to_string(&ip).unwrap()); - match reqsocket.send(&msg, 0) { - Ok(_) => {} - Err(e) => { - println!("{e:?}") - } - }; - match reqsocket.recv_string(0) { - Ok(o) => match o { - Ok(_) => {} - Err(ee) => { - println!("{ee:?}") - } - }, - Err(e) => { - println!("{e:?}") - } - }; -} - -async fn send_to_ipbl_ws(ctx: &Context, ip: &mut IpData, ret: &mut Vec) { - ret.push(format!("host: {hostname}", hostname = ctx.hostname)); - loop { - match push_ip(&ctx, &ip, ret).await { - Ok(_) => { - break; - } - Err(err) => { - println!("{err}"); - sleep_s(1); - } - }; - } -} - -async fn listenpubsub(ctx: &Arc>, txpubsub: Sender, socket: zmq::Socket) { - let ctx = ctx.lock().await; - let prefix = format!( - "{sub} ", - sub = ctx.cfg.zmq.get("pubsub").unwrap().subscription - ); - socket - .set_subscribe(ctx.cfg.zmq.get("pubsub").unwrap().subscription.as_bytes()) - .expect("failed setting subscription"); - drop(ctx); - - tokio::spawn(async move { - loop { - let msgs: Option = match socket.recv_string(0) { - Ok(s) => match s { - Ok(ss) => Some(ss), - Err(e) => { - println!("{e:?}"); - None - } - }, - Err(e) => { - println!("{e:?}"); - None - } - }; - match msgs { - Some(ss) => { - let msg = ss.strip_prefix(prefix.as_str()).unwrap(); - let tosend: IpData = serde_json::from_str(msg).unwrap(); - if tosend.hostname != gethostname(true) || tosend.mode == "init".to_string() { - txpubsub.send(tosend).await.unwrap(); - } - } - None => {} - }; - } - }); -} diff --git a/src/main.rs b/src/main.rs index 30c6b8e..9b36929 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,12 @@ mod config; mod fw; mod ip; mod ipblc; +mod monitoring; mod utils; -mod zmqcom; +mod webservice; +mod websocket; #[tokio::main] pub async fn main() { - // Create a new context ipblc::run().await; } diff --git a/src/monitoring.rs b/src/monitoring.rs new file mode 100644 index 0000000..90b5b10 --- /dev/null +++ b/src/monitoring.rs @@ -0,0 +1,57 @@ +use crate::config::Context; + +use serde_json; +use std::io; +use std::sync::Arc; +use tokio::io::AsyncWriteExt; +use tokio::net::TcpSocket; +use tokio::sync::RwLock; + +pub async fn apiserver(ctxarc: &Arc>) -> io::Result<()> { + let ctxarc = ctxarc.clone(); + let addr; + { + let ctx = ctxarc.read().await; + addr = ctx.cfg.api.parse().unwrap(); + } + + let socket = TcpSocket::new_v4().unwrap(); + socket.bind(addr).unwrap(); + socket.set_reuseaddr(true).unwrap(); + let listener = socket.listen(1024).unwrap(); + + tokio::spawn(async move { + loop { + //apitx.send(String::from("")).await.unwrap(); + match listener.accept().await { + Ok((stream, _addr)) => { + //let mut buf = [0; 1024]; + let data; + { + let ctx = ctxarc.read().await; + data = serde_json::to_string(&ctx.blocklist); + } + + match data { + Ok(dt) => { + let (_reader, mut writer) = stream.into_split(); + match writer.write_all(format!("{dt}").as_bytes()).await { + Ok(_) => {} + Err(err) => { + println!("{err}"); + } + } + } + Err(err) => { + println!("unable to serialize data: {err}"); + } + } + } + Err(err) => { + println!("couldn't get client: {}", err) + } + } + } + }); + Ok(()) +} diff --git a/src/utils.rs b/src/utils.rs index d16b248..3b754ca 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -5,7 +5,7 @@ use std::boxed::Box; use std::fs::File; use std::io::*; use std::path::Path; -use std::time::Duration; +use tokio::time::{sleep, Duration}; lazy_static! { static ref R_FILE_GZIP: Regex = Regex::new(r".*\.gz.*").unwrap(); @@ -33,12 +33,12 @@ pub fn _dedup(list: &mut Vec) -> usize { list.len() } -pub fn _sleep_ms(ms: u64) { - std::thread::sleep(Duration::from_millis(ms)); +pub async fn _sleep_ms(ms: u64) { + sleep(Duration::from_millis(ms)).await; } -pub fn sleep_s(s: u64) { - std::thread::sleep(Duration::from_secs(s)); +pub async fn sleep_s(s: u64) { + sleep(Duration::from_secs(s)).await; } pub fn gethostname(show_fqdn: bool) -> String { diff --git a/src/webservice.rs b/src/webservice.rs new file mode 100644 index 0000000..48891f8 --- /dev/null +++ b/src/webservice.rs @@ -0,0 +1,83 @@ +use crate::config::{httpclient, Context}; +use crate::ip::{IpData, IpEvent}; +use crate::utils::sleep_s; + +use reqwest::Client; +use reqwest::Error as ReqError; + +const MAX_FAILED_API_RATE: u64 = 10; + +pub async fn send_to_ipbl_api(server: &str, ip: &IpEvent) { + let mut try_req = 0; + let client = httpclient(); + loop { + match push_ip(&client, &server, &ip.ipdata).await { + Ok(_) => { + break; + } + Err(err) => { + println!("{err}"); + sleep_s(1).await; + if try_req == MAX_FAILED_API_RATE { + break; + } + try_req += 1; + } + }; + } +} + +async fn push_ip(client: &Client, server: &str, ip: &IpData) -> Result<(), ReqError> { + let mut data: Vec = vec![]; + + data.push(IpData { + ip: ip.ip.to_string(), + src: ip.src.to_string(), + date: ip.date.to_string(), + hostname: ip.hostname.to_string(), + }); + + client + .post(format!("{server}/ips")) + .json(&data) + .send() + .await?; + + Ok(()) +} + +async fn _push_ip_bulk( + ctx: &Context, + ips: &Vec, + ret: &mut Vec, +) -> Result<(), ReqError> { + let result: String; + let mut data: Vec = vec![]; + + for ip in ips { + data.push(IpData { + ip: ip.ip.to_string(), + src: ip.src.to_string(), + date: ip.date.to_string(), + hostname: ip.hostname.to_string(), + }) + } + + let resp = httpclient() + .post(format!("{server}/ips", server = ctx.flags.server)) + .json(&data) + .send() + .await?; + ret.push(format!("status: {status}", status = resp.status())); + + let res = resp.text().await.unwrap(); + + if res.trim().len() > 0 { + result = res.trim().to_string(); + } else { + result = "".to_string(); + } + + ret.push(format!("response: {result}")); + Ok(()) +} diff --git a/src/websocket.rs b/src/websocket.rs new file mode 100644 index 0000000..596b3f3 --- /dev/null +++ b/src/websocket.rs @@ -0,0 +1,134 @@ +use crate::config::{Context, WebSocketCfg}; +use crate::ip::IpEvent; +use crate::utils::{gethostname, sleep_s}; + +use serde_json::json; +use std::io::{self, Write}; +use std::net::TcpStream; +use std::sync::Arc; +use tokio::sync::mpsc::Sender; +use tokio::sync::RwLock; +use tungstenite::stream::*; +use tungstenite::*; + +pub async fn websocketreqrep( + ctxarc: &Arc>, +) -> WebSocket> { + let (mut wssocketrr, bootstrap_event, cfg); + { + let ctx = ctxarc.read().await; + bootstrap_event = ctx.cfg.bootstrap_event().clone(); + cfg = ctx.cfg.ws.get("reqrep").unwrap().clone(); + } + wssocketrr = websocketconnect(&cfg, &gethostname(true)).await.unwrap(); + send_to_ipbl_websocket(&mut wssocketrr, &bootstrap_event).await; + + return wssocketrr; +} + +pub async fn websocketpubsub( + ctxarc: &Arc>, + txpubsub: Arc>>, +) { + let cfg; + { + let ctx = ctxarc.read().await; + cfg = ctx.cfg.ws.get("pubsub").unwrap().clone(); + } + let mut websocket = Arc::new(RwLock::new( + websocketconnect(&cfg, &gethostname(true)).await.unwrap(), + )); + tokio::spawn(async move { + loop { + let mut ws = websocket.write().await; + match ws.read_message() { + Ok(msg) => { + let tosend: IpEvent = match serde_json::from_str(msg.to_string().as_str()) { + Ok(o) => o, + Err(_e) => { + continue; + } + }; + if tosend.ipdata.hostname != gethostname(true) + || tosend.msgtype == "init".to_string() + { + let txps = txpubsub.write().await; + txps.send(tosend).await.unwrap(); + } + } + Err(e) => { + println!("error in pubsub: {e:?}"); + ws.close(None).unwrap(); + drop(ws); + websocket = Arc::new(RwLock::new( + websocketconnect(&cfg, &gethostname(true)).await.unwrap(), + )); + } + }; + } + }); +} + +pub async fn websocketconnect<'a>( + wscfg: &WebSocketCfg, + hostname: &String, +) -> Result>, Error> { + let endpoint = &wscfg.endpoint; + print!("connecting to {} ... ", endpoint); + io::stdout().flush().unwrap(); + let mut socket; + loop { + (socket, _) = match connect(endpoint) { + Ok((o, e)) => (o, e), + _ => { + println!("error connecting to {endpoint}, retrying"); + sleep_s(1).await; + continue; + } + }; + break; + } + println!("connected to {endpoint}"); + let msg = json!({ "hostname": hostname }); + socket + .write_message(Message::Text(msg.to_string())) + .unwrap(); + Ok(socket) +} + +pub async fn send_to_ipbl_websocket( + ws: &mut WebSocket>, + ip: &IpEvent, +) -> bool { + let msg = format!("{val}", val = serde_json::to_string(&ip).unwrap()); + + if ws.can_write() { + match ws.write_message(Message::Text(msg)) { + Ok(_) => {} + Err(e) => { + println!("err send read: {e:?}"); + return handle_websocket_error(ws); + } + }; + } else { + return handle_websocket_error(ws); + }; + + if ws.can_read() { + match ws.read_message() { + Ok(_) => {} + Err(e) => { + println!("err send read: {e:?}"); + return handle_websocket_error(ws); + } + }; + } else { + return handle_websocket_error(ws); + }; + true +} + +fn handle_websocket_error(ws: &mut WebSocket>) -> bool { + ws.close(None).unwrap(); + return false; +} diff --git a/src/zmqcom.rs b/src/zmqcom.rs deleted file mode 100644 index 7733ca9..0000000 --- a/src/zmqcom.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::config::ZMQ; - -const ZMQPROTO: &str = "tcp"; - -pub async fn zconnect(zmqcfg: &ZMQ, zmqtype: zmq::SocketType) -> Result { - let zctx = zmq::Context::new(); - let zmqhost = &zmqcfg.hostname; - let zmqport = &zmqcfg.port; - let socket = zctx.socket(zmqtype).unwrap(); - let connectstring = format!("{ZMQPROTO}://{zmqhost}:{zmqport}"); - socket.connect(&connectstring.as_str())?; - Ok(socket) -}