diff --git a/Cargo.lock b/Cargo.lock index 149d518..3608cbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,14 +5,29 @@ name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bumpalo" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cc" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -33,6 +48,58 @@ name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "futures-core" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hermit-abi" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "js-sys" +version = "0.3.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -40,7 +107,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.66" +version = "0.2.73" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "mio" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-uds" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "net2" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "once_cell" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -52,7 +195,7 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -61,7 +204,7 @@ name = "openssl-src" version = "111.6.1+1.1.1d" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -70,41 +213,319 @@ version = "0.9.53" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-src 111.6.1+1.1.1d (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pin-project-lite" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pkg-config" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "proc-macro2" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ring" +version = "0.16.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustls" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)", + "sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sct" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "syn" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-macros" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-rustls" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "vcpkg" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "wasm-bindgen" +version = "0.2.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.65" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "web-sys" +version = "0.3.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "webpki" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "wireguard-proxy" version = "0.1.0" dependencies = [ + "base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +"checksum base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" +"checksum bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" +"checksum bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" +"checksum cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" +"checksum hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" +"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +"checksum js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" +"checksum libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)" = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9" +"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +"checksum mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)" = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +"checksum mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" +"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +"checksum once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" "checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585" "checksum openssl-src 111.6.1+1.1.1d (registry+https://github.com/rust-lang/crates.io-index)" = "c91b04cb43c1a8a90e934e0cd612e2a5715d976d2d6cff4490278a0cddf35005" "checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" +"checksum pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" +"checksum proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" +"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +"checksum ring 0.16.15 (registry+https://github.com/rust-lang/crates.io-index)" = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4" +"checksum rustls 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac94b333ee2aac3284c5b8a1b7fb4dd11cba88c244e3fe33cdbd047af0eb693" +"checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" +"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +"checksum syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0" +"checksum tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" +"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +"checksum tokio-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "228139ddd4fea3fa345a29233009635235833e52807af7ea6448ead03890d6a9" +"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +"checksum untrusted 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" "checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" +"checksum wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d" +"checksum wasm-bindgen-backend 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d" +"checksum wasm-bindgen-macro 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e" +"checksum wasm-bindgen-macro-support 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6" +"checksum wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87" +"checksum web-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2" +"checksum webpki 0.21.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/Cargo.toml b/Cargo.toml index 7d04a58..85d85bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,18 @@ include = [ ] [features] -default = [] +default = ["async"] tls = ["openssl"] openssl_vendored = ["openssl/vendored"] verbose = [] +async = ["tokio", "tokio-rustls", "ring", "base64"] [dependencies] +# only for non-async build with TLS support openssl = { version = "0.10.26", optional = true } +# the rest of these are only required for async build +tokio = { version = "0.2", features = [ "macros", "net", "udp", "io-std", "io-util", "rt-threaded" ], optional = true } +tokio-rustls = { version = "0.14", features = ["dangerous_configuration"], optional = true } +# probably should try to keep ring the exact same version as rustls, same features too +ring = { version = "0.16.11", optional = true } +base64 = { version = "0.12.3", optional = true } diff --git a/README.md b/README.md index fe07a99..e19ddea 100644 --- a/README.md +++ b/README.md @@ -75,9 +75,10 @@ Binaries: Building: -- `cargo build --release` - minimal build without TLS support, no dependencies -- `cargo build --release --feature tls` - links to system openssl -- `cargo build --release --feature openssl_vendored` - compiles vendored openssl and link to it +- `cargo build --release` - async build with TLS support supplied by rustls +- `cargo build --release --no-default-features ` - minimal build without TLS support, no dependencies +- `cargo build --release --no-default-features --feature tls` - links to system openssl +- `cargo build --release --no-default-features --feature openssl_vendored` - compiles vendored openssl and link to it Testing: diff --git a/src/asyncmod.rs b/src/asyncmod.rs new file mode 100644 index 0000000..75fc4c9 --- /dev/null +++ b/src/asyncmod.rs @@ -0,0 +1,304 @@ + +use tokio::net::UdpSocket; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::runtime::Runtime; +use tokio_rustls::webpki::DNSNameRef; + +use crate::error; +use crate::error::Result; +use crate::*; + +pub struct TcpUdpPipe { + buf: [u8; 2050], // 2048 + 2 for len + tcp_stream: T, + udp_socket: UdpSocket, +} + +impl TcpUdpPipe { + + pub fn new(tcp_stream: T, udp_socket: UdpSocket) -> TcpUdpPipe { + TcpUdpPipe { + tcp_stream, + udp_socket, + buf: [0u8; 2050], + } + } + + pub async fn shuffle_after_first_udp(mut self) -> Result { + let (len, src_addr) = self.udp_socket.recv_from(&mut self.buf[2..]).await?; + + println!("first packet from {}, connecting to that", src_addr); + self.udp_socket.connect(src_addr).await?; + + send_udp(&mut self.buf, &mut self.tcp_stream, len).await?; + + self.shuffle().await + } + + pub async fn shuffle(self) -> Result { + // todo: investigate https://docs.rs/tokio/0.2.22/tokio/net/struct.TcpStream.html#method.into_split + let (mut tcp_rd, mut tcp_wr) = tokio::io::split(self.tcp_stream); + let (mut udp_rd, mut udp_wr) = self.udp_socket.split(); + let mut recv_buf = self.buf.clone(); // or zeroed or? + + tokio::spawn(async move { + loop { + let len = udp_rd.recv(&mut recv_buf[2..]).await?; + send_udp(&mut recv_buf, &mut tcp_wr, len).await?; + } + + // Sometimes, the rust type inferencer needs + // a little help + #[allow(unreachable_code)] + { + unsafe { std::hint::unreachable_unchecked(); } + Ok::<_, error::Error>(()) + } + }); + + let mut send_buf = self.buf.clone(); // or zeroed or? + + loop { + tcp_rd.read_exact(&mut send_buf[..2]).await?; + let len = ((send_buf[0] as usize) << 8) + send_buf[1] as usize; + #[cfg(feature = "verbose")] + println!("tcp expecting len: {}", len); + tcp_rd.read_exact(&mut send_buf[..len]).await?; + #[cfg(feature = "verbose")] + println!("tcp got len: {}", len); + udp_wr.send(&send_buf[..len]).await?; + } + + #[allow(unreachable_code)] + { + unsafe { std::hint::unreachable_unchecked(); } + Ok(0) + } + } +} + +async fn send_udp(buf: &mut [u8; 2050], tcp_stream: &mut T, len: usize) -> Result<()> { + #[cfg(feature = "verbose")] + println!("udp got len: {}", len); + + buf[0] = ((len >> 8) & 0xFF) as u8; + buf[1] = (len & 0xFF) as u8; + + // todo: tcp_stream.write_all(&buf[..len + 2]).await + Ok(tcp_stream.write_all(&buf[..len + 2]).await?) + // todo: do this? self.tcp_stream.flush() +} + +impl ProxyClient { + + pub async fn start_async(&self) -> Result { + let tcp_stream = self.tcp_connect()?; + + let udp_socket = self.udp_connect()?; + + TcpUdpPipe::new(tokio::net::TcpStream::from_std(tcp_stream).expect("how could this tokio tcp fail?"), UdpSocket::from_std(udp_socket).expect("how could this tokio udp fail?")) + .shuffle_after_first_udp().await + } + + pub fn start(&self) -> Result { + let mut rt = Runtime::new()?; + + rt.block_on(async { + self.start_async().await + }) + } + + pub async fn start_tls_async(&self, hostname: Option<&str>, pinnedpubkey: Option<&str>) -> Result { + let tcp_stream = self.tcp_connect()?; + let tcp_stream = tokio::net::TcpStream::from_std(tcp_stream).expect("how could this tokio tcp fail?"); + + use tokio_rustls::{ TlsConnector, rustls::ClientConfig }; + + let mut config = ClientConfig::new(); + config.dangerous().set_certificate_verifier(match pinnedpubkey { + Some(pinnedpubkey) => Arc::new(PinnedpubkeyCertVerifier { pinnedpubkey: pinnedpubkey.to_owned() }), + None => Arc::new(DummyCertVerifier{}), + }); + + let hostname = match hostname { + Some(hostname) => match DNSNameRef::try_from_ascii_str(hostname) { + Ok(hostname) => hostname, + Err(_) => { + config.enable_sni = false; + DNSNameRef::try_from_ascii_str(&"dummy.hostname").unwrap() // why does rustls ABSOLUTELY REQUIRE this ???? + } + }, + None => { + config.enable_sni = false; + DNSNameRef::try_from_ascii_str(&"dummy.hostname").unwrap() // why does rustls ABSOLUTELY REQUIRE this ???? + } + }; + //println!("hostname: {:?}", hostname); + + let connector = TlsConnector::from(Arc::new(config)); + + let tcp_stream= connector.connect(hostname, tcp_stream).await?; + + let udp_socket = self.udp_connect()?; + + // we want to wait for first udp packet from client first, to set the target to respond to + TcpUdpPipe::new(tcp_stream, UdpSocket::from_std(udp_socket).expect("how could this tokio udp fail?")) + .shuffle_after_first_udp().await + } + + pub fn start_tls(&self, hostname: Option<&str>, pinnedpubkey: Option<&str>) -> Result { + let mut rt = Runtime::new()?; + + rt.block_on(async { + self.start_tls_async(hostname, pinnedpubkey).await + }) + } +} + +use tokio_rustls::rustls; +use tokio_rustls::webpki; + +struct DummyCertVerifier; + +impl rustls::ServerCertVerifier for DummyCertVerifier { + fn verify_server_cert(&self, + _roots: &rustls::RootCertStore, + _certs: &[rustls::Certificate], + _hostname: webpki::DNSNameRef<'_>, + _ocsp: &[u8]) -> core::result::Result { + // verify nothing, subject to MITM + Ok(rustls::ServerCertVerified::assertion()) + } +} + +struct PinnedpubkeyCertVerifier { + pinnedpubkey: String, +} + +impl rustls::ServerCertVerifier for PinnedpubkeyCertVerifier { + fn verify_server_cert(&self, + _roots: &rustls::RootCertStore, + certs: &[rustls::Certificate], + _hostname: webpki::DNSNameRef<'_>, + _ocsp: &[u8]) -> core::result::Result { + if certs.is_empty() { + return Err(rustls::TLSError::NoCertificatesPresented); + } + let cert = webpki::trust_anchor_util::cert_der_as_trust_anchor(&certs[0].0) + .map_err(rustls::TLSError::WebPKIError)?; + + //println!("spki.len(): {}", cert.spki.len()); + //println!("spki: {:?}", cert.spki); + // todo: what is wrong with webpki? it returns *almost* the right answer but missing these leading bytes: + // guess I'll open an issue... (I assume this is some type of algorithm identifying header or something) + let mut pubkey: Vec = vec![48, 130, 1, 34]; + pubkey.extend(cert.spki); + + let pubkey = ring::digest::digest(&ring::digest::SHA256, &pubkey); + let pubkey = base64::encode(pubkey); + let pubkey = ["sha256//", &pubkey].join(""); + + for key in self.pinnedpubkey.split(";") { + if key == pubkey { + return Ok(rustls::ServerCertVerified::assertion()); + } + } + + Err(rustls::TLSError::General(format!("pubkey '{}' not found in allowed list '{}'", pubkey, self.pinnedpubkey))) + } +} + +impl ProxyServer { + + pub async fn start_async(&self) -> Result<()> { + let mut listener = tokio::net::TcpListener::bind(&self.tcp_host).await?; + println!("Listening for connections on {}", &self.tcp_host); + + loop { + let (stream, _) = listener.accept().await?; + let client_handler = self.client_handler.clone(); + tokio::spawn(async move { + client_handler + .handle_client_async(stream).await + .expect("error handling connection"); + }); + } + + #[allow(unreachable_code)] + { + unsafe { std::hint::unreachable_unchecked(); } + Ok(()) + } + } + + pub fn start(&self) -> Result<()> { + let mut rt = Runtime::new()?; + + rt.block_on(async { + self.start_async().await + }) + } + + pub async fn start_tls_async(&self, tls_key: &str, tls_cert: &str) -> Result<()> { + + use std::fs::File; + use std::io::BufReader; + use std::io; + use tokio_rustls::rustls::internal::pemfile::{ certs, pkcs8_private_keys }; + + let mut tls_key = pkcs8_private_keys(&mut BufReader::new(File::open(tls_key)?)) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))?; + if tls_key.is_empty() { + return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))?; + } + let tls_key = tls_key.remove(0); + + let tls_cert = certs(&mut BufReader::new(File::open(tls_cert)?)) + .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))?; + + let mut config = rustls::ServerConfig::new(rustls::NoClientAuth::new()); + config.set_single_cert(tls_cert, tls_key) + .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?; + let acceptor = tokio_rustls::TlsAcceptor::from(Arc::new(config)); + + let mut listener = tokio::net::TcpListener::bind(&self.tcp_host).await?; + println!("Listening for TLS connections on {}", &self.tcp_host); + + loop { + let (stream, _) = listener.accept().await?; + let client_handler = self.client_handler.clone(); + let acceptor = acceptor.clone(); + + tokio::spawn(async move { + let stream = acceptor.accept(stream).await.expect("failed to wrap with TLS?"); + + client_handler + .handle_client_async(stream).await + .expect("error handling connection"); + }); + } + + #[allow(unreachable_code)] + { + unsafe { std::hint::unreachable_unchecked(); } + Ok(()) + } + } + + pub fn start_tls(&self, tls_key: &str, tls_cert: &str) -> Result<()> { + let mut rt = Runtime::new()?; + + rt.block_on(async { + self.start_tls_async(tls_key, tls_cert).await + }) + } +} + +impl ProxyServerClientHandler { + + pub async fn handle_client_async(&self, tcp_stream: T) -> Result { + TcpUdpPipe::new(tcp_stream, + UdpSocket::from_std(self.udp_bind()?).expect("how could this tokio udp fail?") + ).shuffle().await + } +} \ No newline at end of file diff --git a/src/bin/wireguard-proxy.rs b/src/bin/wireguard-proxy.rs index ef3e7b9..0f43d86 100644 --- a/src/bin/wireguard-proxy.rs +++ b/src/bin/wireguard-proxy.rs @@ -7,11 +7,13 @@ fn main() { if args.flag("-V") || args.flag("--version") { print!("wireguard-proxy {} ", env!("CARGO_PKG_VERSION")); - #[cfg(not(any(feature = "tls", feature = "openssl_vendored")))] + #[cfg(not(any(feature = "tls", feature = "openssl_vendored", feature = "async")))] println!("TLS support: None"); - #[cfg(feature = "openssl_vendored")] + #[cfg(feature = "async")] + println!("TLS support: tokio-rustls"); + #[cfg(all(feature = "openssl_vendored", not(feature = "async")))] println!("TLS support: Static/Vendored OpenSSL"); - #[cfg(feature = "tls")] + #[cfg(all(feature = "tls", not(feature = "openssl_vendored"), not(feature = "async")))] println!("TLS support: System OpenSSL"); return; } diff --git a/src/error.rs b/src/error.rs index d6f713d..1f84545 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,7 +1,6 @@ use core::result; -use std::error::Error as StdError; - +#[cfg(not(any(feature = "async")))] pub type IoResult = result::Result; pub type Result = result::Result; @@ -32,7 +31,7 @@ impl std::error::Error for Error { impl From for Error { fn from(value: std::io::Error) -> Self { - Error::new(value.description()) + Error::new(&format!("{}", value)) } } diff --git a/src/lib.rs b/src/lib.rs index 3adb5e3..61e4fa1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,29 +1,11 @@ -use std::io::{Read, Write}; -use std::net::{TcpListener, TcpStream, UdpSocket}; +use std::net::{TcpStream, UdpSocket}; use std::str::FromStr; use std::sync::Arc; -use std::thread; use std::time::Duration; mod error; use error::Result; -#[cfg(any(feature = "tls", feature = "openssl_vendored"))] -#[path = ""] -mod tls { - pub mod openssl; - pub use crate::tls::openssl::{TlsStream, TlsListener}; -} - -#[cfg(not(any(feature = "tls", feature = "openssl_vendored")))] -#[path = ""] -mod tls { - pub mod notls; - pub use crate::tls::notls::{TlsStream, TlsListener}; -} - -use tls::{TlsStream, TlsListener}; - fn arg_to_env(arg: &str) -> Option { if !arg.starts_with("--") { return None; @@ -41,7 +23,6 @@ fn env_for_arg(arg: &str) -> Option { #[cfg(test)] mod tests { use super::*; - #[test] fn test_arg_to_env() { assert_eq!(arg_to_env("--tcp-host"), Some("WGP_TCP_HOST".to_owned())); @@ -107,89 +88,41 @@ impl<'a> Args<'a> { } } -pub struct TcpUdpPipe + Send + 'static> { - buf: [u8; 2050], // 2048 + 2 for len - tcp_stream: T, - udp_socket: UdpSocket, -} - -impl + Send + 'static> TcpUdpPipe { - pub fn new(tcp_stream: T, udp_socket: UdpSocket) -> TcpUdpPipe { - TcpUdpPipe { - tcp_stream, - udp_socket, - buf: [0u8; 2050], - } - } - - pub fn try_clone(&self) -> Result> { - Ok(TcpUdpPipe::new( - self.tcp_stream.try_clone()?, - self.udp_socket.try_clone()?, - )) - } - - pub fn shuffle_after_first_udp(&mut self) -> Result { - let (len, src_addr) = self.udp_socket.recv_from(&mut self.buf[2..])?; - - println!("first packet from {}, connecting to that", src_addr); - self.udp_socket.connect(src_addr)?; - - self.send_udp(len)?; - - self.shuffle() - } - - pub fn udp_to_tcp(&mut self) -> Result<()> { - let len = self.udp_socket.recv(&mut self.buf[2..])?; - self.send_udp(len) - } - - fn send_udp(&mut self, len: usize) -> Result<()> { - #[cfg(feature = "verbose")] - println!("udp got len: {}", len); - - self.buf[0] = ((len >> 8) & 0xFF) as u8; - self.buf[1] = (len & 0xFF) as u8; - - Ok(self.tcp_stream.write_all(&self.buf[..len + 2])?) - // todo: do this? self.tcp_stream.flush() - } - - pub fn tcp_to_udp(&mut self) -> Result { - self.tcp_stream.read_exact(&mut self.buf[..2])?; - let len = ((self.buf[0] as usize) << 8) + self.buf[1] as usize; - #[cfg(feature = "verbose")] - println!("tcp expecting len: {}", len); - self.tcp_stream.read_exact(&mut self.buf[..len])?; - #[cfg(feature = "verbose")] - println!("tcp got len: {}", len); - Ok(self.udp_socket.send(&self.buf[..len])?) - - //let sent = udp_socket.send_to(&buf[..len], &self.udp_target)?; - //assert_eq!(sent, len); - } - - pub fn shuffle(&mut self) -> Result { - let mut udp_pipe_clone = self.try_clone()?; - thread::spawn(move || loop { - udp_pipe_clone - .udp_to_tcp() - .expect("cannot write to tcp_clone"); - }); - - loop { - self.tcp_to_udp()?; - } - } -} - pub struct ProxyClient { pub udp_host: String, pub tcp_target: String, pub socket_timeout: Option, } +pub struct ProxyServer { + pub tcp_host: String, + pub client_handler: Arc, +} + +pub struct ProxyServerClientHandler { + pub udp_target: String, + pub udp_host: String, + pub udp_low_port: u16, + pub udp_high_port: u16, + pub socket_timeout: Option, +} + +#[cfg(any(feature = "async"))] +#[path = ""] +mod net { + mod asyncmod; +} + +#[cfg(not(any(feature = "async")))] +#[path = ""] +mod net { + + + + mod syncmod; +} + + impl ProxyClient { pub fn new(udp_host: String, tcp_target: String, secs: u64) -> ProxyClient { ProxyClient { @@ -213,48 +146,6 @@ impl ProxyClient { udp_socket.set_read_timeout(self.socket_timeout)?; Ok(udp_socket) } - - pub fn start(&self) -> Result { - let tcp_stream = self.tcp_connect()?; - - let udp_socket = self.udp_connect()?; - - // we want to wait for first udp packet from client first, to set the target to respond to - TcpUdpPipe::new(tcp_stream, udp_socket).shuffle_after_first_udp() - } - - pub fn start_tls(&self, hostname: Option<&str>, pinnedpubkey: Option<&str>) -> Result { - let tcp_stream = self.tcp_connect()?; - - let tcp_stream = TlsStream::client(hostname, pinnedpubkey, tcp_stream)?; - - let udp_socket = self.udp_connect()?; - - // we want to wait for first udp packet from client first, to set the target to respond to - TcpUdpPipe::new(tcp_stream, udp_socket).shuffle_after_first_udp() - } -} - - -pub trait TryClone { - fn try_clone(&self) -> Result; -} - -impl TryClone for UdpSocket { - fn try_clone(&self) -> Result { - Ok(self.try_clone()?) - } -} - -impl TryClone for TcpStream { - fn try_clone(&self) -> Result { - Ok(self.try_clone()?) - } -} - -pub struct ProxyServer { - pub tcp_host: String, - pub client_handler: Arc, } impl ProxyServer { @@ -281,66 +172,6 @@ impl ProxyServer { client_handler, } } - - pub fn start(&self) -> Result<()> { - let listener = TcpListener::bind(&self.tcp_host)?; - println!("Listening for connections on {}", &self.tcp_host); - - for stream in listener.incoming() { - match stream { - Ok(stream) => { - let client_handler = self.client_handler.clone(); - client_handler.set_tcp_options(&stream).expect("cannot set tcp options"); - - thread::spawn(move || { - client_handler - .handle_client(stream) - .expect("error handling connection") - }); - } - Err(e) => { - println!("Unable to connect: {}", e); - } - } - } - Ok(()) - } - - pub fn start_tls(&self, tls_key: &str, tls_cert: &str) -> Result<()> { - let tls_listener = Arc::new(TlsListener::new(tls_key, tls_cert)?); - - let listener = TcpListener::bind(&self.tcp_host)?; - println!("Listening for TLS connections on {}", &self.tcp_host); - - for stream in listener.incoming() { - match stream { - Ok(stream) => { - let client_handler = self.client_handler.clone(); - client_handler.set_tcp_options(&stream).expect("cannot set tcp options"); - - let tls_listener = tls_listener.clone(); - thread::spawn(move || { - let stream = tls_listener.wrap(stream).expect("cannot wrap with tls"); - client_handler - .handle_client_tls(stream) - .expect("error handling connection") - }); - } - Err(e) => { - println!("Unable to connect: {}", e); - } - } - } - Ok(()) - } -} - -pub struct ProxyServerClientHandler { - pub udp_target: String, - pub udp_host: String, - pub udp_low_port: u16, - pub udp_high_port: u16, - pub socket_timeout: Option, } impl ProxyServerClientHandler { @@ -361,16 +192,4 @@ impl ProxyServerClientHandler { udp_socket.connect(&self.udp_target)?; Ok(udp_socket) } - - pub fn set_tcp_options(&self, tcp_stream: &TcpStream) -> Result<()> { - Ok(tcp_stream.set_read_timeout(self.socket_timeout)?) - } - - pub fn handle_client(&self, tcp_stream: TcpStream) -> Result { - TcpUdpPipe::new(tcp_stream, self.udp_bind()?).shuffle() - } - - pub fn handle_client_tls(&self, tcp_stream: TlsStream) -> Result { - TcpUdpPipe::new(tcp_stream, self.udp_bind()?).shuffle() - } } diff --git a/src/notls.rs b/src/notls.rs index 83aaa51..deef90f 100644 --- a/src/notls.rs +++ b/src/notls.rs @@ -1,5 +1,5 @@ use std::net::TcpStream; -use crate::TryClone; +use super::super::TryClone; use std::io::{Read, Write}; use crate::error::*; diff --git a/src/openssl.rs b/src/openssl.rs index da4a620..11d91a7 100644 --- a/src/openssl.rs +++ b/src/openssl.rs @@ -3,11 +3,11 @@ use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode, SslAccepto use std::sync::Arc; use std::cell::UnsafeCell; use std::net::TcpStream; -use crate::TryClone; use std::io::{Read, Write}; +use super::super::TryClone; + use crate::error::*; -use std::error::Error as StdError; impl TryClone for TlsStream { fn try_clone(&self) -> Result { @@ -37,7 +37,8 @@ impl TlsStream { let cert = x509_store_ctx.current_cert().expect("could not get TLS cert"); let pubkey = cert.public_key().expect("could not get public key from TLS cert"); let pubkey = pubkey.public_key_to_der().expect("could not get TLS public key bytes"); - //println!("pubkey.len(): {}", pubkey.len()); + //println!("spki.len(): {}", pubkey.len()); + //println!("spki: {:?}", pubkey); let mut sha256 = openssl::sha::Sha256::new(); sha256.update(&pubkey); @@ -148,6 +149,6 @@ impl From for Error { impl From> for Error { fn from(value: HandshakeError) -> Self { - Error::new(value.description()) + Error::new(&format!("{}", value)) } } diff --git a/src/syncmod.rs b/src/syncmod.rs new file mode 100644 index 0000000..3ad3cc8 --- /dev/null +++ b/src/syncmod.rs @@ -0,0 +1,208 @@ +use std::thread; +use crate::error::Result; +use crate::*; + +use std::net::TcpListener; +use std::io::{Write, Read}; + +#[cfg(any(feature = "tls", feature = "openssl_vendored"))] +#[path = ""] +mod tls { + pub mod openssl; + pub use super::tls::openssl::{TlsStream, TlsListener}; +} + +#[cfg(not(any(feature = "tls", feature = "openssl_vendored")))] +#[path = ""] +mod tls { + pub mod notls; + pub use super::tls::notls::{TlsStream, TlsListener}; +} + +use tls::{TlsStream, TlsListener}; + +pub struct TcpUdpPipe + Send + 'static> { + buf: [u8; 2050], // 2048 + 2 for len + tcp_stream: T, + udp_socket: UdpSocket, +} + +impl + Send + 'static> TcpUdpPipe { + pub fn new(tcp_stream: T, udp_socket: UdpSocket) -> TcpUdpPipe { + TcpUdpPipe { + tcp_stream, + udp_socket, + buf: [0u8; 2050], + } + } + + pub fn try_clone(&self) -> Result> { + Ok(TcpUdpPipe::new( + self.tcp_stream.try_clone()?, + self.udp_socket.try_clone()?, + )) + } + + pub fn shuffle_after_first_udp(&mut self) -> Result { + let (len, src_addr) = self.udp_socket.recv_from(&mut self.buf[2..])?; + + println!("first packet from {}, connecting to that", src_addr); + self.udp_socket.connect(src_addr)?; + + self.send_udp(len)?; + + self.shuffle() + } + + pub fn udp_to_tcp(&mut self) -> Result<()> { + let len = self.udp_socket.recv(&mut self.buf[2..])?; + self.send_udp(len) + } + + fn send_udp(&mut self, len: usize) -> Result<()> { + #[cfg(feature = "verbose")] + println!("udp got len: {}", len); + + self.buf[0] = ((len >> 8) & 0xFF) as u8; + self.buf[1] = (len & 0xFF) as u8; + + Ok(self.tcp_stream.write_all(&self.buf[..len + 2])?) + // todo: do this? self.tcp_stream.flush() + } + + pub fn tcp_to_udp(&mut self) -> Result { + self.tcp_stream.read_exact(&mut self.buf[..2])?; + let len = ((self.buf[0] as usize) << 8) + self.buf[1] as usize; + #[cfg(feature = "verbose")] + println!("tcp expecting len: {}", len); + self.tcp_stream.read_exact(&mut self.buf[..len])?; + #[cfg(feature = "verbose")] + println!("tcp got len: {}", len); + Ok(self.udp_socket.send(&self.buf[..len])?) + + //let sent = udp_socket.send_to(&buf[..len], &self.udp_target)?; + //assert_eq!(sent, len); + } + + pub fn shuffle(&mut self) -> Result { + let mut udp_pipe_clone = self.try_clone()?; + thread::spawn(move || loop { + udp_pipe_clone + .udp_to_tcp() + .expect("cannot write to tcp_clone"); + }); + + loop { + self.tcp_to_udp()?; + } + } +} + +pub trait TryClone { + fn try_clone(&self) -> Result; +} + +impl TryClone for UdpSocket { + fn try_clone(&self) -> Result { + Ok(self.try_clone()?) + } +} + +impl TryClone for TcpStream { + fn try_clone(&self) -> Result { + Ok(self.try_clone()?) + } +} + +impl ProxyClient { + + pub fn start(&self) -> Result { + let tcp_stream = self.tcp_connect()?; + + let udp_socket = self.udp_connect()?; + + // we want to wait for first udp packet from client first, to set the target to respond to + TcpUdpPipe::new(tcp_stream, udp_socket).shuffle_after_first_udp() + } + + pub fn start_tls(&self, hostname: Option<&str>, pinnedpubkey: Option<&str>) -> Result { + let tcp_stream = self.tcp_connect()?; + + let tcp_stream = TlsStream::client(hostname, pinnedpubkey, tcp_stream)?; + + let udp_socket = self.udp_connect()?; + + // we want to wait for first udp packet from client first, to set the target to respond to + TcpUdpPipe::new(tcp_stream, udp_socket).shuffle_after_first_udp() + } +} + +impl ProxyServer { + + pub fn start(&self) -> Result<()> { + let listener = TcpListener::bind(&self.tcp_host)?; + println!("Listening for connections on {}", &self.tcp_host); + + for stream in listener.incoming() { + match stream { + Ok(stream) => { + let client_handler = self.client_handler.clone(); + client_handler.set_tcp_options(&stream).expect("cannot set tcp options"); + + thread::spawn(move || { + client_handler + .handle_client(stream) + .expect("error handling connection") + }); + } + Err(e) => { + println!("Unable to connect: {}", e); + } + } + } + Ok(()) + } + + pub fn start_tls(&self, tls_key: &str, tls_cert: &str) -> Result<()> { + let tls_listener = Arc::new(TlsListener::new(tls_key, tls_cert)?); + + let listener = TcpListener::bind(&self.tcp_host)?; + println!("Listening for TLS connections on {}", &self.tcp_host); + + for stream in listener.incoming() { + match stream { + Ok(stream) => { + let client_handler = self.client_handler.clone(); + client_handler.set_tcp_options(&stream).expect("cannot set tcp options"); + + let tls_listener = tls_listener.clone(); + thread::spawn(move || { + let stream = tls_listener.wrap(stream).expect("cannot wrap with tls"); + client_handler + .handle_client_tls(stream) + .expect("error handling connection") + }); + } + Err(e) => { + println!("Unable to connect: {}", e); + } + } + } + Ok(()) + } +} + +impl ProxyServerClientHandler { + + pub fn set_tcp_options(&self, tcp_stream: &TcpStream) -> Result<()> { + Ok(tcp_stream.set_read_timeout(self.socket_timeout)?) + } + + pub fn handle_client(&self, tcp_stream: TcpStream) -> Result { + TcpUdpPipe::new(tcp_stream, self.udp_bind()?).shuffle() + } + + pub fn handle_client_tls(&self, tcp_stream: TlsStream) -> Result { + TcpUdpPipe::new(tcp_stream, self.udp_bind()?).shuffle() + } +} \ No newline at end of file