diff --git a/Cargo.lock b/Cargo.lock index 63782ef..2781e43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,7 +81,7 @@ checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -92,7 +92,7 @@ checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -242,6 +242,43 @@ dependencies = [ "inout", ] +[[package]] +name = "clap" +version = "4.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce38afc168d8665cfc75c7b1dd9672e50716a137f433f070991619744a67342a" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fddf67631444a3a3e3e5ac51c36a5e01335302de677bd78759eaa90ab1f46644" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[package]] +name = "clap_lex" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -428,7 +465,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn", + "syn 1.0.107", ] [[package]] @@ -445,7 +482,7 @@ checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -488,7 +525,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -576,6 +613,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -611,6 +669,18 @@ dependencies = [ "version_check", ] +[[package]] +name = "filetime" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.45.0", +] + [[package]] name = "flate2" version = "1.0.25" @@ -852,12 +922,24 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + [[package]] name = "hkdf" version = "0.12.3" @@ -934,6 +1016,19 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.53" @@ -1017,6 +1112,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd6da19f25979c7270e70fa95ab371ec3b701cd0eefc47667a09785b3c59155" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.45.0", +] + [[package]] name = "ipnet" version = "2.7.1" @@ -1026,6 +1132,18 @@ dependencies = [ "serde", ] +[[package]] +name = "is-terminal" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.45.0", +] + [[package]] name = "itertools" version = "0.10.5" @@ -1077,6 +1195,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "lock_api" version = "0.4.9" @@ -1310,7 +1434,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1332,6 +1456,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + [[package]] name = "overload" version = "0.1.1" @@ -1422,7 +1552,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1505,10 +1635,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] -name = "proc-macro2" -version = "1.0.50" +name = "proc-macro-error" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.107", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" dependencies = [ "unicode-ident", ] @@ -1521,7 +1675,7 @@ checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "version_check", "yansi", ] @@ -1543,9 +1697,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -1626,7 +1780,7 @@ checksum = "9f9c0c92af03644e4806106281fe2e068ac5bc0ae74a707266d06ea27bccee5f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1654,12 +1808,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "reqwest" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" dependencies = [ - "winapi", + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", ] [[package]] @@ -1713,7 +1895,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn", + "syn 1.0.107", "unicode-xid", ] @@ -1744,6 +1926,20 @@ dependencies = [ "uncased", ] +[[package]] +name = "rustix" +version = "0.36.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fe885c3a125aa45213b68cc1472a49880cb5923dc23f522ad2791b882228778" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.45.0", +] + [[package]] name = "rustversion" version = "1.0.11" @@ -1808,22 +2004,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.152" +version = "1.0.157" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "707de5fcf5df2b5788fca98dd7eab490bc2fd9b7ef1404defc462833b83f25ca" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.157" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "78997f4555c22a7971214540c4a661291970619afd56de19f77e0de86296e1e5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.2", ] [[package]] @@ -1846,6 +2042,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha1" version = "0.10.5" @@ -2019,7 +2227,7 @@ dependencies = [ "sha2", "sqlx-core", "sqlx-rt", - "syn", + "syn 1.0.107", "url", ] @@ -2063,6 +2271,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.4.1" @@ -2080,6 +2294,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59d3276aee1fa0c33612917969b5172b5be2db051232a6e4826f1a1a9191b045" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -2088,22 +2313,32 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "unicode-xid", ] [[package]] -name = "tempfile" -version = "3.3.0" +name = "tar" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" dependencies = [ "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.42.0", ] [[package]] @@ -2118,6 +2353,17 @@ dependencies = [ [[package]] name = "tfclient" version = "0.1.0" +dependencies = [ + "clap", + "flate2", + "hex", + "hex-literal", + "reqwest", + "serde", + "sha2", + "tar", + "tempfile", +] [[package]] name = "thiserror" @@ -2136,7 +2382,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2229,7 +2475,7 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2355,7 +2601,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2561,7 +2807,7 @@ checksum = "c1b300a878652a387d2a0de915bdae8f1a548f0c6d45e072fe2688794b656cc9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2631,10 +2877,22 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.84" @@ -2653,7 +2911,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2839,6 +3097,15 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "x25519-dalek" version = "2.0.0-pre.1" @@ -2850,6 +3117,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "xattr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +dependencies = [ + "libc", +] + [[package]] name = "yansi" version = "0.5.1" @@ -2873,6 +3149,6 @@ checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "synstructure", ] diff --git a/tfclient/Cargo.toml b/tfclient/Cargo.toml index 04938fe..be9c617 100644 --- a/tfclient/Cargo.toml +++ b/tfclient/Cargo.toml @@ -2,7 +2,19 @@ name = "tfclient" version = "0.1.0" edition = "2021" +description = "An open-source reimplementation of a Defined Networking-compatible client" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +clap = { version = "4.1.10", features = ["derive"] } +hex-literal = "0.3.4" + +[build-dependencies] +serde = { version = "1.0.157", features = ["derive"] } +reqwest = { version = "0.11.14", features = ["blocking", "json"] } +flate2 = "1.0.25" +tar = "0.4.38" +hex = "0.4.3" +tempfile = "3.4.0" +sha2 = "0.10.6" \ No newline at end of file diff --git a/tfclient/build.rs b/tfclient/build.rs new file mode 100644 index 0000000..27fbdfe --- /dev/null +++ b/tfclient/build.rs @@ -0,0 +1,298 @@ +/* +[ + { + "url": "https://api.github.com/repos/octocat/Hello-World/releases/1", + "html_url": "https://github.com/octocat/Hello-World/releases/v1.0.0", + "assets_url": "https://api.github.com/repos/octocat/Hello-World/releases/1/assets", + "upload_url": "https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label}", + "tarball_url": "https://api.github.com/repos/octocat/Hello-World/tarball/v1.0.0", + "zipball_url": "https://api.github.com/repos/octocat/Hello-World/zipball/v1.0.0", + "id": 1, + "node_id": "MDc6UmVsZWFzZTE=", + "tag_name": "v1.0.0", + "target_commitish": "master", + "name": "v1.0.0", + "body": "Description of the release", + "draft": false, + "prerelease": false, + "created_at": "2013-02-27T19:35:32Z", + "published_at": "2013-02-27T19:35:32Z", + "author": { + "login": "octocat", + "id": 1, + "node_id": "MDQ6VXNlcjE=", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "assets": [ + { + "url": "https://api.github.com/repos/octocat/Hello-World/releases/assets/1", + "browser_download_url": "https://github.com/octocat/Hello-World/releases/download/v1.0.0/example.zip", + "id": 1, + "node_id": "MDEyOlJlbGVhc2VBc3NldDE=", + "name": "example.zip", + "label": "short description", + "state": "uploaded", + "content_type": "application/zip", + "size": 1024, + "download_count": 42, + "created_at": "2013-02-27T19:35:32Z", + "updated_at": "2013-02-27T19:35:32Z", + "uploader": { + "login": "octocat", + "id": 1, + "node_id": "MDQ6VXNlcjE=", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + } + } + ] + } +] + */ + + +use std::fs; +use std::fs::{File, remove_file}; +use std::io::{Read, Write}; +use std::os::unix::fs::PermissionsExt; +use std::path::Path; +use std::process::{Command, Output}; +use flate2::read::GzDecoder; +use reqwest::blocking::Response; +use reqwest::header::HeaderMap; +use tar::Archive; +use tempfile::{NamedTempFile, tempfile}; + +#[derive(serde::Deserialize, Debug)] +struct GithubRelease { + url: String, + html_url: String, + assets_url: String, + upload_url: String, + tarball_url: String, + zipball_url: String, + id: i64, + node_id: String, + tag_name: String, + target_commitish: String, + name: String, + body: String, + draft: bool, + prerelease: bool, + created_at: String, + published_at: String, + author: GithubUser, + assets: Vec +} + +#[derive(serde::Deserialize, Debug)] +struct GithubUser { + login: String, + id: i64, + node_id: String, + avatar_url: String, + gravatar_id: String, + url: String, + html_url: String, + followers_url: String, + following_url: String, + gists_url: String, + starred_url: String, + subscriptions_url: String, + organizations_url: String, + repos_url: String, + events_url: String, + received_events_url: String, + r#type: String, + site_admin: bool +} + +#[derive(serde::Deserialize, Debug)] +struct GithubReleaseAsset { + url: String, + browser_download_url: String, + id: i64, + node_id: String, + name: String, + label: String, + state: String, + content_type: String, + size: i64, + download_count: i64, + created_at: String, + updated_at: String, + uploader: GithubUser +} + +fn main() { + println!("[*] Fetching nebula releaseinfo..."); + + let mut headers = HeaderMap::new(); + let mut has_api_key = false; + + if let Ok(api_key) = std::env::var("GH_API_KEY") { + headers.insert("Authorization", format!("Bearer {}", api_key).parse().unwrap()); + has_api_key = true; + } + + let client = reqwest::blocking::Client::builder().user_agent("curl/7.57.1").default_headers(headers).build().unwrap(); + + let resp: Response = client.get("https://api.github.com/repos/slackhq/nebula/releases/latest").send().unwrap(); + + if resp.headers().get("X-Ratelimit-Remaining").unwrap().to_str().unwrap() == "0" { + println!("You've been ratelimited from the GitHub API. Wait a while (1 hour)"); + if !has_api_key { + println!("You can also set a GitHub API key with the environment variable GH_API_KEY, which will increase your ratelimit ( a lot )"); + } + panic!("Ratelimited"); + } + + + let release: GithubRelease = resp.json().unwrap(); + + println!("[*] Fetching target triplet..."); + let target = std::env::var("TARGET").unwrap(); + + println!("[*] Compiling for target {}", target); + + let target_file = match target.as_str() { + "x86_64-apple-darwin" | "aarch64-apple-darwin" => "nebula-darwin", + "x86_64-unknown-freebsd" => "nebula-freebsd-amd64", + "x86_64-unknown-linux-gnu" => "nebula-linux-amd64", + "armv5te-unknown-linux-gnueabi" => "nebula-linux-arm-5", + "arm-unknown-linux-gnueabi" | "arm-unknown-linux-gnueabihf" => "nebula-linux-arm-6", + "armv7-unknown-linux-gnueabihf" | "armv7-unknown-linux-gnueabi" => "nebula-linux-arm-7", + "aarch64-unknown-linux-gnu" => "nebula-linux-arm64", + "x86_64-pc-windows-msvc" => "nebula-windows-amd64", + "aarch64-pc-windows-msvc" => "nebula-windows-arm64", + _ => { + println!("This architecture is not supported yet :("); + println!("Nebula has a limited set of architectures it is able to function on."); + println!("tfclient can only be compiled on these architectures."); + println!("See https://github.com/slackhq/nebula/releases for a list of supported architectures"); + println!("Is your system supported by Nebula? Shoot a message to the mailing list. Include the target triplet (above) in your response, as well as a link to the functioning Nebula binary. We will happily add your machine to the list!"); + panic!("Unsupported architecture"); + } + }; + + println!("[*] Embedding {} {}", target_file, release.name); + + let download = release.assets.iter().find(|r| r.name == format!("{}.tar.gz", target_file)).expect("That architecture isn't avaliable :("); + + println!("[*] Downloading {}.tar.gz ({}, {} bytes) from {}", target_file, target, download.size, download.browser_download_url); + + let response = reqwest::blocking::get(&download.browser_download_url).unwrap(); + let content = response.bytes().unwrap().to_vec(); + let bytes = content.as_slice(); + + let tar = GzDecoder::new(bytes); + let mut archive = Archive::new(tar); + let entries = archive.entries().unwrap(); + + let mut nebula_bin = vec![]; + let mut nebula_cert_bin = vec![]; + let mut shasum = vec![]; + + for entry in entries { + let mut entry = entry.unwrap(); + if entry.path().unwrap() == Path::new("nebula") || entry.path().unwrap() == Path::new("nebula.exe") { + nebula_bin.reserve(entry.size() as usize); + entry.read_to_end(&mut nebula_bin).unwrap(); + } else if entry.path().unwrap() == Path::new("nebula-cert") || entry.path().unwrap() == Path::new("nebula-cert.exe") { + nebula_cert_bin.reserve(entry.size() as usize); + entry.read_to_end(&mut nebula_cert_bin).unwrap(); + } else if entry.path().unwrap() == Path::new("SHASUM256.txt") { + shasum.reserve(entry.size() as usize); + entry.read_to_end(&mut shasum).unwrap(); + } + } + + if nebula_bin.is_empty() { + panic!("[x] Release did not contain nebula binary"); + } + if nebula_cert_bin.is_empty() { + panic!("[x] Release did not contain nebula_cert binary"); + } + + let mut nebula_file = File::create(format!("{}/nebula.bin", std::env::var("OUT_DIR").unwrap())).unwrap(); + nebula_file.write_all(&nebula_bin).unwrap(); + + codegen_version(&nebula_bin, "nebula.bin", "NEBULA"); + + let mut nebula_cert_file = File::create(format!("{}/nebula_cert.bin", std::env::var("OUT_DIR").unwrap())).unwrap(); + nebula_cert_file.write_all(&nebula_cert_bin).unwrap(); + + codegen_version(&nebula_cert_bin, "nebula_cert.bin", "NEBULA_CERT"); + + // get version info and codegen + + println!("cargo:rerun-if-changed=build.rs"); +} + +fn codegen_version(bin: &[u8], fp: &str, name: &str) { + // get version + let output = execim(bin, &vec!["-version"]); + let stdout = output.stdout; + let stdout_str = String::from_utf8(stdout).unwrap(); + if !stdout_str.starts_with("Version: ") { + panic!("Binary did not have expected version output. Unable to get version info."); + } + let mut version = stdout_str.split(' ').collect::>()[1].to_string(); + version.pop(); + + let code = format!("// This code was automatically @generated by build.rs. It should not be modified.\npub const {}_BIN: &[u8] = include_bytes!(concat!(env!(\"OUT_DIR\"), \"/{}\"));\npub const {}_VERSION: &str = \"{}\";", name, fp, name, version); + + let mut file = File::create(format!("{}/{}.rs", std::env::var("OUT_DIR").unwrap(), fp)).unwrap(); + file.write_all(code.as_bytes()).unwrap(); +} + +#[cfg(not(unix))] +fn execim(buf: &[u8], args: &Vec<&str>) -> Output { + let mut file = File::create("tmpexec.bin").unwrap(); + file.write_all(buf).unwrap(); + std::mem::drop(file); + let output = Command::new("./tmpexec.bin").args(args).output().unwrap(); + remove_file("./tmpexec.bin").unwrap(); + output +} + +#[cfg(unix)] +fn execim(buf: &[u8], args: &Vec<&str>) -> Output { + let mut file = File::create("tmpexec.bin").unwrap(); + file.write_all(buf).unwrap(); + let metadata = file.metadata().unwrap(); + let mut permissions = metadata.permissions(); + permissions.set_mode(0o0755); + fs::set_permissions("./tmpexec.bin", permissions).unwrap(); + std::mem::drop(file); + let output = Command::new("./tmpexec.bin").args(args).output().unwrap(); + remove_file("./tmpexec.bin").unwrap(); + output +} \ No newline at end of file diff --git a/tfclient/src/main.rs b/tfclient/src/main.rs index 82c783f..f420b51 100644 --- a/tfclient/src/main.rs +++ b/tfclient/src/main.rs @@ -14,6 +14,36 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -fn main() { - println!("Hello, world!"); +pub mod nebula_bin { + include!(concat!(env!("OUT_DIR"), "/nebula.bin.rs")); } +pub mod nebula_cert_bin { + include!(concat!(env!("OUT_DIR"), "/nebula_cert.bin.rs")); +} + +use clap::{Parser, ArgAction}; + +#[derive(Parser)] +#[command(author = "c0repwn3r", version, about, long_about = None)] +#[clap(disable_version_flag = true)] +struct Cli { + #[arg(short = 'v', long = "version", action = ArgAction::SetTrue)] + #[clap(global = true)] + version: bool + + +} + +fn main() { + let args = Cli::parse(); + + if args.version { + print_version(); + } +} + +fn print_version() { + println!("tfclient v{}", env!("CARGO_PKG_VERSION")); + println!("embedded nebula v{}", crate::nebula_bin::NEBULA_VERSION); + println!("embedded nebula-cert v{}", crate::nebula_cert_bin::NEBULA_CERT_VERSION); +} \ No newline at end of file