Changes to be committed:

modified:   Cargo.lock
	modified:   Cargo.toml
	modified:   src/client.rs
	modified:   src/main.rs
	modified:   src/server.rs
This commit is contained in:
Michael Wain 2024-08-20 19:46:15 +03:00
parent 5d8c35db45
commit 1f5a198d42
5 changed files with 87 additions and 208 deletions

210
Cargo.lock generated
View File

@ -27,18 +27,6 @@ dependencies = [
"generic-array",
]
[[package]]
name = "aes"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
dependencies = [
"cfg-if",
"cipher 0.3.0",
"cpufeatures",
"opaque-debug",
]
[[package]]
name = "aes"
version = "0.8.4"
@ -57,23 +45,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
dependencies = [
"aead",
"aes 0.8.4",
"aes",
"cipher 0.4.4",
"ctr",
"ghash",
"subtle",
]
[[package]]
name = "aes-soft"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072"
dependencies = [
"cipher 0.2.5",
"opaque-debug",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
@ -271,27 +249,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "cipher"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801"
dependencies = [
"generic-array",
]
[[package]]
name = "cipher"
version = "0.3.0"
@ -381,26 +344,6 @@ dependencies = [
"cipher 0.4.4",
]
[[package]]
name = "ctrlc"
version = "3.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345"
dependencies = [
"nix 0.28.0",
"windows-sys 0.52.0",
]
[[package]]
name = "ctrlc2"
version = "3.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76b9bdf0b3623a4c37b654b319624bae363b94c4e27c22db8d48a61c6d74234f"
dependencies = [
"nix 0.28.0",
"windows-sys 0.52.0",
]
[[package]]
name = "curve25519-dalek"
version = "4.1.3"
@ -670,12 +613,6 @@ dependencies = [
"generic-array",
]
[[package]]
name = "ioctl-sys"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bd11f3a29434026f5ff98c730b668ba74b1033637b8817940b54d040696133c"
[[package]]
name = "ipnet"
version = "2.9.0"
@ -731,7 +668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
dependencies = [
"cfg-if",
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@ -882,18 +819,6 @@ dependencies = [
"libc",
]
[[package]]
name = "nix"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
dependencies = [
"bitflags 2.6.0",
"cfg-if",
"cfg_aliases 0.1.1",
"libc",
]
[[package]]
name = "nix"
version = "0.29.0"
@ -902,7 +827,7 @@ checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.6.0",
"cfg-if",
"cfg_aliases 0.2.1",
"cfg_aliases",
"libc",
]
@ -975,7 +900,7 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@ -1278,9 +1203,7 @@ dependencies = [
name = "rustvpn"
version = "0.1.2"
dependencies = [
"aes 0.7.5",
"aes-gcm",
"aes-soft",
"anyhow",
"base64",
"bincode",
@ -1288,8 +1211,6 @@ dependencies = [
"block-padding",
"clap",
"crossbeam-channel",
"ctrlc",
"ctrlc2",
"env_logger",
"futures",
"generic-array",
@ -1304,7 +1225,6 @@ dependencies = [
"serde_yaml",
"socket2 0.4.10",
"tokio",
"tun",
"tun2",
"x25519-dalek",
]
@ -1517,19 +1437,6 @@ dependencies = [
"syn 2.0.72",
]
[[package]]
name = "tun"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0adb9992bbd5ca76f3847ed579ad4ee8defb2ec2eea918cceef17ccc66fa4fd4"
dependencies = [
"ioctl-sys",
"libc",
"log",
"thiserror",
"wintun 0.3.2",
]
[[package]]
name = "tun2"
version = "2.0.5"
@ -1545,7 +1452,7 @@ dependencies = [
"nix 0.29.0",
"thiserror",
"windows-sys 0.52.0",
"wintun 0.5.0",
"wintun",
]
[[package]]
@ -1643,32 +1550,13 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9"
dependencies = [
"windows-core",
"windows-targets 0.48.5",
]
[[package]]
name = "windows-core"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@ -1677,22 +1565,7 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
"windows-targets",
]
[[package]]
@ -1701,46 +1574,28 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
@ -1753,67 +1608,30 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "wintun"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29b83b0eca06dd125dbcd48a45327c708a6da8aada3d95a3f06db0ce4b17e0d4"
dependencies = [
"c2rust-bitfields",
"libloading",
"log",
"thiserror",
"windows",
]
[[package]]
name = "wintun"
version = "0.5.0"

View File

@ -8,16 +8,12 @@ edition = "2021"
[dependencies]
clap = "2.33"
aes-gcm = "0.10.3"
aes-soft = "0.6"
tokio = { version = "1", features = ["full", "signal"] }
tun = "0.6.1"
serde = "1.0"
serde_derive = "1.0.190"
bincode = "1.3"
rand = { version = "0.8.5", features = ["small_rng", "getrandom", "std_rng"] }
anyhow = "1.0"
ctrlc = "3.1"
aes = "0.7"
block-modes = "0.8"
block-padding = "0.2"
generic-array = "0.14"
@ -27,7 +23,6 @@ log = "0.4.20"
futures = "0.3.30"
tun2 = "2.0.5"
packet = "0.1.4"
ctrlc2 = "3.5"
crossbeam-channel = "0.5.13"
pnet = "0.35.0"
net-route = "0.4.4"

View File

@ -10,6 +10,10 @@ use std::net::{ SocketAddr, Ipv4Addr };
use std::collections::HashMap;
use std::process::Command;
use tokio::io::AsyncReadExt;
use x25519_dalek::{PublicKey, SharedSecret, StaticSecret};
use aes_gcm::{
aead::{Aead, AeadCore, KeyInit, OsRng},
Aes256Gcm, Key, Nonce};
use crate::{UDPVpnHandshake, UDPVpnPacket, VpnPacket, ClientConfiguration, UDPSerializable};
@ -88,6 +92,8 @@ pub async fn client_mode(client_config: ClientConfiguration) {
let (tx, rx) = unbounded::<Vec<u8>>();
let (dx, mx) = unbounded::<Vec<u8>>();
let cipher_shared = Arc::new(Mutex::new(None));
tokio::spawn(async move {
while let Ok(bytes) = rx.recv() {
info!("Write to tun {:?}", hex::encode(&bytes));
@ -102,11 +108,49 @@ pub async fn client_mode(client_config: ClientConfiguration) {
}
});
let priv_key = base64::decode(client_config.client.private_key).unwrap();
let cipher_shared_clone = cipher_shared.clone();
tokio::spawn(async move {
let mut buf = vec![0; 4096];
loop {
if let Ok(l) = sock_rec.recv(&mut buf).await {
tx.send((&buf[..l]).to_vec());
let mut s_cipher = cipher_shared_clone.lock().await;
match buf.first() {
Some(h) => {
match h {
0 => {
let handshake = UDPVpnHandshake::deserialize(&(buf[..l].to_vec()));
let mut k = [0u8; 32];
for (&x, p) in handshake.public_key.iter().zip(k.iter_mut()) {
*p = x;
}
let mut k1 = [0u8; 32];
for (&x, p) in priv_key.iter().zip(k1.iter_mut()) {
*p = x;
}
*s_cipher = Some(StaticSecret::from(k1)
.diffie_hellman(&PublicKey::from(k)));
// Aes256Gcm::new(shared_secret.as_bytes().into());
}, // handshake
1 => {
let wrapped_packet = UDPVpnPacket::deserialize(&(buf[..l].to_vec()));
if s_cipher.is_some() {
let aes = Aes256Gcm::new(s_cipher.as_ref().unwrap().as_bytes().into());
let nonce = Nonce::clone_from_slice(&wrapped_packet.nonce);
match aes.decrypt(&nonce, &wrapped_packet.data[..]) {
Ok(decrypted) => { tx.send(decrypted); },
Err(error) => error!("Decryption error! {:?}", error)
}
}
}, // payload
_ => error!("Unexpected header value.")
}
},
None => error!("There is no header.")
}
drop(s_cipher);
}
}
});
@ -115,12 +159,24 @@ pub async fn client_mode(client_config: ClientConfiguration) {
let handshake = UDPVpnHandshake{ public_key: pkey, request_ip: client_config.client.address.parse::<Ipv4Addr>().unwrap() };
sock_snd.send(&handshake.serialize()).await.unwrap();
let s_cipher = cipher_shared.clone();
loop {
if let Ok(bytes) = mx.recv() {
let vpn_packet = UDPVpnPacket{ data: bytes };
let serialized_data = vpn_packet.serialize();
info!("Writing to sock: {:?}", serialized_data);
sock_snd.send(&serialized_data).await.unwrap();
let mut s_c = s_cipher.lock().await;
if s_c.is_some() {
let aes = Aes256Gcm::new(s_c.as_ref().unwrap().as_bytes().into());
let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
let ciphered_data = aes.encrypt(&nonce, &bytes[..]);
if let Ok(ciphered_d) = ciphered_data {
let vpn_packet = UDPVpnPacket{ data: ciphered_d, nonce: nonce.to_vec()};
let serialized_data = vpn_packet.serialize();
info!("Writing to sock: {:?}", serialized_data);
sock_snd.send(&serialized_data).await.unwrap();
}
}
}
}
}

View File

@ -4,7 +4,6 @@ use std::process::Command;
use clap::{App, Arg, ArgMatches};
use env_logger::Builder;
use log::{error, info, warn, LevelFilter};
use tun::platform::Device;
use serde_derive::Serialize;
use serde_derive::Deserialize;
use std::str::FromStr;
@ -36,13 +35,20 @@ impl VpnPacket {
}
struct UDPVpnPacket {
nonce: Vec<u8>, // [u8; 64]
data: Vec<u8>
}
impl UDPSerializable for UDPVpnPacket {
fn serialize(&self) -> Vec<u8> {
let h: &[u8] = &[1];
[h, &self.data[..]].concat()
[h, &self.nonce, &self.data[..]].concat()
}
}
impl UDPVpnPacket {
fn deserialize(data: &Vec<u8>) -> Self {
UDPVpnPacket { nonce: data[1..=64].to_vec(), data: data[65..].to_vec() }
}
}

View File

@ -100,6 +100,10 @@ pub async fn server_mode(server_config: ServerConfiguration) {
let shared_secret = StaticSecret::from(k1)
.diffie_hellman(&PublicKey::from(k));
mp.insert(internal_ip, UDPeer { addr, shared_secret });
let handshake_response = UDPVpnHandshake{ public_key: server_config.interface.public_key.clone().into_bytes(), request_ip: handshake.request_ip };
sock_rec.send_to(&handshake_response.serialize(), addr);
} else {
info!("Bad handshake");
plp.iter().for_each(|c| info!("ip: {:?}; pkey: {:?}", c.ip, c.public_key));