diff options
Diffstat (limited to 'scarymaze/src/server.rs')
| -rw-r--r-- | scarymaze/src/server.rs | 247 |
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(()) + }) +} |