summaryrefslogtreecommitdiff
path: root/scarymaze/src/server.rs
diff options
context:
space:
mode:
authorJakob L. Kreuze <zerodaysfordays@sdf.org>2021-04-06 12:23:00 -0400
committerJakob L. Kreuze <zerodaysfordays@sdf.org>2021-04-06 12:25:17 -0400
commit983cd29f5a2c3d9cd1d6a9c4f343adcffe54f88c (patch)
tree395f4bf2dfe097d9d09413ad1b805765b2e7eae0 /scarymaze/src/server.rs
Initial import.HEADmaster
Diffstat (limited to 'scarymaze/src/server.rs')
-rw-r--r--scarymaze/src/server.rs247
1 files changed, 247 insertions, 0 deletions
diff --git a/scarymaze/src/server.rs b/scarymaze/src/server.rs
new file mode 100644
index 0000000..59e5621
--- /dev/null
+++ b/scarymaze/src/server.rs
@@ -0,0 +1,247 @@
+const FLAG: &'static str = "UMASS{pL4YZ_s4d_v1oL1n_s4DlY__g0_3a7_50m37hIN_Pl3453}";
+
+use async_std::io;
+use async_std::net::{TcpListener, TcpStream};
+use async_std::prelude::*;
+use async_std::task;
+
+enum ClientMessage {
+ North,
+ South,
+ East,
+ West,
+ Unknown,
+}
+
+const SERVER_MAP: u8 = 0;
+const SERVER_GOTO: u8 = 1;
+const SERVER_MESSAGE: u8 = 2;
+
+const MAZE_SIZE: usize = 24;
+
+use maze_generator::ellers_algorithm::EllersGenerator;
+use maze_generator::prelude::*;
+
+const AES_KEY: &'static str = "STRINGS NOT HERE";
+
+use openssl::symm::{decrypt, encrypt, Cipher};
+use rand::RngCore;
+
+fn my_encrypt(packet: &[u8]) -> Vec<u8> {
+ let mut rng = rand::thread_rng();
+ let mut iv = [0 as u8; 16];
+ rng.fill_bytes(&mut iv);
+
+ let cipher = Cipher::aes_128_cbc();
+ let key = AES_KEY.as_bytes();
+ let mut data = encrypt(cipher, key, Some(&iv), packet).unwrap();
+
+ let mut ciphertext = Vec::from(iv);
+ ciphertext.append(&mut data);
+ ciphertext
+}
+
+fn my_decrypt(packet: &[u8]) -> Vec<u8> {
+ let iv = &packet[..16];
+ let data = &packet[16..];
+ let cipher = Cipher::aes_128_cbc();
+ let key = AES_KEY.as_bytes();
+ let plaintext = decrypt(cipher, key, Some(iv), data).unwrap();
+ plaintext
+}
+
+fn new_map() -> (Vec<Vec<u8>>, (i32, i32)) {
+ let mut generator = EllersGenerator::new(None);
+ let maze = generator.generate((MAZE_SIZE / 3) as i32, (MAZE_SIZE / 3) as i32);
+ let mut map = vec![vec![0; MAZE_SIZE]; MAZE_SIZE];
+
+ for x in 0..MAZE_SIZE {
+ for y in 0..MAZE_SIZE {
+ if x == 0 || x == MAZE_SIZE - 1 || y == 0 || y == MAZE_SIZE - 1 {
+ map[y][x] = 1;
+ }
+ }
+ }
+
+ for x in 0..MAZE_SIZE / 3 {
+ for y in 0..MAZE_SIZE / 3 {
+ if let Some(field) = maze.get_field(&Coordinates::new(x as i32, y as i32)) {
+ if !field.has_passage(&Direction::North) {
+ map[(y * 3)][(x * 3) + 1] = 1;
+ }
+ if !field.has_passage(&Direction::South) {
+ map[(y * 3) + 2][(x * 3) + 1] = 1;
+ }
+ if !field.has_passage(&Direction::East) {
+ map[(y * 3) + 1][(x * 3) + 2] = 1;
+ }
+ if !field.has_passage(&Direction::West) {
+ map[(y * 3) + 1][(x * 3)] = 1;
+ }
+ }
+ }
+ }
+
+ map[(maze.goal.y * 3 + 1) as usize][(maze.goal.x * 3 + 1) as usize] = 2;
+
+ (map, (maze.start.x * 3 + 2, maze.start.y * 3 + 2))
+}
+
+async fn send_map(map: &Vec<Vec<u8>>, writer: &mut TcpStream) -> std::io::Result<usize> {
+ // Serialize map.
+ let mut packet = vec![SERVER_MAP];
+ let mut buf = [0 as u8; MAZE_SIZE * MAZE_SIZE];
+ for y in 0..MAZE_SIZE {
+ for x in 0..MAZE_SIZE {
+ buf[y * MAZE_SIZE + x] = map[x][y];
+ }
+ }
+ packet.append(&mut Vec::from(buf));
+
+ let mut ciphertext = my_encrypt(&packet);
+ let mut packet = Vec::from((ciphertext.len() as u64).to_be_bytes());
+ packet.append(&mut ciphertext);
+ writer.write(&packet).await
+}
+
+async fn send_goto(position: (i32, i32), writer: &mut TcpStream) -> std::io::Result<usize> {
+ let mut packet = vec![SERVER_GOTO];
+ let mut succ = Vec::from(position.0.to_be_bytes());
+ packet.append(&mut succ);
+ let mut succ = Vec::from(position.1.to_be_bytes());
+ packet.append(&mut succ);
+
+ let mut ciphertext = my_encrypt(&packet);
+ let mut packet = Vec::from((ciphertext.len() as u64).to_be_bytes());
+ packet.append(&mut ciphertext);
+ writer.write(&packet).await
+}
+
+async fn send_message(msg: String, writer: &mut TcpStream) -> std::io::Result<usize> {
+ let mut packet = vec![SERVER_MESSAGE];
+ packet.append(&mut Vec::from(msg.as_bytes()));
+
+ let mut ciphertext = my_encrypt(&packet);
+ let mut packet = Vec::from((ciphertext.len() as u64).to_be_bytes());
+ packet.append(&mut ciphertext);
+ writer.write(&packet).await
+}
+
+fn deserialize_client_message(buf: &[u8]) -> ClientMessage {
+ ClientMessage::Unknown
+}
+
+use std::convert::TryInto;
+use std::iter;
+
+async fn process(stream: TcpStream) -> io::Result<()> {
+ println!("Accepted from: {}", stream.peer_addr()?);
+
+ // Two buffers.
+ let mut recv = [0 as u8; 1024];
+ let mut send = [0 as u8; 1024];
+
+ let mut reader = stream.clone();
+ let mut writer = stream;
+
+ let mut map = vec![];
+ let mut position = (2, 2);
+ let mut level: i32 = 1;
+
+ let mut needs_map = true;
+
+ loop {
+ if needs_map {
+ let (new_map, new_position) = new_map();
+ map = new_map;
+ position = new_position;
+ send_map(&map, &mut writer).await?;
+ send_goto(position, &mut writer).await?;
+ needs_map = false;
+ }
+
+ if let Ok(n) = reader.read(&mut recv).await {
+ let encrypted_length = u64::from_be_bytes((&recv[..8]).try_into().unwrap()) as usize;
+ let packet = my_decrypt(&recv[8..8 + encrypted_length]);
+ match packet[0] {
+ 1 => {
+ let tile = map[(position.1 + 1) as usize][position.0 as usize];
+ if tile == 0 {
+ position.1 += 1;
+ } else if tile == 2 {
+ level += 1;
+ send_message(format!("Noice, level {}", level), &mut writer).await;
+ needs_map = true;
+ if level == 25 {
+ send_message(format!("Congratulations nerd, you just wasted a weekend on this. Here's your stupid flag: {}. Hope it was worth it.", FLAG), &mut writer).await;
+ }
+ }
+ }
+ 4 => {
+ let tile = map[(position.1 - 1) as usize][position.0 as usize];
+ if tile == 0 {
+ position.1 -= 1;
+ } else if tile == 2 {
+ level += 1;
+ send_message(format!("Noice, level {}", level), &mut writer).await;
+ needs_map = true;
+ if level == 25 {
+ send_message(format!("Congratulations nerd, you just wasted a weekend on this. Here's your stupid flag: {}. Hope it was worth it.", FLAG), &mut writer).await;
+ }
+ }
+ }
+ 3 => {
+ let tile = map[position.1 as usize][(position.0 - 1) as usize];
+ if tile == 0 {
+ position.0 -= 1;
+ } else if tile == 2 {
+ level += 1;
+ send_message(format!("Noice, level {}", level), &mut writer).await;
+ needs_map = true;
+ if level == 25 {
+ send_message(format!("Congratulations nerd, you just wasted a weekend on this. Here's your stupid flag: {}. Hope it was worth it.", FLAG), &mut writer).await;
+ }
+ }
+ }
+ 2 => {
+ let tile = map[position.1 as usize][(position.0 + 1) as usize];
+ if tile == 0 {
+ position.0 += 1;
+ } else if tile == 2 {
+ level += 1;
+ send_message(format!("Noice, level {}", level), &mut writer).await;
+ needs_map = true;
+ if level == 25 {
+ send_message(format!("Congratulations nerd, you just wasted a weekend on this. Here's your stupid flag: {}. Hope it was worth it.", FLAG), &mut writer).await;
+ }
+ }
+ }
+ _ => {
+ break;
+ }
+ }
+
+ send_goto(position, &mut writer).await?;
+ }
+ }
+
+ Ok(())
+}
+
+fn main() -> io::Result<()> {
+ task::block_on(async {
+ // let listener = TcpListener::bind("127.0.0.1:8080").await?;
+ let listener = TcpListener::bind("0.0.0.0:8080").await?;
+ println!("Listening on {}", listener.local_addr()?);
+
+ let mut incoming = listener.incoming();
+
+ while let Some(stream) = incoming.next().await {
+ let stream = stream?;
+ task::spawn(async {
+ process(stream).await.unwrap();
+ });
+ }
+ Ok(())
+ })
+}