rust/hedgewars-server/src/server/handlers/loggingin.rs
changeset 14457 98ef2913ec73
parent 14415 06672690d71b
child 14671 455865ccd36c
equal deleted inserted replaced
14456:a077aac9df01 14457:98ef2913ec73
     1 use mio;
     1 use mio;
     2 
     2 
     3 use crate::{
     3 use crate::{
       
     4     protocol::messages::{HWProtocolMessage, HWServerMessage::*},
     4     server::{
     5     server::{
       
     6         actions::{Action, Action::*},
     5         client::HWClient,
     7         client::HWClient,
     6         core::HWServer,
     8         core::HWServer,
     7         coretypes::ClientId,
     9         coretypes::ClientId,
     8         actions::{Action, Action::*}
       
     9     },
    10     },
    10     protocol::messages::{
    11     utils::is_name_illegal,
    11         HWProtocolMessage, HWServerMessage::*
       
    12     },
       
    13     utils::is_name_illegal
       
    14 };
    12 };
       
    13 use log::*;
    15 #[cfg(feature = "official-server")]
    14 #[cfg(feature = "official-server")]
    16 use openssl::sha::sha1;
    15 use openssl::sha::sha1;
    17 use std::fmt::{Formatter, LowerHex};
    16 use std::fmt::{Formatter, LowerHex};
    18 use log::*;
       
    19 
    17 
    20 #[derive(PartialEq)]
    18 #[derive(PartialEq)]
    21 struct Sha1Digest([u8; 20]);
    19 struct Sha1Digest([u8; 20]);
    22 
    20 
    23 impl LowerHex for Sha1Digest {
    21 impl LowerHex for Sha1Digest {
    29     }
    27     }
    30 }
    28 }
    31 
    29 
    32 #[cfg(feature = "official-server")]
    30 #[cfg(feature = "official-server")]
    33 fn get_hash(client: &HWClient, salt1: &str, salt2: &str) -> Sha1Digest {
    31 fn get_hash(client: &HWClient, salt1: &str, salt2: &str) -> Sha1Digest {
    34     let s = format!("{}{}{}{}{}", salt1, salt2,
    32     let s = format!(
    35                     client.web_password, client.protocol_number, "!hedgewars");
    33         "{}{}{}{}{}",
       
    34         salt1, salt2, client.web_password, client.protocol_number, "!hedgewars"
       
    35     );
    36     Sha1Digest(sha1(s.as_bytes()))
    36     Sha1Digest(sha1(s.as_bytes()))
    37 }
    37 }
    38 
    38 
    39 pub fn handle(server: & mut HWServer, client_id: ClientId, message: HWProtocolMessage) {
    39 pub fn handle(server: &mut HWServer, client_id: ClientId, message: HWProtocolMessage) {
    40     match message {
    40     match message {
    41         HWProtocolMessage::Nick(nick) => {
    41         HWProtocolMessage::Nick(nick) => {
    42             let client = &mut server.clients[client_id];
    42             let client = &mut server.clients[client_id];
    43             debug!("{} {}", nick, is_name_illegal(&nick));
    43             debug!("{} {}", nick, is_name_illegal(&nick));
    44             let actions = if client.room_id != None {
    44             let actions = if client.room_id != None {
    45                 unreachable!()
    45                 unreachable!()
    46             }
    46             } else if !client.nick.is_empty() {
    47             else if !client.nick.is_empty() {
       
    48                 vec![ProtocolError("Nickname already provided.".to_string())]
    47                 vec![ProtocolError("Nickname already provided.".to_string())]
    49             }
    48             } else if is_name_illegal(&nick) {
    50             else if is_name_illegal(&nick) {
       
    51                 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())]
    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())]
    52             }
    50             } else {
    53             else {
       
    54                 client.nick = nick.clone();
    51                 client.nick = nick.clone();
    55                 vec![Nick(nick).send_self().action(),
    52                 vec![Nick(nick).send_self().action(), CheckRegistered]
    56                      CheckRegistered]
       
    57             };
    53             };
    58 
    54 
    59             server.react(client_id, actions);
    55             server.react(client_id, actions);
    60         }
    56         }
    61         HWProtocolMessage::Proto(proto) => {
    57         HWProtocolMessage::Proto(proto) => {
    62             let client = &mut server.clients[client_id];
    58             let client = &mut server.clients[client_id];
    63             let actions = if client.protocol_number != 0 {
    59             let actions = if client.protocol_number != 0 {
    64                 vec![ProtocolError("Protocol already known.".to_string())]
    60                 vec![ProtocolError("Protocol already known.".to_string())]
    65             }
    61             } else if proto == 0 {
    66             else if proto == 0 {
       
    67                 vec![ProtocolError("Bad number.".to_string())]
    62                 vec![ProtocolError("Bad number.".to_string())]
    68             }
    63             } else {
    69             else {
       
    70                 client.protocol_number = proto;
    64                 client.protocol_number = proto;
    71                 vec![Proto(proto).send_self().action(),
    65                 vec![Proto(proto).send_self().action(), CheckRegistered]
    72                      CheckRegistered]
       
    73             };
    66             };
    74             server.react(client_id, actions);
    67             server.react(client_id, actions);
    75         }
    68         }
    76         #[cfg(feature = "official-server")]
    69         #[cfg(feature = "official-server")]
    77         HWProtocolMessage::Password(hash, salt) => {
    70         HWProtocolMessage::Password(hash, salt) => {
    78             let c = &server.clients[client_id];
    71             let c = &server.clients[client_id];
    79 
    72 
    80             let client_hash = get_hash(c, &salt, &c.server_salt);
    73             let client_hash = get_hash(c, &salt, &c.server_salt);
    81             let server_hash = get_hash(c, &c.server_salt, &salt);
    74             let server_hash = get_hash(c, &c.server_salt, &salt);
    82             let actions = if client_hash == server_hash {
    75             let actions = if client_hash == server_hash {
    83                 vec![ServerAuth(format!("{:x}", server_hash)).send_self().action(),
    76                 vec![
    84                      JoinLobby]
    77                     ServerAuth(format!("{:x}", server_hash))
       
    78                         .send_self()
       
    79                         .action(),
       
    80                     JoinLobby,
       
    81                 ]
    85             } else {
    82             } else {
    86                 vec![ByeClient("Authentication failed".to_string())]
    83                 vec![ByeClient("Authentication failed".to_string())]
    87             };
    84             };
    88             server.react(client_id, actions);
    85             server.react(client_id, actions);
    89         }
    86         }