From a3413083b6cc5bfdc3f0650a267f7292b244a24d Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 1 Nov 2020 07:49:04 -0700 Subject: [PATCH] add auth for interserver connections --- src/bin/login.rs | 4 +++- src/bin/main.rs | 3 ++- src/bin/ship.rs | 3 +++ src/common/interserver.rs | 2 +- src/login/character.rs | 25 ++++++++++++++++++------- src/ship/ship.rs | 23 +++++++++++++++++------ 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/bin/login.rs b/src/bin/login.rs index 7fec40c..608f994 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -3,6 +3,7 @@ use elseware::entity::gateway::postgres::PostgresGateway; use elseware::login::login::LoginServerState; use elseware::login::character::CharacterServerState; use elseware::common::mainloop::{login_mainloop, character_mainloop}; +use elseware::common::interserver::AuthToken; fn main() { let colors = fern::colors::ColoredLevelConfig::new() @@ -33,13 +34,14 @@ fn main() { let db_password = std::env::var("DB_PASSWORD").unwrap(); let db_dbname = std::env::var("DB_DBNAME").unwrap(); let charserv_ip = std::env::var("CHARSERV_IP").unwrap().parse().unwrap(); + let shipgate_token = std::env::var("SHIPGATE_TOKEN").unwrap(); let entity_gateway = PostgresGateway::new(&db_host, &db_dbname, &db_username, &db_password); let thread_entity_gateway = entity_gateway.clone(); let login_state = LoginServerState::new(thread_entity_gateway, charserv_ip); let login_loop = login_mainloop(login_state, elseware::login::login::LOGIN_PORT); - let char_state = CharacterServerState::new(entity_gateway); + let char_state = CharacterServerState::new(entity_gateway, AuthToken(shipgate_token.into())); let character_loop = character_mainloop(char_state, elseware::login::character::CHARACTER_PORT, elseware::login::login::COMMUNICATION_PORT); info!("[auth/character] starting server"); diff --git a/src/bin/main.rs b/src/bin/main.rs index 529fdc2..70820a6 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -9,6 +9,7 @@ use elseware::entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use elseware::entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway}; use elseware::entity::character::NewCharacterEntity; use elseware::entity::item::{NewItemEntity, ItemDetail, ItemLocation}; +use elseware::common::interserver::AuthToken; use elseware::entity::item; use elseware::common::mainloop::*; @@ -405,7 +406,7 @@ fn main() { let thread_entity_gateway = entity_gateway.clone(); info!("[character] starting server"); - let char_state = CharacterServerState::new(thread_entity_gateway); + let char_state = CharacterServerState::new(thread_entity_gateway, AuthToken("".into())); let character_loop = character_mainloop(char_state, elseware::login::character::CHARACTER_PORT, elseware::login::login::COMMUNICATION_PORT); let thread_entity_gateway = entity_gateway.clone(); diff --git a/src/bin/ship.rs b/src/bin/ship.rs index d993ebf..acd0675 100644 --- a/src/bin/ship.rs +++ b/src/bin/ship.rs @@ -2,6 +2,7 @@ use log::{info}; use elseware::entity::gateway::postgres::PostgresGateway; use elseware::ship::ship::ShipServerStateBuilder; use elseware::common::mainloop::ship_mainloop; +use elseware::common::interserver::AuthToken; fn main() { let colors = fern::colors::ColoredLevelConfig::new() @@ -33,6 +34,7 @@ fn main() { let db_dbname = std::env::var("DB_DBNAME").unwrap(); let entity_gateway = PostgresGateway::new(&db_host, &db_dbname, &db_username, &db_password); + let shipgate_token = std::env::var("SHIPGATE_TOKEN").unwrap(); let ship_name = std::env::var("SHIP_NAME").unwrap().parse().unwrap(); let ip = std::env::var("SELF_IP").unwrap().parse().unwrap(); let ship_state = ShipServerStateBuilder::new() @@ -40,6 +42,7 @@ fn main() { .ip(ip) .port(elseware::ship::ship::SHIP_PORT) .gateway(entity_gateway) + .auth_token(AuthToken(shipgate_token.into())) .build(); let shipgate_ip = std::env::var("SHIPGATE_IP").unwrap().parse().unwrap(); diff --git a/src/common/interserver.rs b/src/common/interserver.rs index f1110f8..bd09913 100644 --- a/src/common/interserver.rs +++ b/src/common/interserver.rs @@ -5,7 +5,7 @@ use crate::entity::character::CharacterEntityId; #[derive(Debug, Copy, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct ServerId(pub usize); -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct AuthToken(pub String); #[derive(Debug, Serialize, Deserialize)] diff --git a/src/login/character.rs b/src/login/character.rs index 5bfc2e1..87da4b6 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -1,6 +1,6 @@ #![allow(dead_code, unused_assignments)] use std::io::Read; -use std::collections::{BTreeMap, HashMap}; +use std::collections::{BTreeMap, BTreeSet, HashMap}; use rand::Rng; use crc::{crc32, Hasher32}; @@ -28,6 +28,7 @@ use crate::entity::item::mag::Mag; use crate::entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel}; use crate::login::login::{get_login_status, check_if_already_online}; +use crate::common::interserver::AuthToken; pub const CHARACTER_PORT: u16 = 12001; const SHIP_MENU_ID: u32 = 1; @@ -174,6 +175,8 @@ pub struct CharacterServerState { clients: HashMap, ships: BTreeMap, level_table: CharacterLevelTable, + auth_token: AuthToken, + authenticated_ships: BTreeSet, } @@ -266,7 +269,7 @@ async fn new_character(entity_gateway: &mut EG, user: &UserAc impl CharacterServerState { - pub fn new(entity_gateway: EG) -> CharacterServerState { + pub fn new(entity_gateway: EG, auth_token: AuthToken) -> CharacterServerState { let (param_header, param_data) = generate_param_data("data/param/"); CharacterServerState { @@ -276,6 +279,8 @@ impl CharacterServerState { clients: HashMap::new(), ships: BTreeMap::new(), level_table: CharacterLevelTable::new(), + auth_token: auth_token, + authenticated_ships: BTreeSet::new(), } } @@ -558,9 +563,15 @@ impl InterserverActor for CharacterServerState { async fn action(&mut self, id: ServerId, msg: Self::RecvMessage) -> Result, Self::Error> { match msg { - ShipMessage::Authenticate(_auth_token) => {}, + ShipMessage::Authenticate(auth_token) => { + if self.auth_token == auth_token { + self.authenticated_ships.insert(id); + } + }, ShipMessage::NewShip(new_ship) => { - self.ships.insert(id, new_ship); + if self.authenticated_ships.contains(&id) { + self.ships.insert(id, new_ship); + } }, _ => {} } @@ -681,7 +692,7 @@ mod test { } } - let mut server = CharacterServerState::new(TestData {}); + let mut server = CharacterServerState::new(TestData {}, AuthToken("".into())); let mut clientstate = ClientState::new(); clientstate.user = Some(UserAccountEntity { id: UserAccountId(1), @@ -716,7 +727,7 @@ mod test { #[derive(Clone)] struct TestData; impl EntityGateway for TestData {} - let mut server = CharacterServerState::new(TestData {}); + let mut server = CharacterServerState::new(TestData {}, AuthToken("".into())); let send = server.handle(ClientId(1), &RecvCharacterPacket::Checksum(Checksum {checksum: 1234, padding: 0, })).await.unwrap().collect::>(); @@ -746,7 +757,7 @@ mod test { at_ship: false, }); - let mut server = CharacterServerState::new(test_data.clone()); + let mut server = CharacterServerState::new(test_data.clone(), AuthToken("".into())); server.clients.insert(ClientId(1), fake_user.clone()); let mut send = server.handle(ClientId(1), &RecvCharacterPacket::SetFlag(SetFlag {flags: 1})).await.unwrap().collect::>(); assert!(test_data.get_user_by_id(UserAccountId(3)).await.unwrap().flags == 1); diff --git a/src/ship/ship.rs b/src/ship/ship.rs index ddbcb2d..66e2fbe 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -298,6 +298,7 @@ pub struct ShipServerStateBuilder { name: Option, ip: Option, port: Option, + auth_token: Option, } impl ShipServerStateBuilder { @@ -307,6 +308,7 @@ impl ShipServerStateBuilder { name: None, ip: None, port: None, + auth_token: None, } } @@ -330,6 +332,11 @@ impl ShipServerStateBuilder { self } + pub fn auth_token(mut self, auth_token: AuthToken) -> ShipServerStateBuilder { + self.auth_token = Some(auth_token); + self + } + pub fn build(self) -> ShipServerState { ShipServerState { entity_gateway: self.entity_gateway.unwrap(), @@ -343,6 +350,7 @@ impl ShipServerStateBuilder { ip: self.ip.unwrap_or(Ipv4Addr::new(127,0,0,1)), port: self.port.unwrap_or(SHIP_PORT), shops: Box::new(ItemShops::new()), + auth_token: self.auth_token.unwrap_or(AuthToken("".into())), } } } @@ -359,6 +367,7 @@ pub struct ShipServerState { ip: Ipv4Addr, port: u16, shops: Box, + auth_token: AuthToken, } impl ShipServerState { @@ -626,12 +635,14 @@ impl InterserverActor for ShipServerState { type Error = (); async fn on_connect(&mut self, id: ServerId) -> Vec<(ServerId, Self::SendMessage)> { - vec![ /* ShipMessage::Authenticate(AuthToken("hi".into())), */ (id, ShipMessage::NewShip(Ship { - name: self.name.clone(), - ip: self.ip.clone(), - port: self.port, - block_count: 2, - })) ] + vec![ + (id, ShipMessage::Authenticate(self.auth_token.clone())), + (id, ShipMessage::NewShip(Ship { + name: self.name.clone(), + ip: self.ip.clone(), + port: self.port, + block_count: 2, + })) ] } async fn action(&mut self, _id: ServerId, _msg: Self::RecvMessage) -> Result, Self::Error> {