]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: Add local user authentication method support
authorMarcin Haba <marcin.haba@bacula.pl>
Thu, 18 Jun 2020 18:18:11 +0000 (20:18 +0200)
committerMarcin Haba <marcin.haba@bacula.pl>
Thu, 18 Jun 2020 18:18:11 +0000 (20:18 +0200)
26 files changed:
gui/baculum/protected/Common/Class/Apr1Md5.php
gui/baculum/protected/Common/Class/BCrypt.php
gui/baculum/protected/Common/Class/BasicUserConfig.php
gui/baculum/protected/Common/Class/Crypto.php
gui/baculum/protected/Common/Class/Sha1.php
gui/baculum/protected/Common/Class/Sha256.php
gui/baculum/protected/Common/Class/Sha512.php
gui/baculum/protected/Common/Class/Ssha1.php
gui/baculum/protected/Web/Class/WebBasicUserManager.php
gui/baculum/protected/Web/Class/WebConfig.php
gui/baculum/protected/Web/Class/WebLdapUserManager.php
gui/baculum/protected/Web/Class/WebLocalUserManager.php [new file with mode: 0644]
gui/baculum/protected/Web/Class/WebUserManager.php
gui/baculum/protected/Web/Lang/en/messages.mo
gui/baculum/protected/Web/Lang/en/messages.po
gui/baculum/protected/Web/Lang/ja/messages.mo
gui/baculum/protected/Web/Lang/ja/messages.po
gui/baculum/protected/Web/Lang/pl/messages.mo
gui/baculum/protected/Web/Lang/pl/messages.po
gui/baculum/protected/Web/Lang/pt/messages.mo
gui/baculum/protected/Web/Lang/pt/messages.po
gui/baculum/protected/Web/Pages/LoginPage.page
gui/baculum/protected/Web/Pages/LoginPage.php
gui/baculum/protected/Web/Pages/Security.page
gui/baculum/protected/Web/Pages/Security.php
gui/baculum/protected/Web/Pages/WebConfigWizard.php

index c12106bed45a31ffe1e52617ed99913f81ad26ef..4f29828151e13be7d139a133d8c4491a57dda22d 100644 (file)
@@ -31,6 +31,12 @@ Prado::using('Application.Common.Class.CommonModule');
  */
 class Apr1Md5 extends CommonModule {
 
+       // APR-MD5 hash prefix
+       const HASH_PREFIX = '$apr1';
+
+       // Salt length
+       const DEF_SALT_LEN = 8;
+
        /**
         * Get hashed password using APR1-MD5 algorithm.
         * This function is based on common sample using PHP implementation APR1-MD5.
@@ -38,10 +44,13 @@ class Apr1Md5 extends CommonModule {
         * @see https://stackoverflow.com/questions/1038791/how-to-programmatically-build-an-apr1-md5-using-php
         *
         * @param string $password plain text password
+        * @param string $salt cryptographic salt
         * @return string hashed password
         */
-       public function crypt($password) {
-               $salt = $this->getModule('crypto')->getRandomString(8);
+       public function crypt($password, $salt = null) {
+               if (is_null($salt)) {
+                       $salt = $this->getModule('crypto')->getRandomString(self::DEF_SALT_LEN);
+               }
                $len = strlen($password);
                $text = sprintf('%s$apr1$%s', $password, $salt);
                $bin = pack('H32', md5($password . $salt . $password));
@@ -79,7 +88,25 @@ class Apr1Md5 extends CommonModule {
                        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
                        './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
                );
-               return sprintf('$apr1$%s$%s', $salt, $tmp);
+               return sprintf('%s$%s$%s', self::HASH_PREFIX, $salt, $tmp);
+       }
+
+       /**
+        * Verify if for given hash given password is valid.
+        *
+        * @param string $password password to check
+        * @param string $hash hash to check
+        * @return boolean true if password and hash are match, otherwise false
+        */
+       public function verify($password, $hash) {
+               $valid = false;
+               $parts = explode('$', $hash, 4);
+               if (count($parts) === 4) {
+                       $salt = $parts[2];
+                       $hash2 = $this->crypt($password, $salt);
+                       $valid = ($hash === $hash2);
+               }
+               return $valid;
        }
 }
 ?>
index 2a7d6b806e7ce0a6d03b67062e3cdb627170030f..ca5f347ee930b92dd68c64eaf6f5bdf742ccf6f7 100644 (file)
@@ -32,6 +32,12 @@ Prado::using('Application.Common.Class.CommonModule');
  */
 class BCrypt extends CommonModule {
 
+       // BCrypt hash prefix
+       const HASH_PREFIX = '$2y';
+
+       // Salt length
+       const DEF_SALT_LEN = 22;
+
        // bcrypt uses not standard base64 alphabet
        const BCRYPT_BASE64_CODE = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
 
@@ -42,21 +48,43 @@ class BCrypt extends CommonModule {
         * Get hashed password using BCrypt algorithm and salt.
         *
         * @param string $password plain text password
+        * @param string $salt cryptographic salt
         * @return string hashed password
         */
-       public function crypt($password) {
-               // Suffle string
-               $rand_string = str_shuffle(self::BCRYPT_BASE64_CODE);
+       public function crypt($password, $salt = null) {
+               if (is_null($salt)) {
+                       // Suffle string
+                       $rand_string = str_shuffle(self::BCRYPT_BASE64_CODE);
 
-               // BCrypt salt - 22 characters
-               $salt_str = substr($rand_string, 0, 22);
+                       // BCrypt salt
+                       $salt = substr($rand_string, 0, self::DEF_SALT_LEN);
+               }
 
-               $salt = sprintf(
-                       '$2y$%d$%s$',
+               $salt_val = sprintf(
+                       '%s$%d$%s$',
+                       self::HASH_PREFIX,
                        self::BCRYPT_COST,
-                       $salt_str
+                       $salt
                );
-               return crypt($password, $salt);
+               return crypt($password, $salt_val);
+       }
+
+       /**
+        * Verify if for given hash given password is valid.
+        *
+        * @param string $password password to check
+        * @param string $hash hash to check
+        * @return boolean true if password and hash are match, otherwise false
+        */
+       public function verify($password, $hash) {
+               $valid = false;
+               $parts = explode('$', $hash, 4);
+               if (count($parts) === 4) {
+                       $salt = substr($parts[3], 0, self::DEF_SALT_LEN);
+                       $hash2 = $this->crypt($password, $salt);
+                       $valid = ($hash === $hash2);
+               }
+               return $valid;
        }
 }
 ?>
index ba9119c6f5eedcb5dca7b07104563c762593c652..68c340e097de67a8b380d2d174b1bae4989ce534 100644 (file)
@@ -129,6 +129,24 @@ class BasicUserConfig extends CommonModule {
                return $all_users;
        }
 
+       /**
+        * Get user and password hash from config.
+        *
+        * @param string $user username
+        * @return array username and password hash or empty array if user not found
+        */
+       public function getUserCfg($username) {
+               $user = [];
+               $u = $this->getUsers($username);
+               if (count($u) == 1) {
+                       $user = [
+                               'username' => $username,
+                               'pwd_hash' => $u[$username]
+                       ];
+               }
+               return $user;
+       }
+
        /**
         * Save HTTP Basic users file.
         * Given parameter is associative array with usernames as keys
index e1bc9516cc73876464f96b78dbd6f0ff74703773..14d51189789047aeb1a4d894a7f2321322b4afe1 100644 (file)
@@ -60,15 +60,12 @@ class Crypto extends CommonModule {
        }
 
        /**
-        * Get hashed password to use in web server auth.
-        * If no hash algorithm given, use APR1-MD5.
+        * Get hash algorithm module instance by hash algorithm name.
         *
-        * @access public
-        * @param string $password plain text password
-        * @param string $hash_alg hash algorithm (apr1-md5|sha1)
-        * @return string hashed password
+        * @param string $hash_alg hash algorithm
+        * @return object hash algorithm module instance
         */
-       public function getHashedPassword($password, $hash_alg = null) {
+       private function getModuleByHashAlg($hash_alg) {
                $mod = '';
                switch ($hash_alg) {
                        case self::HASH_ALG_BCRYPT: {
@@ -99,7 +96,59 @@ class Crypto extends CommonModule {
                                $mod = 'apr1md5';
                        }
                }
-               return $this->getModule($mod)->crypt($password);
+               return $this->getModule($mod);
+       }
+
+       /**
+        * Get hashed password to use in web server auth.
+        * If no hash algorithm given, use APR1-MD5.
+        *
+        * @access public
+        * @param string $password plain text password
+        * @param string $hash_alg hash algorithm
+        * @return string hashed password
+        */
+       public function getHashedPassword($password, $hash_alg = null) {
+               if (is_null($hash_alg)) {
+                       $hash_alg = self::HASH_ALG_APR1_MD5;
+               }
+               return $this->getModuleByHashAlg($hash_alg)->crypt($password);
+       }
+
+       /*
+        * Get all supported hash algorithms.
+        * It bases on HASH_ALG_ constants definition.
+        *
+        * @return array supported hash algorithms
+        */
+       private function getSupportedHashAlgs() {
+               $hash_algs = [];
+               $ocls = new ReflectionClass(__CLASS__);
+               foreach ($ocls->getConstants() as $const => $hash_alg) {
+                       if (strpos($const, 'HASH_ALG_') !== 0) {
+                               continue;
+                       }
+                       $hash_algs[$const] = $hash_alg;
+               }
+               return $hash_algs;
+       }
+
+       /**
+        * Get module corresponding a hash string.
+        *
+        * @param string $hash hash string to check
+        * @return object|null module object on true, false if hash algorithm not recognized
+        */
+       public function getModuleByHash($hash) {
+               $module = null;
+               foreach ($this->getSupportedHashAlgs() as $const => $hash_alg) {
+                       $mod = $this->getModuleByHashAlg($hash_alg);
+                       if (strpos($hash, $mod::HASH_PREFIX) === 0) {
+                               $module = $mod;
+                               break;
+                       }
+               }
+               return $module;
        }
 }
 ?>
index 1ce829ef25a75fe053fbd5b5c0d4720005bdd6f3..b14ed7d93e1c472f6d520ae994fa2387bb7d14c8 100644 (file)
@@ -32,6 +32,9 @@ Prado::using('Application.Common.Class.CommonModule');
  */
 class Sha1 extends CommonModule {
 
+       // SHA-1 hash prefix
+       const HASH_PREFIX = '{SHA}';
+
        /**
         * Get hashed password using SHA-1 algorithm.
         *
@@ -41,9 +44,20 @@ class Sha1 extends CommonModule {
        public function crypt($password) {
                $hash = sha1($password, true);
                $bh = base64_encode($hash);
-               $ret = '{SHA}' . $bh;
+               $ret = self::HASH_PREFIX . $bh;
                return $ret;
        }
 
+       /**
+        * Verify if for given hash given password is valid.
+        *
+        * @param string $password password to check
+        * @param string $hash hash to check
+        * @return boolean true if password and hash are match, otherwise false
+        */
+       public function verify($password, $hash) {
+               $hash2 = $this->crypt($password);
+               return ($hash === $hash2);
+       }
 }
 ?>
index 631040558e14b032e2f3ab28d9555d298ae7133d..9177cc3f39fd1975de3e12bcbebab157f4b00571 100644 (file)
@@ -32,24 +32,52 @@ Prado::using('Application.Common.Class.CommonModule');
  */
 class Sha256 extends CommonModule {
 
+       // SHA-256 hash prefix
+       const HASH_PREFIX = '$5';
+
+       // Salt length
+       const DEF_SALT_LEN = 16;
+
        const SHA256_ROUNDS = 10000;
 
        /**
         * Get hashed password using SHA-256 algorithm and salt.
         *
         * @param string $password plain text password
+        * @param string $salt cryptographic salt
         * @return string hashed password
         */
-       public function crypt($password) {
-               // Salt string  - 16 characters for SHA-256
-               $salt_str = $this->getModule('crypto')->getRandomString(16);
+       public function crypt($password, $salt = null) {
+               if (is_null($salt)) {
+                       // Salt string  - 16 characters for SHA-256
+                       $salt = $this->getModule('crypto')->getRandomString(self::DEF_SALT_LEN);
+               }
 
-               $salt = sprintf(
-                       '$5$rounds=%d$%s$',
+               $salt_val = sprintf(
+                       '%s$rounds=%d$%s$',
+                       self::HASH_PREFIX,
                        self::SHA256_ROUNDS,
-                       $salt_str
+                       $salt
                );
-               return crypt($password, $salt);
+               return crypt($password, $salt_val);
+       }
+
+       /**
+        * Verify if for given hash given password is valid.
+        *
+        * @param string $password password to check
+        * @param string $hash hash to check
+        * @return boolean true if password and hash are match, otherwise false
+        */
+       public function verify($password, $hash) {
+               $valid = false;
+               $parts = explode('$', $hash, 5);
+               if (count($parts) === 5) {
+                       $salt = $parts[3];
+                       $hash2 = $this->crypt($password, $salt);
+                       $valid = ($hash === $hash2);
+               }
+               return $valid;
        }
 }
 ?>
index 85fcfeca838e39ef5ce3e84f07469222e0c0ac9f..b010d5bc43657c08a120ece2466e4094d3ce878c 100644 (file)
@@ -32,24 +32,52 @@ Prado::using('Application.Common.Class.CommonModule');
  */
 class Sha512 extends CommonModule {
 
+       // SHA-512 hash prefix
+       const HASH_PREFIX = '$6';
+
+       // Salt length
+       const DEF_SALT_LEN = 16;
+
        const SHA512_ROUNDS = 10000;
 
        /**
         * Get hashed password using SHA-512 algorithm and salt.
         *
         * @param string $password plain text password
+        * @param string $salt cryptographic salt
         * @return string hashed password
         */
-       public function crypt($password) {
-               // Salt string  - 16 characters for SHA-512
-               $salt_str = $this->getModule('crypto')->getRandomString(16);
+       public function crypt($password, $salt = null) {
+               if (is_null($salt)) {
+                       // Salt string  - 16 characters for SHA-512
+                       $salt = $this->getModule('crypto')->getRandomString(self::DEF_SALT_LEN);
+               }
 
-               $salt = sprintf(
-                       '$6$rounds=%d$%s$',
+               $salt_val = sprintf(
+                       '%s$rounds=%d$%s$',
+                       self::HASH_PREFIX,
                        self::SHA512_ROUNDS,
-                       $salt_str
+                       $salt
                );
-               return crypt($password, $salt);
+               return crypt($password, $salt_val);
+       }
+
+       /**
+        * Verify if for given hash given password is valid.
+        *
+        * @param string $password password to check
+        * @param string $hash hash to check
+        * @return boolean true if password and hash are match, otherwise false
+        */
+       public function verify($password, $hash) {
+               $valid = false;
+               $parts = explode('$', $hash, 5);
+               if (count($parts) === 5) {
+                       $salt = $parts[3];
+                       $hash2 = $this->crypt($password, $salt);
+                       $valid = ($hash === $hash2);
+               }
+               return $valid;
        }
 }
 ?>
index 3b617f9ba5d3292d7af8781470fa7476375c96a5..9ded33b6ec57a54e64a385f2ffab21684810fbb2 100644 (file)
@@ -33,6 +33,12 @@ Prado::using('Application.Common.Class.CommonModule');
  */
 class Ssha1 extends CommonModule {
 
+       // Salted SHA-1 hash prefix
+       const HASH_PREFIX = '{SSHA}';
+
+       // Salt length
+       const DEF_SALT_LEN = 4;
+
        /**
         * Get hashed password using SHA-1 algorithm and salt.
         *
@@ -40,15 +46,30 @@ class Ssha1 extends CommonModule {
         * @param string $salt cryptographic salt
         * @return string hashed password
         */
-       public function crypt($password) {
-               // Salt string  - 16 characters for SHA-256
-               $salt = $this->getModule('crypto')->getRandomString(4);
-
+       public function crypt($password, $salt = null) {
+               if (is_null($salt)) {
+                       $salt = $this->getModule('crypto')->getRandomString(self::DEF_SALT_LEN);
+               }
                $hash = sha1($password . $salt, true);
                $bh = base64_encode($hash . $salt);
-               $ret = '{SSHA}' . $bh;
+               $ret = self::HASH_PREFIX . $bh;
                return $ret;
        }
 
+       /**
+        * Verify if for given hash given password is valid.
+        *
+        * @param string $password password to check
+        * @param string $hash hash to check
+        * @return boolean true if password and hash are match, otherwise false
+        */
+       public function verify($password, $hash) {
+               $pos = strlen(self::HASH_PREFIX) - 1;
+               $bh = substr($hash, $pos);
+               $h = base64_decode($bh);
+               $salt = substr($h, -(self::DEF_SALT_LEN));
+               $hash2 = $this->crypt($password, $salt);
+               return ($hash === $hash2);
+       }
 }
 ?>
index ea3a6db060e1867646d17a0fde9bccbf2ce24e9e..52de9253727818ec9dfdc0a4491e34b90e21f3d6 100644 (file)
@@ -31,9 +31,22 @@ Prado::using('Application.Web.Class.WebModule');
  */
 class WebBasicUserManager extends WebModule implements UserManager {
 
+       /**
+        * Module initialization.
+        *
+        * @param TXmlElement $config module configuration
+        */
        public function init($config) {
        }
 
+       /**
+        * Validate username and password.
+        * Used during logging in process.
+        *
+        * @param string $username username
+        * @param string $password password
+        * @return boolean true if user and password valid, otherwise false
+        */
        public function validateUser($username, $password) {
                /**
                 * Basic auth is realized by web server, so validating
index 27f75b5d45fb36e3401d94123e5c06b558c484e5..faaf5b547965c9022791e786b28954ef88d6465e 100644 (file)
@@ -72,6 +72,7 @@ class WebConfig extends ConfigFileModule {
        /**
         * Supported authentication methods.
         */
+       const AUTH_METHOD_LOCAL = 'local';
        const AUTH_METHOD_BASIC = 'basic';
        const AUTH_METHOD_LDAP = 'ldap';
 
@@ -264,6 +265,15 @@ class WebConfig extends ConfigFileModule {
                return ($this->getAuthMethod() === self::AUTH_METHOD_LDAP);
        }
 
+       /**
+        * Check if current authentication method is set to Local.
+        *
+        * @return boolean true if is set local auth, otherwise false
+        */
+       public function isAuthMethodLocal() {
+               return ($this->getAuthMethod() === self::AUTH_METHOD_LOCAL);
+       }
+
        /**
         * Check if current default access method for not existing users
         * in configuration file is set to no access.
index 3f939de53cfa5126610d0158213cef30cf7f19ea..4e6d4c9a361e8031260b1155e0785e59abefbf00 100644 (file)
@@ -31,8 +31,16 @@ Prado::using('Application.Web.Class.WebModule');
  */
 class WebLdapUserManager extends WebModule implements UserManager {
 
+       /**
+        * LDAP module object.
+        */
        private $ldap = null;
 
+       /**
+        * Module initialization.
+        *
+        * @param TXmlElement $config module configuration
+        */
        public function init($config) {
                parent::init($config);
                $web_config = $this->getModule('web_config')->getConfig();
@@ -42,6 +50,14 @@ class WebLdapUserManager extends WebModule implements UserManager {
                }
        }
 
+       /**
+        * Validate username and password.
+        * Used during logging in process.
+        *
+        * @param string $username username
+        * @param string $password password
+        * @return boolean true if user and password valid, otherwise false
+        */
        public function validateUser($username, $password) {
                return $this->ldap->login($username, $password);
        }
diff --git a/gui/baculum/protected/Web/Class/WebLocalUserManager.php b/gui/baculum/protected/Web/Class/WebLocalUserManager.php
new file mode 100644 (file)
index 0000000..a69a4fb
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2020 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+Prado::using('Application.Web.Class.WebModule');
+
+/**
+ * Web local user manager module.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Module
+ * @package Baculum Web
+ */
+class WebLocalUserManager extends WebModule implements UserManager {
+
+       /**
+        * Module initialization.
+        *
+        * @param TXmlElement $config module configuration
+        */
+       public function init($config) {
+       }
+
+       /**
+        * Validate username and password.
+        * Used during logging in process.
+        *
+        * @param string $username username
+        * @param string $password password
+        * @return boolean true if user and password valid, otherwise false
+        */
+       public function validateUser($username, $password) {
+               $valid = false;
+               $user = $this->getModule('basic_webuser')->getUserCfg($username);
+               if (count($user) == 2) {
+                       if (!empty($user['pwd_hash'])) {
+                               $mod = $this->getModule('crypto')->getModuleByHash($user['pwd_hash']);
+                               if (is_object($mod)) {
+                                       $valid = $mod->verify($password, $user['pwd_hash']);
+                               }
+                       }
+               }
+               return $valid;
+       }
+}
+?>
index dc2416b1c72b40f72787977b563e01f14301c59b..6a9d341b598aeb84efb95d051c664cf6c0d1070b 100644 (file)
@@ -202,6 +202,9 @@ class WebUserManager extends WebModule implements IUserManager {
                $auth_method = $this->getModule('web_config')->getAuthMethod();
 
                switch ($auth_method) {
+                       case WebConfig::AUTH_METHOD_LOCAL:
+                               $cls = 'Application.Web.Class.WebLocalUserManager';
+                               break;
                        case WebConfig::AUTH_METHOD_BASIC:
                                $cls = 'Application.Web.Class.WebBasicUserManager';
                                break;
index 48cc6850de3f4103a350707ea2b64a1c864355ef..773d5dadd1d6ab46facfc2e2003905cf4d62325f 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/en/messages.mo and b/gui/baculum/protected/Web/Lang/en/messages.mo differ
index 198e5ca1b047327e184faa107ba871049a27ac5b..f107c6667bfeb9b91ffd1241c18fa7c753aca397 100644 (file)
@@ -2983,3 +2983,12 @@ msgstr "24-hours format time 17:22:41"
 
 msgid "12-hours format time 5:22:41 PM"
 msgstr "12-hours format time 5:22:41 PM"
+
+msgid "Local user authentication method"
+msgstr "Local user authentication method"
+
+msgid "This type of authentication is fully realized by Baculum Web. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+msgstr "This type of authentication is fully realized by Baculum Web. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+
+msgid "This type of authentication is realized by an external directory service. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+msgstr "This type of authentication is realized by an external directory service. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
index b0a264462a28b6919d7e52197b395fe1ee77abc8..022e92237d83490c48e7622b9bee673feeb4258d 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/ja/messages.mo and b/gui/baculum/protected/Web/Lang/ja/messages.mo differ
index 8a3576888c6ea6c14fd1328666d658e09e449fcf..3a1e57cb1dfbf8c2d604c06c145efb3ad1db18b7 100644 (file)
@@ -3069,3 +3069,12 @@ msgstr "24-hours format time 17:22:41"
 
 msgid "12-hours format time 5:22:41 PM"
 msgstr "12-hours format time 5:22:41 PM"
+
+msgid "Local user authentication method"
+msgstr "Local user authentication method"
+
+msgid "This type of authentication is fully realized by Baculum Web. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+msgstr "This type of authentication is fully realized by Baculum Web. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+
+msgid "This type of authentication is realized by an external directory service. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+msgstr "This type of authentication is realized by an external directory service. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
index fba5b67f26f81475660ac44fc9b0dd4b8ba51078..e53b8301fb85da38bac682329a46758c5d834aa8 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/pl/messages.mo and b/gui/baculum/protected/Web/Lang/pl/messages.mo differ
index c342e7490557e218c4dfce79a2ea7f2280d9f340..9b6fa8a40500990b5b61d6e40ba63344ac1f4c61 100644 (file)
@@ -2991,3 +2991,12 @@ msgstr "24-godzinny format czasu 17:22:41"
 
 msgid "12-hours format time 5:22:41 PM"
 msgstr "12-godzinny format czasu 5:22:41 PM"
+
+msgid "Local user authentication method"
+msgstr "Metoda uwierzytelniania lokalnych użytkowników"
+
+msgid "This type of authentication is fully realized by Baculum Web. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+msgstr "Ten typ uwierzytelniania jest w pełni realizowany Baculum Web. Do uwierzytelniania używa formularza logowania Baculum Web. Uwierzytelnianie basic serwera WWW może być wyłączone w tej metodzie."
+
+msgid "This type of authentication is realized by an external directory service. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+msgstr "Ten typ uwierzytelniania jest realizowany przez zewnętrzną usługę katalogową. Do uwierzytelniania używa formularza logowania Baculum Web. Uwierzytelnianie basic serwera WWW może być wyłączone w tej metodzie."
index 1ef06b3b9924019bc19e34955c4998d762dc690c..11adf66035b15a5e71958f240183851508cf41ed 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/pt/messages.mo and b/gui/baculum/protected/Web/Lang/pt/messages.mo differ
index b1b8bdb37499912b2899da84dbcf274585c20e0c..f04cde06582ce9d27184755ccb0ce4fee3a9af91 100644 (file)
@@ -2991,3 +2991,12 @@ msgstr "24-hours format time 17:22:41"
 
 msgid "12-hours format time 5:22:41 PM"
 msgstr "12-hours format time 5:22:41 PM"
+
+msgid "Local user authentication method"
+msgstr "Local user authentication method"
+
+msgid "This type of authentication is fully realized by Baculum Web. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+msgstr "This type of authentication is fully realized by Baculum Web. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+
+msgid "This type of authentication is realized by an external directory service. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
+msgstr "This type of authentication is realized by an external directory service. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method."
index e0298215b1dac29e1ac7e76cb6cf68f6b59dbd8d..ed1d8bf3dc0d6883e0d1f922f184b04c7ce3cec2 100644 (file)
@@ -25,8 +25,8 @@
                                        OnClick="logout"
                                >
                                        <prop:ClientSide.OnComplete>
-                                               if (!window.chrome || window.navigator.webdriver)  {
-                                                       window.location.href = main_side_bar_reload_url;
+                                               if (login_form_reload_url && (!window.chrome || window.navigator.webdriver))  {
+                                                       window.location.href = login_form_reload_url;
                                                } else if (window.chrome) {
                                                        // For chrome this reload is required to show login Basic auth prompt
                                                        window.location.reload();
index 2515f291d59aeda2e4282b7325121d9333e81b4e..12ea78e06931943bd93a4f3821e850155be5963d 100644 (file)
@@ -72,8 +72,8 @@ class LoginPage extends BaculumWebPage {
                                        $this->LoginForm->Display = 'None';
                                        $this->AuthorizationError->Display = 'Dynamic';
                                }
-                       } else if ($web_config->isAuthMethodLdap() && !$authorized) {
-                               // Ldap - user authenticated but not authorized
+                       } else if (($web_config->isAuthMethodLdap() || $web_config->isAuthMethodLocal()) && !$authorized) {
+                               // Ldap and Local - user authenticated but not authorized
                                $this->LoginForm->Display = 'None';
                                $this->AuthorizationError->Display = 'Dynamic';
                        }
index bdd68755eb1b0cfea0285a4b30d49abec14fb634..5764db1df10bba00c06563ddd3944397336c0130 100644 (file)
                </div>
 
                <h4><%[ Authentication method ]%></h4>
+               <div class="w3-container w3-row w3-padding opt_row">
+                       <div class="w3-col" style="width: 40px">
+                               <com:TRadioButton
+                                       ID="LocalAuth"
+                                       GroupName="AuthMethod"
+                                       CssClass="w3-radio"
+                                       Attributes.onclick="oUserSecurity.select_auth_method('local');"
+                               />
+                       </div>
+                       <label for="<%=$this->LocalAuth->ClientID%>"><%[ Local user authentication method  ]%></label>
+               </div>
+               <div id="authentication_method_local" class="w3-container" style="display: none">
+                       <%[ This type of authentication is fully realized by Baculum Web. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method. ]%>
+               </div>
                <div class="w3-container w3-row w3-padding opt_row">
                        <div class="w3-col" style="width: 40px">
                                <com:TRadioButton
                        <label for="<%=$this->LdapAuth->ClientID%>"><%[ LDAP authentication ]%></label>
                </div>
                <div id="authentication_method_ldap" class="w3-container w3-half w3-margin-left" style="display: none">
+                       <%[ This type of authentication is realized by an external directory service. To authenticate it uses the Baculum Web login form. The web server basic authentication can be disabled in this method. ]%>
                        <h5><%[ LDAP server options ]%></h5>
                        <div class="w3-container w3-row w3-padding">
                                <div class="w3-third w3-col">
 <script>
 var oUserSecurity = {
        ids: {
+               auth_method_local: 'authentication_method_local',
                auth_method_basic: 'authentication_method_basic',
                auth_method_ldap: 'authentication_method_ldap',
                get_users: 'get_users_table',
@@ -764,15 +780,21 @@ var oUserSecurity = {
                this.set_events();
        },
        select_auth_method: function(auth) {
+               var auth_local = document.getElementById(this.ids.auth_method_local);
                var auth_basic = document.getElementById(this.ids.auth_method_basic);
                var auth_ldap = document.getElementById(this.ids.auth_method_ldap);
 
                // hide all auth containers
-               [auth_basic, auth_ldap].forEach(function(el) {
+               [auth_local, auth_basic, auth_ldap].forEach(function(el) {
                        el.style.display = 'none';
                });
 
                switch (auth) {
+                       case 'local': {
+                               auth_local.style.display = 'block';
+                               this.user_obj = oLocalUserSecurity;
+                               break;
+                       }
                        case 'basic': {
                                auth_basic.style.display = 'block';
                                this.user_obj = oBasicUserSecurity;
@@ -895,6 +917,23 @@ var oUserSecurity = {
                }
        }
 };
+
+var oLocalUserSecurity = {
+       ids: {},
+       name: 'local',
+       table_title: '',
+       supported_fields: [],
+       enabled: <%=$this->LocalAuth->Checked ? 'true' : 'false'%>,
+       init: function() {
+               jQuery.extend(this.ids, oUserSecurity.ids);
+               if (this.enabled) {
+                       oUserSecurity.select_auth_method(this.name);
+               }
+       },
+       show_user_modal: function() {
+       }
+};
+
 var oBasicUserSecurity = {
        ids: {},
        name: 'basic',
@@ -945,6 +984,7 @@ function validate_ips(sender, parameter) {
        return validate_comma_separated_list(parameter);
 }
 oUserSecurity.init();
+oLocalUserSecurity.init();
 oBasicUserSecurity.init();
 oLdapUserSecurity.init();
 </script>
index 319c916a44647f5a2e4775edb58960322753a0ff..a9d8decff965f27cdbcfa3a1ee4648ecc5c57d42 100644 (file)
@@ -36,6 +36,7 @@ Prado::using('System.Web.UI.WebControls.TRadioButton');
 Prado::using('System.Web.UI.WebControls.TRegularExpressionValidator');
 Prado::using('System.Web.UI.WebControls.TRequiredFieldValidator');
 Prado::using('System.Web.UI.WebControls.TValidationSummary');
+Prado::using('Application.Common.Class.Crypto');
 Prado::using('Application.Common.Class.Ldap');
 Prado::using('Application.Web.Class.BaculumWebPage');
 
@@ -132,7 +133,9 @@ class Security extends BaculumWebPage {
         */
        public function initAuthForm() {
                if (isset($this->web_config['security']['auth_method'])) {
-                       if ($this->web_config['security']['auth_method'] ===  WebConfig::AUTH_METHOD_BASIC) {
+                       if ($this->web_config['security']['auth_method'] ===  WebConfig::AUTH_METHOD_LOCAL) {
+                               $this->LocalAuth->Checked = true;
+                       } elseif ($this->web_config['security']['auth_method'] ===  WebConfig::AUTH_METHOD_BASIC) {
                                $this->BasicAuth->Checked = true;
                        } elseif ($this->web_config['security']['auth_method'] ===  WebConfig::AUTH_METHOD_LDAP) {
                                $this->LdapAuth->Checked = true;
@@ -322,9 +325,14 @@ class Security extends BaculumWebPage {
 
                // Set password if auth method supports it
                if ($result === true && !empty($this->UserPassword->Text) && $this->isManageUsersAvail()) {
-                       // Set Basic auth users password
-                       if ($this->getModule('web_config')->isAuthMethodBasic() &&
-                               isset($this->web_config['auth_basic']['user_file'])) {
+                       $basic = $this->getModule('basic_webuser');
+                       if ($this->getModule('web_config')->isAuthMethodLocal()) {
+                               $basic->setUsersConfig(
+                                       $username,
+                                       $this->UserPassword->Text
+                               );
+                       } elseif ($this->getModule('web_config')->isAuthMethodBasic() &&
+                               isset($this->web_config['auth_basic']['user_file'])) { // Set Basic auth users password
 
                                $opts = [];
                                if (isset($this->web_config['auth_basic']['hash_alg'])) {
@@ -332,7 +340,6 @@ class Security extends BaculumWebPage {
                                }
 
                                // Setting basic users works both for adding and editing users
-                               $basic = $this->getModule('basic_webuser');
                                $basic->setUsersConfig(
                                        $username,
                                        $this->UserPassword->Text,
@@ -367,9 +374,10 @@ class Security extends BaculumWebPage {
                }
                $result = $this->getModule('user_config')->setConfig($config);
 
-               if ($result === true && $this->isManageUsersAvail() &&
-                       $this->getModule('web_config')->isAuthMethodBasic() &&
-                       isset($this->web_config['auth_basic']['user_file'])) {
+               $wcm = $this->getModule('web_config');
+               if ($result === true &&
+                       (($this->isManageUsersAvail() && $wcm->isAuthMethodBasic() && isset($this->web_config['auth_basic']['user_file'])) ||
+                       $wcm->isAuthMethodLocal())) {
                        // Remove basic auth users too
                        $basic = $this->getModule('basic_webuser');
                        $basic->removeUsers($usernames);
@@ -558,7 +566,8 @@ class Security extends BaculumWebPage {
         * @return none
         */
        private function setBasicAuthConfig() {
-               if ($this->isManageUsersAvail() && isset($this->web_config['auth_basic']['user_file'])) {
+               $is_basic = $this->getModule('web_config')->isAuthMethodBasic();
+               if ($is_basic && $this->isManageUsersAvail() && isset($this->web_config['auth_basic']['user_file'])) {
                        $this->getModule('basic_webuser')->setConfigPath($this->web_config['auth_basic']['user_file']);
                }
        }
@@ -1128,7 +1137,9 @@ class Security extends BaculumWebPage {
                        $config['security']['def_role'] = $this->GeneralDefaultAccessRole->SelectedValue;
                        $config['security']['def_api_host'] = $this->GeneralDefaultAccessAPIHost->SelectedValue;
                }
-               if ($this->BasicAuth->Checked) {
+               if ($this->LocalAuth->Checked) {
+                       $config['security']['auth_method'] = WebConfig::AUTH_METHOD_LOCAL;
+               } elseif ($this->BasicAuth->Checked) {
                        $config['security']['auth_method'] = WebConfig::AUTH_METHOD_BASIC;
                        $config['auth_basic'] = $this->getBasicParams();
                } else if ($this->LdapAuth->Checked) {
@@ -1152,10 +1163,11 @@ class Security extends BaculumWebPage {
         * @return boolean true if managing users is enabled, otherwise false
         */
        private function isManageUsersAvail() {
+               $is_local = $this->getModule('web_config')->isAuthMethodLocal();
                $is_basic = $this->getModule('web_config')->isAuthMethodBasic();
                $allow_manage_users = (isset($this->web_config['auth_basic']['allow_manage_users']) &&
                        $this->web_config['auth_basic']['allow_manage_users'] == 1);
-               return ($is_basic && $allow_manage_users);
+               return (($is_basic && $allow_manage_users) || $is_local);
        }
 
        /**
index 56c2a84dfb8e7d6efd5b068c4b2204750a50b275..278130649f1e32a492da5a0df60b84c14d2d9170 100644 (file)
@@ -136,7 +136,7 @@ class WebConfigWizard extends BaculumWebPage
                        ]);
 
                        $basic_webuser = $this->getModule('basic_webuser');
-                       if($this->first_run && $ret && $web_config->isAuthMethodBasic()) {
+                       if ($this->first_run && $ret && $web_config->isAuthMethodBasic()) {
                                // set new user on first wizard run
                                $previous_user = parent::DEFAULT_AUTH_USER;
                                $ret = $basic_webuser->setUsersConfig(