12152
|
1 |
use mio;
|
|
2 |
|
13671
|
3 |
use crate::{
|
14462
|
4 |
protocol::messages::{HWProtocolMessage, HWServerMessage::*},
|
13671
|
5 |
server::{
|
14462
|
6 |
actions::{Action, Action::*},
|
13805
|
7 |
client::HWClient,
|
14379
|
8 |
core::HWServer,
|
13671
|
9 |
coretypes::ClientId,
|
|
10 |
},
|
14462
|
11 |
utils::is_name_illegal,
|
13424
|
12 |
};
|
14462
|
13 |
use log::*;
|
13805
|
14 |
#[cfg(feature = "official-server")]
|
|
15 |
use openssl::sha::sha1;
|
|
16 |
use std::fmt::{Formatter, LowerHex};
|
|
17 |
|
|
18 |
#[derive(PartialEq)]
|
|
19 |
struct Sha1Digest([u8; 20]);
|
|
20 |
|
|
21 |
impl LowerHex for Sha1Digest {
|
|
22 |
fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
|
|
23 |
for byte in &self.0 {
|
|
24 |
write!(f, "{:02x}", byte)?;
|
|
25 |
}
|
|
26 |
Ok(())
|
|
27 |
}
|
|
28 |
}
|
|
29 |
|
|
30 |
#[cfg(feature = "official-server")]
|
|
31 |
fn get_hash(client: &HWClient, salt1: &str, salt2: &str) -> Sha1Digest {
|
14462
|
32 |
let s = format!(
|
|
33 |
"{}{}{}{}{}",
|
|
34 |
salt1, salt2, client.web_password, client.protocol_number, "!hedgewars"
|
|
35 |
);
|
13805
|
36 |
Sha1Digest(sha1(s.as_bytes()))
|
|
37 |
}
|
12152
|
38 |
|
14462
|
39 |
pub fn handle(server: &mut HWServer, client_id: ClientId, message: HWProtocolMessage) {
|
12152
|
40 |
match message {
|
13421
|
41 |
HWProtocolMessage::Nick(nick) => {
|
13671
|
42 |
let client = &mut server.clients[client_id];
|
|
43 |
debug!("{} {}", nick, is_name_illegal(&nick));
|
|
44 |
let actions = if client.room_id != None {
|
|
45 |
unreachable!()
|
14462
|
46 |
} else if !client.nick.is_empty() {
|
13671
|
47 |
vec![ProtocolError("Nickname already provided.".to_string())]
|
14462
|
48 |
} else if is_name_illegal(&nick) {
|
13671
|
49 |
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())]
|
14462
|
50 |
} else {
|
13671
|
51 |
client.nick = nick.clone();
|
14462
|
52 |
vec![Nick(nick).send_self().action(), CheckRegistered]
|
13671
|
53 |
};
|
|
54 |
|
13424
|
55 |
server.react(client_id, actions);
|
13803
|
56 |
}
|
12152
|
57 |
HWProtocolMessage::Proto(proto) => {
|
13671
|
58 |
let client = &mut server.clients[client_id];
|
|
59 |
let actions = if client.protocol_number != 0 {
|
|
60 |
vec![ProtocolError("Protocol already known.".to_string())]
|
14462
|
61 |
} else if proto == 0 {
|
13671
|
62 |
vec![ProtocolError("Bad number.".to_string())]
|
14462
|
63 |
} else {
|
13671
|
64 |
client.protocol_number = proto;
|
14462
|
65 |
vec![Proto(proto).send_self().action(), CheckRegistered]
|
13671
|
66 |
};
|
13424
|
67 |
server.react(client_id, actions);
|
13803
|
68 |
}
|
|
69 |
#[cfg(feature = "official-server")]
|
13805
|
70 |
HWProtocolMessage::Password(hash, salt) => {
|
|
71 |
let c = &server.clients[client_id];
|
|
72 |
|
|
73 |
let client_hash = get_hash(c, &salt, &c.server_salt);
|
|
74 |
let server_hash = get_hash(c, &c.server_salt, &salt);
|
|
75 |
let actions = if client_hash == server_hash {
|
14462
|
76 |
vec![
|
|
77 |
ServerAuth(format!("{:x}", server_hash))
|
|
78 |
.send_self()
|
|
79 |
.action(),
|
|
80 |
JoinLobby,
|
|
81 |
]
|
13805
|
82 |
} else {
|
|
83 |
vec![ByeClient("Authentication failed".to_string())]
|
|
84 |
};
|
|
85 |
server.react(client_id, actions);
|
|
86 |
}
|
|
87 |
#[cfg(feature = "official-server")]
|
13803
|
88 |
HWProtocolMessage::Checker(protocol, nick, password) => {
|
|
89 |
let c = &mut server.clients[client_id];
|
|
90 |
c.nick = nick;
|
|
91 |
c.web_password = password;
|
|
92 |
c.set_is_checker(true);
|
|
93 |
}
|
12152
|
94 |
_ => warn!("Incorrect command in logging-in state"),
|
|
95 |
}
|
|
96 |
}
|