--- deliantra/server/ext/login.ext 2012/11/15 07:08:15 1.122 +++ deliantra/server/ext/login.ext 2012/11/16 12:02:46 1.123 @@ -245,7 +245,7 @@ cf::client->attach (on_addme => sub { my ($ns) = @_; - $ns->pl and return $ns->destroy; + $ns->{addme}++ and return $ns->destroy; $ns->async (sub { $Coro::current->{desc} = "addme init"; @@ -409,20 +409,67 @@ on_version => sub { my ($ns, $arg) = @_; - $ns->ext_msg (nonces => map { join "", map { chr rand 256 } 0..63 } 1..2); + srand 1;#d# + $ns->{nonces} = [map { join "", map { chr rand 256 } 0..63 } 1..2]; + $ns->ext_msg (nonces => @{ $ns->{nonces} }); }, ); #cf::register_async_exticmd create_login => sub { # my ($ns, $reply, $user, $pass) = @_; # -# $ns->pl and return $ns->destroy; +# $ns->{addme}++ and return $ns->destroy; #}; cf::register_async_exticmd login => sub { my ($ns, $reply, $user, $hash) = @_; - $ns->pl and return $ns->destroy; + $ns->{addme}++ and return $ns->destroy; + + $ns->async (sub { + local $cf::LOGIN_LOCK{$user} = 1; + + $Coro::current->{desc} = "login($user) check"; + + my $fail = sub { + $reply->(0, $_[0]); + $ns->flush; # does not ensure that the data reaches the client - TODO + # need to do this in another thread, as this one gets canceled + Coro::async_pool { + Coro::AnyEvent::sleep 0.1; # TODO, see above, extra hack + $ns->destroy; + }; + Coro::schedule; # do the destroy, should not return + }; + + # try to read the user file and check the password + my $pl = cf::player::find $user + or return $fail->("User '$user' does not exist - wrong spelling?"); + + aio_stat $pl->path + and return $ns->destroy; + + my $mtime = (stat _)[9]; + my $token = $pl->password; + + $token = $token =~ /^!/ + ? Deliantra::Util::hash_pw pack "H*", substr $token, 1 + : pack "H*", $token; + + $token = Deliantra::Util::auth_pw $token, $ns->{nonces}[0], $ns->{nonces}[1]; + + $token eq $hash + or $cf::CFG{ext_login_nocheck} + or return $fail->("User exists, but the password doesn't match - check your spelling, NumLock/CapsLock etc."); + + # player exists and passwords match - we can proceed + + $pl->connect ($ns); + enter_map $pl; + login_done $pl; + + $reply->(1, "Success"); + }); }; cf::register_command password => sub {