21 Ok(()) |
27 Ok(()) |
22 } |
28 } |
23 } |
29 } |
24 |
30 |
25 #[cfg(feature = "official-server")] |
31 #[cfg(feature = "official-server")] |
26 fn get_hash(client: &HWClient, salt1: &str, salt2: &str) -> Sha1Digest { |
32 fn get_hash(client: &HWAnteClient, salt1: &str, salt2: &str) -> Sha1Digest { |
27 let s = format!( |
33 let s = format!( |
28 "{}{}{}{}{}", |
34 "{}{}{}{}{}", |
29 salt1, salt2, client.web_password, client.protocol_number, "!hedgewars" |
35 salt1, salt2, client.web_password, client.protocol_number, "!hedgewars" |
30 ); |
36 ); |
31 Sha1Digest(sha1(s.as_bytes())) |
37 Sha1Digest(sha1(s.as_bytes())) |
32 } |
38 } |
33 |
39 |
|
40 pub enum LoginResult { |
|
41 Unchanged, |
|
42 Complete, |
|
43 Exit, |
|
44 } |
|
45 |
34 pub fn handle( |
46 pub fn handle( |
35 server: &mut HWServer, |
47 anteroom: &mut HWAnteroom, |
36 client_id: ClientId, |
48 client_id: ClientId, |
37 response: &mut super::Response, |
49 response: &mut super::Response, |
38 message: HWProtocolMessage, |
50 message: HWProtocolMessage, |
39 ) { |
51 ) -> LoginResult { |
40 match message { |
52 match message { |
|
53 HWProtocolMessage::Quit(_) => { |
|
54 response.add(Bye("User quit".to_string()).send_self()); |
|
55 LoginResult::Exit |
|
56 } |
41 HWProtocolMessage::Nick(nick) => { |
57 HWProtocolMessage::Nick(nick) => { |
42 let client = &mut server.clients[client_id]; |
58 let client = &mut anteroom.clients[client_id]; |
43 debug!("{} {}", nick, is_name_illegal(&nick)); |
59 debug!("{} {}", nick, is_name_illegal(&nick)); |
44 if client.room_id != None { |
60 if !client.nick.is_some() { |
45 unreachable!() |
|
46 } else if !client.nick.is_empty() { |
|
47 response.add(Error("Nickname already provided.".to_string()).send_self()); |
61 response.add(Error("Nickname already provided.".to_string()).send_self()); |
|
62 LoginResult::Unchanged |
48 } else if is_name_illegal(&nick) { |
63 } else if is_name_illegal(&nick) { |
49 super::common::remove_client(server, response, "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()) |
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 |
50 } else { |
66 } else { |
51 client.nick = nick.clone(); |
67 client.nick = Some(nick.clone()); |
52 response.add(Nick(nick).send_self()); |
68 response.add(Nick(nick).send_self()); |
53 |
69 |
54 if client.protocol_number > 0 { |
70 if client.protocol_number.is_some() { |
55 super::common::process_login(server, response); |
71 LoginResult::Complete |
|
72 } else { |
|
73 LoginResult::Unchanged |
56 } |
74 } |
57 } |
75 } |
58 } |
76 } |
59 HWProtocolMessage::Proto(proto) => { |
77 HWProtocolMessage::Proto(proto) => { |
60 let client = &mut server.clients[client_id]; |
78 let client = &mut anteroom.clients[client_id]; |
61 if client.protocol_number != 0 { |
79 if client.protocol_number.is_some() { |
62 response.add(Error("Protocol already known.".to_string()).send_self()); |
80 response.add(Error("Protocol already known.".to_string()).send_self()); |
|
81 LoginResult::Unchanged |
63 } else if proto == 0 { |
82 } else if proto == 0 { |
64 response.add(Error("Bad number.".to_string()).send_self()); |
83 response.add(Error("Bad number.".to_string()).send_self()); |
|
84 LoginResult::Unchanged |
65 } else { |
85 } else { |
66 client.protocol_number = proto; |
86 client.protocol_number = NonZeroU16::new(proto); |
67 response.add(Proto(proto).send_self()); |
87 response.add(Proto(proto).send_self()); |
68 |
88 |
69 if client.nick != "" { |
89 if client.nick.is_some() { |
70 super::common::process_login(server, response); |
90 LoginResult::Complete |
|
91 } else { |
|
92 LoginResult::Unchanged |
71 } |
93 } |
72 } |
94 } |
73 } |
95 } |
74 #[cfg(feature = "official-server")] |
96 #[cfg(feature = "official-server")] |
75 HWProtocolMessage::Password(hash, salt) => { |
97 HWProtocolMessage::Password(hash, salt) => { |
76 let c = &server.clients[client_id]; |
98 let client = &anteroom.clients[client_id]; |
77 |
99 |
78 let client_hash = get_hash(c, &salt, &c.server_salt); |
100 let client_hash = get_hash(client, &salt, &client.server_salt); |
79 let server_hash = get_hash(c, &c.server_salt, &salt); |
101 let server_hash = get_hash(client, &client.server_salt, &salt); |
80 if client_hash == server_hash { |
102 if client_hash == server_hash { |
81 response.add(ServerAuth(format!("{:x}", server_hash)).send_self()); |
103 response.add(ServerAuth(format!("{:x}", server_hash)).send_self()); |
82 //TODO enter lobby |
104 LoginResult::Complete |
83 } else { |
105 } else { |
84 super::common::remove_client(server, response, "Authentication failed".to_string()) |
106 response.add(Bye("Authentication failed".to_string()).send_self()); |
|
107 LoginResult::Exit |
85 } |
108 } |
86 } |
109 } |
87 #[cfg(feature = "official-server")] |
110 #[cfg(feature = "official-server")] |
88 HWProtocolMessage::Checker(protocol, nick, password) => { |
111 HWProtocolMessage::Checker(protocol, nick, password) => { |
89 let c = &mut server.clients[client_id]; |
112 let client = &mut anteroom.clients[client_id]; |
90 c.nick = nick; |
113 client.protocol_number = Some(protocol); |
91 c.web_password = password; |
114 client.nick = Some(nick); |
92 c.set_is_checker(true); |
115 client.web_password = password; |
|
116 //client.set_is_checker(true); |
|
117 LoginResult::Complete |
93 } |
118 } |
94 _ => warn!("Incorrect command in logging-in state"), |
119 _ => { |
|
120 warn!("Incorrect command in logging-in state"); |
|
121 LoginResult::Unchanged |
|
122 } |
95 } |
123 } |
96 } |
124 } |