rust/hedgewars-server/src/server/handlers/loggingin.rs
changeset 14693 6a2e13e36b7f
parent 14690 f61ce544d436
child 14695 216d39de1a44
equal deleted inserted replaced
14692:e5415faa117b 14693:6a2e13e36b7f
     1 use mio;
     1 use mio;
     2 
     2 
     3 use crate::{
     3 use crate::{
     4     protocol::messages::{HWProtocolMessage, HWServerMessage::*},
     4     protocol::messages::{HWProtocolMessage, HWServerMessage::*},
     5     server::{client::HWClient, core::HWServer, coretypes::ClientId},
     5     server::{
       
     6         core::{HWAnteClient, HWAnteroom},
       
     7         coretypes::ClientId,
       
     8     },
     6     utils::is_name_illegal,
     9     utils::is_name_illegal,
     7 };
    10 };
     8 use log::*;
    11 use log::*;
     9 #[cfg(feature = "official-server")]
    12 #[cfg(feature = "official-server")]
    10 use openssl::sha::sha1;
    13 use openssl::sha::sha1;
    11 use std::fmt::{Formatter, LowerHex};
    14 use std::{
       
    15     fmt::{Formatter, LowerHex},
       
    16     num::NonZeroU16,
       
    17 };
    12 
    18 
    13 #[derive(PartialEq)]
    19 #[derive(PartialEq)]
    14 struct Sha1Digest([u8; 20]);
    20 struct Sha1Digest([u8; 20]);
    15 
    21 
    16 impl LowerHex for Sha1Digest {
    22 impl LowerHex for Sha1Digest {
    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 }