Added support for passwords
This commit is contained in:
parent
9e1cf429e4
commit
7ec28b778d
2 changed files with 43 additions and 2 deletions
|
@ -5,4 +5,5 @@ edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.31", features = ["derive"] }
|
clap = { version = "4.5.31", features = ["derive"] }
|
||||||
|
sha2 = "0.10.8"
|
||||||
time = { version = "0.3.37", features = ["formatting", "local-offset"] }
|
time = { version = "0.3.37", features = ["formatting", "local-offset"] }
|
||||||
|
|
44
src/main.rs
44
src/main.rs
|
@ -1,6 +1,7 @@
|
||||||
#![feature(random)]
|
#![feature(random)]
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use sha2::{Digest, Sha512};
|
||||||
use std::io::{ErrorKind, prelude::*};
|
use std::io::{ErrorKind, prelude::*};
|
||||||
use std::net::{TcpListener, TcpStream};
|
use std::net::{TcpListener, TcpStream};
|
||||||
use std::random;
|
use std::random;
|
||||||
|
@ -13,6 +14,10 @@ struct Args {
|
||||||
/// Port to bind on.
|
/// Port to bind on.
|
||||||
#[arg(short, long, default_value_t = 7867)]
|
#[arg(short, long, default_value_t = 7867)]
|
||||||
port: u16,
|
port: u16,
|
||||||
|
/// Password. Will be stored as a SHA512 hashed string.
|
||||||
|
/// Will not require a password if none provided.
|
||||||
|
#[arg(short = 'P', long, default_value = None)]
|
||||||
|
password: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
|
@ -86,7 +91,7 @@ fn display_msg(stream: &mut TcpStream, msg: &Message) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_client(mut stream: TcpStream, channel: Channel) {
|
fn handle_client(mut stream: TcpStream, channel: Channel, password: Option<Vec<u8>>) {
|
||||||
stream
|
stream
|
||||||
.write_all(b"\x1b[33mEnter your chosen nickname(up to 30 characters):\x1b[0m\x1b[4m\n")
|
.write_all(b"\x1b[33mEnter your chosen nickname(up to 30 characters):\x1b[0m\x1b[4m\n")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -172,6 +177,34 @@ fn handle_client(mut stream: TcpStream, channel: Channel) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if password.is_some() {
|
||||||
|
let password = password.unwrap();
|
||||||
|
|
||||||
|
stream
|
||||||
|
.write_all(b"\x1b[0m\x1b[33mThis server requires a password. Enter the password:\x1b[0m\x1b[4m\n")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut buf = vec![];
|
||||||
|
let mut buf1 = [0u8];
|
||||||
|
'bufreadloop3: while buf1[0] != b'\n' || i == 0 {
|
||||||
|
stream.read_exact(&mut buf1).unwrap();
|
||||||
|
if buf1[0] == b'\n' {
|
||||||
|
let mut sha512 = Sha512::new();
|
||||||
|
sha512.update(buf);
|
||||||
|
|
||||||
|
if password != sha512.finalize().to_vec() {
|
||||||
|
stream
|
||||||
|
.write_all(b"\x1b[0m\x1b[31mIncorrect.\x1b[0m\n")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break 'bufreadloop3;
|
||||||
|
}
|
||||||
|
buf.push(buf1[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let lock = channel.lock().unwrap();
|
let lock = channel.lock().unwrap();
|
||||||
for msg in &lock.messages {
|
for msg in &lock.messages {
|
||||||
|
@ -476,6 +509,12 @@ fn handle_client(mut stream: TcpStream, channel: Channel) {
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
let mut password = None;
|
||||||
|
if args.password.is_some() {
|
||||||
|
let mut sha512 = sha2::Sha512::new();
|
||||||
|
sha512.update(args.password.unwrap());
|
||||||
|
password = Some(sha512.finalize().to_vec());
|
||||||
|
}
|
||||||
|
|
||||||
let listener = TcpListener::bind(format!("0.0.0.0:{}", args.port))?;
|
let listener = TcpListener::bind(format!("0.0.0.0:{}", args.port))?;
|
||||||
let channel: Channel = Arc::new(Mutex::new(UnwrappedChannel {
|
let channel: Channel = Arc::new(Mutex::new(UnwrappedChannel {
|
||||||
|
@ -486,8 +525,9 @@ fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
let channel: Channel = channel.clone();
|
let channel: Channel = channel.clone();
|
||||||
|
let password = password.clone();
|
||||||
thread::spawn(|| {
|
thread::spawn(|| {
|
||||||
handle_client(stream.unwrap(), channel);
|
handle_client(stream.unwrap(), channel, password);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue