mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-25 16:19:00 +01:00
* Setup/Authentication: added an authentication log and fallback authentication for all backends
This commit is contained in:
parent
47f9f80e61
commit
1a0660a6cc
@ -65,13 +65,13 @@ class Auth
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function backendType()
|
||||
public static function backendType()
|
||||
{
|
||||
return Cache::getSession(__CLASS__, 'backend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Instanciate a backend
|
||||
* Instantiate a backend
|
||||
*
|
||||
* Type will be stored in session, to automatic use the same type eg. for conditional use of SAML.
|
||||
*
|
||||
@ -83,7 +83,7 @@ class Auth
|
||||
{
|
||||
if (is_null($type))
|
||||
{
|
||||
$type = Cache::getSession(__CLASS__, 'backend') ?: null;
|
||||
$type = self::backendType() ?: null;
|
||||
}
|
||||
// do we have a hostname specific auth type set
|
||||
if (is_null($type) && !empty($GLOBALS['egw_info']['server']['auth_type_host']) &&
|
||||
@ -93,24 +93,53 @@ class Auth
|
||||
}
|
||||
if (is_null($type)) $type = $GLOBALS['egw_info']['server']['auth_type'];
|
||||
|
||||
$backend_class = __CLASS__.'\\'.ucfirst($type);
|
||||
|
||||
// try old location / name, if not found
|
||||
if (!class_exists($backend_class))
|
||||
$account_storage = $GLOBALS['egw_info']['server']['account_storage'] ?? $type;
|
||||
if (!empty($GLOBALS['egw_info']['server']['auth_fallback']) && $type !== $account_storage)
|
||||
{
|
||||
$backend_class = 'auth_'.$type;
|
||||
$backend = new Auth\Fallback($type, $account_storage);
|
||||
self::log("Instantiated Auth\\Fallback('$type', '$account_storage')");
|
||||
}
|
||||
else
|
||||
{
|
||||
$backend_class = __CLASS__.'\\'.ucfirst($type);
|
||||
|
||||
// try old location / name, if not found
|
||||
if (!class_exists($backend_class) && class_exists('auth_'.$type))
|
||||
{
|
||||
$backend_class = 'auth_'.$type;
|
||||
}
|
||||
$backend = new $backend_class;
|
||||
self::log("Instantiated $backend_class() (for type '$type')");
|
||||
}
|
||||
$backend = new $backend_class;
|
||||
|
||||
if (!($backend instanceof Auth\Backend))
|
||||
{
|
||||
throw new Exception\AssertionFailed("Auth backend class $backend_class is NO EGroupware\\Api\Auth\\Backend!");
|
||||
}
|
||||
if ($save_in_session) Cache::setSession(__CLASS__, 'backend', $type);
|
||||
if ($save_in_session)
|
||||
{
|
||||
Cache::setSession(__CLASS__, 'backend', $type);
|
||||
}
|
||||
|
||||
return $backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log $message to auth.log, if enabled
|
||||
*
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function log(string $message)
|
||||
{
|
||||
if (!empty($GLOBALS['egw_info']['server']['auth_log']) &&
|
||||
($fp = fopen($GLOBALS['egw_info']['server']['files_dir'].'/auth.log', 'a')))
|
||||
{
|
||||
fwrite($fp, date('Y-m-d H:i:s: ').$message."\n");
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt a SSO login
|
||||
*
|
||||
@ -318,11 +347,24 @@ class Auth
|
||||
*/
|
||||
function authenticate($username, $passwd, $passwd_type='text')
|
||||
{
|
||||
return Cache::getCache($GLOBALS['egw_info']['server']['install_id'],
|
||||
__CLASS__, sha1($username.':'.$passwd.':'.$passwd_type), function($username, $passwd, $passwd_type)
|
||||
if (preg_match(Auth\Token::TOKEN_REGEXP, $passwd, $matches))
|
||||
{
|
||||
return $this->backend->authenticate($username, $passwd, $passwd_type);
|
||||
$log_passwd = substr($passwd, 0, strlen(Auth\Token::PREFIX)+1+strlen($matches[1]));
|
||||
$log_passwd .= str_repeat('*', strlen($passwd)-strlen($log_passwd));
|
||||
}
|
||||
else
|
||||
{
|
||||
$log_passwd = str_repeat('*', strlen($passwd));
|
||||
}
|
||||
$ret = Cache::getCache($GLOBALS['egw_info']['server']['install_id'],
|
||||
__CLASS__, sha1($username.':'.$passwd.':'.$passwd_type), function($username, $passwd, $passwd_type) use ($log_passwd)
|
||||
{
|
||||
$ret = $this->backend->authenticate($username, $passwd, $passwd_type);
|
||||
self::log(get_class($this->backend)."('$username', '$log_passwd', '$passwd_type') returned ".json_encode($ret));
|
||||
return $ret;
|
||||
}, [$username, $passwd, $passwd_type], self::AUTH_CACHE_TIME);
|
||||
self::log(__METHOD__."('$username', '$log_passwd', '$passwd_type') returned ".json_encode($ret));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -339,6 +381,7 @@ class Auth
|
||||
{
|
||||
if (($err = self::crackcheck($new_passwd,null,null,null,$account_id)))
|
||||
{
|
||||
self::log(__METHOD__."(..., $account_id) new password rejected by crackcheck: $err");
|
||||
throw new Exception\WrongUserinput($err);
|
||||
}
|
||||
if (($ret = $this->backend->change_password($old_passwd, $new_passwd, $account_id)))
|
||||
@ -360,6 +403,7 @@ class Auth
|
||||
Cache::unsetCache($GLOBALS['egw_info']['server']['install_id'],
|
||||
__CLASS__, sha1(Accounts::id2name($account_id).':'.$old_passwd.':text'));
|
||||
}
|
||||
self::log(__METHOD__."(..., $account_id) returned ".json_encode($ret));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
@ -66,18 +66,21 @@ class Fallback implements Backend
|
||||
{
|
||||
$backup_currentapp = $GLOBALS['egw_info']['flags']['currentapp'];
|
||||
$GLOBALS['egw_info']['flags']['currentapp'] = 'admin'; // otherwise
|
||||
$this->fallback_backend->change_password('', $passwd, $account_id);
|
||||
$ret = $this->fallback_backend->change_password('', $passwd, $account_id);
|
||||
Api\Auth::log(__METHOD__."('$username', ...) fallback_backend(".get_class($this->fallback_backend).
|
||||
")->change_password('', '".str_repeat('*', strlen($passwd))."', $account_id) returned ".json_encode($ret));
|
||||
$GLOBALS['egw_info']['flags']['currentapp'] = $backup_currentapp;
|
||||
//error_log(__METHOD__."('$username', \$passwd) updated password for #$account_id on fallback ".($ret ? 'successfull' : 'failed!'));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if ($this->fallback_backend->authenticate($username,$passwd, $passwd_type))
|
||||
if (($ret = $this->fallback_backend->authenticate($username,$passwd, $passwd_type)))
|
||||
{
|
||||
Api\Cache::setInstance(__CLASS__,'backend_used-'.$username,'fallback');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
Api\Auth::log(__METHOD__."('$username', ...) fallback_backend(".get_class($this->fallback_backend).
|
||||
")->authenticate('$username', '".str_repeat('*', strlen($passwd))."', ...) returned ".json_encode($ret));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,12 +110,16 @@ class Fallback implements Backend
|
||||
if (($ret = $this->primary_backend->change_password($old_passwd, $new_passwd, $account_id)))
|
||||
{
|
||||
// if password successfully changed on primary, also update fallback
|
||||
$this->fallback_backend->change_password($old_passwd, $new_passwd, $account_id);
|
||||
$change_pwd = $this->fallback_backend->change_password($old_passwd, $new_passwd, $account_id);
|
||||
Api\Auth::log(__METHOD__."(..., $account_id) fallback_backend(".get_class($this->fallback_backend).
|
||||
")->change_password('', '".str_repeat('*', strlen($new_passwd))."', $account_id) returned ".json_encode($change_pwd));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = $this->fallback_backend->change_password($old_passwd, $new_passwd, $account_id);
|
||||
Api\Auth::log(__METHOD__."(..., $account_id) fallback_backend(".get_class($this->fallback_backend).
|
||||
")->change_password('', '".str_repeat('*', strlen($new_passwd))."', $account_id) returned ".json_encode($ret));
|
||||
}
|
||||
//error_log(__METHOD__."('$old_passwd', '$new_passwd', $account_id) username='$username', backend=".Api\Cache::getInstance(__CLASS__,'backend_used-'.$username)." returning ".array2string($ret));
|
||||
return $ret;
|
||||
@ -172,4 +179,4 @@ class Fallback implements Backend
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -51,6 +51,8 @@ class Token extends APi\Storage\Base
|
||||
return null; // not a token
|
||||
}
|
||||
try {
|
||||
$log_passwd = substr($token, 0, strlen(Auth\Token::PREFIX)+1+strlen($matches[1]));
|
||||
$log_passwd .= str_repeat('*', strlen($token)-strlen($log_passwd));
|
||||
$data = self::getInstance()->read([
|
||||
'token_id' => $matches[1],
|
||||
'account_id' => [0, Api\Accounts::getInstance()->name2id($user)],
|
||||
@ -59,12 +61,15 @@ class Token extends APi\Storage\Base
|
||||
]);
|
||||
if (!password_verify($matches[2], $data['token_hash']))
|
||||
{
|
||||
Api\Auth::log(__METHOD__."('$user', '$log_passwd', ...') returned false (no active token found)");
|
||||
return false; // invalid token password
|
||||
}
|
||||
$limits = $data['token_limits'];
|
||||
Api\Auth::log(__METHOD__."('$user', '$log_passwd', ...) returned true");
|
||||
return true;
|
||||
}
|
||||
catch (Api\Exception\NotFound $e) {
|
||||
Api\Auth::log(__METHOD__."('$user', '$log_passwd, ...) returned false: ".$e->getMessage());
|
||||
return false; // token not found
|
||||
}
|
||||
}
|
||||
|
@ -104,28 +104,29 @@ if(@$_POST['submit'] && @$newsettings)
|
||||
|
||||
$GLOBALS['egw_setup']->html->show_header(lang('Configuration'),False,'config',$GLOBALS['egw_setup']->ConfigDomain . '(' . $GLOBALS['egw_domain'][$GLOBALS['egw_setup']->ConfigDomain]['db_type'] . ')');
|
||||
|
||||
$current_config = [];
|
||||
// if we have an validation error, use the new settings made by the user and not the stored config
|
||||
if($GLOBALS['error'] && is_array($newsettings))
|
||||
{
|
||||
$GLOBALS['current_config'] = $newsettings;
|
||||
$current_config = $newsettings;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table,'*',false,__LINE__,__FILE__) as $row)
|
||||
{
|
||||
$GLOBALS['current_config'][$row['config_name']] = $row['config_value'];
|
||||
$current_config[$row['config_name']] = $row['config_value'];
|
||||
}
|
||||
}
|
||||
$setup_tpl->pparse('out','T_config_pre_script');
|
||||
|
||||
/* Now parse each of the templates we want to show here */
|
||||
class phpgw
|
||||
class egw
|
||||
{
|
||||
var $accounts;
|
||||
var $applications;
|
||||
var $db;
|
||||
}
|
||||
$GLOBALS['egw'] = new phpgw;
|
||||
$GLOBALS['egw'] = new egw;
|
||||
$GLOBALS['egw']->db =& $GLOBALS['egw_setup']->db;
|
||||
|
||||
$t = new Framework\Template(Framework\Template::get_dir('setup'));
|
||||
@ -157,17 +158,18 @@ foreach($vars as $value)
|
||||
}
|
||||
else
|
||||
{
|
||||
$t->set_var($value,@$current_config[$newval]);
|
||||
$t->set_var($value, $current_config[$newval]);
|
||||
}
|
||||
break;
|
||||
case 'selected':
|
||||
case 'checked':
|
||||
$newvals = explode(' ',$newval);
|
||||
$setting = array_pop($newvals);
|
||||
$config = implode('_',$newvals);
|
||||
/* echo $config . '=' . $current_config[$config]; */
|
||||
if(@$current_config[$config] == $setting)
|
||||
if($current_config[$config] == $setting)
|
||||
{
|
||||
$t->set_var($value,' selected');
|
||||
$t->set_var($value,' '.$type);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -206,4 +208,4 @@ $setup_tpl->set_var('lang_submit',lang('Save'));
|
||||
$setup_tpl->set_var('lang_cancel',lang('Cancel'));
|
||||
$setup_tpl->pparse('out','T_config_post_script');
|
||||
|
||||
$GLOBALS['egw_setup']->html->show_footer();
|
||||
$GLOBALS['egw_setup']->html->show_footer();
|
@ -15,8 +15,8 @@
|
||||
%1 not allowed to create in univention. setup de Es ist nicht erlaubt unter Univention %1 anzulegen.
|
||||
%1 password set in %2. setup de %1 Passwort gesetzt in %2.
|
||||
%1 passwords updated, %3 errors setup de %1 Passwörter aktualisiert, %3 Fehler
|
||||
%1 users and %2 groups created, %3 errors setup de %1 Benutzer und %2 Gruppen angelegt, %3 Fehler
|
||||
%1 the configuration file. setup de %1 der Konfigurationsdatei.
|
||||
%1 users and %2 groups created, %3 errors setup de %1 Benutzer und %2 Gruppen angelegt, %3 Fehler
|
||||
'%1' is no valid domain name! setup de '%1' ist kein gültiger Domainname!
|
||||
'%1' is not allowed as %2. arguments of option %3 !!! setup de '%1' ist nicht erlaubt als %2. Parameter für die Option %3 !!!
|
||||
'%1' must be integer setup de %1 muß ein Integer-Wert sein.
|
||||
@ -291,6 +291,7 @@ email (standard maildomain should be set) setup de email (Standard Maildomaine m
|
||||
email-address setup de EMail Adresse
|
||||
emailadmin profile updated: setup de EMailAdmin Profil aktualisiert:
|
||||
enable for extra debug-messages setup de ankreuzen für zusätzliche Diagnosemeldungen
|
||||
enable logging of authentication to files-directory setup de Aktiviere Logging der Authentifizierung in das Datei Verzeichnis
|
||||
enable mcrypt setup de MCrypt einschalten
|
||||
enforce ssl (allows to specify just a path above) setup de Erzwinge SSL (erlaubt darüber nur einen Pfad anzugeben)
|
||||
enter some random text for app session encryption setup de Zufallstext zur Verschlüsselung der Anwendungssitzung
|
||||
@ -322,6 +323,7 @@ export has been completed! setup de Export ist abgeschlossen!
|
||||
failed to mount backup directory! setup de Konnte Datensicherungsverzeichnis nicht mounten!
|
||||
failed updating user "%1" dn="%2"! setup de Konnte Benutzer "%1" dn="%2" nicht aktualisieren!
|
||||
failed writing configuration file header.inc.php, check the permissions !!! setup de Fehler beim Schreiben der Konfigurationsdatei header.inc.php, bitte überprüfen Sie die Zugriffsrechte !!!
|
||||
fallback authentication setup de Rückfall Authentifizierung
|
||||
false setup de Falsch
|
||||
file setup de DATEI
|
||||
file type, size, version, etc. setup de Dateityp, Größe, Version usw.
|
||||
@ -367,6 +369,7 @@ however, the application may still work setup de Wie auch immer, die Anwendung m
|
||||
http auth types (comma-separated) to use without login-page, eg. "ntlm" setup de HTTP Authetifizierungs Typen (Komma-getrennt) die ohne Login Seite benutzt werden sollen, zB. "NTLM"
|
||||
identity provider setup de Identitätsprovider
|
||||
if no acl records for user or any group the user is a member of setup de Wenn es keinen ACL-Eintrag für einen Benutzer oder eine Gruppe, der er angehört gibt
|
||||
if primary authentication is not successful fall back to passwords synced into account-storage setup de Wenn die primäre Authentifizierung NICHT erfolgreich ist, falle auf die synchronisierten Passwörter des Benutzer Storage zurück
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup de Wenn safe_mode eingeschaltet ist, kann EGw verschiedene Einstellungen nicht mehr zur Laufzeit ändern, noch können wir nicht geladene Erweiterungen (php extensions) laden.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup de Wenn die Anwendung keine definierten Tabellen hat, wählen Sie überarbeiten. Das Problem sollte damit behoben werden.
|
||||
if using ads (active directory) setup de Wenn Sie ADS (Active Directory) benutzen
|
||||
@ -827,4 +830,4 @@ your tables are current setup de Ihre Tabellen sind aktuell
|
||||
your tables will be dropped and you will lose data setup de Ihre Tabellen werden gelöscht werden und Sie werden alle Daten verlieren!
|
||||
your temporary directory '%1' %2 setup de Ihr temporäres Verzeichnis '%1' %2
|
||||
{db | php(default) | php-restore} setup de {db | php(Vorgabe) | php-restore}
|
||||
{off(default) | on} setup de {off(Vorgabe) | on}
|
||||
{off(default) | on} setup de {off(Vorgabe) | on}
|
||||
|
@ -15,8 +15,8 @@
|
||||
%1 not allowed to create in univention. setup en %1 not allowed to create in Univention.
|
||||
%1 password set in %2. setup en %1 password set in %2.
|
||||
%1 passwords updated, %3 errors setup en %1 passwords updated, %3 errors
|
||||
%1 users and %2 groups created, %3 errors setup en %1 users and %2 groups created, %3 errors.
|
||||
%1 the configuration file. setup en %1 the configuration file.
|
||||
%1 users and %2 groups created, %3 errors setup en %1 users and %2 groups created, %3 errors.
|
||||
'%1' is no valid domain name! setup en '%1' is no valid domain name!
|
||||
'%1' is not allowed as %2. arguments of option %3 !!! setup en '%1' is not allowed as %2. arguments of option %3 !!!
|
||||
'%1' must be integer setup en %1 must be an integer value.
|
||||
@ -293,6 +293,7 @@ email-address setup en EMail-address
|
||||
emailadmin mail account saved: setup en EMailAdmin mail account saved:
|
||||
emailadmin profile updated: setup en eMailAdmin profile updated:
|
||||
enable for extra debug-messages setup en Enable for extra debug messages
|
||||
enable logging of authentication to files-directory setup en Enable logging of authentication to files-directory
|
||||
enable mcrypt setup en Enable MCrypt
|
||||
enforce ssl (allows to specify just a path above) setup en Enforce SSL (allows to specify just a path above)
|
||||
enter some random text for app session encryption setup en Enter some random text for app session encryption
|
||||
@ -324,6 +325,7 @@ export has been completed! setup en Export has been completed!
|
||||
failed to mount backup directory! setup en Failed to mount Backup directory!
|
||||
failed updating user "%1" dn="%2"! setup en Failed updating user "%1" dn="%2"!
|
||||
failed writing configuration file header.inc.php, check the permissions !!! setup en Failed writing configuration file header.inc.php, check the permissions!
|
||||
fallback authentication setup en Fallback Authentication
|
||||
false setup en False
|
||||
file setup en FILE
|
||||
file type, size, version, etc. setup en File type, size, version, etc.
|
||||
@ -370,6 +372,7 @@ however, the application may still work setup en The application may still work
|
||||
http auth types (comma-separated) to use without login-page, eg. "ntlm" setup en HTTP auth types, comma-separated to use without login page, eg. "NTLM"
|
||||
identity provider setup en Identity Provider
|
||||
if no acl records for user or any group the user is a member of setup en If no ACL records for user or any group the user is a member of
|
||||
if primary authentication is not successful fall back to passwords synced into account-storage setup en If primary authentication is NOT successful fall back to passwords synced into account-storage
|
||||
if safe_mode is turned on, egw is not able to change certain settings on runtime, nor can we load any not yet loaded module. setup en If safe_mode is turned on, EGw is not able to change certain settings on runtime, nor can we load any not yet loaded module.
|
||||
if the application has no defined tables, selecting upgrade should remedy the problem setup en If the application has no defined tables, selecting upgrade should remedy the problem
|
||||
if using ads (active directory) setup en If using ADS (Active Directory) authentication
|
||||
@ -831,4 +834,4 @@ your tables are current setup en Your tables are current
|
||||
your tables will be dropped and you will lose data setup en Your tables will be dropped and you will lose data!
|
||||
your temporary directory '%1' %2 setup en Your temporary directory '%1' %2
|
||||
{db | php(default) | php-restore} setup en {db | php(default) | php-restore}
|
||||
{off(default) | on} setup en {off(default) | on}
|
||||
{off(default) | on} setup en {off(default) | on}
|
||||
|
@ -129,6 +129,8 @@
|
||||
<select name="newsettings[auth_type]">
|
||||
{hook_auth_types}
|
||||
</select>
|
||||
<label><input type="checkbox" value="True" {checked_auth_log_True} name="newsettings[auth_log]"/>
|
||||
{lang_Enable_logging_of_authentication_to_files-directory}: auth.log</label>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -172,7 +174,14 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<tr class="row_off">
|
||||
<td>{lang_Fallback_Authentication}:</td>
|
||||
<td>
|
||||
<label><input type="checkbox" value="True" {checked_auth_fallback_True} name="newsettings[auth_fallback]"/>
|
||||
{lang_If_primary_authentication_is_NOT_successful_fall_back_to_passwords_synced_into_account-storage}</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row_on">
|
||||
<td>{lang_Select_where_you_want_to_store/retrieve_user_accounts}:</td>
|
||||
<td>
|
||||
<select name="newsettings[account_repository]">
|
||||
@ -181,14 +190,14 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_on">
|
||||
<tr class="row_off">
|
||||
<td>{lang_sql_encryption_type}:</td>
|
||||
<td>
|
||||
<select name="newsettings[sql_encryption_type]">{hook_sql_passwdhashes}</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_off">
|
||||
<tr class="row_on">
|
||||
<td>{lang_Allow_password_migration}:</td>
|
||||
<td>
|
||||
<select name="newsettings[pwd_migration_allowed]">
|
||||
@ -198,7 +207,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="row_on">
|
||||
<tr class="row_off">
|
||||
<td>{lang_Allowed_migration_types_(comma-separated)}:</td>
|
||||
<td>
|
||||
<input name="newsettings[pwd_migration_types]" value="{value_pwd_migration_types}" size="20" />
|
||||
|
Loading…
Reference in New Issue
Block a user