ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/login.ext
(Generate patch)

Comparing deliantra/server/ext/login.ext (file contents):
Revision 1.119 by root, Thu Nov 15 05:54:02 2012 UTC vs.
Revision 1.124 by root, Sat Nov 17 06:41:16 2012 UTC

2 2
3# login handling 3# login handling
4 4
5use Fcntl; 5use Fcntl;
6use Coro::AIO; 6use Coro::AIO;
7use Deliantra::Util ();
7 8
8CONF MAX_DISCONNECT_TIME = 3600; 9CONF MAX_DISCONNECT_TIME = 3600;
9 10
10sub query { 11sub query {
11 my ($ns, $flags, $text) = @_; 12 my ($ns, $flags, $text) = @_;
57 my $y = $ob->y; 58 my $y = $ob->y;
58 59
59 # never happens normally, but helps when shell users make mistakes 60 # never happens normally, but helps when shell users make mistakes
60 $m->linkable 61 $m->linkable
61 or return 1; 62 or return 1;
62
63# return 0;#d#
64# warn join ":", $m->at ($x, $y);#d#
65# warn "FOO$m { ".scalar ($m->at ($x, $y))." }\n";
66# return 0;
67 63
68 scalar grep $_->type == cf::SAVEBED, $m->at ($x, $y) 64 scalar grep $_->type == cf::SAVEBED, $m->at ($x, $y)
69} 65}
70 66
71sub enter_map { 67sub enter_map {
170 166
171 # just to make sure nothing is left over 167 # just to make sure nothing is left over
172 # normally, nothing is there. 168 # normally, nothing is there.
173 nuke_playerdir $user; 169 nuke_playerdir $user;
174 170
175 my $pass2 = query $ns, cf::CS_QUERY_HIDEINPUT, "Please type your password again.";
176
177 if ($pass2 ne $pass) {
178 $ns->send_drawinfo (
179 "The passwords do not match, please try again.",
180 cf::NDI_RED
181 );
182 Coro::Timer::sleep 0.5;
183 next;
184 }
185
186 my $pl = cf::player::new $user; 171 my $pl = cf::player::new $user;
187 $pl->password (encode_password $pass); 172 $pl->password (encode_password $pass);
188 $pl->connect ($ns); 173 $pl->connect ($ns);
189 my $ob = $pl->ob; 174 my $ob = $pl->ob;
190 175
258} 243}
259 244
260cf::client->attach (on_addme => sub { 245cf::client->attach (on_addme => sub {
261 my ($ns) = @_; 246 my ($ns) = @_;
262 247
263 $ns->pl and return $ns->destroy; 248 $ns->{addme}++ and return $ns->destroy;
264 249
265 $ns->async (sub { 250 $ns->async (sub {
266 $Coro::current->{desc} = "addme init"; 251 $Coro::current->{desc} = "addme init";
267 252
268 my ($user, $pass); 253 my ($user, $pass);
345 my $token = $pl->password; 330 my $token = $pl->password;
346 331
347 if ($cf::CFG{ext_login_nocheck} or compare_password $pass, $token) { 332 if ($cf::CFG{ext_login_nocheck} or compare_password $pass, $token) {
348 # player exists and passwords match - we can proceed 333 # player exists and passwords match - we can proceed
349 334
350 $pl->password (encode_password $pass); # make sure we store the new encoding #d#
351 # password matches, wonderful 335 # password matches, wonderful
352 my $pl = cf::player::find $user or next; 336 my $pl = cf::player::find $user or next;
353 $pl->connect ($ns); 337 $pl->connect ($ns);
354 enter_map $pl; 338 enter_map $pl;
355 login_done $pl; 339 login_done $pl;
397 ); 381 );
398 next; 382 next;
399 } 383 }
400 } 384 }
401 385
386 my $pass2 = query $ns, cf::CS_QUERY_HIDEINPUT, "Please type your password again.";
387
388 if ($pass2 ne $pass) {
389 $ns->send_drawinfo (
390 "The passwords do not match, please try again.",
391 cf::NDI_RED
392 );
393 Coro::Timer::sleep 0.5;
394 next;
395 }
396
402 last; 397 last;
403 } 398 }
404 399
405 # lock again, too layz to make this nicer 400 # lock again, too layz to make this nicer
406 local $cf::LOGIN_LOCK{$user} = 1; 401 local $cf::LOGIN_LOCK{$user} = 1;
402
407 chargen $ns, $user, $pass; 403 chargen $ns, $user, $pass;
408 login_done $ns->pl; 404 login_done $ns->pl;
409 }); 405 });
410}); 406});
407
408cf::client->attach (
409 on_version => sub {
410 my ($ns, $arg) = @_;
411
412 $ns->{nonces} = [map { join "", map { chr rand 256 } 0..63 } 1..2];
413 $ns->ext_msg (nonces => @{ $ns->{nonces} });
414 },
415);
416
417#cf::register_async_exticmd create_login => sub {
418# my ($ns, $reply, $user, $pass) = @_;
419#
420# $ns->{addme}++ and return $ns->destroy;
421#};
422
423cf::register_async_exticmd login => sub {
424 my ($ns, $reply, $user, $hash) = @_;
425
426 $ns->{addme}++ and return $ns->destroy;
427
428 $ns->async (sub {
429 local $cf::LOGIN_LOCK{$user} = 1;
430
431 $Coro::current->{desc} = "login($user) check";
432
433 my $fail = sub {
434 $reply->(0, $_[0]);
435 $ns->flush; # does not ensure that the data reaches the client - TODO
436 # need to do this in another thread, as this one gets canceled
437 Coro::async_pool {
438 Coro::AnyEvent::sleep 0.1; # TODO, see above, extra hack
439 $ns->destroy;
440 };
441 Coro::schedule; # do the destroy, should not return
442 };
443
444 # try to read the user file and check the password
445 my $pl = cf::player::find $user
446 or return $fail->("User '$user' does not exist - wrong spelling?");
447
448 aio_stat $pl->path
449 and return $ns->destroy;
450
451 my $mtime = (stat _)[9];
452 my $token = $pl->password;
453
454 $token = $token =~ /^!/
455 ? Deliantra::Util::hash_pw pack "H*", substr $token, 1
456 : pack "H*", $token;
457
458 $token = Deliantra::Util::auth_pw $token, $ns->{nonces}[0], $ns->{nonces}[1];
459
460 $token eq $hash
461 or $cf::CFG{ext_login_nocheck}
462 or return $fail->("User exists, but the password doesn't match - check your spelling, NumLock/CapsLock etc.");
463
464 # player exists and passwords match - we can proceed
465
466 $pl->connect ($ns);
467 enter_map $pl;
468 login_done $pl;
469
470 $reply->(1, "Success");
471 });
472};
411 473
412cf::register_command password => sub { 474cf::register_command password => sub {
413 my ($pl, $arg) = @_; 475 my ($pl, $arg) = @_;
414 476
415 unless ($pl->flag (cf::FLAG_WIZ)) { 477 unless ($pl->flag (cf::FLAG_WIZ)) {
416 $pl->message ( 478 $pl->message (
417 "The password can currently only changed by a DM.", 479 "The password can currently only changed by a DM.",
418 cf::NDI_UNIQUE | cf::NDI_REPLY); 480 cf::NDI_UNIQUE | cf::NDI_REPLY);
419 return; 481 return;
420 } 482 }
483
484 $pl->message (#d#
485 "Passwords cannot currently be changed.",#d#
486 cf::NDI_UNIQUE | cf::NDI_REPLY);#d#
487 return;#d#
421 488
422 my (@args) = split /\s+/, $arg; 489 my (@args) = split /\s+/, $arg;
423 my ($player, $new_pw) = @args; 490 my ($player, $new_pw) = @args;
424 491
425 if ($pl->flag (cf::FLAG_WIZ) && $player eq '') { 492 if ($pl->flag (cf::FLAG_WIZ) && $player eq '') {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines