diff options
Diffstat (limited to 'Bugzilla/MFA.pm')
-rw-r--r-- | Bugzilla/MFA.pm | 188 |
1 files changed, 96 insertions, 92 deletions
diff --git a/Bugzilla/MFA.pm b/Bugzilla/MFA.pm index 43c722364..4ce03817d 100644 --- a/Bugzilla/MFA.pm +++ b/Bugzilla/MFA.pm @@ -12,152 +12,156 @@ use strict; use warnings; use Bugzilla::RNG qw( irand ); -use Bugzilla::Token qw( issue_short_lived_session_token set_token_extra_data get_token_extra_data delete_token ); +use Bugzilla::Token + qw( issue_short_lived_session_token set_token_extra_data get_token_extra_data delete_token ); use Bugzilla::Util qw( trick_taint ); sub new { - my ($class, $user) = @_; - return bless({ user => $user }, $class); + my ($class, $user) = @_; + return bless({user => $user}, $class); } sub new_from { - my ($class, $user, $mfa) = @_; - $mfa //= ''; - if ($mfa eq 'TOTP') { - require Bugzilla::MFA::TOTP; - return Bugzilla::MFA::TOTP->new($user); - } - elsif ($mfa eq 'Duo' && Bugzilla->params->{duo_host}) { - require Bugzilla::MFA::Duo; - return Bugzilla::MFA::Duo->new($user); - } - else { - require Bugzilla::MFA::Dummy; - return Bugzilla::MFA::Dummy->new($user); - } + my ($class, $user, $mfa) = @_; + $mfa //= ''; + if ($mfa eq 'TOTP') { + require Bugzilla::MFA::TOTP; + return Bugzilla::MFA::TOTP->new($user); + } + elsif ($mfa eq 'Duo' && Bugzilla->params->{duo_host}) { + require Bugzilla::MFA::Duo; + return Bugzilla::MFA::Duo->new($user); + } + else { + require Bugzilla::MFA::Dummy; + return Bugzilla::MFA::Dummy->new($user); + } } # abstract methods # called during enrollment -sub enroll {} +sub enroll { } # api call, returns required data to user-prefs enrollment page -sub enroll_api {} +sub enroll_api { } # called after the user has confirmed enrollment -sub enrolled {} +sub enrolled { } # display page with verification prompt -sub prompt {} +sub prompt { } # throws errors if code is invalid -sub check {} +sub check { } # if true verifcation can happen inline (during enrollment/pref changes) # if false then the mfa provider requires an intermediate verification page -sub can_verify_inline { 0 } +sub can_verify_inline {0} # verification sub verify_prompt { - my ($self, $event) = @_; - my $user = delete $event->{user} // Bugzilla->user; - - # generate token and attach mfa data - my $token = issue_short_lived_session_token('mfa', $user); - set_token_extra_data($token, $event); - - # trigger provider verification - my $token_field = $event->{postback}->{token_field} // 'mfa_token'; - $event->{postback}->{fields}->{$token_field} = $token; - $self->prompt($event); - exit; + my ($self, $event) = @_; + my $user = delete $event->{user} // Bugzilla->user; + + # generate token and attach mfa data + my $token = issue_short_lived_session_token('mfa', $user); + set_token_extra_data($token, $event); + + # trigger provider verification + my $token_field = $event->{postback}->{token_field} // 'mfa_token'; + $event->{postback}->{fields}->{$token_field} = $token; + $self->prompt($event); + exit; } sub verify_token { - my ($self, $token) = @_; + my ($self, $token) = @_; - # check token - my ($user_id) = Bugzilla::Token::GetTokenData($token); - my $user = Bugzilla::User->check({ id => $user_id, cache => 1 }); + # check token + my ($user_id) = Bugzilla::Token::GetTokenData($token); + my $user = Bugzilla::User->check({id => $user_id, cache => 1}); - # verify mfa - $self->verify_check(Bugzilla->input_params); + # verify mfa + $self->verify_check(Bugzilla->input_params); - # return event data - my $event = get_token_extra_data($token); - delete_token($token); - if (!$event) { - print Bugzilla->cgi->redirect('index.cgi'); - exit; - } - return $event; + # return event data + my $event = get_token_extra_data($token); + delete_token($token); + if (!$event) { + print Bugzilla->cgi->redirect('index.cgi'); + exit; + } + return $event; } sub verify_check { - my ($self, $params) = @_; - $params->{code} //= ''; - - # recovery code verification - if (length($params->{code}) == 9) { - my $code = $params->{code}; - foreach my $i (1..10) { - my $key = "recovery.$i"; - if (($self->property_get($key) // '') eq $code) { - $self->property_delete($key); - return; - } - } + my ($self, $params) = @_; + $params->{code} //= ''; + + # recovery code verification + if (length($params->{code}) == 9) { + my $code = $params->{code}; + foreach my $i (1 .. 10) { + my $key = "recovery.$i"; + if (($self->property_get($key) // '') eq $code) { + $self->property_delete($key); + return; + } } + } - # mfa verification - $self->check($params); + # mfa verification + $self->check($params); } # methods sub generate_recovery_codes { - my ($self) = @_; - - my @codes; - foreach my $i (1..10) { - # generate 9 digit code - my $code; - $code .= irand(10) for 1..9; - push @codes, $code; - # store (replacing existing) - $self->property_set("recovery.$i", $code); - } + my ($self) = @_; + + my @codes; + foreach my $i (1 .. 10) { + + # generate 9 digit code + my $code; + $code .= irand(10) for 1 .. 9; + push @codes, $code; + + # store (replacing existing) + $self->property_set("recovery.$i", $code); + } - return \@codes; + return \@codes; } # helpers sub property_get { - my ($self, $name) = @_; - trick_taint($name); - return scalar Bugzilla->dbh->selectrow_array( - "SELECT value FROM profile_mfa WHERE user_id = ? AND name = ?", - undef, $self->{user}->id, $name); + my ($self, $name) = @_; + trick_taint($name); + return + scalar Bugzilla->dbh->selectrow_array( + "SELECT value FROM profile_mfa WHERE user_id = ? AND name = ?", + undef, $self->{user}->id, $name); } sub property_set { - my ($self, $name, $value) = @_; - trick_taint($name); - trick_taint($value); - Bugzilla->dbh->do( - "INSERT INTO profile_mfa (user_id, name, value) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE value = ?", - undef, $self->{user}->id, $name, $value, $value); + my ($self, $name, $value) = @_; + trick_taint($name); + trick_taint($value); + Bugzilla->dbh->do( + "INSERT INTO profile_mfa (user_id, name, value) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE value = ?", + undef, $self->{user}->id, $name, $value, $value + ); } sub property_delete { - my ($self, $name) = @_; - trick_taint($name); - Bugzilla->dbh->do( - "DELETE FROM profile_mfa WHERE user_id = ? AND name = ?", - undef, $self->{user}->id, $name); + my ($self, $name) = @_; + trick_taint($name); + Bugzilla->dbh->do("DELETE FROM profile_mfa WHERE user_id = ? AND name = ?", + undef, $self->{user}->id, $name); } 1; |