diff --git a/docs/autoinstall_samples/autoinstall.conf_sample.php b/docs/autoinstall_samples/autoinstall.conf_sample.php index 904d65403cb40c4060094c813dcc2eae4f121803..c8bf209f9fcb2d9284f2fed8b33f96091ec36496 100644 --- a/docs/autoinstall_samples/autoinstall.conf_sample.php +++ b/docs/autoinstall_samples/autoinstall.conf_sample.php @@ -29,7 +29,7 @@ $autoinstall['ssl_cert_email'] = 'hostmaster@'.$autoinstall['hostname']; /* optional expert mode settings, needed only for expert mode */ $autoinstall['mysql_ispconfig_user'] = 'ispconfig'; // default: ispconfig -$autoinstall['mysql_ispconfig_password'] = md5(uniqid(rand())); +$autoinstall['mysql_ispconfig_password'] = bin2hex(random_bytes(20)); $autoinstall['join_multiserver_setup'] = 'n'; // y, n (default) $autoinstall['mysql_master_hostname'] = 'master.example.com'; $autoinstall['mysql_master_root_user'] = 'root'; @@ -70,4 +70,4 @@ $autoupdate['svc_detect_change_firewall_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_vserver_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_db_server'] = 'yes'; // yes (default), no -?> \ No newline at end of file +?> diff --git a/install/dist/conf/centos80.conf.php b/install/dist/conf/centos80.conf.php index 0411fb9ce5e95238cf29c0cf1afb374cd5458209..36e85e02d2448f6e9dba8a216eaa3561d46478cb 100644 --- a/install/dist/conf/centos80.conf.php +++ b/install/dist/conf/centos80.conf.php @@ -63,14 +63,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation diff --git a/install/dist/conf/debian100.conf.php b/install/dist/conf/debian100.conf.php index 0861af83deb1729230d9d978e0cdd38b0d0371d4..b6b0dc4135156e154a58c0793d53b4d2475b1f1d 100644 --- a/install/dist/conf/debian100.conf.php +++ b/install/dist/conf/debian100.conf.php @@ -65,14 +65,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation diff --git a/install/dist/conf/debian110.conf.php b/install/dist/conf/debian110.conf.php index c60152df5c846daa79feaa03868cc65236f0e32a..10f57d88a1f04af767c4b783a14095360c831b2c 100644 --- a/install/dist/conf/debian110.conf.php +++ b/install/dist/conf/debian110.conf.php @@ -65,14 +65,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation diff --git a/install/dist/conf/debian90.conf.php b/install/dist/conf/debian90.conf.php index e5d1d8a9b4f43c767ee5520b3cb61ce9d6f29424..b253a31f227c67e02c38e7289f70bb17a168cfa8 100644 --- a/install/dist/conf/debian90.conf.php +++ b/install/dist/conf/debian90.conf.php @@ -65,14 +65,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation diff --git a/install/dist/conf/debiantesting.conf.php b/install/dist/conf/debiantesting.conf.php index cbc380fffb931252aba4593aad1a8376a0b4d84a..3a06dfb86b5f2a310dcebe0b56469e295002dd6c 100644 --- a/install/dist/conf/debiantesting.conf.php +++ b/install/dist/conf/debiantesting.conf.php @@ -65,14 +65,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation diff --git a/install/dist/conf/gentoo.conf.php b/install/dist/conf/gentoo.conf.php index 24c7d0633e0b5b62db4004f329e83d503fb66aad..23558a164d7f11a2bea85d20833052481da06a85 100644 --- a/install/dist/conf/gentoo.conf.php +++ b/install/dist/conf/gentoo.conf.php @@ -63,14 +63,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* SuPHP $conf['suphp']['config_file'] = '/etc/suphp.conf'; diff --git a/install/dist/conf/ubuntu1604.conf.php b/install/dist/conf/ubuntu1604.conf.php index 0d3fe23bada198df3c9aae42b6cb42784973a6c1..bd8d0bcd1cbb794cbd1ea39cdb4591328517738b 100644 --- a/install/dist/conf/ubuntu1604.conf.php +++ b/install/dist/conf/ubuntu1604.conf.php @@ -65,14 +65,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation diff --git a/install/dist/conf/ubuntu1710.conf.php b/install/dist/conf/ubuntu1710.conf.php index 0730f8f2d533c712ee78173ebb28b3fed477c514..d3653885492dc3d3ae2ded30eef5815ab65065af 100644 --- a/install/dist/conf/ubuntu1710.conf.php +++ b/install/dist/conf/ubuntu1710.conf.php @@ -65,14 +65,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation diff --git a/install/dist/conf/ubuntu1804.conf.php b/install/dist/conf/ubuntu1804.conf.php index 2a09f787db46f5abf8fc7d2e15e4804dfe9d3222..fa96f7a5cabf6b691a9d335691744578a699678e 100644 --- a/install/dist/conf/ubuntu1804.conf.php +++ b/install/dist/conf/ubuntu1804.conf.php @@ -65,14 +65,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation diff --git a/install/dist/conf/ubuntu2004.conf.php b/install/dist/conf/ubuntu2004.conf.php index fe5a9b083b84db4cd400ef655e9cf5a84170f546..28d4bf3c140e2dad91a04087a0959b2b07f422a5 100644 --- a/install/dist/conf/ubuntu2004.conf.php +++ b/install/dist/conf/ubuntu2004.conf.php @@ -65,14 +65,14 @@ $conf['mysql']['admin_user'] = 'root'; $conf['mysql']['admin_password'] = ''; $conf['mysql']['charset'] = 'utf8'; $conf['mysql']['ispconfig_user'] = 'ispconfig'; -$conf['mysql']['ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['ispconfig_password'] = md5(random_bytes(20)); $conf['mysql']['master_slave_setup'] = 'n'; $conf['mysql']['master_host'] = ''; $conf['mysql']['master_database'] = 'dbispconfig'; $conf['mysql']['master_admin_user'] = 'root'; $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; -$conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); +$conf['mysql']['master_ispconfig_password'] = md5(random_bytes(20)); //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 103abaef1909859b45017bde0f9c6bda9174e7e3..3a3d415bb51c0ab19a5744e442da02d1d7a35210 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -190,6 +190,7 @@ class installer_base { $salt_length = 12; } + // todo: replace the below with password_hash() when we drop php5.4 support if(function_exists('openssl_random_pseudo_bytes')) { $salt .= substr(bin2hex(openssl_random_pseudo_bytes($salt_length)), 0, $salt_length); } else { diff --git a/install/tpl/apache_apps.vhost.master b/install/tpl/apache_apps.vhost.master index 8d6df71b7da0cf2c07e7e57cce50c77d04787b2e..6957ed5eb8062dc8f65021710ebb637c5e22dc7d 100644 --- a/install/tpl/apache_apps.vhost.master +++ b/install/tpl/apache_apps.vhost.master @@ -9,10 +9,12 @@ ServerAdmin webmaster@localhost {tmpl_var name='apps_vhost_servername'} - - - SetHandler None - + + + + SetHandler None + + # SSL Configuration SSLEngine On @@ -96,7 +98,7 @@ DocumentRoot {tmpl_var name='apps_vhost_dir'} SuexecUserGroup ispapps ispapps - Options +Indexes +FollowSymLinks +MultiViews +ExecCGI + Options -Indexes +FollowSymLinks +MultiViews +ExecCGI AllowOverride AuthConfig Indexes Limit Options FileInfo SetHandler fcgid-script @@ -109,6 +111,8 @@ Allow from all + IPCCommTimeout 7200 + MaxRequestLen 15728640 {tmpl_if name="use_rspamd"} diff --git a/install/tpl/debian_postfix.conf.master b/install/tpl/debian_postfix.conf.master index 5023caf6bee402159e822caa7a396ccd8f910242..8bd34f6928b8a57c516bf4edd848c7892f8018c8 100644 --- a/install/tpl/debian_postfix.conf.master +++ b/install/tpl/debian_postfix.conf.master @@ -59,3 +59,5 @@ smtp_sender_dependent_authentication = yes smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous, noplaintext smtp_sasl_tls_security_options = noanonymous +authorized_flush_users = +authorized_mailq_users = nagios, icinga diff --git a/install/tpl/fedora_postfix.conf.master b/install/tpl/fedora_postfix.conf.master index c5786c6ea8cf54262d0325a0ebccbe97d2cca640..8d2b1a9dc25b5211e0c7a42dfb69354d53455b78 100644 --- a/install/tpl/fedora_postfix.conf.master +++ b/install/tpl/fedora_postfix.conf.master @@ -55,3 +55,5 @@ smtp_sender_dependent_authentication = yes smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous, noplaintext smtp_sasl_tls_security_options = noanonymous +authorized_flush_users = +authorized_mailq_users = nagios, icinga diff --git a/install/tpl/gentoo_postfix.conf.master b/install/tpl/gentoo_postfix.conf.master index 405640f52a9dd4310289db241ee6fce61fec8aea..c6b1c2f9c509c6ba20ef94572192c676ac274d4a 100644 --- a/install/tpl/gentoo_postfix.conf.master +++ b/install/tpl/gentoo_postfix.conf.master @@ -54,3 +54,5 @@ smtp_sender_dependent_authentication = yes smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous, noplaintext smtp_sasl_tls_security_options = noanonymous +authorized_flush_users = +authorized_mailq_users = nagios, icinga diff --git a/install/tpl/opensuse_postfix.conf.master b/install/tpl/opensuse_postfix.conf.master index a98f4223e13ee1d9221885d4ee6775b08de239ce..03f134bb0804ae2d70f12afef0068736e5b1e506 100644 --- a/install/tpl/opensuse_postfix.conf.master +++ b/install/tpl/opensuse_postfix.conf.master @@ -57,3 +57,5 @@ smtp_sender_dependent_authentication = yes smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous, noplaintext smtp_sasl_tls_security_options = noanonymous +authorized_flush_users = +authorized_mailq_users = nagios, icinga diff --git a/interface/lib/app.inc.php b/interface/lib/app.inc.php index ee4713cd98981ea80e10146d3c1ddedb822ed5a8..7ff158fbdc47a094523a57f86ad95cd901d30547 100755 --- a/interface/lib/app.inc.php +++ b/interface/lib/app.inc.php @@ -28,6 +28,8 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +require_once 'compatibility.inc.php'; + //* Enable gzip compression for the interface ob_start('ob_gzhandler'); diff --git a/interface/lib/classes/auth.inc.php b/interface/lib/classes/auth.inc.php index a69d43da2ec1a079c0d4aefe906684f389d4ffa4..3a4cc1603cca1972f8711c7e09ff19f7c53cc8f9 100644 --- a/interface/lib/classes/auth.inc.php +++ b/interface/lib/classes/auth.inc.php @@ -231,7 +231,7 @@ class auth { public function get_random_password($minLength = 8, $special = false) { if($minLength < 8) $minLength = 8; $maxLength = $minLength + 5; - $length = mt_rand($minLength, $maxLength); + $length = random_int($minLength, $maxLength); $alphachars = "abcdefghijklmnopqrstuvwxyz"; $upperchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -240,28 +240,28 @@ class auth { $num_special = 0; if($special == true) { - $num_special = intval(mt_rand(0, round($length / 4))) + 1; + $num_special = intval(random_int(0, round($length / 4))) + 1; } - $numericlen = mt_rand(1, 2); + $numericlen = random_int(1, 2); $alphalen = $length - $num_special - $numericlen; $upperlen = intval($alphalen / 2); $alphalen = $alphalen - $upperlen; $password = ''; for($i = 0; $i < $alphalen; $i++) { - $password .= substr($alphachars, mt_rand(0, strlen($alphachars) - 1), 1); + $password .= substr($alphachars, random_int(0, strlen($alphachars) - 1), 1); } for($i = 0; $i < $upperlen; $i++) { - $password .= substr($upperchars, mt_rand(0, strlen($upperchars) - 1), 1); + $password .= substr($upperchars, random_int(0, strlen($upperchars) - 1), 1); } for($i = 0; $i < $num_special; $i++) { - $password .= substr($specialchars, mt_rand(0, strlen($specialchars) - 1), 1); + $password .= substr($specialchars, random_int(0, strlen($specialchars) - 1), 1); } for($i = 0; $i < $numericlen; $i++) { - $password .= substr($numchars, mt_rand(0, strlen($numchars) - 1), 1); + $password .= substr($numchars, random_int(0, strlen($numchars) - 1), 1); } return str_shuffle($password); @@ -298,8 +298,8 @@ class auth { public function csrf_token_get($form_name) { /* CSRF PROTECTION */ // generate csrf protection id and key - $_csrf_id = uniqid($form_name . '_'); // form id - $_csrf_key = sha1(uniqid(microtime(true), true)); // the key + $_csrf_id = $form_name . '_' . bin2hex(random_bytes(12)); // form id + $_csrf_key = sha1(random_bytes(20)); // the key if(!isset($_SESSION['_csrf'])) $_SESSION['_csrf'] = array(); if(!isset($_SESSION['_csrf_timeout'])) $_SESSION['_csrf_timeout'] = array(); $_SESSION['_csrf'][$_csrf_id] = $_csrf_key; diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php index 02d573a77812258d68dbd3716f24f5b2fb85234f..1b396686740bc026b11204d09697debff3cd1a45 100644 --- a/interface/lib/classes/functions.inc.php +++ b/interface/lib/classes/functions.inc.php @@ -28,6 +28,8 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +require_once __DIR__.'/../compatibility.inc.php'; + //* The purpose of this library is to provide some general functions. //* This class is loaded automatically by the ispconfig framework. @@ -437,10 +439,10 @@ class functions { $iteration = 0; $password = ""; $maxLength = $minLength + 5; - $length = $this->getRandomInt($minLength, $maxLength); + $length = random_int($minLength, $maxLength); while($iteration < $length){ - $randomNumber = (floor(((mt_rand() / mt_getrandmax()) * 100)) % 94) + 33; + $randomNumber = random_int(33, 126); if(!$special){ if (($randomNumber >=33) && ($randomNumber <=47)) { continue; } if (($randomNumber >=58) && ($randomNumber <=64)) { continue; } @@ -455,10 +457,6 @@ class functions { return $password; } - public function getRandomInt($min, $max){ - return floor((mt_rand() / mt_getrandmax()) * ($max - $min + 1)) + $min; - } - public function generate_customer_no(){ global $app; // generate customer no. @@ -474,14 +472,17 @@ class functions { global $app; // generate the SSH key pair for the client - $id_rsa_file = '/tmp/'.uniqid('',true); + if (! $tmpdir = $app->system->exec_safe('mktemp -dt id_rsa.XXXXXXXX')) { + $app->log("mktemp failed, cannot create SSH keypair for ".$username, LOGLEVEL_WARN); + } + $id_rsa_file = $tmpdir . uniqid('',true); $id_rsa_pub_file = $id_rsa_file.'.pub'; if(file_exists($id_rsa_file)) unset($id_rsa_file); if(file_exists($id_rsa_pub_file)) unset($id_rsa_pub_file); if(!file_exists($id_rsa_file) && !file_exists($id_rsa_pub_file)) { $app->system->exec_safe('ssh-keygen -t rsa -C ? -f ? -N ""', $username.'-rsa-key-'.time(), $id_rsa_file); $app->db->query("UPDATE client SET created_at = UNIX_TIMESTAMP(), id_rsa = ?, ssh_rsa = ? WHERE client_id = ?", @file_get_contents($id_rsa_file), @file_get_contents($id_rsa_pub_file), $client_id); - $app->system->exec_safe('rm -f ? ?', $id_rsa_file, $id_rsa_pub_file); + $app->system->rmdir($tmpdir, true); } else { $app->log("Failed to create SSH keypair for ".$username, LOGLEVEL_WARN); } diff --git a/interface/lib/classes/remoting.inc.php b/interface/lib/classes/remoting.inc.php index 80e30bf849e203be1fc405ad1a1160a26ed3cc2e..8b888cb231dce17f1741cb09f1a0d04586e47404 100644 --- a/interface/lib/classes/remoting.inc.php +++ b/interface/lib/classes/remoting.inc.php @@ -138,8 +138,8 @@ class remoting { } //* Create a remote user session - //srand ((double)microtime()*1000000); - $remote_session = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'),0,1).sha1(mt_rand().uniqid('ispco',true)); + // session id must begin with a char, not digit, to avoid mysql type confusion abuse + $remote_session = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'),0,1).bin2hex(random_bytes(20)); $remote_userid = $user['userid']; $remote_functions = ''; $tstamp = time() + $this->session_timeout; @@ -210,8 +210,8 @@ class remoting { return false; } //* Create a remote user session - //srand ((double)microtime()*1000000); - $remote_session = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'),0,1).sha1(mt_rand().uniqid('ispco',true)); + // session id must begin with a char, not digit, to avoid mysql type confusion abuse + $remote_session = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'),0,1).bin2hex(random_bytes(20)); $remote_userid = $remote_user['remote_userid']; $remote_functions = $remote_user['remote_functions']; $tstamp = time() + $this->session_timeout; diff --git a/interface/lib/classes/system.inc.php b/interface/lib/classes/system.inc.php index d6b0ef149e285dbe3e3c438cff36bbe44daddac8..9cb171cae5d2f230ede4b117bc1b6900625f1d69 100644 --- a/interface/lib/classes/system.inc.php +++ b/interface/lib/classes/system.inc.php @@ -79,6 +79,32 @@ class system { return false; } + function rmdir($path, $recursive=false) { + // Disallow operating on root directory + if(realpath($path) == '/') { + $app->log("rmdir: afraid I might delete root: $path", LOGLEVEL_WARN); + return false; + } + + $path = rtrim($path, '/'); + if (is_dir($path) && !is_link($path)) { + $objects = array_diff(scandir($path), array('.', '..')); + foreach ($objects as $object) { + if ($recursive) { + if (is_dir("$path/$object") && !is_link("$path/$object")) { + $this->rmdir("$path/$object", $recursive); + } else { + unlink ("$path/$object"); + } + } else { + $app->log("rmdir: invoked non-recursive, not removing $path (expect rmdir failure)", LOGLEVEL_DEBUG); + } + } + return rmdir($path); + } + return false; + } + public function last_exec_out() { return $this->_last_exec_out; } diff --git a/interface/lib/compatibility.inc.php b/interface/lib/compatibility.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..562e07ada42f404cae0708f32105dcf39a84768c --- /dev/null +++ b/interface/lib/compatibility.inc.php @@ -0,0 +1,80 @@ + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* random_bytes can be dropped when php 5.6 support is dropped */ +if (! function_exists('random_bytes')) { + function random_bytes($length) { + return openssl_random_pseudo_bytes($length); + } +} + +/* random_int can be dropped when php 5.6 support is dropped */ +if (! function_exists('random_int')) { + function random_int($min=null, $max=null) { + if (null === $min) { + $min = PHP_INT_MIN; + } + + if (null === $max) { + $min = PHP_INT_MAX; + } + + if (!is_int($min) || !is_int($max)) { + trigger_error('random_int: $min and $max must be integer values', E_USER_NOTICE); + $min = (int)$min; + $max = (int)$max; + } + + if ($min > $max) { + trigger_error('random_int: $max can\'t be lesser than $min', E_USER_WARNING); + return null; + } + + $range = $counter = $max - $min; + $bits = 1; + + while ($counter >>= 1) { + ++$bits; + } + + $bytes = (int)max(ceil($bits/8), 1); + $bitmask = pow(2, $bits) - 1; + + if ($bitmask >= PHP_INT_MAX) { + $bitmask = PHP_INT_MAX; + } + + do { + $result = hexdec(bin2hex(random_bytes($bytes))) & $bitmask; + } while ($result > $range); + + return $result + $min; + } +} diff --git a/interface/web/login/password_reset.php b/interface/web/login/password_reset.php index db4ad71c22d2614566b0c2658cb4254ee8e7afdb..659075483c918c4813a28e74bf1a67eb8faa7ea9 100644 --- a/interface/web/login/password_reset.php +++ b/interface/web/login/password_reset.php @@ -71,7 +71,7 @@ if(isset($_POST['username']) && is_string($_POST['username']) && $_POST['usernam } elseif ($continue) { if($client['client_id'] > 0) { $username = $client['username']; - $password_hash = sha1(uniqid('ispc_pw')); + $password_hash = sha1(random_bytes(20)); $app->db->query("UPDATE sys_user SET lost_password_reqtime = NOW(), lost_password_hash = ? WHERE username = ?", $password_hash, $username); $server_domain = (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST']); diff --git a/server/lib/classes/functions.inc.php b/server/lib/classes/functions.inc.php index 5296c3012b65cb4bf0d9889c893252e99ec9d4a8..34e5943cda865a11fd279c88dcb57785abf810a4 100644 --- a/server/lib/classes/functions.inc.php +++ b/server/lib/classes/functions.inc.php @@ -468,14 +468,16 @@ class functions { global $app; // generate the SSH key pair for the client - $id_rsa_file = '/tmp/'.uniqid('',true); + $app->system->exec_safe('mktemp -dt id_rsa.XXXXXXXX'); + $tmpdir = $app->system->last_exec_out(); + $id_rsa_file = $tmpdir . uniqid('',true); $id_rsa_pub_file = $id_rsa_file.'.pub'; if(file_exists($id_rsa_file)) unset($id_rsa_file); if(file_exists($id_rsa_pub_file)) unset($id_rsa_pub_file); if(!file_exists($id_rsa_file) && !file_exists($id_rsa_pub_file)) { $app->system->exec_safe('ssh-keygen -t rsa -C ? -f ? -N ""', $username.'-rsa-key-'.time(), $id_rsa_file); $app->db->query("UPDATE client SET created_at = UNIX_TIMESTAMP(), id_rsa = ?, ssh_rsa = ? WHERE client_id = ?", $app->system->file_get_contents($id_rsa_file), $app->system->file_get_contents($id_rsa_pub_file), $client_id); - $app->system->exec_safe('rm -f ? ?', $id_rsa_file, $id_rsa_pub_file); + $app->system->rmdir($tmpdir, true); } else { $app->log("Failed to create SSH keypair for ".$username, LOGLEVEL_WARN); } diff --git a/server/lib/classes/letsencrypt.inc.php b/server/lib/classes/letsencrypt.inc.php index ac805a6b67340506236d995c84dc9c8868adf755..c9f22f14c52d2c97d252cc7f5abb3e20c72f4bee 100644 --- a/server/lib/classes/letsencrypt.inc.php +++ b/server/lib/classes/letsencrypt.inc.php @@ -373,7 +373,7 @@ class letsencrypt { $temp_domains = array_unique($temp_domains); // check if domains are reachable to avoid letsencrypt verification errors - $le_rnd_file = uniqid('le-') . '.txt'; + $le_rnd_file = uniqid('le-', true) . '.txt'; $le_rnd_hash = md5(uniqid('le-', true)); if(!is_dir('/usr/local/ispconfig/interface/acme/.well-known/acme-challenge/')) { $app->system->mkdir('/usr/local/ispconfig/interface/acme/.well-known/acme-challenge/', false, 0755, true); diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index f2a121825b75464ee9af81dd935866509b59ee42..35133ae322e4b3a57e239ed2cfe0ecc954233de5 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -296,16 +296,9 @@ class apache2_plugin { if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); $rand_file = $ssl_dir.'/random_file'; - $rand_data = md5(uniqid(microtime(), 1)); - for($i=0; $i<1000; $i++) { - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - } - $app->system->file_put_contents($rand_file, $rand_data); + $app->system->exec_safe('dd if=/dev/urandom of=? bs=256 count=1', $rand_file); - $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); + $ssl_password = bin2hex(random_bytes(12)); $ssl_cnf = " RANDFILE = $rand_file diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index 0e2cacaef9bfd0da4db665ef3cdc3fe68057461f..9e111e72d9e0129563ccad1c610611355af34ca3 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -129,16 +129,10 @@ class nginx_plugin { if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); $rand_file = $ssl_dir.'/random_file'; - $rand_data = md5(uniqid(microtime(), 1)); - for($i=0; $i<1000; $i++) { - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - } - $app->system->file_put_contents($rand_file, $rand_data); + $app->system->exec_safe('dd if=/dev/urandom of=? bs=256 count=1', $rand_file); + + $ssl_password = bin2hex(random_bytes(12)); - $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); $ssl_cnf = " RANDFILE = $rand_file