mirror of
https://github.com/MeexReay/bRAC.git
synced 2025-05-06 13:38:04 +03:00
SSL support and secure
This commit is contained in:
parent
978fe2265e
commit
a2be0e3235
180
Cargo.lock
generated
180
Cargo.lock
generated
@ -82,6 +82,7 @@ dependencies = [
|
|||||||
"crossterm",
|
"crossterm",
|
||||||
"homedir",
|
"homedir",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"native-tls",
|
||||||
"rand",
|
"rand",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
@ -100,6 +101,15 @@ version = "1.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.2.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda"
|
||||||
|
dependencies = [
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -114,9 +124,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.28"
|
version = "4.5.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff"
|
checksum = "8acebd8ad879283633b343856142139f2da2317c96b05b4dd6181c61e2480184"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@ -124,9 +134,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.27"
|
version = "4.5.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
|
checksum = "f6ba32cbda51c7e1dfd49acc1457ba1a7dec5b64fe360e828acb13ca8dc9c2f9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
@ -167,6 +177,22 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "crossterm"
|
name = "crossterm"
|
||||||
version = "0.28.1"
|
version = "0.28.1"
|
||||||
@ -208,6 +234,27 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"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]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -328,6 +375,23 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "native-tls"
|
||||||
|
version = "0.2.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"openssl",
|
||||||
|
"openssl-probe",
|
||||||
|
"openssl-sys",
|
||||||
|
"schannel",
|
||||||
|
"security-framework",
|
||||||
|
"security-framework-sys",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.29.0"
|
version = "0.29.0"
|
||||||
@ -346,6 +410,50 @@ version = "1.20.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl"
|
||||||
|
version = "0.10.70"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6"
|
||||||
|
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.105"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@ -369,6 +477,12 @@ dependencies = [
|
|||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.20"
|
version = "0.2.20"
|
||||||
@ -484,12 +598,44 @@ version = "1.0.19"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
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]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.217"
|
version = "1.0.217"
|
||||||
@ -525,6 +671,12 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook"
|
name = "signal-hook"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
@ -578,6 +730,20 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"fastrand",
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"rustix",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.16"
|
version = "1.0.16"
|
||||||
@ -590,6 +756,12 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vcpkg"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
|
@ -12,4 +12,5 @@ crossterm = "0.28.1"
|
|||||||
serde = { version = "1.0.217", features = ["serde_derive"] }
|
serde = { version = "1.0.217", features = ["serde_derive"] }
|
||||||
serde_yml = "0.0.12"
|
serde_yml = "0.0.12"
|
||||||
homedir = "0.3.4"
|
homedir = "0.3.4"
|
||||||
clap = { version = "4.5.28", features = ["derive"] }
|
clap = { version = "4.5.29", features = ["derive"] }
|
||||||
|
native-tls = "0.2.13"
|
50
src/chat.rs
50
src/chat.rs
@ -4,7 +4,7 @@ use colored::{Color, Colorize};
|
|||||||
use crossterm::{cursor::{MoveLeft, MoveRight}, event::{self, Event, KeyCode, KeyModifiers, MouseEventKind}, execute, terminal::{self, disable_raw_mode, enable_raw_mode}};
|
use crossterm::{cursor::{MoveLeft, MoveRight}, event::{self, Event, KeyCode, KeyModifiers, MouseEventKind}, execute, terminal::{self, disable_raw_mode, enable_raw_mode}};
|
||||||
use rand::random;
|
use rand::random;
|
||||||
|
|
||||||
use crate::{proto::send_message_auth, util::{char_index_to_byte_index, string_chunks}, IP_REGEX};
|
use crate::{proto::{connect, send_message_auth}, util::{char_index_to_byte_index, string_chunks}, IP_REGEX};
|
||||||
|
|
||||||
use super::{proto::read_messages, util::sanitize_text, COLORED_USERNAMES, DATE_REGEX, config::Context, proto::send_message};
|
use super::{proto::read_messages, util::sanitize_text, COLORED_USERNAMES, DATE_REGEX, config::Context, proto::send_message};
|
||||||
|
|
||||||
@ -43,12 +43,12 @@ fn on_command(ctx: Arc<Context>, command: &str) -> Result<(), Box<dyn Error>> {
|
|||||||
let args = args.split(" ").collect::<Vec<&str>>();
|
let args = args.split(" ").collect::<Vec<&str>>();
|
||||||
|
|
||||||
if command == "clear" {
|
if command == "clear" {
|
||||||
send_message(&ctx.host,
|
send_message(&mut connect(&ctx.host, ctx.enable_ssl)?,
|
||||||
&prepare_message(ctx.clone(),
|
&prepare_message(ctx.clone(),
|
||||||
&format!("\r\x1B[1A{}", " ".repeat(64)).repeat(ctx.max_messages)
|
&format!("\r\x1B[1A{}", " ".repeat(64)).repeat(ctx.max_messages)
|
||||||
))?;
|
))?;
|
||||||
} else if command == "spam" {
|
} else if command == "spam" {
|
||||||
send_message(&ctx.host,
|
send_message(&mut connect(&ctx.host, ctx.enable_ssl)?,
|
||||||
&prepare_message(ctx.clone(),
|
&prepare_message(ctx.clone(),
|
||||||
&format!("\r\x1B[1A{}{}", args.join(" "), " ".repeat(10)).repeat(ctx.max_messages)
|
&format!("\r\x1B[1A{}{}", args.join(" "), " ".repeat(10)).repeat(ctx.max_messages)
|
||||||
))?;
|
))?;
|
||||||
@ -65,9 +65,9 @@ Press enter to close")?;
|
|||||||
let mut before = ctx.messages.packet_size();
|
let mut before = ctx.messages.packet_size();
|
||||||
let start = SystemTime::now();
|
let start = SystemTime::now();
|
||||||
let message = format!("Checking ping... {:X}", random::<u16>());
|
let message = format!("Checking ping... {:X}", random::<u16>());
|
||||||
send_message(&ctx.host, &message)?;
|
send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?;
|
||||||
loop {
|
loop {
|
||||||
let data = read_messages(&ctx.host, ctx.max_messages, before).ok().flatten();
|
let data = read_messages(&mut connect(&ctx.host, ctx.enable_ssl)?, ctx.max_messages, before, !ctx.enable_ssl).ok().flatten();
|
||||||
|
|
||||||
if let Some((data, size)) = data {
|
if let Some((data, size)) = data {
|
||||||
if let Some(last) = data.iter().rev().find(|o| o.contains(&message)) {
|
if let Some(last) = data.iter().rev().find(|o| o.contains(&message)) {
|
||||||
@ -81,7 +81,7 @@ Press enter to close")?;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
send_message(&ctx.host, &format!("Ping = {}ms", start.elapsed().unwrap().as_millis()))?;
|
send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, &format!("Ping = {}ms", start.elapsed().unwrap().as_millis()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -92,14 +92,22 @@ pub fn print_console(ctx: Arc<Context>, messages: Vec<String>, input: &str) -> R
|
|||||||
let (width, height) = terminal::size()?;
|
let (width, height) = terminal::size()?;
|
||||||
let (width, height) = (width as usize, height as usize);
|
let (width, height) = (width as usize, height as usize);
|
||||||
|
|
||||||
let messages = messages
|
let mut messages = messages
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|o| string_chunks(&o, width as usize - 1))
|
.flat_map(|o| string_chunks(&o, width as usize - 1))
|
||||||
.collect::<Vec<(String, usize)>>();
|
.collect::<Vec<(String, usize)>>();
|
||||||
|
|
||||||
let scroll = min(ctx.scroll.load(Ordering::SeqCst), messages.len()-height);
|
let messages_size = if messages.len() >= height {
|
||||||
let scroll_f = ((1f64 - scroll as f64 / (messages.len()-height+1) as f64) * (height-2) as f64).round() as usize+1;
|
messages.len()-height
|
||||||
|
} else {
|
||||||
|
for _ in 0..height-messages.len() {
|
||||||
|
messages.insert(0, (String::new(), 0));
|
||||||
|
}
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
let scroll = min(ctx.scroll.load(Ordering::SeqCst), messages_size);
|
||||||
|
let scroll_f = ((1f64 - scroll as f64 / (messages_size+1) as f64) * (height-2) as f64).round() as usize+1;
|
||||||
|
|
||||||
let messages = if height < messages.len() {
|
let messages = if height < messages.len() {
|
||||||
if scroll < messages.len() - height {
|
if scroll < messages.len() - height {
|
||||||
@ -169,7 +177,7 @@ fn prepare_message(context: Arc<Context>, message: &str) -> String {
|
|||||||
},
|
},
|
||||||
message,
|
message,
|
||||||
if !context.disable_hiding_ip {
|
if !context.disable_hiding_ip {
|
||||||
let spaces = if context.auth {
|
let spaces = if context.enable_auth {
|
||||||
39
|
39
|
||||||
} else {
|
} else {
|
||||||
54
|
54
|
||||||
@ -202,11 +210,15 @@ fn format_message(ctx: Arc<Context>, message: String) -> Option<String> {
|
|||||||
(None, message)
|
(None, message)
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = message.trim_start_matches("(UNREGISTERED)").trim().to_string()+" ";
|
let message = message
|
||||||
|
.trim_start_matches("(UNREGISTERED)")
|
||||||
|
.trim_start_matches("(UNAUTHORIZED)")
|
||||||
|
.trim()
|
||||||
|
.to_string()+" ";
|
||||||
|
|
||||||
let prefix = if ctx.enable_ip_viewing {
|
let prefix = if ctx.enable_ip_viewing {
|
||||||
if let Some(ip) = ip {
|
if let Some(ip) = ip {
|
||||||
format!("{}{} [{}]", ip, " ".repeat(15-ip.len()), date)
|
format!("{}{} [{}]", ip, " ".repeat(if 15 >= ip.chars().count() {15-ip.chars().count()} else {0}), date)
|
||||||
} else {
|
} else {
|
||||||
format!("{} [{}]", " ".repeat(15), date)
|
format!("{} [{}]", " ".repeat(15), date)
|
||||||
}
|
}
|
||||||
@ -319,10 +331,10 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
|||||||
.replace("{text}", &message)
|
.replace("{text}", &message)
|
||||||
);
|
);
|
||||||
|
|
||||||
if ctx.auth {
|
if ctx.enable_auth {
|
||||||
send_message_auth(&ctx.host, &message)?;
|
send_message_auth(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?;
|
||||||
} else {
|
} else {
|
||||||
send_message(&ctx.host, &message)?;
|
send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -466,7 +478,8 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
||||||
if let Ok(Some((messages, size))) = read_messages(&ctx.host, ctx.max_messages, ctx.messages.packet_size()) {
|
match read_messages(&mut connect(&ctx.host, ctx.enable_ssl)?, ctx.max_messages, ctx.messages.packet_size(), !ctx.enable_ssl) {
|
||||||
|
Ok(Some((messages, size))) => {
|
||||||
let messages: Vec<String> = if ctx.disable_formatting {
|
let messages: Vec<String> = if ctx.disable_formatting {
|
||||||
messages
|
messages
|
||||||
} else {
|
} else {
|
||||||
@ -475,6 +488,11 @@ pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
|||||||
ctx.messages.update(messages.clone(), size);
|
ctx.messages.update(messages.clone(), size);
|
||||||
print_console(ctx.clone(), messages, &ctx.input.read().unwrap())?;
|
print_console(ctx.clone(), messages, &ctx.input.read().unwrap())?;
|
||||||
}
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("{:?}", e);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
thread::sleep(Duration::from_millis(ctx.update_time as u64));
|
thread::sleep(Duration::from_millis(ctx.update_time as u64));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,8 @@ pub struct Config {
|
|||||||
pub disable_ip_hiding: bool,
|
pub disable_ip_hiding: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub enable_auth: bool,
|
pub enable_auth: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub enable_ssl: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_max_messages() -> usize { 200 }
|
fn default_max_messages() -> usize { 200 }
|
||||||
@ -72,6 +74,7 @@ pub fn configure(path: PathBuf) -> Config {
|
|||||||
let enable_ip_viewing = ask_bool("Enable users IP viewing?", false);
|
let enable_ip_viewing = ask_bool("Enable users IP viewing?", false);
|
||||||
let disable_ip_hiding = ask_bool("Enable your IP viewing?", false);
|
let disable_ip_hiding = ask_bool("Enable your IP viewing?", false);
|
||||||
let enable_auth = ask_bool("Enable auth-mode?", false);
|
let enable_auth = ask_bool("Enable auth-mode?", false);
|
||||||
|
let enable_ssl = ask_bool("Enable SSL?", false);
|
||||||
|
|
||||||
let config = Config {
|
let config = Config {
|
||||||
host,
|
host,
|
||||||
@ -81,7 +84,8 @@ pub fn configure(path: PathBuf) -> Config {
|
|||||||
max_messages,
|
max_messages,
|
||||||
enable_ip_viewing,
|
enable_ip_viewing,
|
||||||
disable_ip_hiding,
|
disable_ip_hiding,
|
||||||
enable_auth
|
enable_auth,
|
||||||
|
enable_ssl
|
||||||
};
|
};
|
||||||
|
|
||||||
let config_text = serde_yml::to_string(&config).expect("Config save error");
|
let config_text = serde_yml::to_string(&config).expect("Config save error");
|
||||||
@ -180,6 +184,10 @@ pub struct Args {
|
|||||||
/// Enable authentication
|
/// Enable authentication
|
||||||
#[arg(short='a', long)]
|
#[arg(short='a', long)]
|
||||||
pub enable_auth: bool,
|
pub enable_auth: bool,
|
||||||
|
|
||||||
|
/// Enable SSL
|
||||||
|
#[arg(short='S', long)]
|
||||||
|
pub enable_ssl: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
@ -195,7 +203,8 @@ pub struct Context {
|
|||||||
pub max_messages: usize,
|
pub max_messages: usize,
|
||||||
pub enable_ip_viewing: bool,
|
pub enable_ip_viewing: bool,
|
||||||
pub scroll: Arc<AtomicUsize>,
|
pub scroll: Arc<AtomicUsize>,
|
||||||
pub auth: bool,
|
pub enable_auth: bool,
|
||||||
|
pub enable_ssl: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
@ -213,7 +222,8 @@ impl Context {
|
|||||||
max_messages: config.max_messages,
|
max_messages: config.max_messages,
|
||||||
enable_ip_viewing: args.enable_users_ip_viewing || config.enable_ip_viewing,
|
enable_ip_viewing: args.enable_users_ip_viewing || config.enable_ip_viewing,
|
||||||
scroll: Arc::new(AtomicUsize::new(0)),
|
scroll: Arc::new(AtomicUsize::new(0)),
|
||||||
auth: args.enable_auth || config.enable_auth
|
enable_auth: args.enable_auth || config.enable_auth,
|
||||||
|
enable_ssl: args.enable_ssl || config.enable_ssl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
15
src/main.rs
15
src/main.rs
@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use colored::Color;
|
use colored::Color;
|
||||||
use config::{configure, get_config_path, load_config, Args, Context};
|
use config::{configure, get_config_path, load_config, Args, Context};
|
||||||
use proto::{read_messages, send_message};
|
use proto::{connect, read_messages, send_message};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use chat::run_main_loop;
|
use chat::run_main_loop;
|
||||||
@ -47,11 +47,20 @@ fn main() {
|
|||||||
let ctx = Arc::new(Context::new(&config, &args));
|
let ctx = Arc::new(Context::new(&config, &args));
|
||||||
|
|
||||||
if args.read_messages {
|
if args.read_messages {
|
||||||
print!("{}", read_messages(&ctx.host, ctx.max_messages, 0).ok().flatten().expect("Error reading messages").0.join("\n"));
|
let mut stream = connect(&ctx.host, ctx.enable_ssl).expect("Error reading message");
|
||||||
|
print!("{}", read_messages(
|
||||||
|
&mut stream,
|
||||||
|
ctx.max_messages,
|
||||||
|
0,
|
||||||
|
!ctx.enable_ssl
|
||||||
|
)
|
||||||
|
.ok().flatten()
|
||||||
|
.expect("Error reading messages").0.join("\n")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(message) = &args.send_message {
|
if let Some(message) = &args.send_message {
|
||||||
send_message(&ctx.host, message).expect("Error sending message");
|
send_message(&mut connect(&ctx.host, ctx.enable_ssl).expect("Error sending message"), message).expect("Error sending message");
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.send_message.is_some() || args.read_messages {
|
if args.send_message.is_some() || args.read_messages {
|
||||||
|
64
src/proto.rs
64
src/proto.rs
@ -1,18 +1,35 @@
|
|||||||
use std::{error::Error, io::{Read, Write}, net::TcpStream};
|
use std::{error::Error, fmt::Debug, io::{Read, Write}, net::TcpStream};
|
||||||
|
|
||||||
|
use native_tls::TlsConnector;
|
||||||
|
|
||||||
|
pub trait RacStream: Read + Write + Unpin + Send + Sync + Debug {}
|
||||||
|
impl<T: Read + Write + Unpin + Send + Sync + Debug> RacStream for T {}
|
||||||
|
|
||||||
pub fn send_message(host: &str, message: &str) -> Result<(), Box<dyn Error>> {
|
pub fn connect(host: &str, ssl: bool) -> Result<Box<dyn RacStream>, Box<dyn Error>> {
|
||||||
let mut stream = TcpStream::connect(host)?;
|
Ok(if ssl {
|
||||||
|
let ip: String = host.split_once(":")
|
||||||
|
.map(|o| o.0)
|
||||||
|
.unwrap_or(host).to_string();
|
||||||
|
|
||||||
|
Box::new(TlsConnector::builder()
|
||||||
|
.danger_accept_invalid_certs(true)
|
||||||
|
.danger_accept_invalid_hostnames(true)
|
||||||
|
.build()?
|
||||||
|
.connect(&ip, connect(host, false)?)?)
|
||||||
|
} else {
|
||||||
|
Box::new(TcpStream::connect(host)?)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_message(stream: &mut (impl Read + Write), message: &str) -> Result<(), Box<dyn Error>> {
|
||||||
stream.write_all(&[0x01])?;
|
stream.write_all(&[0x01])?;
|
||||||
stream.write_all(message.as_bytes())?;
|
stream.write_all(message.as_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_message_auth(host: &str, message: &str) -> Result<(), Box<dyn Error>> {
|
pub fn send_message_auth(stream: &mut (impl Read + Write), message: &str) -> Result<(), Box<dyn Error>> {
|
||||||
let Some((name, message)) = message.split_once("> ") else { return send_message(host, message) };
|
let Some((name, message)) = message.split_once("> ") else { return send_message(stream, message) };
|
||||||
|
|
||||||
let mut stream = TcpStream::connect(host)?;
|
|
||||||
stream.write_all(&[0x02])?;
|
stream.write_all(&[0x02])?;
|
||||||
stream.write_all(name.as_bytes())?;
|
stream.write_all(name.as_bytes())?;
|
||||||
stream.write_all(b"\n")?;
|
stream.write_all(b"\n")?;
|
||||||
@ -23,16 +40,15 @@ pub fn send_message_auth(host: &str, message: &str) -> Result<(), Box<dyn Error>
|
|||||||
let mut buf = vec![0; 1];
|
let mut buf = vec![0; 1];
|
||||||
if let Ok(_) = stream.read_exact(&mut buf) {
|
if let Ok(_) = stream.read_exact(&mut buf) {
|
||||||
let name = format!("\x1f{name}");
|
let name = format!("\x1f{name}");
|
||||||
register_user(host, &name, &name)?;
|
register_user(stream, &name, &name)?;
|
||||||
let message = format!("{name}> {message}");
|
let message = format!("{name}> {message}");
|
||||||
send_message_auth(host, &message)
|
send_message_auth(stream, &message)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_user(host: &str, name: &str, password: &str) -> Result<(), Box<dyn Error>> {
|
pub fn register_user(stream: &mut (impl Read + Write), name: &str, password: &str) -> Result<(), Box<dyn Error>> {
|
||||||
let mut stream = TcpStream::connect(host)?;
|
|
||||||
stream.write_all(&[0x03])?;
|
stream.write_all(&[0x03])?;
|
||||||
stream.write_all(name.as_bytes())?;
|
stream.write_all(name.as_bytes())?;
|
||||||
stream.write_all(&[b'\n'])?;
|
stream.write_all(&[b'\n'])?;
|
||||||
@ -40,7 +56,7 @@ pub fn register_user(host: &str, name: &str, password: &str) -> Result<(), Box<d
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_null(stream: &mut TcpStream) -> Result<Vec<u8>, Box<dyn Error>> {
|
fn skip_null(stream: &mut impl Read) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||||
loop {
|
loop {
|
||||||
let mut buf = vec![0; 1];
|
let mut buf = vec![0; 1];
|
||||||
stream.read_exact(&mut buf)?;
|
stream.read_exact(&mut buf)?;
|
||||||
@ -50,13 +66,12 @@ fn skip_null(stream: &mut TcpStream) -> Result<Vec<u8>, Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_messages(host: &str, max_messages: usize, last_size: usize) -> Result<Option<(Vec<String>, usize)>, Box<dyn Error>> {
|
pub fn read_messages(stream: &mut (impl Read + Write), max_messages: usize, last_size: usize, skip_null_: bool) -> Result<Option<(Vec<String>, usize)>, Box<dyn Error>> {
|
||||||
let mut stream = TcpStream::connect(host)?;
|
|
||||||
|
|
||||||
stream.write_all(&[0x00])?;
|
stream.write_all(&[0x00])?;
|
||||||
|
|
||||||
let packet_size = {
|
let packet_size = {
|
||||||
let mut data = skip_null(&mut stream)?;
|
let data = if skip_null_ {
|
||||||
|
let mut data = skip_null(stream)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut buf = vec![0; 1];
|
let mut buf = vec![0; 1];
|
||||||
@ -67,6 +82,13 @@ pub fn read_messages(host: &str, max_messages: usize, last_size: usize) -> Resul
|
|||||||
}
|
}
|
||||||
data.push(ch);
|
data.push(ch);
|
||||||
}
|
}
|
||||||
|
data
|
||||||
|
} else {
|
||||||
|
let mut data = vec![0; 10];
|
||||||
|
let len = stream.read(&mut data)?;
|
||||||
|
data.truncate(len);
|
||||||
|
data
|
||||||
|
};
|
||||||
|
|
||||||
String::from_utf8(data)?
|
String::from_utf8(data)?
|
||||||
.trim_matches(char::from(0))
|
.trim_matches(char::from(0))
|
||||||
@ -80,19 +102,27 @@ pub fn read_messages(host: &str, max_messages: usize, last_size: usize) -> Resul
|
|||||||
stream.write_all(&[0x01])?;
|
stream.write_all(&[0x01])?;
|
||||||
|
|
||||||
let packet_data = {
|
let packet_data = {
|
||||||
let mut data = skip_null(&mut stream)?;
|
let data = if skip_null_ {
|
||||||
|
let mut data = skip_null(stream)?;
|
||||||
while data.len() < packet_size {
|
while data.len() < packet_size {
|
||||||
let mut buf = vec![0; packet_size - data.len()];
|
let mut buf = vec![0; packet_size - data.len()];
|
||||||
let read_bytes = stream.read(&mut buf)?;
|
let read_bytes = stream.read(&mut buf)?;
|
||||||
buf.truncate(read_bytes);
|
buf.truncate(read_bytes);
|
||||||
data.append(&mut buf);
|
data.append(&mut buf);
|
||||||
}
|
}
|
||||||
|
data
|
||||||
|
} else {
|
||||||
|
let mut data = vec![0; packet_size];
|
||||||
|
stream.read_exact(&mut data)?;
|
||||||
|
data
|
||||||
|
};
|
||||||
|
|
||||||
String::from_utf8_lossy(&data).to_string()
|
String::from_utf8_lossy(&data).to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
let lines: Vec<&str> = packet_data.split("\n").collect();
|
let lines: Vec<&str> = packet_data.split("\n").collect();
|
||||||
let lines: Vec<String> = lines.clone().into_iter()
|
let lines: Vec<String> = lines.clone().into_iter()
|
||||||
.skip(lines.len() - max_messages)
|
.skip(if lines.len() >= max_messages { lines.len() - max_messages } else { 0 })
|
||||||
.map(|o| o.to_string())
|
.map(|o| o.to_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user