]> wagnertech.de Git - kivitendo-erp.git/commitdiff
Keine Passwörter mehr in Sessions speichern.
authorSven Schöling <s.schoeling@linet-services.de>
Mon, 2 Jul 2012 13:58:12 +0000 (15:58 +0200)
committerSven Schöling <s.schoeling@linet-services.de>
Mon, 2 Jul 2012 13:58:12 +0000 (15:58 +0200)
Der vorherige Mechanismus hat Passwörter in der Session hinterlegt, um bei
jedem Request überprüfen zu können, ob die Zugriffsrechte immernoch bestehen.
Gedacht war das vor allem für LDAP Authetifizierung, wo der Admin den Zugang
eines Benutzers speichern konnte und das System das sonst nicht mitbekommt.

Ein großes Problem was daraus entsteht ist, dass das Passwort auch akzeptiert
wird, wenn die gehashte Version übergeben wird, weil zur Überprüfungszeit nicht
mehr festgestellt werden kann, ob das gehashte Passwort aus der Session kommt
oder vom User.

Diese Änderung sorgt dafür, dass Passwörter weder im Klartext, noch crypted in
der Session gespeichert werden, sondern der Authetifizierungsstatus.

Eine Session bleibt jetzt eutentifiziert, auch wenn zwischendurch das Passwort
geändert wird. Lokal wird das später abgefangen werden, dass Sessions
invalidiert werden, wenn der Admin das Passwort ändert, im LDAP ist es garnicht
mehr der Fall. Auf der positiven Seite reduziert das den load auf dem LDAP
Server, weil nicht mehr für jeden Request ein Bind passieren muss.

Da die Passwörter nicht mehr verglichen werden müssen, werden gehashte
Passwörter jetzt nicht mehr akzeptiert. Jedes Passwort wird vor dem Vergleichen
unkonditional gehasht.

Die Backend Routinen erkennen jetzt wenn garkein Passwort übergeben wurde, und
triggern dafür den 5s Penalty nicht. Das macht das Aufrufen der Administration
das erste Mal wie erwartet schneller.

SL/Auth.pm
SL/Auth/DB.pm
SL/Dispatcher.pm
bin/mozilla/admin.pl
bin/mozilla/login.pl

index 7df576b1fc5e467eb4e09eb272647ac8bd9263a4..6652aed4b0113cc58527ba2476ec5dde8c7911f1 100644 (file)
@@ -23,6 +23,9 @@ use SL::DBUtils;
 
 use strict;
 
+use constant SESSION_KEY_ROOT_AUTH => 'session_auth_status_root';
+use constant SESSION_KEY_USER_AUTH => 'session_auth_status_user';
+
 sub new {
   $main::lxdebug->enter_sub();
 
@@ -146,14 +149,27 @@ sub authenticate_root {
 
   my ($self, $password) = @_;
 
-  $password             = SL::Auth::Password->hash_if_unhashed(login => 'root', password => $password);
+  my $session_root_auth = $self->get_session_value(SESSION_KEY_ROOT_AUTH);
+  if (defined $session_root_auth && $session_root_auth == OK) {
+    $::lxdebug->leave_sub;
+    return OK;
+  }
+
+  if (!defined $password) {
+    $::lxdebug->leave_sub;
+    return ERR_PASSWORD;
+  }
+
+  $password             = SL::Auth::Password->hash(login => 'root', password => $password);
   my $admin_password    = SL::Auth::Password->hash_if_unhashed(login => 'root', password => $self->{admin_password}->());
 
-  $main::lxdebug->leave_sub();
+  my $result = $password eq $admin_password ? OK : ERR_PASSWORD;
+  $self->set_session_value(SESSION_KEY_ROOT_AUTH ,=> $result);
+
+  sleep 5 if $result != OK;
 
-  return OK if $password eq $admin_password;
-  sleep 5;
-  return ERR_PASSWORD;
+  $::lxdebug->leave_sub;
+  return $result;
 }
 
 sub authenticate {
@@ -161,31 +177,24 @@ sub authenticate {
 
   my ($self, $login, $password) = @_;
 
-  $main::lxdebug->leave_sub();
-
-  my $result = $login ? $self->{authenticator}->authenticate($login, $password) : ERR_USER;
-  return OK if $result eq OK;
-  sleep 5;
-  return $result;
-}
-
-sub store_credentials_in_session {
-  my ($self, %params) = @_;
+  my $session_auth = $self->get_session_value(SESSION_KEY_USER_AUTH);
+  if (defined $session_auth && $session_auth == OK) {
+    $::lxdebug->leave_sub;
+    return OK;
+  }
 
-  if (!$self->{authenticator}->requires_cleartext_password) {
-    $params{password} = SL::Auth::Password->hash_if_unhashed(login             => $params{login},
-                                                             password          => $params{password},
-                                                             look_up_algorithm => 1,
-                                                             auth              => $self);
+  if (!defined $password) {
+    $::lxdebug->leave_sub;
+    return ERR_PASSWORD;
   }
 
-  $self->set_session_value(login => $params{login}, password => $params{password});
-}
+  my $result = $login ? $self->{authenticator}->authenticate($login, $password) : ERR_USER;
+  $self->set_session_value(SESSION_KEY_USER_AUTH ,=> $result, login => $login);
 
-sub store_root_credentials_in_session {
-  my ($self, $rpw) = @_;
+  sleep 5 if $result != OK;
 
-  $self->set_session_value(rpw => SL::Auth::Password->hash_if_unhashed(login => 'root', password => $rpw));
+  $::lxdebug->leave_sub;
+  return $result;
 }
 
 sub get_stored_password {
@@ -404,11 +413,6 @@ sub change_password {
 
   my $result = $self->{authenticator}->change_password($login, $new_password);
 
-  $self->store_credentials_in_session(login             => $login,
-                                      password          => $new_password,
-                                      look_up_algorithm => 1,
-                                      auth              => $self);
-
   $main::lxdebug->leave_sub();
 
   return $result;
index ab8788abda9cf7c4f8b255cd8e49bfb68ecb148e..0bbc050166466d7a419ab4dfbdf7368af544894e 100644 (file)
@@ -44,7 +44,7 @@ sub authenticate {
   # passwords. Hash it for easier comparison.
   $stored_password               = SL::Auth::Password->hash(password => $stored_password) unless $stored_password;
   ($algorithm, $stored_password) = SL::Auth::Password->parse($stored_password);
-  ($algorithm2, $password)       = SL::Auth::Password->parse(SL::Auth::Password->hash_if_unhashed(password => $password, algorithm => $algorithm, login => $login));
+  ($algorithm2, $password)       = SL::Auth::Password->parse(SL::Auth::Password->hash(password => $password, algorithm => $algorithm, login => $login));
 
   $main::lxdebug->leave_sub();
 
index 30a4b819ccb2e70c2a008a7fc7ade4d479b5eb7b..21398ccca72671947e279bd6a228a926b32c06d4 100644 (file)
@@ -204,15 +204,18 @@ sub handle_request {
 
     } else {
       show_error('login/password_error', 'session') if SL::Auth::SESSION_EXPIRED == $session_result;
-      %::myconfig = $::auth->read_user(login => $::form->{login});
+
+      my $login = $::auth->get_session_value('login');
+      show_error('login/password_error', 'password') if not defined $login;
+
+      %::myconfig = $::auth->read_user(login => $login);
 
       show_error('login/password_error', 'password') unless $::myconfig{login};
 
       $::locale = Locale->new($::myconfig{countrycode});
 
-      show_error('login/password_error', 'password') if SL::Auth::OK != $::auth->authenticate($::form->{login}, $::form->{password});
+      show_error('login/password_error', 'password') if SL::Auth::OK != $::auth->authenticate($login, undef);
 
-      $::auth->store_credentials_in_session(login => $::form->{login}, password => $::form->{password});
       $::auth->create_or_refresh_session;
       $::auth->delete_session_value('FLASH');
       delete $::form->{password};
index 6f3d70904a93130bcf786b971acb6ec16b19f67d..23fe978fe8d8c4eddedcf5668b6be2b9984165bd 100755 (executable)
@@ -91,8 +91,6 @@ sub run {
   $locale = $::locale;
   $auth   = $::auth;
 
-  $::auth->store_root_credentials_in_session($form->{rpw}) if $session_result == SL::Auth->SESSION_OK;
-
   $form->{stylesheet} = "lx-office-erp.css";
   $form->{favicon}    = "favicon.ico";
 
@@ -103,7 +101,6 @@ sub run {
       adminlogin();
     } else {
       if ($auth->session_tables_present()) {
-        $::auth->store_root_credentials_in_session($::form->{rpw});
         delete $::form->{rpw};
         _apply_dbupgrade_scripts();
       }
index 3c90891183c444a67254de8fc1169ad0adf8e1d5..0bfd39cb38864827275fed20289e80b8ebf1bcf1 100644 (file)
@@ -68,7 +68,6 @@ sub run {
       $form->{error_message} = $::locale->text('Incorrect username or password!');
       login_screen();
     } else {
-      $auth->store_credentials_in_session(login => $form->{login}, password => $form->{password});
       $auth->create_or_refresh_session();
       delete $form->{password};