Skip to content

Commit

Permalink
Allow disable encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
Snowiiii committed Sep 28, 2024
1 parent 92fef82 commit 1ddaca1
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 101 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 20 additions & 5 deletions pumpkin-config/src/compression.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
// Packet compression
/// Packet compression
pub struct CompressionConfig {
/// Is compression enabled ?
pub enabled: bool,
#[serde(flatten)]
pub compression_info: CompressionInfo,
}

#[derive(Deserialize, Serialize, Clone)]
/// We have this in a Seperate struct so we can use it outside of the Config
pub struct CompressionInfo {
/// The compression threshold used when compression is enabled
pub compression_threshold: u32,
pub threshold: u32,
/// A value between 0..9
/// 1 = Optimize for the best speed of encoding.
/// 9 = Optimize for the size of data being encoded.
pub compression_level: u32,
pub level: u32,
}

impl Default for CompressionInfo {
fn default() -> Self {
Self {
threshold: 256,
level: 4,
}
}
}

impl Default for CompressionConfig {
fn default() -> Self {
Self {
enabled: true,
compression_threshold: 256,
compression_level: 4,
compression_info: Default::default(),
}
}
}
2 changes: 1 addition & 1 deletion pumpkin-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub use pvp::PVPConfig;
pub use rcon::RCONConfig;

mod commands;
mod compression;
pub mod compression;
mod pvp;
mod rcon;

Expand Down
1 change: 1 addition & 0 deletions pumpkin-protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version.workspace = true
edition.workspace = true

[dependencies]
pumpkin-config = { path = "../pumpkin-config" }
pumpkin-macros = { path = "../pumpkin-macros" }
pumpkin-world = { path = "../pumpkin-world" }
pumpkin-core = { path = "../pumpkin-core" }
Expand Down
27 changes: 17 additions & 10 deletions pumpkin-protocol/src/packet_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type Cipher = cfb8::Decryptor<aes::Aes128>;
pub struct PacketDecoder {
buf: BytesMut,
decompress_buf: BytesMut,
compression: Option<u32>,
compression: bool,
cipher: Option<Cipher>,
}

Expand All @@ -45,7 +45,7 @@ impl PacketDecoder {
let packet_len_len = VarInt(packet_len).written_size();

let mut data;
if self.compression.is_some() {
if self.compression {
r = &r[..packet_len as usize];

let data_len = VarInt::decode(&mut r).map_err(|_| PacketError::TooLong)?.0;
Expand Down Expand Up @@ -96,19 +96,26 @@ impl PacketDecoder {
}))
}

pub fn enable_encryption(&mut self, key: &[u8; 16]) {
assert!(self.cipher.is_none(), "encryption is already enabled");
pub fn set_encryption(&mut self, key: Option<&[u8; 16]>) {
if let Some(key) = key {
assert!(self.cipher.is_none(), "encryption is already enabled");

let mut cipher = Cipher::new_from_slices(key, key).expect("invalid key");
let mut cipher = Cipher::new_from_slices(key, key).expect("invalid key");

// Don't forget to decrypt the data we already have.
Self::decrypt_bytes(&mut cipher, &mut self.buf);
// Don't forget to decrypt the data we already have.

self.cipher = Some(cipher);
Self::decrypt_bytes(&mut cipher, &mut self.buf);

self.cipher = Some(cipher);
} else {
assert!(self.cipher.is_some(), "encryption is already disabled");

self.cipher = None;
}
}

/// Enables ZLib Deompression
pub fn set_compression(&mut self, compression: Option<u32>) {
/// Sets ZLib Deompression
pub fn set_compression(&mut self, compression: bool) {
self.compression = compression;
}

Expand Down
24 changes: 16 additions & 8 deletions pumpkin-protocol/src/packet_encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::io::Write;

use aes::cipher::{generic_array::GenericArray, BlockEncryptMut, BlockSizeUser, KeyIvInit};
use bytes::{BufMut, BytesMut};
use pumpkin_config::compression::CompressionInfo;

use std::io::Read;

Expand All @@ -19,7 +20,7 @@ type Cipher = cfb8::Encryptor<aes::Aes128>;
pub struct PacketEncoder {
buf: BytesMut,
compress_buf: Vec<u8>,
compression: Option<(u32, u32)>,
compression: Option<CompressionInfo>,
cipher: Option<Cipher>,
}

Expand All @@ -40,10 +41,10 @@ impl PacketEncoder {

let data_len = self.buf.len() - start_len;

if let Some((threshold, compression_level)) = self.compression {
if data_len > threshold as usize {
if let Some(compression) = &self.compression {
if data_len > compression.threshold as usize {
let mut z =
ZlibEncoder::new(&self.buf[start_len..], Compression::new(compression_level));
ZlibEncoder::new(&self.buf[start_len..], Compression::new(compression.level));

self.compress_buf.clear();

Expand Down Expand Up @@ -117,13 +118,20 @@ impl PacketEncoder {
Ok(())
}

pub fn enable_encryption(&mut self, key: &[u8; 16]) {
assert!(self.cipher.is_none(), "encryption is already enabled");
self.cipher = Some(Cipher::new_from_slices(key, key).expect("invalid key"));
pub fn set_encryption(&mut self, key: Option<&[u8; 16]>) {
if let Some(key) = key {
assert!(self.cipher.is_none(), "encryption is already enabled");

self.cipher = Some(Cipher::new_from_slices(key, key).expect("invalid key"));
} else {
assert!(self.cipher.is_some(), "encryption is disabled");

self.cipher = None;
}
}

/// Enables ZLib Compression
pub fn set_compression(&mut self, compression: Option<(u32, u32)>) {
pub fn set_compression(&mut self, compression: Option<CompressionInfo>) {
self.compression = compression;
}

Expand Down
7 changes: 3 additions & 4 deletions pumpkin-world/src/block/block_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ impl BlockId {
.iter();

let block_state = match properties {
Some(properties) => match block_states.find(|state| &state.properties == properties) {
Some(state) => state,
None => return Err(WorldError::BlockStateIdNotFound),
},
Some(properties) => block_states
.find(|state| &state.properties == properties)
.ok_or_else(|| WorldError::BlockStateIdNotFound)?,
None => block_states
.find(|state| state.is_default)
.expect("Every Block should have at least 1 default state"),
Expand Down
43 changes: 14 additions & 29 deletions pumpkin-world/src/level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ impl Level {
}
}

pub fn get_block() {}

/// Reads/Generates many chunks in a world
/// MUST be called from a tokio runtime thread
///
Expand All @@ -147,7 +149,6 @@ impl Level {
) {
chunks.into_par_iter().for_each(|at| {
if is_alive {
dbg!("a");
return;
}
let mut loaded_chunks = self.loaded_chunks.lock();
Expand Down Expand Up @@ -235,29 +236,21 @@ impl Level {

// Read the file using the offset and size
let mut file_buf = {
let seek_result = region_file.seek(std::io::SeekFrom::Start(offset));
if seek_result.is_err() {
return Err(WorldError::RegionIsInvalid);
}
region_file
.seek(std::io::SeekFrom::Start(offset))
.map_err(|_| WorldError::RegionIsInvalid)?;
let mut out = vec![0; size];
let read_result = region_file.read_exact(&mut out);
if read_result.is_err() {
return Err(WorldError::RegionIsInvalid);
}
region_file
.read_exact(&mut out)
.map_err(|_| WorldError::RegionIsInvalid)?;
out
};

// TODO: check checksum to make sure chunk is not corrupted
let header = file_buf.drain(0..5).collect_vec();

let compression = match Compression::from_byte(header[4]) {
Some(c) => c,
None => {
return Err(WorldError::Compression(
CompressionError::UnknownCompression,
))
}
};
let compression = Compression::from_byte(header[4])
.ok_or_else(|| WorldError::Compression(CompressionError::UnknownCompression))?;

let size = u32::from_be_bytes(header[..4].try_into().unwrap());

Expand All @@ -277,23 +270,15 @@ impl Level {
Compression::Gzip => {
let mut z = GzDecoder::new(&compressed_data[..]);
let mut chunk_data = Vec::with_capacity(compressed_data.len());
match z.read_to_end(&mut chunk_data) {
Ok(_) => {}
Err(e) => {
return Err(CompressionError::GZipError(e));
}
}
z.read_to_end(&mut chunk_data)
.map_err(CompressionError::GZipError)?;
Ok(chunk_data)
}
Compression::Zlib => {
let mut z = ZlibDecoder::new(&compressed_data[..]);
let mut chunk_data = Vec::with_capacity(compressed_data.len());
match z.read_to_end(&mut chunk_data) {
Ok(_) => {}
Err(e) => {
return Err(CompressionError::ZlibError(e));
}
}
z.read_to_end(&mut chunk_data)
.map_err(CompressionError::ZlibError)?;
Ok(chunk_data)
}
Compression::None => Ok(compressed_data),
Expand Down
24 changes: 12 additions & 12 deletions pumpkin/src/client/client_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,15 @@ impl Client {
) {
let shared_secret = server.decrypt(&encryption_response.shared_secret).unwrap();

self.enable_encryption(&shared_secret)
self.set_encryption(Some(&shared_secret))
.unwrap_or_else(|e| self.kick(&e.to_string()));

let mut gameprofile = self.gameprofile.lock();

if BASIC_CONFIG.online_mode {
let hash = server.digest_secret(&shared_secret);
let ip = self.address.lock().ip();

match authentication::authenticate(
&gameprofile.as_ref().unwrap().name,
&hash,
Expand All @@ -123,15 +124,15 @@ impl Client {
)
.await
{
Ok(p) => {
Ok(profile) => {
// Check if player should join
if let Some(p) = &p.profile_actions {
if let Some(actions) = &profile.profile_actions {
if !ADVANCED_CONFIG
.authentication
.player_profile
.allow_banned_players
{
if !p.is_empty() {
if !actions.is_empty() {
self.kick("Your account can't join");
}
} else {
Expand All @@ -140,28 +141,27 @@ impl Client {
.player_profile
.allowed_actions
{
if !p.contains(allowed) {
if !actions.contains(allowed) {
self.kick("Your account can't join");
}
}
}
}
*gameprofile = Some(p);
*gameprofile = Some(profile);
}
Err(e) => self.kick(&e.to_string()),
}
}
for property in &gameprofile.as_ref().unwrap().properties {
// TODO: use this (this was the todo here before, ill add it again cuz its prob here for a reason)
let _ = unpack_textures(property, &ADVANCED_CONFIG.authentication.textures);
unpack_textures(property, &ADVANCED_CONFIG.authentication.textures)
.unwrap_or_else(|e| self.kick(&e.to_string()));
}

// enable compression
if ADVANCED_CONFIG.packet_compression.enabled {
let threshold = ADVANCED_CONFIG.packet_compression.compression_threshold;
let level = ADVANCED_CONFIG.packet_compression.compression_level;
self.send_packet(&CSetCompression::new(threshold.into()));
self.set_compression(Some((threshold, level)));
let compression = ADVANCED_CONFIG.packet_compression.compression_info.clone();
self.send_packet(&CSetCompression::new(compression.threshold.into()));
self.set_compression(Some(compression));
}

if let Some(profile) = gameprofile.as_ref() {
Expand Down
Loading

0 comments on commit 1ddaca1

Please sign in to comment.