--- a/gameServer2/src/protocol/messages.rs Thu Sep 06 23:12:32 2018 +0300
+++ b/gameServer2/src/protocol/messages.rs Fri Sep 07 04:16:05 2018 +0300
@@ -77,6 +77,7 @@
Bye(String),
Nick(String),
Proto(u16),
+ ServerAuth(String),
LobbyLeft(String, String),
LobbyJoined(Vec<String>),
ChatMsg {nick: String, msg: String},
@@ -267,6 +268,7 @@
Bye(msg) => msg!["BYE", msg],
Nick(nick) => msg!["NICK", nick],
Proto(proto) => msg!["PROTO", proto],
+ ServerAuth(hash) => msg!["SERVER_AUTH", hash],
LobbyLeft(nick, msg) => msg!["LOBBY:LEFT", nick, msg],
LobbyJoined(nicks) =>
construct_message(&["LOBBY:JOINED"], &nicks),
--- a/gameServer2/src/server/handlers/loggingin.rs Thu Sep 06 23:12:32 2018 +0300
+++ b/gameServer2/src/server/handlers/loggingin.rs Fri Sep 07 04:16:05 2018 +0300
@@ -2,6 +2,7 @@
use crate::{
server::{
+ client::HWClient,
server::HWServer,
coretypes::ClientId,
actions::{Action, Action::*}
@@ -11,6 +12,28 @@
},
utils::is_name_illegal
};
+#[cfg(feature = "official-server")]
+use openssl::sha::sha1;
+use std::fmt::{Formatter, LowerHex};
+
+#[derive(PartialEq)]
+struct Sha1Digest([u8; 20]);
+
+impl LowerHex for Sha1Digest {
+ fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
+ for byte in &self.0 {
+ write!(f, "{:02x}", byte)?;
+ }
+ Ok(())
+ }
+}
+
+#[cfg(feature = "official-server")]
+fn get_hash(client: &HWClient, salt1: &str, salt2: &str) -> Sha1Digest {
+ let s = format!("{}{}{}{}{}", salt1, salt2,
+ client.web_password, client.protocol_number, "!hedgewars");
+ Sha1Digest(sha1(s.as_bytes()))
+}
pub fn handle(server: & mut HWServer, client_id: ClientId, message: HWProtocolMessage) {
match message {
@@ -23,7 +46,7 @@
else if !client.nick.is_empty() {
vec![ProtocolError("Nickname already provided.".to_string())]
}
- else if is_name_illegal(&nick) {
+ else if is_name_illegal(&nick) {
vec![ByeClient("Illegal nickname! Nicknames must be between 1-40 characters long, must not have a trailing or leading space and must not have any of these characters: $()*+?[]^{|}".to_string())]
}
else {
@@ -50,6 +73,20 @@
server.react(client_id, actions);
}
#[cfg(feature = "official-server")]
+ HWProtocolMessage::Password(hash, salt) => {
+ let c = &server.clients[client_id];
+
+ let client_hash = get_hash(c, &salt, &c.server_salt);
+ let server_hash = get_hash(c, &c.server_salt, &salt);
+ let actions = if client_hash == server_hash {
+ vec![ServerAuth(format!("{:x}", server_hash)).send_self().action(),
+ JoinLobby]
+ } else {
+ vec![ByeClient("Authentication failed".to_string())]
+ };
+ server.react(client_id, actions);
+ }
+ #[cfg(feature = "official-server")]
HWProtocolMessage::Checker(protocol, nick, password) => {
let c = &mut server.clients[client_id];
c.nick = nick;