Browse Source

add auth for interserver connections

pbs
jake 4 years ago
parent
commit
a3413083b6
  1. 4
      src/bin/login.rs
  2. 3
      src/bin/main.rs
  3. 3
      src/bin/ship.rs
  4. 2
      src/common/interserver.rs
  5. 23
      src/login/character.rs
  6. 13
      src/ship/ship.rs

4
src/bin/login.rs

@ -3,6 +3,7 @@ use elseware::entity::gateway::postgres::PostgresGateway;
use elseware::login::login::LoginServerState; use elseware::login::login::LoginServerState;
use elseware::login::character::CharacterServerState; use elseware::login::character::CharacterServerState;
use elseware::common::mainloop::{login_mainloop, character_mainloop}; use elseware::common::mainloop::{login_mainloop, character_mainloop};
use elseware::common::interserver::AuthToken;
fn main() { fn main() {
let colors = fern::colors::ColoredLevelConfig::new() let colors = fern::colors::ColoredLevelConfig::new()
@ -33,13 +34,14 @@ fn main() {
let db_password = std::env::var("DB_PASSWORD").unwrap(); let db_password = std::env::var("DB_PASSWORD").unwrap();
let db_dbname = std::env::var("DB_DBNAME").unwrap(); let db_dbname = std::env::var("DB_DBNAME").unwrap();
let charserv_ip = std::env::var("CHARSERV_IP").unwrap().parse().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 entity_gateway = PostgresGateway::new(&db_host, &db_dbname, &db_username, &db_password);
let thread_entity_gateway = entity_gateway.clone(); let thread_entity_gateway = entity_gateway.clone();
let login_state = LoginServerState::new(thread_entity_gateway, charserv_ip); let login_state = LoginServerState::new(thread_entity_gateway, charserv_ip);
let login_loop = login_mainloop(login_state, elseware::login::login::LOGIN_PORT); 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); let character_loop = character_mainloop(char_state, elseware::login::character::CHARACTER_PORT, elseware::login::login::COMMUNICATION_PORT);
info!("[auth/character] starting server"); info!("[auth/character] starting server");

3
src/bin/main.rs

@ -9,6 +9,7 @@ use elseware::entity::account::{NewUserAccountEntity, NewUserSettingsEntity};
use elseware::entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway}; use elseware::entity::gateway::{EntityGateway, InMemoryGateway, PostgresGateway};
use elseware::entity::character::NewCharacterEntity; use elseware::entity::character::NewCharacterEntity;
use elseware::entity::item::{NewItemEntity, ItemDetail, ItemLocation}; use elseware::entity::item::{NewItemEntity, ItemDetail, ItemLocation};
use elseware::common::interserver::AuthToken;
use elseware::entity::item; use elseware::entity::item;
use elseware::common::mainloop::*; use elseware::common::mainloop::*;
@ -405,7 +406,7 @@ fn main() {
let thread_entity_gateway = entity_gateway.clone(); let thread_entity_gateway = entity_gateway.clone();
info!("[character] starting server"); 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 character_loop = character_mainloop(char_state, elseware::login::character::CHARACTER_PORT, elseware::login::login::COMMUNICATION_PORT);
let thread_entity_gateway = entity_gateway.clone(); let thread_entity_gateway = entity_gateway.clone();

3
src/bin/ship.rs

@ -2,6 +2,7 @@ use log::{info};
use elseware::entity::gateway::postgres::PostgresGateway; use elseware::entity::gateway::postgres::PostgresGateway;
use elseware::ship::ship::ShipServerStateBuilder; use elseware::ship::ship::ShipServerStateBuilder;
use elseware::common::mainloop::ship_mainloop; use elseware::common::mainloop::ship_mainloop;
use elseware::common::interserver::AuthToken;
fn main() { fn main() {
let colors = fern::colors::ColoredLevelConfig::new() let colors = fern::colors::ColoredLevelConfig::new()
@ -33,6 +34,7 @@ fn main() {
let db_dbname = std::env::var("DB_DBNAME").unwrap(); let db_dbname = std::env::var("DB_DBNAME").unwrap();
let entity_gateway = PostgresGateway::new(&db_host, &db_dbname, &db_username, &db_password); 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 ship_name = std::env::var("SHIP_NAME").unwrap().parse().unwrap();
let ip = std::env::var("SELF_IP").unwrap().parse().unwrap(); let ip = std::env::var("SELF_IP").unwrap().parse().unwrap();
let ship_state = ShipServerStateBuilder::new() let ship_state = ShipServerStateBuilder::new()
@ -40,6 +42,7 @@ fn main() {
.ip(ip) .ip(ip)
.port(elseware::ship::ship::SHIP_PORT) .port(elseware::ship::ship::SHIP_PORT)
.gateway(entity_gateway) .gateway(entity_gateway)
.auth_token(AuthToken(shipgate_token.into()))
.build(); .build();
let shipgate_ip = std::env::var("SHIPGATE_IP").unwrap().parse().unwrap(); let shipgate_ip = std::env::var("SHIPGATE_IP").unwrap().parse().unwrap();

2
src/common/interserver.rs

@ -5,7 +5,7 @@ use crate::entity::character::CharacterEntityId;
#[derive(Debug, Copy, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Copy, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct ServerId(pub usize); pub struct ServerId(pub usize);
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AuthToken(pub String); pub struct AuthToken(pub String);
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]

23
src/login/character.rs

@ -1,6 +1,6 @@
#![allow(dead_code, unused_assignments)] #![allow(dead_code, unused_assignments)]
use std::io::Read; use std::io::Read;
use std::collections::{BTreeMap, HashMap};
use std::collections::{BTreeMap, BTreeSet, HashMap};
use rand::Rng; use rand::Rng;
use crc::{crc32, Hasher32}; use crc::{crc32, Hasher32};
@ -28,6 +28,7 @@ use crate::entity::item::mag::Mag;
use crate::entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel}; use crate::entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel};
use crate::login::login::{get_login_status, check_if_already_online}; use crate::login::login::{get_login_status, check_if_already_online};
use crate::common::interserver::AuthToken;
pub const CHARACTER_PORT: u16 = 12001; pub const CHARACTER_PORT: u16 = 12001;
const SHIP_MENU_ID: u32 = 1; const SHIP_MENU_ID: u32 = 1;
@ -174,6 +175,8 @@ pub struct CharacterServerState<EG: EntityGateway> {
clients: HashMap<ClientId, ClientState>, clients: HashMap<ClientId, ClientState>,
ships: BTreeMap<ServerId, Ship>, ships: BTreeMap<ServerId, Ship>,
level_table: CharacterLevelTable, level_table: CharacterLevelTable,
auth_token: AuthToken,
authenticated_ships: BTreeSet<ServerId>,
} }
@ -266,7 +269,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
impl<EG: EntityGateway> CharacterServerState<EG> { impl<EG: EntityGateway> CharacterServerState<EG> {
pub fn new(entity_gateway: EG) -> CharacterServerState<EG> {
pub fn new(entity_gateway: EG, auth_token: AuthToken) -> CharacterServerState<EG> {
let (param_header, param_data) = generate_param_data("data/param/"); let (param_header, param_data) = generate_param_data("data/param/");
CharacterServerState { CharacterServerState {
@ -276,6 +279,8 @@ impl<EG: EntityGateway> CharacterServerState<EG> {
clients: HashMap::new(), clients: HashMap::new(),
ships: BTreeMap::new(), ships: BTreeMap::new(),
level_table: CharacterLevelTable::new(), level_table: CharacterLevelTable::new(),
auth_token: auth_token,
authenticated_ships: BTreeSet::new(),
} }
} }
@ -558,9 +563,15 @@ impl<EG: EntityGateway> InterserverActor for CharacterServerState<EG> {
async fn action(&mut self, id: ServerId, msg: Self::RecvMessage) -> Result<Vec<(ServerId, Self::SendMessage)>, Self::Error> { async fn action(&mut self, id: ServerId, msg: Self::RecvMessage) -> Result<Vec<(ServerId, Self::SendMessage)>, Self::Error> {
match msg { 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) => { ShipMessage::NewShip(new_ship) => {
if self.authenticated_ships.contains(&id) {
self.ships.insert(id, new_ship); 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(); let mut clientstate = ClientState::new();
clientstate.user = Some(UserAccountEntity { clientstate.user = Some(UserAccountEntity {
id: UserAccountId(1), id: UserAccountId(1),
@ -716,7 +727,7 @@ mod test {
#[derive(Clone)] #[derive(Clone)]
struct TestData; struct TestData;
impl EntityGateway for 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, let send = server.handle(ClientId(1), &RecvCharacterPacket::Checksum(Checksum {checksum: 1234,
padding: 0, padding: 0,
})).await.unwrap().collect::<Vec<_>>(); })).await.unwrap().collect::<Vec<_>>();
@ -746,7 +757,7 @@ mod test {
at_ship: false, 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()); server.clients.insert(ClientId(1), fake_user.clone());
let mut send = server.handle(ClientId(1), &RecvCharacterPacket::SetFlag(SetFlag {flags: 1})).await.unwrap().collect::<Vec<_>>(); let mut send = server.handle(ClientId(1), &RecvCharacterPacket::SetFlag(SetFlag {flags: 1})).await.unwrap().collect::<Vec<_>>();
assert!(test_data.get_user_by_id(UserAccountId(3)).await.unwrap().flags == 1); assert!(test_data.get_user_by_id(UserAccountId(3)).await.unwrap().flags == 1);

13
src/ship/ship.rs

@ -298,6 +298,7 @@ pub struct ShipServerStateBuilder<EG: EntityGateway> {
name: Option<String>, name: Option<String>,
ip: Option<Ipv4Addr>, ip: Option<Ipv4Addr>,
port: Option<u16>, port: Option<u16>,
auth_token: Option<AuthToken>,
} }
impl<EG: EntityGateway> ShipServerStateBuilder<EG> { impl<EG: EntityGateway> ShipServerStateBuilder<EG> {
@ -307,6 +308,7 @@ impl<EG: EntityGateway> ShipServerStateBuilder<EG> {
name: None, name: None,
ip: None, ip: None,
port: None, port: None,
auth_token: None,
} }
} }
@ -330,6 +332,11 @@ impl<EG: EntityGateway> ShipServerStateBuilder<EG> {
self self
} }
pub fn auth_token(mut self, auth_token: AuthToken) -> ShipServerStateBuilder<EG> {
self.auth_token = Some(auth_token);
self
}
pub fn build(self) -> ShipServerState<EG> { pub fn build(self) -> ShipServerState<EG> {
ShipServerState { ShipServerState {
entity_gateway: self.entity_gateway.unwrap(), entity_gateway: self.entity_gateway.unwrap(),
@ -343,6 +350,7 @@ impl<EG: EntityGateway> ShipServerStateBuilder<EG> {
ip: self.ip.unwrap_or(Ipv4Addr::new(127,0,0,1)), ip: self.ip.unwrap_or(Ipv4Addr::new(127,0,0,1)),
port: self.port.unwrap_or(SHIP_PORT), port: self.port.unwrap_or(SHIP_PORT),
shops: Box::new(ItemShops::new()), shops: Box::new(ItemShops::new()),
auth_token: self.auth_token.unwrap_or(AuthToken("".into())),
} }
} }
} }
@ -359,6 +367,7 @@ pub struct ShipServerState<EG: EntityGateway> {
ip: Ipv4Addr, ip: Ipv4Addr,
port: u16, port: u16,
shops: Box<ItemShops>, shops: Box<ItemShops>,
auth_token: AuthToken,
} }
impl<EG: EntityGateway> ShipServerState<EG> { impl<EG: EntityGateway> ShipServerState<EG> {
@ -626,7 +635,9 @@ impl<EG: EntityGateway> InterserverActor for ShipServerState<EG> {
type Error = (); type Error = ();
async fn on_connect(&mut self, id: ServerId) -> Vec<(ServerId, Self::SendMessage)> { async fn on_connect(&mut self, id: ServerId) -> Vec<(ServerId, Self::SendMessage)> {
vec![ /* ShipMessage::Authenticate(AuthToken("hi".into())), */ (id, ShipMessage::NewShip(Ship {
vec![
(id, ShipMessage::Authenticate(self.auth_token.clone())),
(id, ShipMessage::NewShip(Ship {
name: self.name.clone(), name: self.name.clone(),
ip: self.ip.clone(), ip: self.ip.clone(),
port: self.port, port: self.port,

Loading…
Cancel
Save