diff options
author | Jake McGinty <me@jake.su> | 2017-12-22 13:59:24 -0600 |
---|---|---|
committer | Jake McGinty <me@jake.su> | 2017-12-22 14:00:06 -0600 |
commit | e6aadd208877f7b187046d0656f72dd39501a0a1 (patch) | |
tree | d27e80246ad503615909eda752281f26db5ff457 | |
download | wireguard-rs-e6aadd208877f7b187046d0656f72dd39501a0a1.tar.xz wireguard-rs-e6aadd208877f7b187046d0656f72dd39501a0a1.zip |
early, early rough draft
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | Cargo.lock | 1103 | ||||
-rw-r--r-- | Cargo.toml | 45 | ||||
-rw-r--r-- | src/error.rs | 27 | ||||
-rw-r--r-- | src/interface/config.rs | 300 | ||||
-rw-r--r-- | src/interface/mod.rs | 317 | ||||
-rw-r--r-- | src/main.rs | 100 | ||||
-rw-r--r-- | src/protocol/mod.rs | 3 | ||||
-rw-r--r-- | src/protocol/peer.rs | 189 | ||||
-rw-r--r-- | src/types.rs | 107 |
10 files changed, 2196 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d6b8a48 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ + +/target/ +**/*.rs.bk +.idea/ +up.sh diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..41ba6f5 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1103 @@ +[[package]] +name = "aho-corasick" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "arrayvec" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "arrayvec" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.3" +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)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "dbghelp-sys 0.2.0 (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.34 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "byteorder" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bytes" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "chacha20-poly1305-aead" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "chashmap" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clap" +version = "2.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "daemonize" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dbghelp-sys" +version = "0.2.0" +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 = "env_logger" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "error-chain" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "futures" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "gcc" +version = "0.3.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "iovec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 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)", +] + +[[package]] +name = "ipnetwork" +version = "0.12.7" +source = "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.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazycell" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "log" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (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.31 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-utun" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.9.0 (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.31 (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.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (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.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 = "nix" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nodrop" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "odds" +version = "0.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "owning_ref" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "parking_lot" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-id 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.2.8" +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)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pnet" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_base 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_datalink 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_packet 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_sys 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_transport 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pnet_base" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pnet_datalink" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_base 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_sys 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pnet_macros" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.42.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pnet_macros_support" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pnet_base 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pnet_packet" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_base 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_macros 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_macros_support 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.42.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pnet_sys" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 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 = "pnet_transport" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_base 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_packet 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_sys 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rust-crypto" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scoped-tls" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slab" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slab" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "smallvec" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "smallvec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "snow" +version = "0.1.8-preview" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "chacha20-poly1305-aead 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "static_slice" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "strsim" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "structopt" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "structopt-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syntex" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syntex_errors 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syntex_errors" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_pos 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syntex_pos" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syntex_syntax" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_errors 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_pos 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tai64" +version = "0.1.0" +source = "git+https://github.com/sopium/tai64#f43108fdb71075c2ee72351713c64da6fd88f9a8" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "take" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "term" +version = "0.4.6" +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)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread-id" +version = "3.2.0" +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)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.38" +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)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-io" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-proto" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-service" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-timer" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds-proto" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-utun" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-utun 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "treebitmap" +version = "0.2.2" +source = "git+https://github.com/sopium/treebitmap#fb5f2235c9841d2a4acb4f0b64a13c268bae58e7" + +[[package]] +name = "unicode-width" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vec_map" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "wgrs" +version = "0.6.0" +dependencies = [ + "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "chashmap 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "daemonize 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "snow 0.1.8-preview (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tai64 0.1.0 (git+https://github.com/sopium/tai64)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-utun 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "treebitmap 0.2.2 (git+https://github.com/sopium/treebitmap)", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "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 = "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 aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" +"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455" +"checksum arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e003cbf6e0e1c43a0fc8df2ea8ea24174514d35cbcf60c35ca6112e0139f65e2" +"checksum arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0ef4a9820019a0c91d918918c93dc71d469f581a49b47ddc1d285d4270bbe2" +"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" +"checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" +"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" +"checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" +"checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" +"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" +"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" +"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" +"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" +"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" +"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" +"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" +"checksum chacha20-poly1305-aead 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77d2058ba29594f69c75e8a9018e0485e3914ca5084e3613cd64529042f5423b" +"checksum chashmap 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47e651a8c1eb0cbbaa730f705e2531e75276c6f2bbe2eb12662cfd305213dff8" +"checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f" +"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"checksum daemonize 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0239832c1b4ca406d5ec73728cf4c7336d25cf85dd32db9e047e9e706ee0e935" +"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" +"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" +"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" +"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" +"checksum fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd510087c325af53ba24f3be8f1c081b0982319adcb8b03cad764512923ccc19" +"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" +"checksum fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "08b3a6f13ad6b96572b53ce7af74543132f1a7055ccceb6d073dd36c54481859" +"checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" +"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" +"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "459d3cf58137bb02ad4adeef5036377ff59f066dbb82517b7192e3a5462a2abc" +"checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" +"checksum ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2134e210e2a024b5684f90e1556d5f71a1ce7f8b12e9ac9924c67fb36f63b336" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" +"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" +"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" +"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" +"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" +"checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb" +"checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673" +"checksum mio-utun 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8ed33b4a824985cedd49c2efde3d90487b7801ab98917c2ed8bb2acdbe08a3e5" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" +"checksum nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32" +"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +"checksum odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "4eae0151b9dacf24fcc170d9995e511669a082856a91f958a2fe380bfab3fb22" +"checksum owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d52571ddcb42e9c900c901a18d8d67e393df723fcd51dd59c5b1a85d0acb6cc" +"checksum parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fa12d706797d42551663426a45e2db2e0364bd1dbf6aeada87e89c5f981f43e9" +"checksum parking_lot_core 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "12d20aac4f67aa75f681aded784bac91f910ba3f2af1812573cdcf687414e122" +"checksum pnet 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e866218222e997f8aeebbbda7761d29c3b75772573e65da68fff97c21c5754ad" +"checksum pnet_base 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ef91690b568c732663a6b4ccaf6e14fb62b985c9edee933c32c42d55f05a7b5" +"checksum pnet_datalink 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf82511ad5ea82f6d632a624edf7c60592271a1f76ecaeb7a7f2ae55f6e0c38a" +"checksum pnet_macros 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60fa5bee262cdfd7cb3871a9b205b2858c262e2e90e48b5e00626f5c0fa32182" +"checksum pnet_macros_support 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc4fa05e0ee7d4911bc88f9da16eb0c8f238c5e001f45379e42c2b7cb35e53fc" +"checksum pnet_packet 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "081e4b575f26366f33f195281e07a0bde6f2be810f904921887b15a3e82e58e4" +"checksum pnet_sys 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b834fac796acd6a4c66010d7fa14aa34d8a69d780e28aa754a24661d3738df3" +"checksum pnet_transport 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "257eec056138182230f7f3c5dd065848fdfb09c93456adfdb583ec457dd3ed5a" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" +"checksum rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d5f78082e6a6d042862611e9640cf20776185fee506cf6cf67e93c6225cee31" +"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322" +"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" +"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" +"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" +"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" +"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" +"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" +"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" +"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9" +"checksum snow 0.1.8-preview (registry+https://github.com/rust-lang/crates.io-index)" = "f48c2e9c3e713e6e17beedb4ae145f1f4b6c7bd2e8ee993cece40607dd09d49e" +"checksum static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "92a7e0c5e3dfb52e8fbe0e63a1b947bbb17b4036408b151353c4491374931362" +"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum structopt 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "daed460ef88cdfdc6cc665f974feea29883c40f479b6976302c8ad8bf05de722" +"checksum structopt-derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4da119c9a7a1eccb7c6de0c1eb3f7ed1c11138624d092b3687222aeed8f1375c" +"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum syntex 0.42.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0a30b08a6b383a22e5f6edc127d169670d48f905bb00ca79a00ea3e442ebe317" +"checksum syntex_errors 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04c48f32867b6114449155b2a82114b86d4b09e1bddb21c47ff104ab9172b646" +"checksum syntex_pos 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd49988e52451813c61fecbe9abb5cfd4e1b7bb6cdbb980a6fbcbab859171a6" +"checksum syntex_syntax 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7628a0506e8f9666fdabb5f265d0059b059edac9a3f810bda077abb5d826bd8d" +"checksum tai64 0.1.0 (git+https://github.com/sopium/tai64)" = "<none>" +"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" +"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" +"checksum thread-id 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2af4d6289a69a35c4d3aea737add39685f2784122c28119a7713165a63d68c9d" +"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" +"checksum tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c87c27560184212c9dc45cd8f38623f37918248aad5b58fb65303b5d07a98c6e" +"checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743" +"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" +"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" +"checksum tokio-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6131e780037787ff1b3f8aad9da83bca02438b72277850dd6ad0d455e0e20efc" +"checksum tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "65ae5d255ce739e8537221ed2942e0445f4b3b813daebac1c0050ddaaa3587f9" +"checksum tokio-uds-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93842f83f760d2a48eb54225f819d05549e69c481f56be4a1b1f51decf99da5b" +"checksum tokio-utun 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e44b976406c6edfd4bede61feb70f5f0751d6dc5e965e5d817136cdc6051a2d" +"checksum treebitmap 0.2.2 (git+https://github.com/sopium/treebitmap)" = "<none>" +"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" +"checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"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 new file mode 100644 index 0000000..5764a2e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "wgrs" +version = "0.6.0" +authors = ["Jake McGinty <me@jake.su>"] +license = "GPL-3.0" +repository = "https://git.zx2c4.com/wireguard-rs/" +description = "Userspace implementation of WireGuard, a fast, modern and secure VPN tunnel." + +[dependencies] +blake2-rfc = "0.2" +byteorder = "^1.2" +structopt = "^0.1" +structopt-derive = "^0.1" +daemonize = "0.2" +error-chain = "^0.11" +rand = "^0.4" +libc = "0.2" +nix = "0.9" +rustc-serialize = "0.3.22" +tai64 = { git = "https://github.com/sopium/tai64" } +treebitmap = { git = "https://github.com/sopium/treebitmap" } +chashmap = "^2.2" + +env_logger = "^0.4" +log = "^0.3" + +mio = "^0.6" +mio-uds = "^0.6" +bytes = "0.4" +futures = "0.1" +tokio-io = "0.1" +tokio-core = "0.1" +tokio-proto = "0.1" +tokio-service = "0.1" +tokio-uds = "0.1" +tokio-uds-proto = "0.1" +tokio-utun = "0.1" +tokio-timer = "^0.1" + +snow = "^0.1.8-preview" +base64 = "^0.5" +hex = "^0.3" +rust-crypto = "*" +time = "*" +pnet = "*" diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..4492444 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,27 @@ +use daemonize; +use std::io; + + error_chain! { + foreign_links { + Io(io::Error) #[doc = "Error during IO"]; + Daemonize(daemonize::DaemonizeError) #[doc = "Error during IO"]; + } + + errors { +// Launch(phase: LaunchStage) { +// description("An error occurred during startup") +// display("Startup aborted: {:?} did not complete successfully", phase) +// } +// +// ConfigLoad(path: String) { +// description("Config file not found") +// display("Unable to read file `{}`", path) +// } + } + } + +// impl From<LaunchStage> for ErrorKind { +// fn from(v: LaunchStage) -> Self { +// ErrorKind::Launch(v) +// } +// } diff --git a/src/interface/config.rs b/src/interface/config.rs new file mode 100644 index 0000000..6a76a23 --- /dev/null +++ b/src/interface/config.rs @@ -0,0 +1,300 @@ +//! The configuration logic for userspace WireGuard. + +// Dev notes: +// * Configuration service should use channels to report updates it receives over its interface. + +use bytes::BytesMut; +use error::Result; +use std; +use std::fs::{create_dir, remove_file}; +use std::iter::Iterator; +use std::path::{Path, PathBuf}; +use std::io; +use std::str; +use std::net::{SocketAddr, IpAddr}; +use types::{PeerInfo, InterfaceInfo}; +use hex::{FromHex}; + +use futures::{Future, Stream}; +use futures::unsync::mpsc; +use tokio_io::{AsyncRead, AsyncWrite}; +use tokio_io::codec::{Encoder, Decoder}; + +#[derive(Debug)] +pub enum Command { + Set(usize, Vec<UpdateEvent>), + Get(usize) +} + +#[derive(Debug)] +#[allow(dead_code)] +pub enum UpdateEvent { + PrivateKey([u8; 32]), + ListenPort(u16), + UpdatePeer(PeerInfo), + RemovePeer([u8; 32]), + RemoveAllPeers, +} + +impl UpdateEvent { + fn from(items: Vec<(String, String)>) -> Vec<UpdateEvent> { + let mut events = vec![]; + let mut public_key: Option<[u8; 32]> = None; + let mut preshared_key: Option<[u8; 32]> = None; + let mut allowed_ips: Vec<(IpAddr, u32)> = vec![]; + let mut keep_alive_interval: Option<u16> = None; + let mut endpoint: Option<SocketAddr> = None; + + for (key, value) in items { + match key.as_ref() { + "private_key" => { + let key = <[u8; 32]>::from_hex(&value).unwrap(); + events.push(UpdateEvent::PrivateKey(key)); + }, + "listen_port" => { events.push(UpdateEvent::ListenPort(value.parse().unwrap())); }, + "public_key" => { + if let Some(ref pubkey) = public_key { + events.push(UpdateEvent::UpdatePeer(PeerInfo { + pub_key: pubkey.clone(), + psk: preshared_key.clone(), + endpoint: endpoint.clone(), + allowed_ips: allowed_ips.clone(), + keep_alive_interval: keep_alive_interval.clone(), + })); + } + let key = <[u8; 32]>::from_hex(&value).unwrap(); + public_key = Some(key); + }, + "preshared_key" => { preshared_key = Some(<[u8; 32]>::from_hex(&value).unwrap()); }, + "allowed_ip" => { + let (ip, cidr) = value.split_at(value.find('/').unwrap()); + allowed_ips.push((ip.parse().unwrap(), (&cidr[1..]).parse().unwrap())) + }, + "persistent_keepalive_interval" => { + keep_alive_interval = Some(value.parse().unwrap()); + }, + "endpoint" => { endpoint = Some(value.parse().unwrap()); }, + _ => {} + } + } + + if let Some(ref pubkey) = public_key { + events.push(UpdateEvent::UpdatePeer(PeerInfo { + pub_key: pubkey.clone(), + psk: preshared_key.clone(), + endpoint: endpoint.clone(), + allowed_ips: allowed_ips.clone(), + keep_alive_interval: keep_alive_interval.clone(), + })); + } + debug!("events {:?}", events); + events + } +} + +pub struct ConfigurationCodec; + +impl Decoder for ConfigurationCodec { + type Item = Command; + type Error = io::Error; + + fn decode(&mut self, buf: &mut BytesMut) -> std::result::Result<Option<Self::Item>, Self::Error> { + // Determine we have a full command ready for parsing. + let mut items = Vec::new(); + let utf8 = String::from_utf8(buf.to_vec()).unwrap(); + let mut data_iter = utf8.split("\n\n"); + let blob = data_iter.next().unwrap(); + if data_iter.next().is_none() { + return Ok(None) + } + + // Parse the key-value pairs into something more usable + for line in blob.split('\n') { + let mut entry = line.split('='); + items.push((entry.next().unwrap().to_owned(), entry.next().unwrap().to_owned())); + } + buf.split_to(blob.len()+1); + + let (ref cmd, ref version) = items.remove(0); + let command = if cmd == "get" { + Command::Get(version.parse().unwrap()) + } else { + Command::Set(version.parse().unwrap(), UpdateEvent::from(items)) + }; + + Ok(Some(command)) + } +} + +impl Encoder for ConfigurationCodec { + type Item = String; + type Error = io::Error; + + fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> std::result::Result<(), Self::Error> { + buf.extend(msg.as_bytes()); + buf.extend(b"\n\n"); + Ok(()) + } +} + + +//pub struct ConfigurationService { +// interface_name: String, +// peers: Rc<RefCell<HashMap<[u8; 32], Rc<RefCell<Peer>>>>>, +// interface_info: Rc<RefCell<InterfaceInfo>>, +// tx: mpsc::Sender<UpdateEvent>, +//} + +//impl Service for ConfigurationService { +// type Request = Command; +// type Response = String; +// type Error = io::Error; +// type Future = Box<Future<Item=Self::Response, Error=Self::Error>>; +// +// fn call(&self, req: Self::Request) -> Self::Future { +// debug!("{:?}", req); +// match req { +// Command::Get(version) => { +// // see: https://www.wireguard.com/xplatform/ +// // this is just bullshit fillin +// let buf = "private_key=e84b5a6d2717c1003a13b431570353dbaca9146cf150c5f8575680feba52027a +//listen_port=12912 +//public_key=b85996fecc9c7f1fc6d2572a76eda11d59bcd20be8e543b15ce4bd85a8e75a33 +//preshared_key=188515093e952f5f22e865cef3012e72f8b5f0b598ac0309d5dacce3b70fcf52 +//allowed_ip=192.168.4.4/32 +//endpoint=[abcd:23::33%2]:51820 +//public_key=58402e695ba1772b1cc9309755f043251ea77fdcf10fbe63989ceb7e19321376 +//tx_bytes=38333 +//rx_bytes=2224 +//allowed_ip=192.168.4.6/32 +//persistent_keepalive_interval=111 +//endpoint=182.122.22.19:3233 +//public_key=662e14fd594556f522604703340351258903b64f35553763f19426ab2a515c58 +//endpoint=5.152.198.39:51820 +//allowed_ip=192.168.4.10/32 +//allowed_ip=192.168.4.11/32 +//tx_bytes=1212111 +//rx_bytes=1929999999 +//errno=0 +//\n"; +// Box::new(future::ok(buf.into())) +// }, +// Command::Set(version, items) => { +// let mut public_key = None; +// let mut preshared_key = None; +// let mut allowed_ips: Vec<(IpAddr, u32)> = vec![]; +// let mut persistent_keepalive_interval: Option<u16> = None; +// let mut endpoint: Option<SocketAddr> = None; +// +// for (key, value) in items { +// match key.as_ref() { +//// "private_key" => { config.key = Some(value); }, +//// "fwmark" => { config.fwmark = Some(value.parse().unwrap()); }, +//// "listen_port" => { config.listen_port = Some(value.parse().unwrap()); }, +// "public_key" => { +// if let Some(ref pubkey) = public_key { +//// config.peers.push(Peer { +//// peer_pubkey: [0u8; 32], +//// psk: preshared_key, +//// endpoint: endpoint, +//// allowed_ips: allowed_ips.clone(), +//// keep_alive_interval: persistent_keepalive_interval, +//// }); +// } +// public_key = Some(value); +// }, +// "preshared_key" => { preshared_key = Some([0u8; 32]); }, +// "allowed_ip" => { +// let (ip, cidr) = value.split_at(value.find('/').unwrap()); +// debug!("parsed allowed ip as ({}, {})", ip, &cidr[1..]); +// allowed_ips.push((ip.parse().unwrap(), (&cidr[1..]).parse().unwrap())) +// }, +// "persistent_keepalive_interval" => { +// debug!("persistent_keepalive_interval"); +// persistent_keepalive_interval = Some(value.parse().unwrap()); +// }, +// "endpoint" => { endpoint = Some(value.parse().unwrap()); }, +// _ => {} +// } +// } +// Box::new(future::ok("errno=0\nerrno=0\n\n".into())) +// }, +// _ => { +// Box::new(future::ok("errno=1\nerrno=1\n\n".into())) +// } +// } +// } +//} + +pub struct ConfigurationServiceManager { + interface_name: String, +} + +impl ConfigurationServiceManager { + pub fn new(interface_name: &str) -> Self { + ConfigurationServiceManager { + interface_name: interface_name.into(), + } + } + + /// Creates a new `WireGuard` instance + pub fn get_path(name: &str) -> Result<PathBuf> { + // let _tun = Tun::create(Some("hey")); + // Create the socket directory if not existing + let mut socket_path = Self::get_run_path().join("wireguard"); + + if !socket_path.exists() { + debug!("Creating socket path: {}", socket_path.display()); + create_dir(&socket_path)?; + } + debug!("Setting chmod 0700 of socket path: {}", + socket_path.display()); + Self::chmod(&socket_path, 0o700)?; + + // Finish the socket path + socket_path.push(&name); + socket_path.set_extension("sock"); + if socket_path.exists() { + debug!("Removing existing socket: {}", socket_path.display()); + remove_file(&socket_path)?; + } + + Ok(socket_path) + } + + #[cfg(unix)] + /// Sets the permissions to a given `Path` + fn chmod(path: &Path, perms: u32) -> Result<()> { + use std::os::unix::prelude::PermissionsExt; + use std::fs::{set_permissions, Permissions}; + set_permissions(path, Permissions::from_mode(perms))?; + Ok(()) + } + + #[cfg(windows)] + /// Sets the permissions to a given `Path` + fn chmod(_path: &Path, _perms: u32) -> Result<()> { + Ok(()) + } + + /// Returns the path where the socket and pid file will be stored + pub fn get_run_path() -> PathBuf { + if Path::new("/run").exists() { + PathBuf::from("/run") + } else { + PathBuf::from("/var").join("run") + } + } +} + +impl Drop for ConfigurationServiceManager { + fn drop(&mut self) { + let mut socket_path = Self::get_run_path().join("wireguard"); + socket_path.push(&self.interface_name); + socket_path.set_extension("sock"); + if socket_path.exists() { + debug!("Removing socket on drop: {}", socket_path.display()); + let _ = remove_file(&socket_path); + } + } +} diff --git a/src/interface/mod.rs b/src/interface/mod.rs new file mode 100644 index 0000000..8cbbfb3 --- /dev/null +++ b/src/interface/mod.rs @@ -0,0 +1,317 @@ +mod config; + +use self::config::{ConfigurationServiceManager, UpdateEvent, Command, ConfigurationCodec}; +use base64; +use hex; +use byteorder::{ByteOrder, BigEndian, LittleEndian}; +use snow::NoiseBuilder; +use protocol::Peer; +use std::io; +use std::rc::Rc; +use std::cell::RefCell; +use std::collections::HashMap; +use std::net::SocketAddr; +use std::time::Duration; +use types::{InterfaceInfo}; + +use pnet::packet::ipv4::Ipv4Packet; + +use futures::{Future, Stream, Sink, future, unsync, sync, stream}; +use tokio_core::reactor::{Core, Handle}; +use tokio_core::net::{UdpSocket, UdpCodec}; +use tokio_utun::{UtunStream, UtunCodec}; +use tokio_io::{AsyncRead}; +use tokio_io::codec::{Framed, Encoder, Decoder}; +use tokio_uds::{UnixListener}; +use tokio_timer::{Interval, Timer}; + +fn debug_packet(header: &str, packet: &[u8]) { + let packet = Ipv4Packet::new(packet); + debug!("{} {:?}", header, packet); +} + +pub struct Interface { + name: String, + info: Rc<RefCell<InterfaceInfo>>, + peers: Rc<RefCell<HashMap<[u8; 32], Rc<RefCell<Peer>>>>>, + ids: Rc<RefCell<HashMap<u32, Rc<RefCell<Peer>>>>>, +} + +struct VecUdpCodec; +impl UdpCodec for VecUdpCodec { + type In = (SocketAddr, Vec<u8>); + type Out = (SocketAddr, Vec<u8>); + + fn decode(&mut self, src: &SocketAddr, buf: &[u8]) -> io::Result<Self::In> { + Ok((*src, buf.to_vec())) + } + + fn encode(&mut self, msg: Self::Out, buf: &mut Vec<u8>) -> SocketAddr { + let (addr, mut data) = msg; + buf.append(&mut data); + addr + } +} + +struct VecUtunCodec; +#[allow(dead_code)] +enum UtunPacket { + Inet4(Vec<u8>), + Inet6(Vec<u8>), +} +impl UtunCodec for VecUtunCodec { + type In = Vec<u8>; + type Out = Vec<u8>; + + fn decode(&mut self, buf: &[u8]) -> io::Result<Self::In> { + debug!("utun packet type {}", buf[3]); + Ok(buf[4..].to_vec()) + } + + fn encode(&mut self, mut msg: Self::Out, buf: &mut Vec<u8>) { + buf.extend_from_slice(&[0u8, 0, 0, 2]); + buf.append(&mut msg); + } +} + +impl Interface { + pub fn new(name: &str) -> Self { + let info = Rc::new(RefCell::new(InterfaceInfo::default())); + let peers = Rc::new(RefCell::new(HashMap::new())); + let ids = Rc::new(RefCell::new(HashMap::new())); + let _config_service = ConfigurationServiceManager::new(name); + Interface { + name: name.to_owned(), + info, + peers, + ids, + } + } + + pub fn start(&mut self) { + let mut core = Core::new().unwrap(); + + let (utun_tx, utun_rx) = unsync::mpsc::channel::<Vec<u8>>(1024); + let udp_socket = UdpSocket::bind(&([0,0,0,0], 0).into(), &core.handle()).unwrap(); + let (tx, rx) = unsync::mpsc::channel::<(SocketAddr, Vec<u8>)>(1024); + let (udp_writer, udp_reader) = udp_socket.framed(VecUdpCodec{}).split(); + let udp_read_fut = udp_reader.for_each({ + let ids_ref = self.ids.clone(); + let handle = core.handle(); + let tx = tx.clone(); + let interface_info = self.info.clone(); + move |(_socket_addr, packet)| { + debug!("got a UDP packet of length {}, packet type {}", packet.len(), packet[0]); + match packet[0] { + 1 => { + info!("got handshake initialization."); + }, + 2 => { + let their_index = LittleEndian::read_u32(&packet[4..]); + let our_index = LittleEndian::read_u32(&packet[8..]); + let mut ids = ids_ref.borrow_mut(); + let peer_ref = ids.get(&our_index).unwrap().clone(); + let mut peer = peer_ref.borrow_mut(); + peer.sessions.next.as_mut().unwrap().their_index = their_index; + let payload_len = peer.next_noise().expect("pending noise session") + .read_message(&packet[12..60], &mut []).unwrap(); + assert!(payload_len == 0); + peer.ratchet_session().unwrap(); + info!("got handshake response, ratcheted session."); + let tx = tx.clone(); + + let interface_info = interface_info.borrow(); + let noise = NoiseBuilder::new("Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s".parse().unwrap()) + .local_private_key(&interface_info.private_key.expect("no private key!")) + .remote_public_key(&peer.info.pub_key) + .prologue("WireGuard v1 zx2c4 Jason@zx2c4.com".as_bytes()) + .psk(2, &peer.info.psk.expect("no psk!")) + .build_initiator().unwrap(); + peer.set_next_session(noise.into()); + + let _ = ids.insert(peer.our_next_index().unwrap(), peer_ref.clone()); + + let init_packet = peer.get_handshake_packet(); + let endpoint = peer.info.endpoint.unwrap().clone(); + + let timer = Timer::default(); + let sleep = timer.sleep(Duration::from_secs(120)); + let boop = sleep.and_then({ + let handle = handle.clone(); + let peer_ref = peer_ref.clone(); + let interface_info = interface_info.clone(); + move |_| { + info!("sending rekey!"); + handle.spawn(tx.clone().send((endpoint, init_packet)) + .map(|_| ()) + .map_err(|_| ())); + Ok(()) + } + }).map_err(|_|()); + handle.spawn(boop); + }, + 4 => { + let our_index_received = LittleEndian::read_u32(&packet[4..]); + let nonce = LittleEndian::read_u64(&packet[8..]); + + let mut raw_packet = [0u8; 1500]; + let ids = ids_ref.borrow(); + let lookup = ids.get(&our_index_received); + if let Some(ref peer) = lookup { + let mut peer = peer.borrow_mut(); + // info!("retrieved peer with pubkey {}", base64::encode(&peer.pubkey)); + // info!("ok going to try to decrypt"); + + peer.rx_bytes += packet.len(); + let noise = peer.current_noise().expect("current noise session"); + noise.set_receiving_nonce(nonce).unwrap(); + let payload_len = noise.read_message(&packet[16..], &mut raw_packet).unwrap(); + debug_packet("received TRANSPORT: ", &raw_packet[..payload_len]); + handle.spawn(utun_tx.clone().send(raw_packet[..payload_len].to_owned()) + .map(|_| ()) + .map_err(|_| ())); + } + }, + _ => unimplemented!() + } + Ok(()) + } + }).map_err(|_| ()); + + let udp_write_fut = udp_writer.sink_map_err(|_| ()).send_all( + rx.map(|(addr, packet)| { + debug!("sending encrypted UDP packet"); + (addr, packet) + }).map_err(|_| ())).map_err(|_| ()); + + let utun_stream = UtunStream::connect(&self.name, &core.handle()).unwrap().framed(VecUtunCodec{}); + let (utun_writer, utun_reader) = utun_stream.split(); + let utun_fut = utun_reader.for_each({ + let ids = self.ids.clone(); + let utun_handle = core.handle(); + let udp_tx = tx.clone(); + move |packet| { + debug_packet("received UTUN packet: ", &packet); + let mut ping_packet = [0u8; 1500]; + let ids = ids.borrow(); + let (_key, peer) = ids.iter().next().unwrap(); // TODO destination IP peer lookup + let mut peer = peer.borrow_mut(); + ping_packet[0] = 4; + let their_index = peer.their_current_index().expect("no current index for them"); + let endpoint = peer.info.endpoint.unwrap(); + peer.tx_bytes += packet.len(); + let noise = peer.current_noise().expect("current noise session"); + LittleEndian::write_u32(&mut ping_packet[4..], their_index); + LittleEndian::write_u64(&mut ping_packet[8..], noise.sending_nonce().unwrap()); + let len = noise.write_message(&packet, &mut ping_packet[16..]).expect("failed to encrypt outgoing UDP packet"); + utun_handle.spawn(udp_tx.clone().send((endpoint, ping_packet[..(16+len)].to_owned())) + .map(|_| ()) + .map_err(|_| ())); + Ok(()) + } + }).map_err(|_| ()); + + let utun_write_fut = utun_writer.sink_map_err(|_| ()).send_all( + utun_rx.map(|packet| { + debug_packet("sending UTUN: ", &packet); + packet + }).map_err(|_| ())).map_err(|_| ()); + + let handle = core.handle(); + let listener = UnixListener::bind(ConfigurationServiceManager::get_path(&self.name).unwrap(), &handle).unwrap(); + let (config_tx, config_rx) = sync::mpsc::channel::<UpdateEvent>(1024); + let h = handle.clone(); + let config_server = listener.incoming().for_each({ + let config_tx = config_tx.clone(); + let info = self.info.clone(); + let peers = self.peers.clone(); + move |(stream, _)| { + let (sink, stream) = stream.framed(ConfigurationCodec {}).split(); + debug!("UnixServer connection."); + + let handle = h.clone(); + let responses = stream.and_then({ + let config_tx = config_tx.clone(); + let info = info.clone(); + let peers = peers.clone(); + move |command| { + match command { + Command::Set(_version, items) => { + config_tx.clone().send_all(stream::iter_ok(items)).wait().unwrap(); + future::ok("errno=0\nerrno=0\n\n".to_string()) + }, + Command::Get(_version) => { + let info = info.borrow(); + let peers = peers.borrow(); + let mut s = String::new(); + if let Some(private_key) = info.private_key { + s.push_str(&format!("private_key={}\n", hex::encode(private_key))); + } + + for (_, peer) in peers.iter() { + s.push_str(&peer.borrow().to_config_string()); + } + future::ok(format!("{}errno=0\n\n", s)) + } + } + } + }); + + let fut = sink.send_all(responses).map(|_| ()).map_err(|_| ()); + + handle.spawn(fut); + + Ok(()) + } + }).map_err(|_| ()); + + let config_fut = config_rx.for_each({ + let tx = tx.clone(); + let handle = handle.clone(); + move |event| { + let interface_info = self.info.clone(); + match event { + UpdateEvent::PrivateKey(private_key) => { + let mut interface_info = interface_info.borrow_mut(); + interface_info.private_key = Some(private_key); + debug!("set new private key"); + }, + UpdateEvent::ListenPort(port) => { + let mut interface_info = interface_info.borrow_mut(); + interface_info.listen_port = Some(port); + debug!("set new listen port"); + }, + UpdateEvent::UpdatePeer(info) => { + info!("added new peer: {}", info); + let interface_info = interface_info.borrow(); + let mut noise = NoiseBuilder::new("Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s".parse().unwrap()) + .local_private_key(&interface_info.private_key.expect("no private key!")) + .remote_public_key(&info.pub_key) + .prologue("WireGuard v1 zx2c4 Jason@zx2c4.com".as_bytes()) + .psk(2, &info.psk.expect("no psk!")) + .build_initiator().unwrap(); + + let mut peer = Peer::new(info.clone()); + peer.set_next_session(noise.into()); + + let init_packet = peer.get_handshake_packet(); + let our_index = peer.our_next_index().unwrap(); + let peer = Rc::new(RefCell::new(peer)); + + let _ = self.ids.borrow_mut().insert(our_index, peer.clone()); + let _ = self.peers.borrow_mut().insert(info.pub_key, peer); + + handle.spawn(tx.clone().send((info.endpoint.unwrap(), init_packet)) + .map(|_| ()) + .map_err(|_| ())); + }, + _ => unimplemented!() + } + + future::ok(()) + } + }).map_err(|_| ()); + + core.run(utun_fut.join(utun_write_fut.join(udp_read_fut.join(udp_write_fut.join(config_fut.join(config_server)))))).unwrap(); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..0f3f9e4 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,100 @@ +#![allow(unused_imports)] + +#[macro_use] extern crate log; +extern crate env_logger; + +#[macro_use] extern crate structopt_derive; +#[macro_use] extern crate error_chain; + + +extern crate daemonize; +extern crate rand; +extern crate nix; +extern crate structopt; + +extern crate mio; + +extern crate bytes; +extern crate futures; +extern crate tokio_core; +extern crate tokio_io; +extern crate tokio_proto; +extern crate tokio_service; +extern crate tokio_uds; +extern crate tokio_utun; +extern crate tokio_timer; + +extern crate snow; +extern crate base64; +extern crate hex; +extern crate time; +extern crate byteorder; +extern crate crypto; +extern crate pnet; + +mod error; +mod interface; +mod protocol; +mod types; + +use daemonize::Daemonize; +use error::{ErrorKind, Error, Result}; +use std::path::PathBuf; +use interface::Interface; +use structopt::StructOpt; + +#[derive(StructOpt, Debug)] +#[structopt(name = "wgrs", about = "WireGuard - a network tunnel")] +struct Opt { + /// A flag, true if used in the command line. + #[structopt(short = "d", long = "debug", help = "Activate debug mode")] + debug: bool, + + /// An argument of type float, with a default value. + #[structopt(short = "f", long = "foreground", help = "Run in the foreground")] + foreground: bool, + + /// Needed parameter, the first on the command line. + #[structopt(help = "WireGuard interface name", default_value = "utun4")] + interface: String, + + /// An optional parameter, will be `None` if not present on the + /// command line. + #[structopt(help = "Output file, stdout if not present")] + output: Option<String>, +} + +fn main() { + env_logger::init().unwrap(); + let opt = Opt::from_args(); + + if !opt.foreground { + daemonize().expect("failed to daemonize"); + } + + Interface::new(&opt.interface).start(); +// WireGuard::start(interface_name).expect("failed to start WireGuard interface"); +} + +fn daemonize() -> Result<()> { + if !nix::unistd::getuid().is_root() { + bail!("You are not the root user which can spawn the daemon."); + } + + debug!("Starting daemon."); + + let pid_path = PathBuf::new(); // TODO temporary + +// let pid_path = WireGuard::get_run_path(); + + let daemonize = Daemonize::new() + .pid_file(pid_path.join("wireguard.pid")) + .chown_pid_file(true) + .working_directory(pid_path) + .user("nobody") + .group("daemon") + .umask(0o077); + + daemonize.start()?; + Ok(()) +} diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs new file mode 100644 index 0000000..bae5340 --- /dev/null +++ b/src/protocol/mod.rs @@ -0,0 +1,3 @@ +mod peer; + +pub use self::peer::Peer; diff --git a/src/protocol/peer.rs b/src/protocol/peer.rs new file mode 100644 index 0000000..e26e1bf --- /dev/null +++ b/src/protocol/peer.rs @@ -0,0 +1,189 @@ +use byteorder::{ByteOrder, BigEndian, LittleEndian}; +use crypto::blake2s::Blake2s; +use snow::{self, NoiseBuilder}; +use pnet::packet::Packet; +use pnet::packet::ip::IpNextHeaderProtocols; +use pnet::packet::ipv4::{self, MutableIpv4Packet}; +use pnet::packet::icmp::{self, MutableIcmpPacket, IcmpTypes, echo_reply, echo_request}; +use std::{self, io}; +use std::fmt::{self, Debug, Display, Formatter}; +use std::net::{Ipv4Addr, IpAddr, SocketAddr, ToSocketAddrs}; +use std::str::FromStr; +use std::thread::JoinHandle; +use base64; +use hex; +use time; +use rand::{self, Rng}; +use types::PeerInfo; + +use futures::{self, Future}; +use tokio_core::reactor::Handle; +use tokio_core::net::{UdpSocket, UdpCodec}; + +pub struct Peer { + pub info: PeerInfo, + pub sessions: Sessions, + pub tx_bytes: usize, + pub rx_bytes: usize, +} + +pub struct Session { + pub noise: snow::Session, + pub our_index: u32, + pub their_index: u32, +} + +impl Session { + #[allow(dead_code)] + pub fn with_their_index(session: snow::Session, their_index: u32) -> Session { + Session { + noise: session, + our_index: rand::thread_rng().gen::<u32>(), + their_index, + } + } + + pub fn into_transport_mode(self) -> Session { + Session { + noise: self.noise.into_transport_mode().unwrap(), + our_index: self.our_index, + their_index: self.their_index, + } + } +} + +impl From<snow::Session> for Session { + fn from(session: snow::Session) -> Self { + Session { + noise: session, + our_index: 0, + their_index: 0, + } + } +} + +pub struct Sessions { + pub past: Option<Session>, + pub current: Option<Session>, + pub next: Option<Session>, +} + +impl Display for Peer { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "Peer({})", self.info) + } +} + +impl Debug for Peer { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "Peer( endpoint: {:?}, pubkey: [redacted], psk: [redacted] )", self.info.endpoint) + } +} + +fn memcpy(out: &mut [u8], data: &[u8]) { + out[..data.len()].copy_from_slice(data); +} + +impl Peer { + pub fn new(info: PeerInfo) -> Peer { + Peer { + info, + sessions: Sessions { + past: None, + current: None, + next: None + }, + tx_bytes: 0, + rx_bytes: 0, + } + } + + pub fn set_next_session(&mut self, session: Session) { + let _ = std::mem::replace(&mut self.sessions.next, Some(session)); + } + + pub fn ratchet_session(&mut self) -> Result<(), ()> { + let next = std::mem::replace(&mut self.sessions.next, None).ok_or(())?; + let next = next.into_transport_mode(); + + let current = std::mem::replace(&mut self.sessions.current, Some(next)); + let _ = std::mem::replace(&mut self.sessions.past, current); + Ok(()) + } + + pub fn current_noise(&mut self) -> Option<&mut snow::Session> { + if let Some(ref mut session) = self.sessions.current { + Some(&mut session.noise) + } else { + None + } + } + + pub fn next_noise(&mut self) -> Option<&mut snow::Session> { + if let Some(ref mut session) = self.sessions.next { + Some(&mut session.noise) + } else { + None + } + } + + pub fn our_next_index(&self) -> Option<u32> { + if let Some(ref session) = self.sessions.next { + Some(session.our_index) + } else { + None + } + } + + pub fn our_current_index(&self) -> Option<u32> { + if let Some(ref session) = self.sessions.current { + Some(session.our_index) + } else { + None + } + } + + pub fn their_current_index(&self) -> Option<u32> { + if let Some(ref session) = self.sessions.current { + Some(session.their_index) + } else { + None + } + } + + pub fn get_handshake_packet(&mut self) -> Vec<u8> { + let now = time::get_time(); + let mut tai64n = [0; 12]; + BigEndian::write_i64(&mut tai64n[0..], 4611686018427387914 + now.sec); + BigEndian::write_i32(&mut tai64n[8..], now.nsec); + let mut initiation_packet = vec![0; 148]; + initiation_packet[0] = 1; /* Type: Initiation */ + initiation_packet[1] = 0; /* Reserved */ + initiation_packet[2] = 0; /* Reserved */ + initiation_packet[3] = 0; /* Reserved */ + LittleEndian::write_u32(&mut initiation_packet[4..], self.our_next_index().unwrap()); + self.sessions.next.as_mut().unwrap().noise.write_message(&tai64n, &mut initiation_packet[8..]).unwrap(); + let mut mac_key_input = [0; 40]; + let mut mac_key = [0; 32]; + memcpy(&mut mac_key_input, b"mac1----"); + memcpy(&mut mac_key_input[8..], &self.info.pub_key); + Blake2s::blake2s(&mut mac_key, &mac_key_input, &[0; 0]); + let mut mac = [0; 16]; + Blake2s::blake2s(&mut mac, &initiation_packet[0..116], &mac_key); + memcpy(&mut initiation_packet[116..], &mac); + + initiation_packet + } + + pub fn to_config_string(&self) -> String { + let mut s = format!("public_key={}\n", hex::encode(&self.info.pub_key)); + if let Some(ref psk) = self.info.psk { + s.push_str(&format!("preshared_key={}\n", hex::encode(psk))); + } + if let Some(ref endpoint) = self.info.endpoint { + s.push_str(&format!("endpoint={}:{}\n", endpoint.ip().to_string(),endpoint.port())); + } + s.push_str(&format!("tx_bytes={}\nrx_bytes={}\n", self.tx_bytes, self.rx_bytes)); + s + } +} diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..29b02bb --- /dev/null +++ b/src/types.rs @@ -0,0 +1,107 @@ +use base64; +use std::io::{self, Cursor, Read, Write}; +use byteorder::{BigEndian, LittleEndian, WriteBytesExt, ReadBytesExt}; +use std::fmt::{self, Display, Formatter}; +use std::net::{Ipv4Addr, IpAddr, SocketAddr}; + +#[derive(Clone, Debug)] +pub struct PeerInfo { + pub pub_key: [u8; 32], + pub psk: Option<[u8; 32]>, + pub endpoint: Option<SocketAddr>, + pub allowed_ips: Vec<(IpAddr, u32)>, + pub keep_alive_interval: Option<u16>, +} + +impl Display for PeerInfo { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let encoded = base64::encode(&self.pub_key); + write!(f, "{}...{}", &encoded[..4], &encoded[encoded.len()-4..]) + } +} + +#[derive(Clone, Debug, Default)] +pub struct InterfaceInfo { + pub private_key: Option<[u8; 32]>, + pub pub_key: Option<[u8; 32]>, + pub listen_port: Option<u16>, +} + +pub enum Message { + HandshakeInitiation(HandshakeInitiationMessage), +// HandshakeResponse(HandshakeResponseMessage), +// Transport(TransportMessage), +// CookieReply(CookieReplyMessage), + Other(Vec<u8>) +} + +// TODO use TryFrom +impl<'a> From<&'a [u8]> for Message { + fn from(bytes: &'a [u8]) -> Self { + use self::Message::*; + let mut cursor = Cursor::new(bytes); + match cursor.read_u8().unwrap() { + 1 => HandshakeInitiation(HandshakeInitiationMessage::from(&bytes[4..])), + _ => Other((&bytes[4..]).to_owned()) + } + } +} + +impl From<Message> for Vec<u8> { + fn from(message: Message) -> Self { + use self::Message::*; + match message { + HandshakeInitiation(message) => { + let mut bytes = vec![1u8, 0, 0, 0]; + bytes.append(&mut message.into()); + bytes + }, + _ => unimplemented!() + } + } +} + +pub struct HandshakeInitiationMessage { + pub sender_i: u32, + pub payload: [u8; 76], + pub mac1: [u8; 16], + pub mac2: [u8; 16] +} + +impl HandshakeInitiationMessage { + pub fn new() -> Self { + HandshakeInitiationMessage { + sender_i: 0, + payload: [0u8; 76], + mac1: [0u8; 16], + mac2: [0u8; 16], + } + } +} + +impl<'a> From<&'a [u8]> for HandshakeInitiationMessage { + + fn from(bytes: &'a [u8]) -> Self { + let mut message = HandshakeInitiationMessage::new(); + let mut cursor = Cursor::new(bytes); + + message.sender_i = cursor.read_u32::<LittleEndian>().unwrap(); + cursor.read_exact(&mut message.payload[..]).unwrap(); + cursor.read_exact(&mut message.mac1[..]).unwrap(); + cursor.read_exact(&mut message.mac2[..]).unwrap(); + message + } +} + +impl From<HandshakeInitiationMessage> for Vec<u8> { + fn from(message: HandshakeInitiationMessage) -> Self { + let mut cursor = vec![]; + cursor.write_all(&[1u8, 0, 0, 0]).unwrap(); + cursor.write_u32::<LittleEndian>(message.sender_i).unwrap(); + cursor.write_all(&message.payload).unwrap(); + cursor.write_all(&message.mac1).unwrap(); + cursor.write_all(&message.mac2).unwrap(); + + cursor + } +}
\ No newline at end of file |