fix server and client resource behavior, canonicalize paths in mod requests

This commit is contained in:
Lion Kortlepel
2023-11-23 17:42:10 +01:00
parent 72bec02e21
commit 787f59ba46
4 changed files with 44 additions and 21 deletions

View File

@@ -1,6 +1,7 @@
use std::collections::HashMap;
use std::net::SocketAddr;
use std::ops::DerefMut;
use std::path::Path;
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc;
use std::time::Instant;
@@ -18,6 +19,7 @@ use nalgebra::*;
use serde::Deserialize;
use serde_aux::prelude::*;
use crate::fs_util;
use super::backend::*;
use super::car::*;
@@ -225,21 +227,13 @@ impl Client {
// Handle file download
let mut mod_name = packet.data_as_string().clone();
mod_name.remove(0); // Remove f
debug!("Client requested file {}", mod_name);
debug!("Client is requesting file {}", mod_name);
// making sure that the requested file cant point to files outside of Resources/Client/*
let path = std::path::Path::new(&mod_name);
let mod_name = match path.file_name() {
Some(v) => "/".to_string() + v.to_str().unwrap(),
None => {
error!("Client requests invalid mod. Disconnecting");
self.kick("Invalid mod request").await;
return Ok(());
}, // client requested path (fResources/Client/) or nothing at all (f) - invalid
};
let mod_path = format!("Resources/Client{mod_name}");
if !std::path::Path::new(&mod_path).exists() {
error!("Client requests inexistent mod. Disconnecting");
let client_resources = config.general.get_server_resource_folder()?;
let mod_path = fs_util::join_path_secure(Path::new(&client_resources), Path::new(&mod_name))?;
if !mod_path.exists() || !mod_path.is_file() {
error!("Client requested mod which doesn't exist: {:?}. Disconnecting", mod_path);
self.kick("Invalid mod request").await;
return Ok(()) // client requested mod that doesnt exists within "Resources/Client/*"
}

View File

@@ -27,11 +27,12 @@ pub use plugins::*;
pub use http::*;
pub use crate::config::Config;
use crate::config::GeneralSettings;
fn load_plugins() -> Vec<Plugin> {
fn load_plugins(server_resource_folder: String) -> Vec<Plugin> {
let mut plugins = Vec::new();
for res_entry in std::fs::read_dir("Resources/Server").expect("Failed to read Resources/Server!") {
for res_entry in std::fs::read_dir(server_resource_folder).expect("Failed to read server resource folder!") {
if let Ok(res_entry) = res_entry {
let res_path = res_entry.path();
if res_path.is_dir() {
@@ -158,8 +159,12 @@ impl Server {
Arc::new(UdpSocket::bind(bind_addr).await?)
};
let server_resource_folder = config.general
.get_server_resource_folder()
.expect("Failed to create the client resource folder");
// Load existing plugins
let plugins = load_plugins();
let plugins = load_plugins(server_resource_folder);
// Start client runtime
let (clients_incoming_tx, clients_incoming_rx) = mpsc::channel(100);