Skip to content
Commits on Source (19)
...@@ -17,7 +17,7 @@ syntax:lint: ...@@ -17,7 +17,7 @@ syntax:lint:
- schedules - schedules
- web - web
- merge_requests - merge_requests
- /^\d+\.\d+\.\d+$/ - /^\d+\.\d+\.\d+(p\d+)?$/
script: script:
- echo "Syntax checking PHP files" - echo "Syntax checking PHP files"
...@@ -37,7 +37,7 @@ syntax_diff:lint: ...@@ -37,7 +37,7 @@ syntax_diff:lint:
- schedules - schedules
- web - web
- merge_requests - merge_requests
- /^\d+\.\d+\.\d+$/ - /^\d+\.\d+\.\d+(p\d+)?$/
script: script:
- echo "Syntax checking PHP files" - echo "Syntax checking PHP files"
...@@ -81,7 +81,7 @@ build:package: ...@@ -81,7 +81,7 @@ build:package:
image: edbizarro/gitlab-ci-pipeline-php:7.2 image: edbizarro/gitlab-ci-pipeline-php:7.2
only: only:
refs: refs:
- /^\d+\.\d+\.\d+$/ - /^\d+\.\d+\.\d+(p\d+)?$/
- web - web
script: script:
...@@ -96,7 +96,7 @@ build:package: ...@@ -96,7 +96,7 @@ build:package:
- tar -tvf ISPConfig-${VER}.tar.gz - tar -tvf ISPConfig-${VER}.tar.gz
- echo "Uploading file to download server" - echo "Uploading file to download server"
- curl -u "${DEPLOY_FTP_USER}:${DEPLOY_FTP_PASSWORD}" -T ISPConfig-${VER}.tar.gz ftp://${DEPLOY_FTP_SERVER}/web/ - curl -u "${DEPLOY_FTP_USER}:${DEPLOY_FTP_PASSWORD}" -T ISPConfig-${VER}.tar.gz ftp://${DEPLOY_FTP_SERVER}/web/
- if [[ "$VER" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] ; then echo "Stable release ${VER}" ; curl -u "${DEPLOY_FTP_USER}:${DEPLOY_FTP_PASSWORD}" -T ISPConfig-${VER}.tar.gz ftp://${DEPLOY_FTP_SERVER}/web/ISPConfig-3-stable.tar.gz ; echo -n "${VER}" > ispconfig3_version.txt ; curl -u "${DEPLOY_FTP_USER}:${DEPLOY_FTP_PASSWORD}" -T ispconfig3_version.txt ftp://${DEPLOY_FTP_SERVER}/web/ ; else echo "Dev release ${VER}" ; fi - if [[ "$VER" =~ ^[0-9]+\.[0-9]+\.[0-9]+(p[0-9]+)?$ ]] ; then echo "Stable release ${VER}" ; curl -u "${DEPLOY_FTP_USER}:${DEPLOY_FTP_PASSWORD}" -T ISPConfig-${VER}.tar.gz ftp://${DEPLOY_FTP_SERVER}/web/ISPConfig-3-stable.tar.gz ; echo -n "${VER}" > ispconfig3_version.txt ; curl -u "${DEPLOY_FTP_USER}:${DEPLOY_FTP_PASSWORD}" -T ispconfig3_version.txt ftp://${DEPLOY_FTP_SERVER}/web/ ; else echo "Dev release ${VER}" ; fi
- rm ISPConfig-${VER}.tar.gz - rm ISPConfig-${VER}.tar.gz
- echo "Download url is https://download.ispconfig.org/ISPConfig-${VER}.tar.gz" - echo "Download url is https://download.ispconfig.org/ISPConfig-${VER}.tar.gz"
......
...@@ -26,7 +26,7 @@ Development branch: [![pipeline status](https://git.ispconfig.org/ispconfig/ispc ...@@ -26,7 +26,7 @@ Development branch: [![pipeline status](https://git.ispconfig.org/ispconfig/ispc
[^1]: not actively tested [^1]: not actively tested
## Supported operating systems ## Supported operating systems
- Debian 9, 10, and testing - Debian 9 - 11, and testing
- Ubuntu 16.04 - 20.04 - Ubuntu 16.04 - 20.04
- CentOS 7 and 8 - CentOS 7 and 8
......
...@@ -52,7 +52,7 @@ class installer_base { ...@@ -52,7 +52,7 @@ class installer_base {
} }
public function update_acme() { public function update_acme() {
$acme = explode("\n", shell_exec('which /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh')); $acme = explode("\n", shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh'));
$acme = reset($acme); $acme = reset($acme);
$val = 0; $val = 0;
...@@ -1659,6 +1659,7 @@ class installer_base { ...@@ -1659,6 +1659,7 @@ class installer_base {
$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content); $content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
wf($conf['amavis']['config_dir'].'/conf.d/50-user', $content); wf($conf['amavis']['config_dir'].'/conf.d/50-user', $content);
chmod($conf['amavis']['config_dir'].'/conf.d/50-user', 0640); chmod($conf['amavis']['config_dir'].'/conf.d/50-user', 0640);
chgrp($conf['amavis']['config_dir'].'/conf.d/50-user', 'amavis');
// TODO: chmod and chown on the config file // TODO: chmod and chown on the config file
...@@ -2965,7 +2966,7 @@ class installer_base { ...@@ -2965,7 +2966,7 @@ class installer_base {
$le_client = reset($le_client); $le_client = reset($le_client);
// Check for Neilpang acme.sh as well // Check for Neilpang acme.sh as well
$acme = explode("\n", shell_exec('which /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh')); $acme = explode("\n", shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh'));
$acme = reset($acme); $acme = reset($acme);
if((!$acme || !is_executable($acme)) && (!$le_client || !is_executable($le_client))) { if((!$acme || !is_executable($acme)) && (!$le_client || !is_executable($le_client))) {
...@@ -2973,7 +2974,7 @@ class installer_base { ...@@ -2973,7 +2974,7 @@ class installer_base {
if(!$success) { if(!$success) {
swriteln('Failed installing acme.sh. Will not be able to issue certificate during install.'); swriteln('Failed installing acme.sh. Will not be able to issue certificate during install.');
} else { } else {
$acme = explode("\n", shell_exec('which /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh')); $acme = explode("\n", shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh'));
$acme = reset($acme); $acme = reset($acme);
if($acme && is_executable($acme)) { if($acme && is_executable($acme)) {
swriteln('Installed acme.sh and using it for certificate creation during install.'); swriteln('Installed acme.sh and using it for certificate creation during install.');
...@@ -3016,14 +3017,30 @@ class installer_base { ...@@ -3016,14 +3017,30 @@ class installer_base {
$issued_successfully = false; $issued_successfully = false;
// Backup existing ispserver ssl files // Backup existing ispserver ssl files
if(file_exists($ssl_crt_file) || is_link($ssl_crt_file)) { //
copy($ssl_crt_file, $ssl_crt_file . '-temporary.bak'); // We may find valid or broken symlinks or actual files here.
} //
if(file_exists($ssl_key_file) || is_link($ssl_key_file)) { // - dangling links are broken and get perm renamed (should just delete?).
copy($ssl_key_file, $ssl_key_file . '-temporary.bak'); // possibly web server can't start because vhost file points to non-existing cert files,
} // we're not trying to catch or fix that (and not making it worse)
if(file_exists($ssl_pem_file) || is_link($ssl_pem_file)) { //
copy($ssl_pem_file, $ssl_pem_file . '-temporary.bak'); // - link to valid file is tmp renamed, and file copied to original name.
// if cert request is successful, remove the old symlink;
// if cert request fails, remove file copy and rename symlink to original name
//
// - actual file copied to tmp name.
// if cert request is successful, rename tmp copy to perm rename;
// if cert request fails, delete tmp copy
$cert_files = array( $ssl_crt_file, $ssl_key_file, $ssl_pem_file );
foreach ($cert_files as $f) {
if (is_link($f) && ! file_exists($f)) {
rename($f, $f.'-'.$date->format('YmdHis').'.bak');
} elseif (is_link($f)) {
rename($f, $f.'-temporary.bak');
copy($f.'-temporary.bak', $f);
} elseif(file_exists($f)) {
copy($f, $f.'-temporary.bak');
}
} }
// Attempt to use Neilpang acme.sh first, as it is now the preferred LE client // Attempt to use Neilpang acme.sh first, as it is now the preferred LE client
...@@ -3062,26 +3079,28 @@ class installer_base { ...@@ -3062,26 +3079,28 @@ class installer_base {
umask($old_umask); umask($old_umask);
// Make temporary backup of self-signed certs permanent // Make temporary backup of self-signed certs permanent
if(file_exists($ssl_crt_file.'-temporary.bak') || is_link($ssl_crt_file.'-temporary.bak')) foreach ($cert_files as $f) {
rename($ssl_crt_file.'-temporary.bak', $ssl_crt_file.'-'.$date->format('YmdHis').'.bak'); if (is_link($f.'-temporary.bak')) {
if(file_exists($ssl_key_file.'-temporary.bak') || is_link($ssl_key_file.'-temporary.bak')) unlink($f.'-temporary.bak');
rename($ssl_key_file.'-temporary.bak', $ssl_key_file.'-'.$date->format('YmdHis').'.bak'); } elseif(file_exists($f.'-temporary.bak')) {
if(file_exists($ssl_pem_file.'-temporary.bak') || is_link($ssl_pem_file.'-temporary.bak')) rename($f.'-temporary.bak', $f.'-'.$date->format('YmdHis').'.bak');
rename($ssl_pem_file.'-temporary.bak', $ssl_pem_file.'-'.$date->format('YmdHis').'.bak'); }
}
} else { } else {
swriteln('Issuing certificate via acme.sh failed. Please check that your hostname can be verified by letsencrypt'); swriteln('Issuing certificate via acme.sh failed. Please check that your hostname can be verified by letsencrypt');
umask($old_umask); umask($old_umask);
// Restore temporary backup of self-signed certs // Restore/cleanup temporary backup of self-signed certs
if(file_exists($ssl_crt_file.'-temporary.bak') || is_link($ssl_crt_file.'-temporary.bak')) foreach ($cert_files as $f) {
rename($ssl_crt_file.'-temporary.bak', $ssl_crt_file); if (is_link($f.'-temporary.bak')) {
if(file_exists($ssl_key_file.'-temporary.bak') || is_link($ssl_key_file.'-temporary.bak')) @unlink($f);
rename($ssl_key_file.'-temporary.bak', $ssl_key_file); rename($f.'-temporary.bak', $f);
if(file_exists($ssl_pem_file.'-temporary.bak') || is_link($ssl_pem_file.'-temporary.bak')) } elseif(file_exists($f.'-temporary.bak')) {
rename($ssl_pem_file.'-temporary.bak', $ssl_pem_file); unlink($f.'-temporary.bak');
}
}
} }
// Else, we attempt to use the official LE certbot client certbot // Else, we attempt to use the official LE certbot client certbot
} else { } else {
...@@ -3120,23 +3139,26 @@ class installer_base { ...@@ -3120,23 +3139,26 @@ class installer_base {
$issued_successfully = true; $issued_successfully = true;
// Make temporary backup of self-signed certs permanent // Make temporary backup of self-signed certs permanent
if(file_exists($ssl_crt_file.'-temporary.bak') || is_link($ssl_crt_file.'-temporary.bak')) foreach ($cert_files as $f) {
rename($ssl_crt_file.'-temporary.bak', $ssl_crt_file.'-'.$date->format('YmdHis').'.bak'); if (is_link($f.'-temporary.bak')) {
if(file_exists($ssl_key_file.'-temporary.bak') || is_link($ssl_key_file.'-temporary.bak')) unlink($f.'-temporary.bak');
rename($ssl_key_file.'-temporary.bak', $ssl_key_file.'-'.$date->format('YmdHis').'.bak'); } elseif(file_exists($f.'-temporary.bak')) {
if(file_exists($ssl_pem_file.'-temporary.bak') || is_link($ssl_pem_file.'-temporary.bak')) rename($f.'-temporary.bak', $f.'-'.$date->format('YmdHis').'.bak');
rename($ssl_pem_file.'-temporary.bak', $ssl_pem_file.'-'.$date->format('YmdHis').'.bak'); }
}
} else { } else {
swriteln('Issuing certificate via certbot failed. Please check log files and make sure that your hostname can be verified by letsencrypt'); swriteln('Issuing certificate via certbot failed. Please check log files and make sure that your hostname can be verified by letsencrypt');
// Restore temporary backup of self-signed certs // Restore/cleanup temporary backup of self-signed certs
if(file_exists($ssl_crt_file.'-temporary.bak') || is_link($ssl_crt_file.'-temporary.bak')) foreach ($cert_files as $f) {
rename($ssl_crt_file.'-temporary.bak', $ssl_crt_file); if (is_link($f.'-temporary.bak')) {
if(file_exists($ssl_key_file.'-temporary.bak') || is_link($ssl_key_file.'-temporary.bak')) @unlink($f);
rename($ssl_key_file.'-temporary.bak', $ssl_key_file); rename($f.'-temporary.bak', $f);
if(file_exists($ssl_pem_file.'-temporary.bak') || is_link($ssl_pem_file.'-temporary.bak')) } elseif(file_exists($f.'-temporary.bak')) {
rename($ssl_pem_file.'-temporary.bak', $ssl_pem_file); unlink($f.'-temporary.bak');
}
}
} }
} else { } else {
......
ALTER TABLE `remote_session` ADD `remote_ip` VARCHAR(39) NOT NULL DEFAULT '' AFTER `tstamp`;
\ No newline at end of file
...@@ -1317,6 +1317,7 @@ CREATE TABLE `remote_session` ( ...@@ -1317,6 +1317,7 @@ CREATE TABLE `remote_session` (
`remote_functions` text, `remote_functions` text,
`client_login` tinyint(1) unsigned NOT NULL default '0', `client_login` tinyint(1) unsigned NOT NULL default '0',
`tstamp` int(10) unsigned NOT NULL DEFAULT '0', `tstamp` int(10) unsigned NOT NULL DEFAULT '0',
`remote_ip` varchar(39) NOT NULL DEFAULT '',
PRIMARY KEY (`remote_session`) PRIMARY KEY (`remote_session`)
) DEFAULT CHARSET=utf8 ; ) DEFAULT CHARSET=utf8 ;
......
...@@ -85,10 +85,20 @@ class remoting { ...@@ -85,10 +85,20 @@ class remoting {
//* Delete old remoting sessions //* Delete old remoting sessions
$sql = "DELETE FROM remote_session WHERE tstamp < UNIX_TIMESTAMP()"; $sql = "DELETE FROM remote_session WHERE tstamp < UNIX_TIMESTAMP()";
$app->db->query($sql); $app->db->query($sql);
//* Check for max. login attempts
$ip_md5 = md5($_SERVER['REMOTE_ADDR']);
$sql = "SELECT * FROM `attempts_login` WHERE `ip`= ? AND `login_time` > (NOW() - INTERVAL 5 MINUTE) LIMIT 1";
$alreadyfailed = $app->db->queryOneRecord($sql, $ip_md5);
if($alreadyfailed['times'] >= 10) {
throw new SoapFault('login_failure_limit', 'The login failure limit has been reached.');
return false;
}
if($client_login == true) { if($client_login == true) {
$sql = "SELECT * FROM sys_user WHERE USERNAME = ?"; $sql = "SELECT * FROM sys_user WHERE USERNAME = ?";
$user = $app->db->queryOneRecord($sql, $username); $user = $app->db->queryOneRecord($sql, (string)$username);
if($user) { if($user) {
$saved_password = stripslashes($user['passwort']); $saved_password = stripslashes($user['passwort']);
...@@ -104,6 +114,16 @@ class remoting { ...@@ -104,6 +114,16 @@ class remoting {
} }
} }
} else { } else {
if(!$alreadyfailed['times'] )
{
//* user login the first time wrong
$sql = "INSERT INTO `attempts_login` (`ip`, `times`, `login_time`) VALUES (?, 1, NOW())";
$app->db->query($sql, $ip_md5);
} elseif($alreadyfailed['times'] >= 1) {
//* update times wrong
$sql = "UPDATE `attempts_login` SET `times`=`times`+1, `login_time`=NOW() WHERE `ip` = ? ORDER BY `login_time` DESC LIMIT 1";
$app->db->query($sql, $ip_md5);
}
throw new SoapFault('client_login_failed', 'The login failed. Username or password wrong.'); throw new SoapFault('client_login_failed', 'The login failed. Username or password wrong.');
} }
if($user['active'] != 1) { if($user['active'] != 1) {
...@@ -119,17 +139,23 @@ class remoting { ...@@ -119,17 +139,23 @@ class remoting {
//* Create a remote user session //* Create a remote user session
//srand ((double)microtime()*1000000); //srand ((double)microtime()*1000000);
$remote_session = md5(mt_rand().uniqid('ispco')); $remote_session = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'),0,1).sha1(mt_rand().uniqid('ispco',true));
$remote_userid = $user['userid']; $remote_userid = $user['userid'];
$remote_functions = ''; $remote_functions = '';
$tstamp = time() + $this->session_timeout; $tstamp = time() + $this->session_timeout;
$sql = 'INSERT INTO remote_session (remote_session,remote_userid,remote_functions,client_login,tstamp' $ip = $_SERVER['REMOTE_ADDR'];
.') VALUES (?, ?, ?, 1, ?)'; $sql = 'INSERT INTO remote_session (remote_session,remote_userid,remote_functions,client_login,tstamp,remote_ip'
$app->db->query($sql, $remote_session,$remote_userid,$remote_functions,$tstamp); .') VALUES (?, ?, ?, 1, ?, ?)';
$app->db->query($sql, $remote_session,$remote_userid,$remote_functions,$tstamp,$ip);
//* Delete login attempts after successful login
$sql = "DELETE FROM `attempts_login` WHERE `ip`=?";
$app->db->query($sql, $ip_md5);
return $remote_session; return $remote_session;
} else { } else {
$sql = "SELECT * FROM remote_user WHERE remote_username = ?"; $sql = "SELECT * FROM remote_user WHERE remote_username = ?";
$remote_user = $app->db->queryOneRecord($sql, $username); $remote_user = $app->db->queryOneRecord($sql, (string)$username);
if($remote_user) { if($remote_user) {
if(substr($remote_user['remote_password'], 0, 1) === '$') { if(substr($remote_user['remote_password'], 0, 1) === '$') {
if(crypt(stripslashes($password), $remote_user['remote_password']) != $remote_user['remote_password']) { if(crypt(stripslashes($password), $remote_user['remote_password']) != $remote_user['remote_password']) {
...@@ -138,7 +164,7 @@ class remoting { ...@@ -138,7 +164,7 @@ class remoting {
} elseif(md5($password) == $remote_user['remote_password']) { } elseif(md5($password) == $remote_user['remote_password']) {
// update hash algo // update hash algo
$sql = 'UPDATE `remote_user` SET `remote_password` = ? WHERE `remote_username` = ?'; $sql = 'UPDATE `remote_user` SET `remote_password` = ? WHERE `remote_username` = ?';
$app->db->query($sql, $app->auth->crypt_password($password), $username); $app->db->query($sql, $app->auth->crypt_password($password), (string)$username);
} else { } else {
$remote_user = null; $remote_user = null;
} }
...@@ -170,9 +196,9 @@ class remoting { ...@@ -170,9 +196,9 @@ class remoting {
if(trim($remote_user['remote_ips']) == '') { if(trim($remote_user['remote_ips']) == '') {
$remote_allowed=true; $remote_allowed=true;
} else { } else {
$ip = inet_pton($_SERVER['REMOTE_ADDR']); $ip_bin = inet_pton($ip);
foreach($allowed_ips as $allowed) { foreach($allowed_ips as $allowed) {
if($ip == inet_pton(trim($allowed))) { if($ip_bin == inet_pton(trim($allowed))) {
$remote_allowed=true; $remote_allowed=true;
break; break;
} }
...@@ -185,15 +211,32 @@ class remoting { ...@@ -185,15 +211,32 @@ class remoting {
} }
//* Create a remote user session //* Create a remote user session
//srand ((double)microtime()*1000000); //srand ((double)microtime()*1000000);
$remote_session = md5(mt_rand().uniqid('ispco')); $remote_session = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'),0,1).sha1(mt_rand().uniqid('ispco',true));
$remote_userid = $remote_user['remote_userid']; $remote_userid = $remote_user['remote_userid'];
$remote_functions = $remote_user['remote_functions']; $remote_functions = $remote_user['remote_functions'];
$tstamp = time() + $this->session_timeout; $tstamp = time() + $this->session_timeout;
$sql = 'INSERT INTO remote_session (remote_session,remote_userid,remote_functions,tstamp' $sql = 'INSERT INTO remote_session (remote_session,remote_userid,remote_functions,tstamp,remote_ip'
.') VALUES (?, ?, ?, ?)'; .') VALUES (?, ?, ?, ?, ?)';
$app->db->query($sql, $remote_session,$remote_userid,$remote_functions,$tstamp); $app->db->query($sql, $remote_session,$remote_userid,$remote_functions,$tstamp, $ip);
//* Delete login attempts after successful login
$sql = "DELETE FROM `attempts_login` WHERE `ip`=?";
$app->db->query($sql, $ip_md5);
return $remote_session; return $remote_session;
} else { } else {
if(!$alreadyfailed['times'] )
{
//* user login the first time wrong
$sql = "INSERT INTO `attempts_login` (`ip`, `times`, `login_time`) VALUES (?, 1, NOW())";
$app->db->query($sql, $ip_md5);
} elseif($alreadyfailed['times'] >= 1) {
//* update times wrong
$sql = "UPDATE `attempts_login` SET `times`=`times`+1, `login_time`=NOW() WHERE `ip` = ? ORDER BY `login_time` DESC LIMIT 1";
$app->db->query($sql, $ip_md5);
}
throw new SoapFault('login_failed', 'The login failed. Username or password wrong.'); throw new SoapFault('login_failed', 'The login failed. Username or password wrong.');
return false; return false;
} }
...@@ -212,7 +255,7 @@ class remoting { ...@@ -212,7 +255,7 @@ class remoting {
} }
$sql = "DELETE FROM remote_session WHERE remote_session = ?"; $sql = "DELETE FROM remote_session WHERE remote_session = ?";
if($app->db->query($sql, $session_id) != false) { if($app->db->query($sql, (string)$session_id) != false) {
return true; return true;
} else { } else {
return false; return false;
...@@ -522,12 +565,61 @@ class remoting { ...@@ -522,12 +565,61 @@ class remoting {
throw new SoapFault('session_id_empty', 'The SessionID is empty.'); throw new SoapFault('session_id_empty', 'The SessionID is empty.');
return false; return false;
} }
if(!is_string($session_id)) {
throw new SoapFault('session_id_nostring', 'Wrong SessionID datatype.');
return false;
}
$ip_md5 = md5($_SERVER['REMOTE_ADDR']);
$sql = "SELECT * FROM `attempts_login` WHERE `ip`= ? AND `login_time` > (NOW() - INTERVAL 5 MINUTE) LIMIT 1";
$alreadyfailed = $app->db->queryOneRecord($sql, $ip_md5);
if($alreadyfailed['times'] >= 10) {
throw new SoapFault('session_failure_limit', 'The Session failure limit has been reached.');
return false;
}
$sql = "SELECT * FROM remote_session WHERE remote_session = ? AND tstamp >= UNIX_TIMESTAMP()"; $sql = "SELECT * FROM remote_session WHERE remote_session = ? AND tstamp >= UNIX_TIMESTAMP()";
$session = $app->db->queryOneRecord($sql, $session_id); $session = $app->db->queryOneRecord($sql, (string)$session_id);
if(!is_array($session)) {
if(!$alreadyfailed['times'] )
{
//* user login the first time wrong
$sql = "INSERT INTO `attempts_login` (`ip`, `times`, `login_time`) VALUES (?, 1, NOW())";
$app->db->query($sql, $ip_md5);
} elseif($alreadyfailed['times'] >= 1) {
//* update times wrong
$sql = "UPDATE `attempts_login` SET `times`=`times`+1, `login_time`=NOW() WHERE `ip` = ? ORDER BY `login_time` DESC LIMIT 1";
$app->db->query($sql, $ip_md5);
}
throw new SoapFault('session_does_not_exist', 'The Session is expired or does not exist.');
return false;
}
$ip = $_SERVER['REMOTE_ADDR'];
if($session['remote_ip'] != $ip) {
throw new SoapFault('session_ip_mismatch', 'Session IP mismatch.');
return false;
}
if($session['remote_userid'] > 0) { if($session['remote_userid'] > 0) {
return $session; return $session;
} else { } else {
if(!$alreadyfailed['times'] )
{
//* user login the first time wrong
$sql = "INSERT INTO `attempts_login` (`ip`, `times`, `login_time`) VALUES (?, 1, NOW())";
$app->db->query($sql, $ip_md5);
} elseif($alreadyfailed['times'] >= 1) {
//* update times wrong
$sql = "UPDATE `attempts_login` SET `times`=`times`+1, `login_time`=NOW() WHERE `ip` = ? AND `login_time` < NOW() ORDER BY `login_time` DESC LIMIT 1";
$app->db->query($sql, $ip_md5);
}
throw new SoapFault('session_does_not_exist', 'The Session is expired or does not exist.'); throw new SoapFault('session_does_not_exist', 'The Session is expired or does not exist.');
return false; return false;
} }
......
...@@ -232,7 +232,7 @@ class remoting_lib extends tform_base { ...@@ -232,7 +232,7 @@ class remoting_lib extends tform_base {
if(@is_numeric($primary_id)) { if(@is_numeric($primary_id)) {
if($primary_id > 0) { if($primary_id > 0) {
// Return a single record // Return a single record
return parent::getDataRecord($primary_id); return parent::getDataRecord(intval($primary_id));
} elseif($primary_id == -1) { } elseif($primary_id == -1) {
// Return a array with all records // Return a array with all records
$sql = "SELECT * FROM ??"; $sql = "SELECT * FROM ??";
...@@ -255,8 +255,8 @@ class remoting_lib extends tform_base { ...@@ -255,8 +255,8 @@ class remoting_lib extends tform_base {
} else { } else {
$sql_where .= "?? = ? AND "; $sql_where .= "?? = ? AND ";
} }
$params[] = $key; $params[] = (string)$key;
$params[] = $val; $params[] = (string)$val;
} }
$sql_where = substr($sql_where, 0, -5); $sql_where = substr($sql_where, 0, -5);
if($sql_where == '') $sql_where = '1'; if($sql_where == '') $sql_where = '1';
......
...@@ -70,9 +70,9 @@ class session { ...@@ -70,9 +70,9 @@ class session {
function read ($session_id) { function read ($session_id) {
if($this->timeout > 0) { if($this->timeout > 0) {
$rec = $this->db->queryOneRecord("SELECT * FROM sys_session WHERE session_id = ? AND (`permanent` = 'y' OR last_updated >= DATE_SUB(NOW(), INTERVAL ? MINUTE))", $session_id, $this->timeout); $rec = $this->db->queryOneRecord("SELECT * FROM sys_session WHERE session_id = ? AND (`permanent` = 'y' OR last_updated >= DATE_SUB(NOW(), INTERVAL ? MINUTE))", (string)$session_id, $this->timeout);
} else { } else {
$rec = $this->db->queryOneRecord("SELECT * FROM sys_session WHERE session_id = ?", $session_id); $rec = $this->db->queryOneRecord("SELECT * FROM sys_session WHERE session_id = ?", (string)$session_id);
} }
if (is_array($rec)) { if (is_array($rec)) {
...@@ -91,18 +91,18 @@ class session { ...@@ -91,18 +91,18 @@ class session {
// Dont write session_data to DB if session data has not been changed after reading it. // Dont write session_data to DB if session data has not been changed after reading it.
if(isset($this->session_array['session_data']) && $this->session_array['session_data'] != '' && $this->session_array['session_data'] == $session_data) { if(isset($this->session_array['session_data']) && $this->session_array['session_data'] != '' && $this->session_array['session_data'] == $session_data) {
$this->db->query("UPDATE sys_session SET last_updated = NOW() WHERE session_id = ?", $session_id); $this->db->query("UPDATE sys_session SET last_updated = NOW() WHERE session_id = ?", (string)$session_id);
return true; return true;
} }
if (@$this->session_array['session_id'] == '') { if (@$this->session_array['session_id'] == '') {
$sql = "REPLACE INTO sys_session (session_id,date_created,last_updated,session_data,permanent) VALUES (?,NOW(),NOW(),?,?)"; $sql = "REPLACE INTO sys_session (session_id,date_created,last_updated,session_data,permanent) VALUES (?,NOW(),NOW(),?,?)";
$this->db->query($sql, $session_id, $session_data, ($this->permanent ? 'y' : 'n')); $this->db->query($sql, (string)$session_id, $session_data, ($this->permanent ? 'y' : 'n'));
} else { } else {
$sql = "UPDATE sys_session SET last_updated = NOW(), session_data = ?" . ($this->permanent ? ", `permanent` = 'y'" : "") . " WHERE session_id = ?"; $sql = "UPDATE sys_session SET last_updated = NOW(), session_data = ?" . ($this->permanent ? ", `permanent` = 'y'" : "") . " WHERE session_id = ?";
$this->db->query($sql, $session_data, $session_id); $this->db->query($sql, $session_data, (string)$session_id);
} }
...@@ -112,7 +112,7 @@ class session { ...@@ -112,7 +112,7 @@ class session {
function destroy ($session_id) { function destroy ($session_id) {
$sql = "DELETE FROM sys_session WHERE session_id = ?"; $sql = "DELETE FROM sys_session WHERE session_id = ?";
$this->db->query($sql, $session_id); $this->db->query($sql, (string)$session_id);
return true; return true;
} }
......
This diff is collapsed.
...@@ -96,7 +96,7 @@ if(count($_POST) > 0) { ...@@ -96,7 +96,7 @@ if(count($_POST) > 0) {
/* this is the reseller, that shall be re-logged in */ /* this is the reseller, that shall be re-logged in */
$sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?"; $sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?";
$tmp = $app->db->queryOneRecord($sql, $username, $password); $tmp = $app->db->queryOneRecord($sql, (string)$username, (string)$password);
$client_group_id = $app->functions->intval($tmp['default_group']); $client_group_id = $app->functions->intval($tmp['default_group']);
$tmp_client = $app->db->queryOneRecord("SELECT client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id); $tmp_client = $app->db->queryOneRecord("SELECT client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id);
...@@ -118,7 +118,7 @@ if(count($_POST) > 0) { ...@@ -118,7 +118,7 @@ if(count($_POST) > 0) {
/* this is the user the reseller wants to 'login as' */ /* this is the user the reseller wants to 'login as' */
$sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?"; $sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?";
$tmp = $app->db->queryOneRecord($sql, $username, $password); $tmp = $app->db->queryOneRecord($sql, (string)$username, (string)$password);
$tmp_client = $app->db->queryOneRecord("SELECT client.client_id, client.parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $tmp["default_group"]); $tmp_client = $app->db->queryOneRecord("SELECT client.client_id, client.parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $tmp["default_group"]);
if(!$tmp || $tmp_client["parent_client_id"] != $res_client["client_id"]) { if(!$tmp || $tmp_client["parent_client_id"] != $res_client["client_id"]) {
...@@ -146,13 +146,13 @@ if(count($_POST) > 0) { ...@@ -146,13 +146,13 @@ if(count($_POST) > 0) {
if ($loginAs){ if ($loginAs){
$sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?"; $sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?";
$user = $app->db->queryOneRecord($sql, $username, $password); $user = $app->db->queryOneRecord($sql, (string)$username, (string)$password);
} else { } else {
if(stristr($username, '@')) { if(stristr($username, '@')) {
//* mailuser login //* mailuser login
$sql = "SELECT * FROM mail_user WHERE login = ? or email = ?"; $sql = "SELECT * FROM mail_user WHERE login = ? or email = ?";
$mailuser = $app->db->queryOneRecord($sql, $username, $app->functions->idn_encode($username)); $mailuser = $app->db->queryOneRecord($sql, (string)$username, $app->functions->idn_encode($username));
$user = false; $user = false;
if($mailuser) { if($mailuser) {
$saved_password = stripslashes($mailuser['password']); $saved_password = stripslashes($mailuser['password']);
...@@ -184,7 +184,7 @@ if(count($_POST) > 0) { ...@@ -184,7 +184,7 @@ if(count($_POST) > 0) {
} else { } else {
//* normal cp user login //* normal cp user login
$sql = "SELECT * FROM sys_user WHERE USERNAME = ?"; $sql = "SELECT * FROM sys_user WHERE USERNAME = ?";
$user = $app->db->queryOneRecord($sql, $username); $user = $app->db->queryOneRecord($sql, (string)$username);
if($user) { if($user) {
$saved_password = stripslashes($user['passwort']); $saved_password = stripslashes($user['passwort']);
if(substr($saved_password, 0, 1) == '$') { if(substr($saved_password, 0, 1) == '$') {
...@@ -199,7 +199,7 @@ if(count($_POST) > 0) { ...@@ -199,7 +199,7 @@ if(count($_POST) > 0) {
} else { } else {
// update password with secure algo // update password with secure algo
$sql = 'UPDATE `sys_user` SET `passwort` = ? WHERE `username` = ?'; $sql = 'UPDATE `sys_user` SET `passwort` = ? WHERE `username` = ?';
$app->db->query($sql, $app->auth->crypt_password($password), $username); $app->db->query($sql, $app->auth->crypt_password($password), (string)$username);
} }
} }
} else { } else {
......
...@@ -61,7 +61,7 @@ if($app->auth->get_client_limit($userid, 'mailcatchall') != 0) ...@@ -61,7 +61,7 @@ if($app->auth->get_client_limit($userid, 'mailcatchall') != 0)
'html_id' => 'mail_domain_catchall_list'); 'html_id' => 'mail_domain_catchall_list');
} }
if(! $app->auth->is_admin()) if(! $app->auth->is_admin() && $app->auth->get_client_limit($userid, 'mail_wblist') != 0)
{ {
$items[] = array( 'title' => 'Email Whitelist', $items[] = array( 'title' => 'Email Whitelist',
'target' => 'content', 'target' => 'content',
......
...@@ -44,7 +44,7 @@ class letsencrypt { ...@@ -44,7 +44,7 @@ class letsencrypt {
} }
public function get_acme_script() { public function get_acme_script() {
$acme = explode("\n", shell_exec('which /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh')); $acme = explode("\n", shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh'));
$acme = reset($acme); $acme = reset($acme);
if(is_executable($acme)) { if(is_executable($acme)) {
return $acme; return $acme;
......
...@@ -1371,6 +1371,7 @@ class system{ ...@@ -1371,6 +1371,7 @@ class system{
* Control services to restart etc * Control services to restart etc
* *
*/ */
/*
function daemon_init($daemon, $action){ function daemon_init($daemon, $action){
//* $action = start|stop|restart|reload //* $action = start|stop|restart|reload
global $app; global $app;
...@@ -1409,7 +1410,7 @@ class system{ ...@@ -1409,7 +1410,7 @@ class system{
} }
} }
} }
} } */
function netmask($netmask){ function netmask($netmask){
list($f1, $f2, $f3, $f4) = explode('.', trim($netmask)); list($f1, $f2, $f3, $f4) = explode('.', trim($netmask));
...@@ -2064,36 +2065,103 @@ class system{ ...@@ -2064,36 +2065,103 @@ class system{
} }
function _getinitcommand($servicename, $action, $init_script_directory = '', $check_service) { function _getinitcommand($servicename, $action, $init_script_directory = '', $check_service) {
global $conf; global $conf, $app;
// upstart // upstart
/* removed upstart support - deprecated
if(is_executable('/sbin/initctl')){ if(is_executable('/sbin/initctl')){
exec('/sbin/initctl version 2>/dev/null | /bin/grep -q upstart', $retval['output'], $retval['retval']); exec('/sbin/initctl version 2>/dev/null | /bin/grep -q upstart', $retval['output'], $retval['retval']);
if(intval($retval['retval']) == 0) return 'service '.$servicename.' '.$action; if(intval($retval['retval']) == 0) return 'service '.$servicename.' '.$action;
} }
*/
if(!in_array($action,array('restart','reload','force-reload'))) {
$app->log('Invalid init command action '.$action,LOGLEVEL_WARN);
return false;
}
// systemd //* systemd (now default in all supported OS)
if(is_executable('/bin/systemd') || is_executable('/usr/bin/systemctl')){ if(is_executable('/bin/systemd') || is_executable('/usr/bin/systemctl')){
if ($check_service) { $app->log('Trying to use Systemd to restart service',LOGLEVEL_DEBUG);
$this->exec_safe("systemctl is-enabled ? 2>&1", $servicename);
$ret_val = $this->last_exec_retcode(); //* Test service name via regex
} if(preg_match('/[a-zA-Z0-9\.\-\_]/',$servicename)) {
if ($ret_val == 0 || !$check_service) {
return 'systemctl '.$action.' '.$servicename.'.service'; //* Test if systemd service is enabled
if ($check_service) {
$this->exec_safe("systemctl is-enabled ? 2>&1", $servicename);
$ret_val = $this->last_exec_retcode();
} else {
$app->log('Systemd service '.$servicename.' not found or not enabled.',LOGLEVEL_DEBUG);
}
//* Return service command
if ($ret_val == 0 || !$check_service) {
return 'systemctl '.$action.' '.$servicename.'.service';
} else {
$app->log('Failed to use Systemd to restart service '.$servicename.', we try init script instead.',LOGLEVEL_DEBUG);
}
} else {
$app->log('Systemd service name contains invalid chars: '.$servicename,LOGLEVEL_DEBUG);
} }
} else {
$app->log('Not using Systemd to restart services',LOGLEVEL_DEBUG);
} }
// sysvinit //* sysvinit fallback
$app->log('Using init script to restart service',LOGLEVEL_DEBUG);
//* Get init script directory
if($init_script_directory == '') $init_script_directory = $conf['init_scripts']; if($init_script_directory == '') $init_script_directory = $conf['init_scripts'];
if(substr($init_script_directory, -1) === '/') $init_script_directory = substr($init_script_directory, 0, -1); if(substr($init_script_directory, -1) === '/') $init_script_directory = substr($init_script_directory, 0, -1);
if($check_service && is_executable($init_script_directory.'/'.$servicename)) { $init_script_directory = realpath($init_script_directory);
return $init_script_directory.'/'.$servicename.' '.$action;
//* Check init script dir
if(!is_dir($init_script_directory)) {
$app->log('Init script directory '.$init_script_directory.' not found',LOGLEVEL_WARN);
return false;
}
//* Forbidden init script paths
if(substr($init_script_directory,0,4) == '/var' || substr($init_script_directory,0,4) == '/tmp') {
$app->log('Do not put init scripts in /var or /tmp folder.',LOGLEVEL_WARN);
return false;
}
//* Check init script dir owner
if(fileowner($init_script_directory) !== 0) {
$app->log('Init script directory '.$init_script_directory.' not owned by root user',LOGLEVEL_WARN);
return false;
}
$full_init_script_path = realpath($init_script_directory.'/'.$servicename);
if($full_init_script_path == '') {
$app->log('No init script, we quit here.',LOGLEVEL_WARN);
return false;
}
//* Check init script
if(!is_file($full_init_script_path)) {
$app->log('Init script '.$full_init_script_path.' not found',LOGLEVEL_WARN);
return false;
}
//* Check init script owner
if(fileowner($full_init_script_path) !== 0) {
$app->log('Init script '.$full_init_script_path.' not owned by root user',LOGLEVEL_WARN);
return false;
}
if($check_service && is_executable($full_init_script_path)) {
return $full_init_script_path.' '.$action;
} }
if (!$check_service) { if (!$check_service) {
return $init_script_directory.'/'.$servicename.' '.$action; return $full_init_script_path.' '.$action;
} }
} }
function getinitcommand($servicename, $action, $init_script_directory = '', $check_service=false) { function getinitcommand($servicename, $action, $init_script_directory = '', $check_service=true) {
if (is_array($servicename)) { if (is_array($servicename)) {
foreach($servicename as $service) { foreach($servicename as $service) {
$out = $this->_getinitcommand($service, $action, $init_script_directory, true); $out = $this->_getinitcommand($service, $action, $init_script_directory, true);
......
...@@ -242,15 +242,20 @@ class web_module { ...@@ -242,15 +242,20 @@ class web_module {
return $retval; return $retval;
} }
} }
exec($cmd.' 2>&1', $retval['output'], $retval['retval']); $app->log("Restarting httpd: $cmd", LOGLEVEL_DEBUG);
if($cmd != '') {
exec($cmd.' 2>&1', $retval['output'], $retval['retval']);
} else {
$app->log('We got no init command, restart or reload of service aborted.',LOGLEVEL_WARN);
}
// if restart failed despite successful syntax check => try again // if restart failed despite successful syntax check => try again
if($web_config['server_type'] == 'nginx' && $retval['retval'] > 0){ if($web_config['server_type'] == 'nginx' && $retval['retval'] > 0){
sleep(2); sleep(2);
exec($cmd.' 2>&1', $retval['output'], $retval['retval']); exec($cmd.' 2>&1', $retval['output'], $retval['retval']);
} }
$app->log("Restarting httpd: $cmd", LOGLEVEL_DEBUG);
// nginx: do a syntax check because on some distributions, the init script always returns 0 - even if the syntax is not ok (how stupid is that?) // nginx: do a syntax check because on some distributions, the init script always returns 0 - even if the syntax is not ok (how stupid is that?)
//if($web_config['server_type'] == 'nginx' && $retval['retval'] == 0){ //if($web_config['server_type'] == 'nginx' && $retval['retval'] == 0){
...@@ -307,10 +312,16 @@ class web_module { ...@@ -307,10 +312,16 @@ class web_module {
} }
*/ */
} }
$retval = array('output' => '', 'retval' => 0);
exec($initcommand.' 2>&1', $retval['output'], $retval['retval']);
$app->log("Restarting php-fpm: $initcommand", LOGLEVEL_DEBUG); $app->log("Restarting php-fpm: $initcommand", LOGLEVEL_DEBUG);
if($initcommand != '') {
$retval = array('output' => '', 'retval' => 0);
exec($initcommand.' 2>&1', $retval['output'], $retval['retval']);
} else {
$app->log('We got no init command, restart or reload of php-fpm service aborted.',LOGLEVEL_WARN);
}
return $retval; return $retval;
} }
......