From f50320a49c27b1246433fb2a3a36692348a79d52 Mon Sep 17 00:00:00 2001 From: Darin McBride Date: Tue, 10 Feb 2015 17:38:02 -0700 Subject: [PATCH] Invalid logins no longer count against RPC usage, and will warn the account being attempted. --- lib/Lacuna/RPC/Empire.pm | 75 +++++++++++++++----------- lib/Lacuna/Session.pm | 5 +- lib/Lacuna/Util.pm | 16 +++++- var/messages/invalid_login_attempt.txt | 14 +++++ var/www/public/changes.txt | 1 + 5 files changed, 75 insertions(+), 36 deletions(-) create mode 100644 var/messages/invalid_login_attempt.txt diff --git a/lib/Lacuna/RPC/Empire.pm b/lib/Lacuna/RPC/Empire.pm index 088272a7..3529d730 100644 --- a/lib/Lacuna/RPC/Empire.pm +++ b/lib/Lacuna/RPC/Empire.pm @@ -4,7 +4,7 @@ use Moose; use utf8; no warnings qw(uninitialized); extends 'Lacuna::RPC'; -use Lacuna::Util qw(format_date randint); +use Lacuna::Util qw(format_date randint real_ip_address); use DateTime; use String::Random qw(random_string); use UUID::Tiny ':std'; @@ -84,55 +84,66 @@ sub login { unless (defined $empire) { confess [1002, 'Empire does not exist.', $name]; } - my $throttle = Lacuna->config->get('rpc_throttle') || 30; + + my %session_params = ( + api_key => $api_key, + request => $plack_request, + ); + + if ($empire->is_password_valid($password)) { + if ($empire->stage eq 'new') { + confess [1100, "Your empire has not been completely created. You must complete it in order to play the game.", { empire_id => $empire->id } ]; + } + } + elsif ($password ne '' && $empire->sitter_password eq $password) { + $session_params{is_sitter} = 1; + } + else { + my $ip = real_ip_address($plack_request); + + # might be a mistake, might be an out of date sitter, might be + # a hacking attempt, let the user know. + unless (Lacuna->cache->get('invalid_login_attempt_' . $ip, $empire->id)) { + Lacuna->cache->set('invalid_login_attempt_' . $ip, $empire->id, 1, 12 * 60 * 60); + $empire->send_predefined_message( + filename => 'invalid_login_attempt.txt', + params => [ $ip ], + from => $empire->lacuna_expanse_corp, + tags => [ 'Alert' ], + ); + } + + confess [1004, 'Password incorrect (' . $ip . ')', $password]; + } + + my $config = Lacuna->config; + my $throttle = $config->get('rpc_throttle') || 30; if ($empire->rpc_rate > $throttle) { Lacuna->cache->increment('rpc_limit_'.format_date(undef,'%d'), $empire->id, 1, 60 * 60 * 30); confess [1010, 'Slow down, '.$empire->name.'! No more than '.$throttle.' requests per minute.']; } - my $max = Lacuna->config->get('rpc_limit') || 2500; + my $max = $config->get('rpc_limit') || 2500; if ($empire->rpc_count > $max) { confess [1010, $empire->name.' has already made the maximum number of requests ('.$max.') you can make for one day.']; } - my $config = Lacuna->config; my $firebase_config = $config->get('firebase'); if ($firebase_config) { my $auth_code = Firebase::Auth->new( secret => $firebase_config->{auth}{secret}, data => { - uid => $empire->id, + uid => $empire->id, isModerator => $empire->chat_admin ? \1 : \0, - isStaff => $empire->is_admin ? \1 : \0, + isStaff => $empire->is_admin ? \1 : \0, } - # data => $data, )->create_token; } - if ($empire->is_password_valid($password)) { - if ($empire->stage eq 'new') { - confess [1100, "Your empire has not been completely created. You must complete it in order to play the game.", { empire_id => $empire->id } ]; - } - return { - session_id => $empire->start_session({ - api_key => $api_key, - request => $plack_request, - })->id, - status => $self->format_status($empire), - }; - } - elsif ($password ne '' && $empire->sitter_password eq $password) { - return { - session_id => $empire->start_session({ - api_key => $api_key, - request => $plack_request, - is_sitter => 1, - })->id, - status => $self->format_status($empire), - }; - } - else { - confess [1004, 'Password incorrect.', $password]; - } + return { + session_id => $empire->start_session(\%session_params)->id, + status => $self->format_status($empire), + }; + } diff --git a/lib/Lacuna/Session.pm b/lib/Lacuna/Session.pm index ac7c9151..2f923206 100644 --- a/lib/Lacuna/Session.pm +++ b/lib/Lacuna/Session.pm @@ -4,7 +4,7 @@ use Moose; use utf8; no warnings qw(uninitialized); use UUID::Tiny ':std'; - +use Lacuna::Util qw(real_ip_address); has id => ( is => 'ro', @@ -119,8 +119,7 @@ sub start { $self->empire($empire); my $ip; if (exists $options->{request}) { - $ip = $options->{request}->headers->header('X-Real-IP') // - $options->{request}->address; + $ip = real_ip_address($options->{request}); } Lacuna->db->resultset('Lacuna::DB::Result::Log::Login')->new({ empire_id => $empire->id, diff --git a/lib/Lacuna/Util.pm b/lib/Lacuna/Util.pm index f1f371b1..4e791400 100644 --- a/lib/Lacuna/Util.pm +++ b/lib/Lacuna/Util.pm @@ -6,7 +6,15 @@ use DateTime::Format::Duration; use DateTime::Format::Strptime; require Exporter; @ISA = qw(Exporter); -@EXPORT_OK = qw(randint format_date random_element commify consolidate_items kmbtq); +@EXPORT_OK = qw( + randint + format_date + random_element + commify + consolidate_items + kmbtq + real_ip_address + ); sub format_date { @@ -99,4 +107,10 @@ sub consolidate_items { return $item_arr; } +sub real_ip_address { + my ($plack_request) = @_; + $plack_request->headers->header('X-Real-IP') // + $plack_request->address; +} + 1; diff --git a/var/messages/invalid_login_attempt.txt b/var/messages/invalid_login_attempt.txt new file mode 100644 index 00000000..b2ce4bc3 --- /dev/null +++ b/var/messages/invalid_login_attempt.txt @@ -0,0 +1,14 @@ +WARNING: Invalid login attempt. +~~~ +An invalid login attempt was detected from IP address %s. If this was you accidentally typing your password incorrectly, you can ignore this message and delete it. + +Other possibilities include: + +1. You've changed your sitter password, and not told people running scripts on your behalf. Ensure everyone who has your sitter has it updated. +2. You've forgotten to change your own scripts to use a recently updated password. Ensure your scripts are using an up-to-date password. +3. Someone is trying to hack your account. + +If the first two options do not resolve the issue, please contact an administrator for assistance. + +Lacuna Expanse Corp +Fraud Division. diff --git a/var/www/public/changes.txt b/var/www/public/changes.txt index 0a228e79..434aea24 100644 --- a/var/www/public/changes.txt +++ b/var/www/public/changes.txt @@ -30,6 +30,7 @@ - Mod: Oracle cooldown on BHG movement shortened to a flat 5 minutes. - Mod: BHG Neutralization does not effect own alliance. - Mod: BHG Can no longer swap with seized hostiles. + - Mod: Invalid login attempts warns. 3.0908: - Mod: trash_messages_where now defaults to not returning deleted message IDs. -- 2.51.2