author | alfadur |
Thu, 07 Feb 2019 18:04:53 +0300 | |
changeset 14700 | 216d39de1a44 |
parent 14698 | 6a2e13e36b7f |
child 14701 | 8a45c90f4580 |
permissions | -rw-r--r-- |
12152 | 1 |
use mio; |
2 |
||
13671 | 3 |
use crate::{ |
14462 | 4 |
protocol::messages::{HWProtocolMessage, HWServerMessage::*}, |
14698 | 5 |
server::{ |
6 |
core::{HWAnteClient, HWAnteroom}, |
|
7 |
coretypes::ClientId, |
|
8 |
}, |
|
14462 | 9 |
utils::is_name_illegal, |
13424 | 10 |
}; |
14462 | 11 |
use log::*; |
13805 | 12 |
#[cfg(feature = "official-server")] |
13 |
use openssl::sha::sha1; |
|
14698 | 14 |
use std::{ |
15 |
fmt::{Formatter, LowerHex}, |
|
16 |
num::NonZeroU16, |
|
17 |
}; |
|
13805 | 18 |
|
19 |
#[derive(PartialEq)] |
|
20 |
struct Sha1Digest([u8; 20]); |
|
21 |
||
22 |
impl LowerHex for Sha1Digest { |
|
23 |
fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { |
|
24 |
for byte in &self.0 { |
|
25 |
write!(f, "{:02x}", byte)?; |
|
26 |
} |
|
27 |
Ok(()) |
|
28 |
} |
|
29 |
} |
|
30 |
||
31 |
#[cfg(feature = "official-server")] |
|
14700 | 32 |
fn get_hash(protocol_number: u16, web_password: &str, salt1: &str, salt2: &str) -> Sha1Digest { |
14462 | 33 |
let s = format!( |
34 |
"{}{}{}{}{}", |
|
14700 | 35 |
salt1, salt2, web_password, protocol_number, "!hedgewars" |
14462 | 36 |
); |
13805 | 37 |
Sha1Digest(sha1(s.as_bytes())) |
38 |
} |
|
12152 | 39 |
|
14698 | 40 |
pub enum LoginResult { |
41 |
Unchanged, |
|
42 |
Complete, |
|
43 |
Exit, |
|
44 |
} |
|
45 |
||
14676
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14462
diff
changeset
|
46 |
pub fn handle( |
14698 | 47 |
anteroom: &mut HWAnteroom, |
14676
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14462
diff
changeset
|
48 |
client_id: ClientId, |
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14462
diff
changeset
|
49 |
response: &mut super::Response, |
455865ccd36c
Server action refactoring part 2 of N
alfadur <mail@none>
parents:
14462
diff
changeset
|
50 |
message: HWProtocolMessage, |
14698 | 51 |
) -> LoginResult { |
12152 | 52 |
match message { |
14698 | 53 |
HWProtocolMessage::Quit(_) => { |
54 |
response.add(Bye("User quit".to_string()).send_self()); |
|
55 |
LoginResult::Exit |
|
56 |
} |
|
13421 | 57 |
HWProtocolMessage::Nick(nick) => { |
14698 | 58 |
let client = &mut anteroom.clients[client_id]; |
13671 | 59 |
debug!("{} {}", nick, is_name_illegal(&nick)); |
14698 | 60 |
if !client.nick.is_some() { |
14677
6e6632068a33
Server action refactoring part 3 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
61 |
response.add(Error("Nickname already provided.".to_string()).send_self()); |
14698 | 62 |
LoginResult::Unchanged |
14462 | 63 |
} else if is_name_illegal(&nick) { |
14698 | 64 |
response.add(Bye("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()).send_self()); |
65 |
LoginResult::Exit |
|
14462 | 66 |
} else { |
14698 | 67 |
client.nick = Some(nick.clone()); |
14677
6e6632068a33
Server action refactoring part 3 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
68 |
response.add(Nick(nick).send_self()); |
14678
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
69 |
|
14698 | 70 |
if client.protocol_number.is_some() { |
71 |
LoginResult::Complete |
|
72 |
} else { |
|
73 |
LoginResult::Unchanged |
|
14678
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
74 |
} |
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
75 |
} |
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
76 |
} |
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
77 |
HWProtocolMessage::Proto(proto) => { |
14698 | 78 |
let client = &mut anteroom.clients[client_id]; |
79 |
if client.protocol_number.is_some() { |
|
14678
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
80 |
response.add(Error("Protocol already known.".to_string()).send_self()); |
14698 | 81 |
LoginResult::Unchanged |
14678
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
82 |
} else if proto == 0 { |
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
83 |
response.add(Error("Bad number.".to_string()).send_self()); |
14698 | 84 |
LoginResult::Unchanged |
14678
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
85 |
} else { |
14698 | 86 |
client.protocol_number = NonZeroU16::new(proto); |
14678
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
87 |
response.add(Proto(proto).send_self()); |
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
88 |
|
14698 | 89 |
if client.nick.is_some() { |
90 |
LoginResult::Complete |
|
91 |
} else { |
|
92 |
LoginResult::Unchanged |
|
14678
08a8605bafaf
Server action refactoring part 4 of N
alfadur <mail@none>
parents:
14677
diff
changeset
|
93 |
} |
14677
6e6632068a33
Server action refactoring part 3 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
94 |
} |
13803 | 95 |
} |
96 |
#[cfg(feature = "official-server")] |
|
13805 | 97 |
HWProtocolMessage::Password(hash, salt) => { |
14698 | 98 |
let client = &anteroom.clients[client_id]; |
13805 | 99 |
|
14700 | 100 |
if let (Some(protocol), Some(password)) = (client.protocol_number, client.web_password.as_ref()) { |
101 |
let client_hash = get_hash(protocol.get(), &password, &salt, &client.server_salt); |
|
102 |
let server_hash = get_hash(protocol.get(), &password, &client.server_salt, &salt); |
|
103 |
if client_hash == server_hash { |
|
104 |
response.add(ServerAuth(format!("{:x}", server_hash)).send_self()); |
|
105 |
LoginResult::Complete |
|
106 |
} else { |
|
107 |
response.add(Bye("No protocol provided.".to_string()).send_self()); |
|
108 |
LoginResult::Unchanged |
|
109 |
} |
|
13805 | 110 |
} else { |
14700 | 111 |
response.add(Bye("Authentication failed.".to_string()).send_self()); |
14698 | 112 |
LoginResult::Exit |
14691
9f98086de1b6
Server action refactoring part 9 of N
alfadur <mail@none>
parents:
14688
diff
changeset
|
113 |
} |
14677
6e6632068a33
Server action refactoring part 3 of N
alfadur <mail@none>
parents:
14676
diff
changeset
|
114 |
} |
13805 | 115 |
#[cfg(feature = "official-server")] |
13803 | 116 |
HWProtocolMessage::Checker(protocol, nick, password) => { |
14698 | 117 |
let client = &mut anteroom.clients[client_id]; |
14700 | 118 |
client.protocol_number = NonZeroU16::new(protocol); |
14698 | 119 |
client.nick = Some(nick); |
14700 | 120 |
client.web_password = Some(password); |
14698 | 121 |
//client.set_is_checker(true); |
122 |
LoginResult::Complete |
|
13803 | 123 |
} |
14698 | 124 |
_ => { |
125 |
warn!("Incorrect command in logging-in state"); |
|
126 |
LoginResult::Unchanged |
|
127 |
} |
|
12152 | 128 |
} |
129 |
} |