mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-07-03 08:15:35 +00:00
fix server and client resource behavior, canonicalize paths in mod requests
This commit is contained in:
parent
72bec02e21
commit
787f59ba46
@ -1,5 +1,7 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
use crate::fs_util;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Config {
|
||||
@ -51,6 +53,22 @@ impl GeneralSettings {
|
||||
Uuid::parse_str(auth_key.as_str()).is_ok()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the client resource path, and ensures it exists.
|
||||
/// Default is Resources/Client.
|
||||
pub fn get_client_resource_folder(&self) -> anyhow::Result<String> {
|
||||
let res_client_path = Path::new(self.resource_folder.as_str()).join("Client");
|
||||
fs_util::ensure_path_exists(&res_client_path)?;
|
||||
Ok(fs_util::path_to_string(res_client_path))
|
||||
}
|
||||
|
||||
/// Returns the server resource path, and ensures it exists.
|
||||
/// Default is Resources/Server.
|
||||
pub fn get_server_resource_folder(&self) -> anyhow::Result<String> {
|
||||
let res_server_path = Path::new(self.resource_folder.as_str()).join("Server");
|
||||
fs_util::ensure_path_exists(&res_server_path)?;
|
||||
Ok(fs_util::path_to_string(res_server_path))
|
||||
}
|
||||
}
|
10
src/main.rs
10
src/main.rs
@ -2,6 +2,7 @@
|
||||
#[macro_use] extern crate async_trait;
|
||||
#[macro_use] extern crate lazy_static;
|
||||
|
||||
use std::path::Path;
|
||||
use argh::FromArgs;
|
||||
|
||||
use std::sync::Arc;
|
||||
@ -12,6 +13,7 @@ mod tui;
|
||||
mod server;
|
||||
mod config;
|
||||
mod heartbeat;
|
||||
mod fs_util;
|
||||
|
||||
#[derive(FromArgs)]
|
||||
/// BeamMP Server v3.3.0
|
||||
@ -40,8 +42,12 @@ async fn main() {
|
||||
.map_err(|_| error!("Failed to parse config file!"))
|
||||
.expect("Failed to parse config file!");
|
||||
|
||||
// TODO: This should not error lol
|
||||
for entry in std::fs::read_dir("Resources/Client").expect("Failed to read Resources/Client!") {
|
||||
|
||||
let client_resources = user_config.general
|
||||
.get_client_resource_folder()
|
||||
.expect("Failed to create the client resource folder");
|
||||
|
||||
for entry in std::fs::read_dir(client_resources).expect("Failed to read client resource folder!") {
|
||||
if let Ok(entry) = entry {
|
||||
if entry.path().is_file() {
|
||||
if let Ok(metadata) = entry.metadata() {
|
||||
|
@ -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/*"
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user