From 52963992311a0d15c74085b4934f8e75b01cfd39 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Mon, 14 Apr 2025 16:48:00 +0300 Subject: [PATCH 01/16] some fixes and improvements --- .gitignore | 1 + Cargo.lock | 7 +++++++ PROTOCOL.md | 4 +--- README.md | 10 +++++++++- config.yml | 4 ---- src/main.rs | 28 ++++++++++++++++++++++++++-- 6 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 .gitignore create mode 100644 Cargo.lock delete mode 100644 config.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c41cc9e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..c74d07f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "sRAC" +version = "0.1.0" diff --git a/PROTOCOL.md b/PROTOCOL.md index bb93075..029f1ea 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -55,9 +55,7 @@ Client sends: Server sends: -- `0x00` if successful or `0x01` if the username is already taken - -*legacy servers send nothing on successful registration* +- `0x01` if the username is already taken ## Sending authorized messages diff --git a/README.md b/README.md index 37b4359..25376c5 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,10 @@ # sRAC -server for RAC +simple server for RAC + +## Usage + +```bash +git clone https://github.com/MeexReay/sRAC +cd sRAC +cargo run 127.0.0.1:42666 +``` \ No newline at end of file diff --git a/config.yml b/config.yml deleted file mode 100644 index b2b221d..0000000 --- a/config.yml +++ /dev/null @@ -1,4 +0,0 @@ -host: 127.0.0.1:42666 - -threadpool: 10 -timeout: 5 # in seconds diff --git a/src/main.rs b/src/main.rs index e7a11a9..ef67405 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,27 @@ -fn main() { - println!("Hello, world!"); +use std::{env::args, error::Error, io::Read, net::{TcpListener, TcpStream}, thread}; + +fn accept_stream(mut stream: TcpStream) -> Result<(), Box> { + let mut buf = vec![0; 4096]; + + stream.read(&mut buf)?; + + if buf[0] + + Ok(()) +} + +fn main() { + let addr = args().skip(1).next().expect("needs at least 1 argument (host:port)"); + + let listener = TcpListener::bind(&addr).expect("error trying bind to the provided addr"); + + println!("Server started on {}", &addr); + + for stream in listener.incoming() { + let Ok(stream) = stream else { continue }; + + thread::spawn(move || { + let _ = accept_stream(stream); + }); + } } From fadeff53e02bb4451e0021dd549d2ef473d8b319 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Mon, 14 Apr 2025 17:30:56 +0300 Subject: [PATCH 02/16] accept stream write --- src/main.rs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index ef67405..944abd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,30 @@ -use std::{env::args, error::Error, io::Read, net::{TcpListener, TcpStream}, thread}; +use std::{env::args, error::Error, io::{Read, Write}, net::{TcpListener, TcpStream}, sync::{Arc, RwLock}, thread}; -fn accept_stream(mut stream: TcpStream) -> Result<(), Box> { +fn accept_stream(mut stream: TcpStream, messages: Arc>>) -> Result<(), Box> { let mut buf = vec![0; 4096]; + let size = stream.read(&mut buf)?; + buf.truncate(size); - stream.read(&mut buf)?; + if buf[0] == 0x01 && size == 1 { + stream.write_all(messages.read().unwrap().len().to_string().as_bytes())?; - if buf[0] + let mut buf = vec![0, 16]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + if buf[0] == 0x01 { + stream.write_all(&messages.read().unwrap())?; + } else if buf[0] == 0x02 { + let len: usize = String::from_utf8(buf[1..].to_vec())?.parse()?; + stream.write_all(&messages.read().unwrap().clone()[len..])?; + } + } else if buf[0] == 0x01 { + messages.write().unwrap().append(&mut buf[1..].to_vec()); + } else if buf[0] == 0x02 { + + } else if buf[0] == 0x03 { + + } Ok(()) } @@ -15,13 +34,17 @@ fn main() { let listener = TcpListener::bind(&addr).expect("error trying bind to the provided addr"); + let messages = Arc::new(RwLock::new(Vec::new())); + println!("Server started on {}", &addr); for stream in listener.incoming() { let Ok(stream) = stream else { continue }; + let messages = messages.clone(); + thread::spawn(move || { - let _ = accept_stream(stream); + let _ = accept_stream(stream, messages); }); } } From 151f0bbe7e09e034ba2076ec3b8b5c11a6cb8bd9 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Mon, 14 Apr 2025 17:36:36 +0300 Subject: [PATCH 03/16] protocol fix --- PROTOCOL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PROTOCOL.md b/PROTOCOL.md index 029f1ea..938fd2d 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -15,7 +15,7 @@ Client sends: Client sends: -- Byte `0x01` +- Byte `0x00` Server sends: From 472ff208582cfe8e581132d0fdbed6fa4f5c609e Mon Sep 17 00:00:00 2001 From: MeexReay Date: Mon, 14 Apr 2025 19:16:44 +0300 Subject: [PATCH 04/16] fix whole program --- Cargo.lock | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + PROTOCOL.md | 24 ++--- src/main.rs | 67 +++++++++--- 4 files changed, 353 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c74d07f..2ac5fac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,296 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "cc" +version = "1.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + [[package]] name = "sRAC" version = "0.1.0" +dependencies = [ + "chrono", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-core" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] diff --git a/Cargo.toml b/Cargo.toml index 5af9e23..164ef45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] +chrono = "0.4.40" diff --git a/PROTOCOL.md b/PROTOCOL.md index 938fd2d..da20e60 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -44,6 +44,17 @@ Server sends: *for example: if you want to read last N bytes, last_size = data_size - N* +## Sending authorized messages + +Client sends: + +- Byte `0x02` +- Username +- `\n` +- Password +- `\n` +- Message + ## Registration users Client sends: @@ -55,15 +66,4 @@ Client sends: Server sends: -- `0x01` if the username is already taken - -## Sending authorized messages - -Client sends: - -- Byte `0x02` -- Username -- `\n` -- Password -- `\n` -- Message +- `0x01` if the username is already taken \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 944abd8..b75bb45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,29 +1,62 @@ use std::{env::args, error::Error, io::{Read, Write}, net::{TcpListener, TcpStream}, sync::{Arc, RwLock}, thread}; +use chrono::{DateTime, Local, TimeZone}; + +fn message_prefix(time_millis: i64, address: &str) -> String { + let datetime: DateTime = Local.timestamp_millis_opt(time_millis).unwrap(); + format!( + "[{}] {{{}}}", + datetime.format("%d.%m.%Y %H:%M"), + address + ) +} + fn accept_stream(mut stream: TcpStream, messages: Arc>>) -> Result<(), Box> { - let mut buf = vec![0; 4096]; - let size = stream.read(&mut buf)?; - buf.truncate(size); + let mut buf = vec![0]; + stream.read_exact(&mut buf)?; - if buf[0] == 0x01 && size == 1 { - stream.write_all(messages.read().unwrap().len().to_string().as_bytes())?; + if buf[0] == 0x00 { + let messages = messages.read().unwrap().clone(); - let mut buf = vec![0, 16]; + stream.write_all(messages.len().to_string().as_bytes())?; + + let mut id = vec![0]; + stream.read_exact(&mut id)?; + + if id[0] == 0x01 { + stream.write_all(&messages)?; + } else if id[0] == 0x02 { + let mut buf = vec![0; 10]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + let len: usize = String::from_utf8(buf)?.parse()?; + stream.write_all(&messages[len..])?; + } + } else if buf[0] == 0x01 { + let mut buf = vec![0; 4096]; let size = stream.read(&mut buf)?; buf.truncate(size); - if buf[0] == 0x01 { - stream.write_all(&messages.read().unwrap())?; - } else if buf[0] == 0x02 { - let len: usize = String::from_utf8(buf[1..].to_vec())?.parse()?; - stream.write_all(&messages.read().unwrap().clone()[len..])?; - } - } else if buf[0] == 0x01 { - messages.write().unwrap().append(&mut buf[1..].to_vec()); - } else if buf[0] == 0x02 { - - } else if buf[0] == 0x03 { + let mut msg = Vec::new(); + msg.append(&mut message_prefix( + Local::now().timestamp_millis(), + &stream.peer_addr()?.ip().to_string()).as_bytes().to_vec() + ); + msg.push(b' '); + msg.append(&mut buf); + + println!("{}", String::from_utf8_lossy(&msg)); + + msg.push(b'\n'); + + messages.write().unwrap().append(&mut msg.clone()); + + } else if buf[0] == 0x02 { + // sending authorized messages + } else if buf[0] == 0x03 { + // user registration } Ok(()) From 7834e4ccfd0e38f81b08472b543f5d4a6d0fbce9 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Mon, 14 Apr 2025 20:45:04 +0300 Subject: [PATCH 05/16] bring formatting from bRAC --- Cargo.lock | 948 +++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 1 + src/main.rs | 6 +- 3 files changed, 949 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ac5fac..a52d997 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -17,12 +26,91 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "bRAC" +version = "0.1.1+2.0" +source = "git+https://github.com/MeexReay/bRAC.git#7bf88324e29d96b96861893a0b3f21d1c524b415" +dependencies = [ + "clap", + "colored", + "crossterm", + "homedir", + "lazy_static", + "native-tls", + "rand", + "regex", + "serde", + "serde_yml", +] + +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + [[package]] name = "bumpalo" version = "3.17.0" @@ -44,6 +132,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.40" @@ -58,12 +152,216 @@ dependencies = [ "windows-link", ] +[[package]] +name = "clap" +version = "4.5.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "colored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "convert_case" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "crossterm" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +dependencies = [ + "bitflags", + "crossterm_winapi", + "derive_more", + "document-features", + "mio", + "parking_lot", + "rustix", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "homedir" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bdbbd5bc8c5749697ccaa352fa45aff8730cf21c68029c0eef1ffed7c3d6ba2" +dependencies = [ + "cfg-if", + "nix", + "widestring", + "windows", +] + [[package]] name = "iana-time-zone" version = "0.1.63" @@ -76,7 +374,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core", + "windows-core 0.61.0", ] [[package]] @@ -88,6 +386,28 @@ dependencies = [ "cc", ] +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + [[package]] name = "js-sys" version = "0.3.77" @@ -98,18 +418,103 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +[[package]] +name = "libyml" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980" +dependencies = [ + "anyhow", + "version_check", +] + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -125,6 +530,88 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "openssl" +version = "0.10.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" version = "1.0.94" @@ -143,25 +630,234 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha", + "rand_core", + "zerocopy", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustix" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + [[package]] name = "rustversion" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + [[package]] name = "sRAC" version = "0.1.0" dependencies = [ + "bRAC", "chrono", ] +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_yml" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" +dependencies = [ + "indexmap", + "itoa", + "libyml", + "memchr", + "ryu", + "serde", + "version_check", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.100" @@ -173,12 +869,64 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -237,19 +985,80 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "widestring" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement 0.57.0", + "windows-interface 0.57.0", + "windows-result 0.1.2", + "windows-targets", +] + [[package]] name = "windows-core" version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.60.0", + "windows-interface 0.59.1", "windows-link", - "windows-result", + "windows-result 0.3.2", "windows-strings", ] +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-implement" version = "0.60.0" @@ -261,6 +1070,17 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-interface" version = "0.59.1" @@ -278,6 +1098,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-result" version = "0.3.2" @@ -295,3 +1124,114 @@ checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" dependencies = [ "windows-link", ] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[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.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 164ef45..23bef20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,4 @@ edition = "2024" [dependencies] chrono = "0.4.40" +bRAC = { git = "https://github.com/MeexReay/bRAC.git" } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index b75bb45..1c88d83 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,8 +47,10 @@ fn accept_stream(mut stream: TcpStream, messages: Arc>>) -> Resul msg.push(b' '); msg.append(&mut buf); - println!("{}", String::from_utf8_lossy(&msg)); - + if let Some(msg) = bRAC::chat::format_message(true, String::from_utf8_lossy(&msg).to_string()) { + println!("{}", msg); + } + msg.push(b'\n'); messages.write().unwrap().append(&mut msg.clone()); From a49c4aaa2b718034c561e2e79246526fc59f1b16 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Mon, 14 Apr 2025 22:13:21 +0300 Subject: [PATCH 06/16] clap and auth mode --- Cargo.lock | 523 +++++----------------------------------------------- Cargo.toml | 5 +- PROTOCOL.md | 7 + src/main.rs | 237 ++++++++++++++++++++---- 4 files changed, 259 insertions(+), 513 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a52d997..37bd36e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -73,7 +73,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", "once_cell", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -90,15 +90,12 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bRAC" -version = "0.1.1+2.0" -source = "git+https://github.com/MeexReay/bRAC.git#7bf88324e29d96b96861893a0b3f21d1c524b415" +version = "0.1.2+2.0" +source = "git+https://github.com/MeexReay/bRAC.git?tag=0.1.2%2B2.0#52720c2748c3153f5ada996cc2b32366a9397549" dependencies = [ "clap", "colored", - "crossterm", - "homedir", "lazy_static", - "native-tls", "rand", "regex", "serde", @@ -111,6 +108,15 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.17.0" @@ -132,12 +138,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - [[package]] name = "chrono" version = "0.4.40" @@ -204,26 +204,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "convert_case" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", + "windows-sys", ] [[package]] @@ -233,60 +214,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "crossterm" -version = "0.29.0" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "bitflags", - "crossterm_winapi", - "derive_more", - "document-features", - "mio", - "parking_lot", - "rustix", - "signal-hook", - "signal-hook-mio", - "winapi", + "generic-array", + "typenum", ] [[package]] -name = "crossterm_winapi" -version = "0.9.1" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "winapi", -] - -[[package]] -name = "derive_more" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "document-features" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" -dependencies = [ - "litrs", + "block-buffer", + "crypto-common", ] [[package]] @@ -296,36 +240,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] -name = "errno" -version = "0.3.11" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "libc", - "windows-sys 0.59.0", + "typenum", + "version_check", ] -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "getrandom" version = "0.3.2" @@ -335,7 +258,7 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi", ] [[package]] @@ -350,18 +273,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "homedir" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bdbbd5bc8c5749697ccaa352fa45aff8730cf21c68029c0eef1ffed7c3d6ba2" -dependencies = [ - "cfg-if", - "nix", - "widestring", - "windows", -] - [[package]] name = "iana-time-zone" version = "0.1.63" @@ -374,7 +285,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.61.0", + "windows-core", ] [[package]] @@ -440,81 +351,28 @@ dependencies = [ "version_check", ] -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "litrs" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" -dependencies = [ - "libc", - "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", -] - -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags", - "cfg-if", - "cfg_aliases", - "libc", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -530,79 +388,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "openssl" -version = "0.10.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - [[package]] name = "ppv-lite86" version = "0.2.21" @@ -666,15 +451,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" version = "1.11.1" @@ -704,19 +480,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "rustix" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.59.0", -] - [[package]] name = "rustversion" version = "1.0.20" @@ -735,44 +498,9 @@ version = "0.1.0" dependencies = [ "bRAC", "chrono", -] - -[[package]] -name = "schannel" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" -dependencies = [ - "core-foundation-sys", - "libc", + "clap", + "md-5", + "rand", ] [[package]] @@ -816,42 +544,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" -dependencies = [ - "libc", - "mio", - "signal-hook", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "smallvec" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" - [[package]] name = "strsim" version = "0.11.1" @@ -870,17 +562,10 @@ dependencies = [ ] [[package]] -name = "tempfile" -version = "3.19.1" +name = "typenum" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" -dependencies = [ - "fastrand", - "getrandom", - "once_cell", - "rustix", - "windows-sys 0.59.0", -] +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" @@ -888,36 +573,18 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - [[package]] name = "wasi" version = "0.14.2+wasi-0.2.4" @@ -985,80 +652,19 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "widestring" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" -dependencies = [ - "windows-core 0.57.0", - "windows-targets", -] - -[[package]] -name = "windows-core" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" -dependencies = [ - "windows-implement 0.57.0", - "windows-interface 0.57.0", - "windows-result 0.1.2", - "windows-targets", -] - [[package]] name = "windows-core" version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-implement 0.60.0", - "windows-interface 0.59.1", + "windows-implement", + "windows-interface", "windows-link", - "windows-result 0.3.2", + "windows-result", "windows-strings", ] -[[package]] -name = "windows-implement" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-implement" version = "0.60.0" @@ -1070,17 +676,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-interface" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-interface" version = "0.59.1" @@ -1098,15 +693,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" -[[package]] -name = "windows-result" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-result" version = "0.3.2" @@ -1125,15 +711,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.59.0" diff --git a/Cargo.toml b/Cargo.toml index 23bef20..71bd3ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,7 @@ edition = "2024" [dependencies] chrono = "0.4.40" -bRAC = { git = "https://github.com/MeexReay/bRAC.git" } \ No newline at end of file +bRAC = { git = "https://github.com/MeexReay/bRAC.git", default-features = false, tag = "0.1.2+2.0" } +md-5 = "0.10.6" +rand = "0.9.0" +clap = { version = "4.5.36", features = ["derive"] } diff --git a/PROTOCOL.md b/PROTOCOL.md index da20e60..83655bd 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -55,6 +55,12 @@ Client sends: - `\n` - Message +Server sends: + +- nothing if message was sent successfully +- `0x01` if the user does not exists +- `0x02` if the password is incorrect + ## Registration users Client sends: @@ -66,4 +72,5 @@ Client sends: Server sends: +- nothing if user was registered successfully - `0x01` if the username is already taken \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 1c88d83..a8da05d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,85 +1,244 @@ -use std::{env::args, error::Error, io::{Read, Write}, net::{TcpListener, TcpStream}, sync::{Arc, RwLock}, thread}; +use std::{error::Error, io::{Read, Write}, net::{IpAddr, TcpListener, TcpStream}, sync::{Arc, RwLock}, thread}; +use bRAC::{chat::format_message, util::sanitize_text}; use chrono::{DateTime, Local, TimeZone}; +use md5::{Digest, Md5}; +use rand::{distr::Alphanumeric, Rng}; -fn message_prefix(time_millis: i64, address: &str) -> String { +use clap::Parser; + + +#[derive(Clone)] +pub struct Account { + name: String, + pass: String, + salt: String +} + +fn password_hash(name: &str, pass: &str, salt: &str) -> String { + let mut hasher = Md5::new(); + hasher.update(format!("{name}{pass}{salt}").as_bytes()); + let result = hasher.finalize().to_vec(); + String::from_utf8_lossy(&result).to_string() +} + +fn password_salt() -> String { + rand::rng() + .sample_iter(&Alphanumeric) + .take(16) + .map(char::from) + .collect() +} + +impl Account { + pub fn new(name: String, password: String) -> Self { + let salt = password_salt(); + + Account { + pass: password_hash(&name, &password, &salt), + name: name.clone(), + salt: salt.clone() + } + } + + pub fn check_password(&self, password: &str) -> bool { + password_hash(&self.name, password, &self.salt) == self.pass + } + + pub fn name(&self) -> &str { + &self.name + } +} + +fn message_prefix(time_millis: i64, address: Option) -> String { let datetime: DateTime = Local.timestamp_millis_opt(time_millis).unwrap(); + format!( - "[{}] {{{}}}", + "[{}]{} ", datetime.format("%d.%m.%Y %H:%M"), - address + if let Some(addr) = address { + format!(" {{{addr}}}") + } else { + String::new() + } ) } -fn accept_stream(mut stream: TcpStream, messages: Arc>>) -> Result<(), Box> { +fn add_message( + buf: &mut Vec, + messages: Arc>>, + addr: Option, + sanitize: bool +) -> Result<(), Box> { + let mut msg = Vec::new(); + + msg.append(&mut message_prefix( + Local::now().timestamp_millis(), + addr.map(|o| o.to_string()) + ).as_bytes().to_vec()); + + if sanitize { + msg.append(&mut sanitize_text(&String::from_utf8_lossy(&buf.clone())).as_bytes().to_vec()); + } else { + msg.append(buf); + } + + if let Some(msg) = format_message(addr.is_some(), String::from_utf8_lossy(&msg).to_string()) { + println!("{}", msg); + } + + msg.push(b'\n'); + + messages.write().unwrap().append(&mut msg.clone()); + + Ok(()) +} + +fn accept_stream( + args: Arc, + mut stream: TcpStream, + messages: Arc>>, + accounts: Arc>> +) -> Result<(), Box> { let mut buf = vec![0]; stream.read_exact(&mut buf)?; if buf[0] == 0x00 { - let messages = messages.read().unwrap().clone(); + let mut messages = messages.read().unwrap().clone(); - stream.write_all(messages.len().to_string().as_bytes())?; + if let Some(splash) = &args.splash { + stream.write_all((splash.len() + messages.len()).to_string().as_bytes())?; - let mut id = vec![0]; - stream.read_exact(&mut id)?; + let mut id = vec![0]; + stream.read_exact(&mut id)?; + + if id[0] == 0x01 { + messages.append(&mut splash.clone().as_bytes().to_vec()); + stream.write_all(&messages)?; + } else if id[0] == 0x02 { + let mut buf = vec![0; 10]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + let len: usize = String::from_utf8(buf)?.parse()?; + stream.write_all(&messages[(len - splash.len())..])?; + } + } else { + stream.write_all(messages.len().to_string().as_bytes())?; - if id[0] == 0x01 { - stream.write_all(&messages)?; - } else if id[0] == 0x02 { - let mut buf = vec![0; 10]; - let size = stream.read(&mut buf)?; - buf.truncate(size); + let mut id = vec![0]; + stream.read_exact(&mut id)?; - let len: usize = String::from_utf8(buf)?.parse()?; - stream.write_all(&messages[len..])?; + if id[0] == 0x01 { + stream.write_all(&messages)?; + } else if id[0] == 0x02 { + let mut buf = vec![0; 10]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + let len: usize = String::from_utf8(buf)?.parse()?; + stream.write_all(&messages[len..])?; + } } } else if buf[0] == 0x01 { - let mut buf = vec![0; 4096]; + if !args.auth_only { + let mut buf = vec![0; 1024]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + add_message(&mut buf, messages.clone(), Some(stream.peer_addr()?.ip()), args.sanitize)?; + } + } else if buf[0] == 0x02 { + let mut buf = vec![0; 8192]; let size = stream.read(&mut buf)?; buf.truncate(size); - let mut msg = Vec::new(); + let msg = String::from_utf8_lossy(&buf).to_string(); - msg.append(&mut message_prefix( - Local::now().timestamp_millis(), - &stream.peer_addr()?.ip().to_string()).as_bytes().to_vec() - ); - msg.push(b' '); - msg.append(&mut buf); + let mut segments = msg.split("\n"); - if let Some(msg) = bRAC::chat::format_message(true, String::from_utf8_lossy(&msg).to_string()) { - println!("{}", msg); + let Some(name) = segments.next() else { return Ok(()) }; + let Some(password) = segments.next() else { return Ok(()) }; + let Some(text) = segments.next() else { return Ok(()) }; + + for user in accounts.read().unwrap().iter() { + if user.name() == name { + if user.check_password(password) { + add_message(&mut text.as_bytes().to_vec(), messages.clone(), None, args.sanitize)?; + } else { + stream.write_all(&[0x02])?; + } + return Ok(()); + } } - msg.push(b'\n'); - - messages.write().unwrap().append(&mut msg.clone()); - - } else if buf[0] == 0x02 { - // sending authorized messages + stream.write_all(&[0x01])?; } else if buf[0] == 0x03 { - // user registration + let mut buf = vec![0; 1024]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + let msg = String::from_utf8_lossy(&buf).to_string(); + + let mut segments = msg.split("\n"); + + let Some(name) = segments.next() else { return Ok(()) }; + let Some(password) = segments.next() else { return Ok(()) }; + + for user in accounts.read().unwrap().iter() { + if user.name() == name { + stream.write_all(&[0x01])?; + return Ok(()); + } + } + + accounts.write().unwrap().push(Account::new(name.to_string(), password.to_string())); } Ok(()) } -fn main() { - let addr = args().skip(1).next().expect("needs at least 1 argument (host:port)"); +#[derive(Parser, Debug)] +#[command(version)] +struct Args { + /// Server host + #[arg(short='H', long)] + host: String, - let listener = TcpListener::bind(&addr).expect("error trying bind to the provided addr"); + /// Sanitize messages + #[arg(short, long)] + sanitize: bool, + + /// Allow only authorized messages + #[arg(short, long)] + auth_only: bool, + + /// Splash message + #[arg(short='S', long)] + splash: Option +} + +fn main() { + // let mut args = Args::parse(); + // args.splash = args.splash.map(|o| format!("{o}\n")); + let args = Arc::new(Args::parse()); + + let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr"); let messages = Arc::new(RwLock::new(Vec::new())); + let accounts = Arc::new(RwLock::new(Vec::new())); - println!("Server started on {}", &addr); + println!("Server started on {}", &args.host); for stream in listener.incoming() { let Ok(stream) = stream else { continue }; let messages = messages.clone(); + let accounts = accounts.clone(); + let args = args.clone(); thread::spawn(move || { - let _ = accept_stream(stream, messages); + let _ = accept_stream(args, stream, messages, accounts); }); } } From 3943eb22087f1b99bcdf6ddfe3ee8cc3f38bd6d3 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Mon, 14 Apr 2025 22:14:22 +0300 Subject: [PATCH 07/16] remove fucking comment --- src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index a8da05d..14a47ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -219,8 +219,6 @@ struct Args { } fn main() { - // let mut args = Args::parse(); - // args.splash = args.splash.map(|o| format!("{o}\n")); let args = Arc::new(Args::parse()); let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr"); From 5e8facf0aaab8b7df97e29b3ae2af68542b5e543 Mon Sep 17 00:00:00 2001 From: MeexReay <127148610+MeexReay@users.noreply.github.com> Date: Mon, 14 Apr 2025 22:16:12 +0300 Subject: [PATCH 08/16] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 25376c5..63449ab 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,5 @@ simple server for RAC ```bash git clone https://github.com/MeexReay/sRAC cd sRAC -cargo run 127.0.0.1:42666 -``` \ No newline at end of file +cargo run --help +``` From ee3c0ea64c837bbd7372bd96a0b40fdc4c073f1a Mon Sep 17 00:00:00 2001 From: MeexReay Date: Tue, 15 Apr 2025 02:16:04 +0300 Subject: [PATCH 09/16] good update accounts saving messages saving register timeout and some fixes as always --- .gitignore | 4 +- README.md | 15 ++++- src/main.rs | 176 +++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 178 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index c41cc9e..c8062fa 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -/target \ No newline at end of file +/target +/messages.txt +/accounts.txt \ No newline at end of file diff --git a/README.md b/README.md index 25376c5..7ad8f1d 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,18 @@ simple server for RAC ```bash git clone https://github.com/MeexReay/sRAC cd sRAC -cargo run 127.0.0.1:42666 +cargo run -- -H 127.0.0.1:42666 +``` + +### My server config + +```bash +cargo run -- \ + --host 127.0.0.1:42666 \ + --splash "please register (/register and /login commands in bRAC)" \ + --messages-file "messages.txt" \ + --accounts-file "accounts.txt" \ + --register-timeout 3600 \ + --sanitize \ + --auth-only ``` \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 14a47ee..b56b4b1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use std::{error::Error, io::{Read, Write}, net::{IpAddr, TcpListener, TcpStream}, sync::{Arc, RwLock}, thread}; +use std::{error::Error, fs::{self, OpenOptions}, io::{Cursor, Read, Write}, net::{IpAddr, TcpListener, TcpStream}, sync::{Arc, RwLock}, thread}; use bRAC::{chat::format_message, util::sanitize_text}; use chrono::{DateTime, Local, TimeZone}; @@ -11,15 +11,16 @@ use clap::Parser; #[derive(Clone)] pub struct Account { name: String, - pass: String, - salt: String + pass: Vec, + salt: String, + addr: String, + date: i64 } -fn password_hash(name: &str, pass: &str, salt: &str) -> String { +fn password_hash(name: &str, pass: &str, salt: &str) -> Vec { let mut hasher = Md5::new(); hasher.update(format!("{name}{pass}{salt}").as_bytes()); - let result = hasher.finalize().to_vec(); - String::from_utf8_lossy(&result).to_string() + hasher.finalize().to_vec() } fn password_salt() -> String { @@ -31,13 +32,15 @@ fn password_salt() -> String { } impl Account { - pub fn new(name: String, password: String) -> Self { + pub fn new(name: String, password: String, addr: String, date: i64) -> Self { let salt = password_salt(); Account { pass: password_hash(&name, &password, &salt), name: name.clone(), - salt: salt.clone() + salt: salt.clone(), + addr, + date } } @@ -48,6 +51,75 @@ impl Account { pub fn name(&self) -> &str { &self.name } + + pub fn addr(&self) -> &str { + &self.addr + } + + pub fn date(&self) -> i64 { + self.date + } + + pub fn to_bytes(&self) -> Vec { + let mut data = Vec::new(); + data.append(&mut (self.name.len() as u32).to_le_bytes().to_vec()); + data.append(&mut (self.salt.len() as u32).to_le_bytes().to_vec()); + data.append(&mut (self.addr.len() as u32).to_le_bytes().to_vec()); + data.append(&mut (self.pass.len() as u32).to_le_bytes().to_vec()); + data.append(&mut self.name.as_bytes().to_vec()); + data.append(&mut self.salt.as_bytes().to_vec()); + data.append(&mut self.addr.as_bytes().to_vec()); + data.append(&mut self.pass.clone()); + data.append(&mut self.date.to_le_bytes().to_vec()); + data + } + + pub fn from_bytes(text: Vec) -> Self { + let mut text = Cursor::new(text); + + let mut name_len = [0; 4]; + text.read_exact(&mut name_len).unwrap(); + let name_len = u32::from_le_bytes(name_len) as usize; + + let mut salt_len = [0; 4]; + text.read_exact(&mut salt_len).unwrap(); + let salt_len = u32::from_le_bytes(salt_len) as usize; + + let mut addr_len = [0; 4]; + text.read_exact(&mut addr_len).unwrap(); + let addr_len = u32::from_le_bytes(addr_len) as usize; + + let mut pass_len = [0; 4]; + text.read_exact(&mut pass_len).unwrap(); + let pass_len = u32::from_le_bytes(pass_len) as usize; + + let mut name = vec![0; name_len]; + text.read_exact(&mut name).unwrap(); + let name = String::from_utf8_lossy(&name).to_string(); + + let mut salt = vec![0; salt_len]; + text.read_exact(&mut salt).unwrap(); + let salt = String::from_utf8_lossy(&salt).to_string(); + + let mut addr = vec![0; addr_len]; + text.read_exact(&mut addr).unwrap(); + let addr = String::from_utf8_lossy(&addr).to_string(); + + let mut pass = vec![0; pass_len]; + text.read_exact(&mut pass).unwrap(); + + let mut date = [0; 8]; + text.read_exact(&mut date).unwrap(); + let date = i64::from_le_bytes(date); + + Account { + name, + salt, + pass, + addr, + date + } + } } fn message_prefix(time_millis: i64, address: Option) -> String { @@ -68,7 +140,8 @@ fn add_message( buf: &mut Vec, messages: Arc>>, addr: Option, - sanitize: bool + sanitize: bool, + messages_file: Option ) -> Result<(), Box> { let mut msg = Vec::new(); @@ -89,6 +162,17 @@ fn add_message( msg.push(b'\n'); + if let Some(messages_file) = messages_file { + let mut file = OpenOptions::new() + .write(true) + .append(true) + .create(true) + .open(messages_file)?; + + file.write_all(&msg)?; + file.flush()?; + } + messages.write().unwrap().append(&mut msg.clone()); Ok(()) @@ -146,7 +230,7 @@ fn accept_stream( let size = stream.read(&mut buf)?; buf.truncate(size); - add_message(&mut buf, messages.clone(), Some(stream.peer_addr()?.ip()), args.sanitize)?; + add_message(&mut buf, messages.clone(), Some(stream.peer_addr()?.ip()), args.sanitize, args.messages_file.clone())?; } } else if buf[0] == 0x02 { let mut buf = vec![0; 8192]; @@ -164,7 +248,7 @@ fn accept_stream( for user in accounts.read().unwrap().iter() { if user.name() == name { if user.check_password(password) { - add_message(&mut text.as_bytes().to_vec(), messages.clone(), None, args.sanitize)?; + add_message(&mut text.as_bytes().to_vec(), messages.clone(), None, args.sanitize, args.messages_file.clone())?; } else { stream.write_all(&[0x02])?; } @@ -185,14 +269,38 @@ fn accept_stream( let Some(name) = segments.next() else { return Ok(()) }; let Some(password) = segments.next() else { return Ok(()) }; + let addr = stream.peer_addr()?.ip().to_string(); + + let now: i64 = Local::now().timestamp_millis(); + for user in accounts.read().unwrap().iter() { if user.name() == name { stream.write_all(&[0x01])?; return Ok(()); } + if user.addr() == addr && ((now - user.date()) as usize) < 1000 * args.register_timeout { + stream.write_all(&[0x01])?; + return Ok(()); + } } + + let account = Account::new(name.to_string(), password.to_string(), addr, now); + + if let Some(accounts_file) = args.accounts_file.clone() { + let mut file = OpenOptions::new() + .write(true) + .append(true) + .create(true) + .open(accounts_file)?; + + file.write_all(&account.to_bytes())?; + file.write_all(b"\n")?; + file.flush()?; + } + + println!("user registered: {name}"); - accounts.write().unwrap().push(Account::new(name.to_string(), password.to_string())); + accounts.write().unwrap().push(account); } Ok(()) @@ -215,7 +323,19 @@ struct Args { /// Splash message #[arg(short='S', long)] - splash: Option + splash: Option, + + /// Save messages to file + #[arg(short='M', long)] + messages_file: Option, + + /// Save accounts to file + #[arg(short='A', long)] + accounts_file: Option, + + /// Register timeout in seconds + #[arg(short='r', long, default_value_t = 600)] + register_timeout: usize } fn main() { @@ -223,8 +343,34 @@ fn main() { let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr"); - let messages = Arc::new(RwLock::new(Vec::new())); - let accounts = Arc::new(RwLock::new(Vec::new())); + let messages = Arc::new(RwLock::new( + if let Some(messages_file) = args.messages_file.clone() { + if fs::exists(&messages_file).expect("error checking messages file") { + fs::read(&messages_file).expect("error reading messages file") + } else { + Vec::new() + } + } else { + Vec::new() + } + )); + + let accounts = Arc::new(RwLock::new( + if let Some(accounts_file) = args.accounts_file.clone() { + if fs::exists(&accounts_file).expect("error checking accounts file") { + fs::read(&accounts_file) + .expect("error reading accounts file") + .split(|o| *o == b'\n') + .filter(|o| !o.is_empty()) + .map(|o| Account::from_bytes(o.to_vec())) + .collect() + } else { + Vec::new() + } + } else { + Vec::new() + } + )); println!("Server started on {}", &args.host); From 8c4caaf15bc8bc461d34a68407dbbe464c877ecf Mon Sep 17 00:00:00 2001 From: MeexReay Date: Tue, 15 Apr 2025 02:18:22 +0300 Subject: [PATCH 10/16] roadmap --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 3d84a52..84fcfcf 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,9 @@ cargo run -- \ --sanitize \ --auth-only ``` +## Roadmap + +- Wrap with SSL +- Proxy-mode +- Notifications by ip +- Server comands \ No newline at end of file From 0d4992e99de5934c576617f16ea6c734430b6cf0 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Tue, 15 Apr 2025 12:05:31 +0300 Subject: [PATCH 11/16] roadmap update --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 84fcfcf..d88f5bd 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,8 @@ cargo run -- \ ``` ## Roadmap -- Wrap with SSL -- Proxy-mode -- Notifications by ip -- Server comands \ No newline at end of file +- [ ] Wrap with SSL +- [ ] Proxy-mode +- [ ] Notifications by ip +- [ ] Server commands +- [ ] WRAC proxy \ No newline at end of file From 7e3b2eb341b0b5fb54052d20caeaee5841f2da51 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sat, 19 Apr 2025 17:07:46 +0300 Subject: [PATCH 12/16] racs --- Cargo.lock | 419 +++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 + README.md | 5 +- src/main.rs | 98 +++++++++--- 4 files changed, 499 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 37bd36e..c246bc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -73,7 +73,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", "once_cell", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -88,6 +88,29 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "aws-lc-rs" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b756939cb2f8dc900aa6dcd505e6e2428e9cae7ff7b028c49e3946efa70878" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ddeb19ee86cb16ecfc871e5b0660aff6285760957aaedda6284cf0e790d3769" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "bRAC" version = "0.1.2+2.0" @@ -102,6 +125,35 @@ dependencies = [ "serde_yml", ] +[[package]] +name = "base64ct" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + [[package]] name = "bitflags" version = "2.9.0" @@ -129,9 +181,20 @@ version = "1.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" dependencies = [ + "jobserver", + "libc", "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -152,6 +215,17 @@ dependencies = [ "windows-link", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.36" @@ -192,6 +266,27 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + +[[package]] +name = "cms" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b77c319abfd5219629c45c34c89ba945ed3c5e49fcde9d16b6c3885f118a730" +dependencies = [ + "const-oid", + "der", + "spki", + "x509-cert", +] + [[package]] name = "colorchoice" version = "1.0.3" @@ -204,9 +299,15 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -223,6 +324,30 @@ dependencies = [ "typenum", ] +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "der_derive", + "flagset", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "digest" version = "0.10.7" @@ -233,12 +358,46 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "flagset" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "generic-array" version = "0.14.7" @@ -249,6 +408,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.3.2" @@ -258,9 +428,15 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "wasi", + "wasi 0.14.2+wasi-0.2.4", ] +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + [[package]] name = "hashbrown" version = "0.15.2" @@ -273,6 +449,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "iana-time-zone" version = "0.1.63" @@ -313,12 +498,31 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jobserver" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +dependencies = [ + "getrandom 0.3.2", + "libc", +] + [[package]] name = "js-sys" version = "0.3.77" @@ -335,12 +539,28 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets", +] + [[package]] name = "libyml" version = "0.0.5" @@ -351,6 +571,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "log" version = "0.4.27" @@ -373,6 +599,22 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -388,6 +630,29 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs12" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "695b3df3d3cc1015f12d70235e35b6b79befc5fa7a9b95b951eab1dd07c9efc2" +dependencies = [ + "cms", + "const-oid", + "der", + "spki", + "x509-cert", + "zeroize", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -397,6 +662,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettyplease" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.94" @@ -448,7 +723,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom", + "getrandom 0.3.2", ] [[package]] @@ -480,6 +755,72 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls" +version = "0.23.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-webpki" +version = "0.103.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.20" @@ -500,7 +841,9 @@ dependencies = [ "chrono", "clap", "md-5", + "pkcs12", "rand", + "rustls", ] [[package]] @@ -544,12 +887,28 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.100" @@ -573,6 +932,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "utf8parse" version = "0.2.2" @@ -585,6 +950,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasi" version = "0.14.2+wasi-0.2.4" @@ -652,6 +1023,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "windows-core" version = "0.61.0" @@ -711,6 +1094,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -793,6 +1185,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "x509-cert" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" +dependencies = [ + "const-oid", + "der", + "spki", +] + [[package]] name = "zerocopy" version = "0.8.24" @@ -812,3 +1215,9 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/Cargo.toml b/Cargo.toml index 71bd3ad..892084d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,5 @@ bRAC = { git = "https://github.com/MeexReay/bRAC.git", default-features = false, md-5 = "0.10.6" rand = "0.9.0" clap = { version = "4.5.36", features = ["derive"] } +rustls = "0.23.25" +pkcs12 = "=0.1.0" \ No newline at end of file diff --git a/README.md b/README.md index d88f5bd..951c704 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,7 @@ cargo run -- \ ``` ## Roadmap -- [ ] Wrap with SSL -- [ ] Proxy-mode - [ ] Notifications by ip - [ ] Server commands -- [ ] WRAC proxy \ No newline at end of file +- [ ] WRAC protocol +- [ ] RACS protocol \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index b56b4b1..71fd3bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use std::{error::Error, fs::{self, OpenOptions}, io::{Cursor, Read, Write}, net::{IpAddr, TcpListener, TcpStream}, sync::{Arc, RwLock}, thread}; +use std::{error::Error, fs::{self, OpenOptions}, io::{Cursor, Read, Write}, net::{IpAddr, SocketAddr, TcpListener}, sync::{Arc, RwLock}, thread}; use bRAC::{chat::format_message, util::sanitize_text}; use chrono::{DateTime, Local, TimeZone}; @@ -6,6 +6,7 @@ use md5::{Digest, Md5}; use rand::{distr::Alphanumeric, Rng}; use clap::Parser; +use rustls::{pki_types::{pem::PemObject, CertificateDer, PrivateKeyDer}, ServerConfig, ServerConnection, StreamOwned}; #[derive(Clone)] @@ -180,7 +181,8 @@ fn add_message( fn accept_stream( args: Arc, - mut stream: TcpStream, + stream: &mut (impl Read + Write), + addr: SocketAddr, messages: Arc>>, accounts: Arc>> ) -> Result<(), Box> { @@ -230,7 +232,7 @@ fn accept_stream( let size = stream.read(&mut buf)?; buf.truncate(size); - add_message(&mut buf, messages.clone(), Some(stream.peer_addr()?.ip()), args.sanitize, args.messages_file.clone())?; + add_message(&mut buf, messages.clone(), Some(addr.ip()), args.sanitize, args.messages_file.clone())?; } } else if buf[0] == 0x02 { let mut buf = vec![0; 8192]; @@ -269,7 +271,7 @@ fn accept_stream( let Some(name) = segments.next() else { return Ok(()) }; let Some(password) = segments.next() else { return Ok(()) }; - let addr = stream.peer_addr()?.ip().to_string(); + let addr = addr.ip().to_string(); let now: i64 = Local::now().timestamp_millis(); @@ -306,6 +308,64 @@ fn accept_stream( Ok(()) } +fn run_normal_listener(messages: Arc>>, accounts: Arc>>, args: Arc) { + let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr"); + + for stream in listener.incoming() { + let Ok(mut stream) = stream else { continue }; + + let messages = messages.clone(); + let accounts = accounts.clone(); + let args = args.clone(); + + thread::spawn(move || { + let Ok(addr) = stream.peer_addr() else { return; }; + let _ = accept_stream(args, &mut stream, addr, messages, accounts); + }); + } +} + +fn run_secure_listener( + messages: Arc>>, + accounts: Arc>>, + args: Arc +) { + let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr"); + + let server_config = Arc::new(ServerConfig::builder() + .with_no_client_auth() + .with_single_cert(CertificateDer::pem_file_iter( + args.ssl_cert.clone().expect("--ssl-cert is required")) + .unwrap() + .map(|cert| cert.unwrap()) + .collect(), + PrivateKeyDer::from_pem_file( + args.ssl_key.clone().expect("--ssl-key is required")).unwrap() + ).unwrap()); + + for stream in listener.incoming() { + let Ok(stream) = stream else { continue }; + + let messages = messages.clone(); + let accounts = accounts.clone(); + let args = args.clone(); + let server_config = server_config.clone(); + + thread::spawn(move || { + let Ok(addr) = stream.peer_addr() else { return; }; + + let Ok(connection) = ServerConnection::new(server_config) else { return }; + let mut stream = StreamOwned::new(connection, stream); + + while stream.conn.is_handshaking() { + let Ok(_) = stream.conn.complete_io(&mut stream.sock) else { return }; + } + + let _ = accept_stream(args, &mut stream, addr, messages, accounts); + }); + } +} + #[derive(Parser, Debug)] #[command(version)] struct Args { @@ -335,14 +395,24 @@ struct Args { /// Register timeout in seconds #[arg(short='r', long, default_value_t = 600)] - register_timeout: usize + register_timeout: usize, + + /// Enable SSL (RACS) + #[arg(short='l', long)] + enable_ssl: bool, + + /// Set ssl certificate path (x509) + #[arg(long)] + ssl_key: Option, + + /// Set ssl key path (x509) + #[arg(long)] + ssl_cert: Option } fn main() { let args = Arc::new(Args::parse()); - let listener = TcpListener::bind(&args.host).expect("error trying bind to the provided addr"); - let messages = Arc::new(RwLock::new( if let Some(messages_file) = args.messages_file.clone() { if fs::exists(&messages_file).expect("error checking messages file") { @@ -374,15 +444,9 @@ fn main() { println!("Server started on {}", &args.host); - for stream in listener.incoming() { - let Ok(stream) = stream else { continue }; - - let messages = messages.clone(); - let accounts = accounts.clone(); - let args = args.clone(); - - thread::spawn(move || { - let _ = accept_stream(args, stream, messages, accounts); - }); + if args.enable_ssl { + run_secure_listener(messages, accounts, args); + } else { + run_normal_listener(messages, accounts, args); } } From a364cbced68ac70b400daf47a82c6b565e1f674c Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sat, 19 Apr 2025 17:08:01 +0300 Subject: [PATCH 13/16] roadmap update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 951c704..16a0a3e 100644 --- a/README.md +++ b/README.md @@ -26,4 +26,4 @@ cargo run -- \ - [ ] Notifications by ip - [ ] Server commands - [ ] WRAC protocol -- [ ] RACS protocol \ No newline at end of file +- [x] RACS protocol \ No newline at end of file From 2fdc5e6b8d74b58662edd9003004f9c659a56395 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sat, 19 Apr 2025 21:57:15 +0300 Subject: [PATCH 14/16] wrac protocol --- Cargo.lock | 186 ++++++++++++++++++++++++++-------------------------- Cargo.toml | 2 +- PROTOCOL.md | 49 +++++++++++++- src/main.rs | 18 +++-- 4 files changed, 153 insertions(+), 102 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c246bc5..a32ee75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,12 +125,6 @@ dependencies = [ "serde_yml", ] -[[package]] -name = "base64ct" -version = "1.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" - [[package]] name = "bindgen" version = "0.69.5" @@ -175,6 +169,12 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + [[package]] name = "cc" version = "1.2.19" @@ -275,18 +275,6 @@ dependencies = [ "cc", ] -[[package]] -name = "cms" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b77c319abfd5219629c45c34c89ba945ed3c5e49fcde9d16b6c3885f118a730" -dependencies = [ - "const-oid", - "der", - "spki", - "x509-cert", -] - [[package]] name = "colorchoice" version = "1.0.3" @@ -302,18 +290,21 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -325,28 +316,10 @@ dependencies = [ ] [[package]] -name = "der" -version = "0.7.10" +name = "data-encoding" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "der_derive", - "flagset", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "der_derive" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "digest" @@ -387,10 +360,10 @@ dependencies = [ ] [[package]] -name = "flagset" -version = "0.4.7" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fs_extra" @@ -458,6 +431,23 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + [[package]] name = "iana-time-zone" version = "0.1.63" @@ -630,29 +620,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "pkcs12" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "695b3df3d3cc1015f12d70235e35b6b79befc5fa7a9b95b951eab1dd07c9efc2" -dependencies = [ - "cms", - "const-oid", - "der", - "spki", - "x509-cert", - "zeroize", -] - [[package]] name = "ppv-lite86" version = "0.2.21" @@ -841,9 +808,9 @@ dependencies = [ "chrono", "clap", "md-5", - "pkcs12", "rand", "rustls", + "tungstenite", ] [[package]] @@ -881,22 +848,23 @@ dependencies = [ "version_check", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - [[package]] name = "strsim" version = "0.11.1" @@ -920,6 +888,43 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tungstenite" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "utf-8", +] + [[package]] name = "typenum" version = "1.18.0" @@ -938,6 +943,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" version = "0.2.2" @@ -1185,17 +1196,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "x509-cert" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" -dependencies = [ - "const-oid", - "der", - "spki", -] - [[package]] name = "zerocopy" version = "0.8.24" diff --git a/Cargo.toml b/Cargo.toml index 892084d..ba6a1a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,4 @@ md-5 = "0.10.6" rand = "0.9.0" clap = { version = "4.5.36", features = ["derive"] } rustls = "0.23.25" -pkcs12 = "=0.1.0" \ No newline at end of file +tungstenite = "0.26.2" \ No newline at end of file diff --git a/PROTOCOL.md b/PROTOCOL.md index 83655bd..2090a19 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -13,6 +13,8 @@ Client sends: ## Reading messages +### Getting message length + Client sends: - Byte `0x00` @@ -23,6 +25,8 @@ Server sends: ### Normal reading +*Firstly, process getting message length packet* + Client sends: - Byte `0x01` @@ -33,6 +37,8 @@ Server sends: ### Chunked reading +*Firstly, process getting message length packet* + Client sends: - Byte `0x02` @@ -73,4 +79,45 @@ Client sends: Server sends: - nothing if user was registered successfully -- `0x01` if the username is already taken \ No newline at end of file +- `0x01` if the username is already taken + +# WRAC Protocol + +Default port - 42666 + +Uses websocket for connections, and sends binary data only + +Totally inherits all packets except reading messages packets writed here + +## Reading messages + +### Normal reading + +~~*Firstly, process getting message length packet*~~ + +This packet is independent from getting message length packet. + +Client sends: + +- **Byte `0x00`** +- Byte `0x01` + +Server sends: + +- All messages + +### Chunked reading + +~~*Firstly, process getting message length packet*~~ + +This packet is independent from getting message length packet. + +Client sends: + +- **Byte `0x00`** +- Byte `0x02` +- Size of messages you have in ASCII (last_size) + +Server sends: + +- All new messages diff --git a/src/main.rs b/src/main.rs index 71fd3bc..97cfdba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -181,7 +181,7 @@ fn add_message( fn accept_stream( args: Arc, - stream: &mut (impl Read + Write), + mut stream: impl Read + Write, addr: SocketAddr, messages: Arc>>, accounts: Arc>> @@ -294,14 +294,14 @@ fn accept_stream( .append(true) .create(true) .open(accounts_file)?; - + file.write_all(&account.to_bytes())?; file.write_all(b"\n")?; file.flush()?; } println!("user registered: {name}"); - + accounts.write().unwrap().push(account); } @@ -312,7 +312,7 @@ fn run_normal_listener(messages: Arc>>, accounts: Arc>>, accounts: Arc + ssl_cert: Option, + + /// Enable WRAC + #[arg(short='w', long)] + enable_wrac: bool, } fn main() { From 1a9f7f4e63dc0edb31d02846334bb71c274e7002 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sun, 20 Apr 2025 00:36:32 +0300 Subject: [PATCH 15/16] wrac implementation --- src/main.rs | 312 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 217 insertions(+), 95 deletions(-) diff --git a/src/main.rs b/src/main.rs index 97cfdba..56837d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use rand::{distr::Alphanumeric, Rng}; use clap::Parser; use rustls::{pki_types::{pem::PemObject, CertificateDer, PrivateKeyDer}, ServerConfig, ServerConnection, StreamOwned}; +use tungstenite::{accept, Bytes, Message, WebSocket}; #[derive(Clone)] @@ -186,123 +187,244 @@ fn accept_stream( messages: Arc>>, accounts: Arc>> ) -> Result<(), Box> { - let mut buf = vec![0]; - stream.read_exact(&mut buf)?; + if args.enable_wrac { + let mut websocket = accept(stream).unwrap(); - if buf[0] == 0x00 { - let mut messages = messages.read().unwrap().clone(); + while let Ok(msg) = websocket.read() { + if let Some(data) = if msg.is_binary() { + Some(msg.into_data().to_vec()) + } else if msg.is_text() { + msg.into_text().ok().map(|o| o.as_bytes().to_vec()) + } else { + None + } { + let mut data = data; + let Some(id) = data.drain(..1).next() else { return Ok(()) }; - if let Some(splash) = &args.splash { - stream.write_all((splash.len() + messages.len()).to_string().as_bytes())?; + if id == 0x00 { + let mut messages = messages.read().unwrap().clone(); - let mut id = vec![0]; - stream.read_exact(&mut id)?; - - if id[0] == 0x01 { - messages.append(&mut splash.clone().as_bytes().to_vec()); - stream.write_all(&messages)?; - } else if id[0] == 0x02 { - let mut buf = vec![0; 10]; - let size = stream.read(&mut buf)?; - buf.truncate(size); - - let len: usize = String::from_utf8(buf)?.parse()?; - stream.write_all(&messages[(len - splash.len())..])?; - } - } else { - stream.write_all(messages.len().to_string().as_bytes())?; + if data.is_empty() { + if let Some(splash) = &args.splash { + websocket.write(Message::Binary(Bytes::from((messages.len() + splash.len()).to_string().as_bytes().to_vec())))?; + } else { + websocket.write(Message::Binary(Bytes::from(messages.len().to_string().as_bytes().to_vec())))?; + } + } else { + let Some(id) = data.drain(..1).next() else { return Ok(()) }; - let mut id = vec![0]; - stream.read_exact(&mut id)?; + if id == 0x01 { + if let Some(splash) = &args.splash { + messages.append(&mut splash.clone().as_bytes().to_vec()); + } + websocket.write(Message::Binary(Bytes::from(messages)))?; + } else if id == 0x02 { + let last_size: usize = String::from_utf8(data)?.parse()?; + if let Some(splash) = &args.splash { + websocket.write(Message::Binary(Bytes::from(messages[(last_size - splash.len())..].to_vec())))?; + } else { + websocket.write(Message::Binary(Bytes::from(messages[last_size..].to_vec())))?; + } + } + } + } else if id == 0x01 { + if !args.auth_only { + add_message(&mut data, messages.clone(), Some(addr.ip()), args.sanitize, args.messages_file.clone())?; + } + } else if id == 0x02 { + let msg = String::from_utf8_lossy(&data).to_string(); + + let mut segments = msg.split("\n"); + + let Some(name) = segments.next() else { return Ok(()) }; + let Some(password) = segments.next() else { return Ok(()) }; + let Some(text) = segments.next() else { return Ok(()) }; + + let mut sent = false; - if id[0] == 0x01 { - stream.write_all(&messages)?; - } else if id[0] == 0x02 { - let mut buf = vec![0; 10]; - let size = stream.read(&mut buf)?; - buf.truncate(size); + for user in accounts.read().unwrap().iter() { + if user.name() == name { + if user.check_password(password) { + add_message(&mut text.as_bytes().to_vec(), messages.clone(), None, args.sanitize, args.messages_file.clone())?; + } else { + websocket.write(Message::Binary(Bytes::from(vec![0x02])))?; + } + sent = true; + break; + } + } + + if !sent { + websocket.write(Message::Binary(Bytes::from(vec![0x01])))?; + } + } else if id == 0x03 { + let msg = String::from_utf8_lossy(&data).to_string(); + + let mut segments = msg.split("\n"); + + let Some(name) = segments.next() else { return Ok(()) }; + let Some(password) = segments.next() else { return Ok(()) }; + + let addr = addr.ip().to_string(); + + let now: i64 = Local::now().timestamp_millis(); - let len: usize = String::from_utf8(buf)?.parse()?; - stream.write_all(&messages[len..])?; + let mut continue_send = false; + + for user in accounts.read().unwrap().iter() { + if user.name() == name { + websocket.write(Message::Binary(Bytes::from(vec![0x01])))?; + continue_send = true; + break; + } + if user.addr() == addr && ((now - user.date()) as usize) < 1000 * args.register_timeout { + websocket.write(Message::Binary(Bytes::from(vec![0x01])))?; + continue_send = true; + break; + } + } + + if continue_send { + continue; + } + + let account = Account::new(name.to_string(), password.to_string(), addr, now); + + if let Some(accounts_file) = args.accounts_file.clone() { + let mut file = OpenOptions::new() + .write(true) + .append(true) + .create(true) + .open(accounts_file)?; + + file.write_all(&account.to_bytes())?; + file.write_all(b"\n")?; + file.flush()?; + } + + accounts.write().unwrap().push(account); + } } } - } else if buf[0] == 0x01 { - if !args.auth_only { + } else { + let mut buf = vec![0]; + stream.read_exact(&mut buf)?; + + if buf[0] == 0x00 { + let mut messages = messages.read().unwrap().clone(); + + if let Some(splash) = &args.splash { + stream.write_all((splash.len() + messages.len()).to_string().as_bytes())?; + + let mut id = vec![0]; + stream.read_exact(&mut id)?; + + if id[0] == 0x01 { + messages.append(&mut splash.clone().as_bytes().to_vec()); + stream.write_all(&messages)?; + } else if id[0] == 0x02 { + let mut buf = vec![0; 10]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + let len: usize = String::from_utf8(buf)?.parse()?; + stream.write_all(&messages[(len - splash.len())..])?; + } + } else { + stream.write_all(messages.len().to_string().as_bytes())?; + + let mut id = vec![0]; + stream.read_exact(&mut id)?; + + if id[0] == 0x01 { + stream.write_all(&messages)?; + } else if id[0] == 0x02 { + let mut buf = vec![0; 10]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + let len: usize = String::from_utf8(buf)?.parse()?; + stream.write_all(&messages[len..])?; + } + } + } else if buf[0] == 0x01 { + if !args.auth_only { + let mut buf = vec![0; 1024]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + add_message(&mut buf, messages.clone(), Some(addr.ip()), args.sanitize, args.messages_file.clone())?; + } + } else if buf[0] == 0x02 { + let mut buf = vec![0; 8192]; + let size = stream.read(&mut buf)?; + buf.truncate(size); + + let msg = String::from_utf8_lossy(&buf).to_string(); + + let mut segments = msg.split("\n"); + + let Some(name) = segments.next() else { return Ok(()) }; + let Some(password) = segments.next() else { return Ok(()) }; + let Some(text) = segments.next() else { return Ok(()) }; + + for user in accounts.read().unwrap().iter() { + if user.name() == name { + if user.check_password(password) { + add_message(&mut text.as_bytes().to_vec(), messages.clone(), None, args.sanitize, args.messages_file.clone())?; + } else { + stream.write_all(&[0x02])?; + } + return Ok(()); + } + } + + stream.write_all(&[0x01])?; + } else if buf[0] == 0x03 { let mut buf = vec![0; 1024]; let size = stream.read(&mut buf)?; buf.truncate(size); - - add_message(&mut buf, messages.clone(), Some(addr.ip()), args.sanitize, args.messages_file.clone())?; - } - } else if buf[0] == 0x02 { - let mut buf = vec![0; 8192]; - let size = stream.read(&mut buf)?; - buf.truncate(size); - let msg = String::from_utf8_lossy(&buf).to_string(); + let msg = String::from_utf8_lossy(&buf).to_string(); - let mut segments = msg.split("\n"); + let mut segments = msg.split("\n"); - let Some(name) = segments.next() else { return Ok(()) }; - let Some(password) = segments.next() else { return Ok(()) }; - let Some(text) = segments.next() else { return Ok(()) }; + let Some(name) = segments.next() else { return Ok(()) }; + let Some(password) = segments.next() else { return Ok(()) }; - for user in accounts.read().unwrap().iter() { - if user.name() == name { - if user.check_password(password) { - add_message(&mut text.as_bytes().to_vec(), messages.clone(), None, args.sanitize, args.messages_file.clone())?; - } else { - stream.write_all(&[0x02])?; + let addr = addr.ip().to_string(); + + let now: i64 = Local::now().timestamp_millis(); + + for user in accounts.read().unwrap().iter() { + if user.name() == name { + stream.write_all(&[0x01])?; + return Ok(()); + } + if user.addr() == addr && ((now - user.date()) as usize) < 1000 * args.register_timeout { + stream.write_all(&[0x01])?; + return Ok(()); } - return Ok(()); } - } - stream.write_all(&[0x01])?; - } else if buf[0] == 0x03 { - let mut buf = vec![0; 1024]; - let size = stream.read(&mut buf)?; - buf.truncate(size); + let account = Account::new(name.to_string(), password.to_string(), addr, now); - let msg = String::from_utf8_lossy(&buf).to_string(); + if let Some(accounts_file) = args.accounts_file.clone() { + let mut file = OpenOptions::new() + .write(true) + .append(true) + .create(true) + .open(accounts_file)?; - let mut segments = msg.split("\n"); - - let Some(name) = segments.next() else { return Ok(()) }; - let Some(password) = segments.next() else { return Ok(()) }; - - let addr = addr.ip().to_string(); - - let now: i64 = Local::now().timestamp_millis(); - - for user in accounts.read().unwrap().iter() { - if user.name() == name { - stream.write_all(&[0x01])?; - return Ok(()); - } - if user.addr() == addr && ((now - user.date()) as usize) < 1000 * args.register_timeout { - stream.write_all(&[0x01])?; - return Ok(()); + file.write_all(&account.to_bytes())?; + file.write_all(b"\n")?; + file.flush()?; } + + println!("user registered: {name}"); + + accounts.write().unwrap().push(account); } - - let account = Account::new(name.to_string(), password.to_string(), addr, now); - - if let Some(accounts_file) = args.accounts_file.clone() { - let mut file = OpenOptions::new() - .write(true) - .append(true) - .create(true) - .open(accounts_file)?; - - file.write_all(&account.to_bytes())?; - file.write_all(b"\n")?; - file.flush()?; - } - - println!("user registered: {name}"); - - accounts.write().unwrap().push(account); } Ok(()) From 65a33de7243a70fe28382cf424cf1014b9fad83c Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sun, 20 Apr 2025 00:39:14 +0300 Subject: [PATCH 16/16] roadmap update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16a0a3e..fed9ad6 100644 --- a/README.md +++ b/README.md @@ -25,5 +25,5 @@ cargo run -- \ - [ ] Notifications by ip - [ ] Server commands -- [ ] WRAC protocol +- [x] WRAC protocol - [x] RACS protocol \ No newline at end of file