From d56bf8b7e4f9f4cdc7cadaf31ac169c58e0f16a2 Mon Sep 17 00:00:00 2001 From: Zoey Date: Fri, 19 Apr 2024 13:17:06 -0700 Subject: [PATCH] add per-user server passwords --- src/server/config.rs | 21 ++++++++++++++++++--- src/server/network.rs | 19 ++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/server/config.rs b/src/server/config.rs index 9c43c3f..810f54b 100644 --- a/src/server/config.rs +++ b/src/server/config.rs @@ -1,3 +1,5 @@ +use std::collections::BTreeMap; + use serde::{Deserialize, Serialize}; use crate::level::generation::LevelGeneration; @@ -9,8 +11,9 @@ pub struct ServerConfig { pub name: String, /// the server's motd pub motd: String, - /// the server's password, if any - pub password: Option, + /// the server's protection mode + #[serde(rename = "password")] + pub protection_mode: ServerProtectionMode, /// the level's size pub level_size: Option, /// the level's spawn point @@ -24,7 +27,7 @@ impl Default for ServerConfig { Self { name: "classic server wowie".to_string(), motd: "here's the default server motd".to_string(), - password: None, + protection_mode: ServerProtectionMode::None, level_size: None, spawn: None, generation: LevelGeneration::Empty, @@ -42,3 +45,15 @@ pub struct ConfigCoordinates { /// the Z coordinate pub z: usize, } + +/// enum for the different kinds of server protection +#[derive(Debug, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ServerProtectionMode { + /// the server is unprotected and anyone can join with any username + None, + /// the server requires a password to join, but you can use any username if you know the password + Password(String), + /// the server requires a password to join and the password is checked against each username + PasswordsByUser(BTreeMap), +} diff --git a/src/server/network.rs b/src/server/network.rs index 768f57f..ef3f0f7 100644 --- a/src/server/network.rs +++ b/src/server/network.rs @@ -14,6 +14,7 @@ use crate::{ client::ClientPacket, server::ServerPacket, PacketReader, PacketWriter, ARRAY_LENGTH, }, player::{Player, PlayerType}, + server::config::ServerProtectionMode, }; use super::ServerData; @@ -113,9 +114,21 @@ async fn handle_stream_inner( let mut data = data.write().await; - if let Some(password) = &data.config.password { - if verification_key != *password { - return Ok(Some("Incorrect password!".to_string())); + match &data.config.protection_mode { + ServerProtectionMode::None => {} + ServerProtectionMode::Password(password) => { + if verification_key != *password { + return Ok(Some("Incorrect password!".to_string())); + } + } + ServerProtectionMode::PasswordsByUser(passwords) => { + if !passwords + .get(&username) + .map(|password| verification_key == *password) + .unwrap_or_default() + { + return Ok(Some("Incorrect password!".to_string())); + } } }