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 { 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 { 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>, (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>, writer: &mut TcpStream) -> std::io::Result { // 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 { 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 { 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(()) }) }