began to 'clean up' for future releases (APS, Autoresponder and Backup)

Signed-off-by: Michael Kaufmann (d00p) <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann (d00p)
2013-12-04 18:32:46 +01:00
parent 47b1675dea
commit 2800ca05a1
29 changed files with 81 additions and 5821 deletions

View File

@@ -1,21 +0,0 @@
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Florian Lippert <flo@syscp.org> (2003-2009)
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Cron
*
*/
$Aps = new ApsInstaller($settings);
$Aps->InstallHandler();

View File

@@ -1,21 +0,0 @@
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Florian Lippert <flo@syscp.org> (2003-2009)
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Cron
*
*/
$Aps = new ApsUpdater($cronlog);
$Aps->UpdateHandler();

View File

@@ -1,258 +0,0 @@
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
/**
* This file is part of the Froxlor project.
* Copyright (c) 2003-2009 the SysCP Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Florian Lippert <flo@syscp.org> (2003-2009)
* @author Remo Fritzsche
* @author Manuel Aller
* @author Michael Schlechtinger
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Cron
*
* @todo skip mail parsing after x bytes for large mails
*/
$mail = new PHPMailer(true);
//dont do anything when module is disabled
if ((int)$settings['autoresponder']['autoresponder_active'] == 0) {
return;
}
//only send autoresponder to mails which were delivered since last run
if ((int)$settings['autoresponder']['last_autoresponder_run'] == 0) {
//mails from last 5 minutes, otherwise all mails will be parsed -> mailbomb prevention
$cycle = 300;
} else {
// calculate seconds since last check
$cycle = time() - (int)$settings['autoresponder']['last_autoresponder_run'];
//prevent mailbombs when cycle is bigger than two days
if($cycle > (2 * 60 * 60 * 24))$cycle = (60 * 60 * 24);
}
// set last_autoresponder_run
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = :timeval
WHERE `settinggroup` = 'autoresponder' AND `varname` = 'last_autoresponder_run'
");
Database::pexecute($upd_stmt, array('timeval' => time()));
// get all customer set ip autoresponders
$result_stmt = Database::query("
SELECT * FROM `" . TABLE_MAIL_AUTORESPONDER . "` INNER JOIN `" . TABLE_MAIL_USERS . "`
ON `" . TABLE_MAIL_AUTORESPONDER . "`.`email` = `" . TABLE_MAIL_USERS . "`.`email`
WHERE `enabled` = 1
");
if (Database::num_rows() > 0) {
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
//check if specific autoresponder should be used
$ts_now = time();
$ts_start = (int)$row['date_from'];
$ts_end = (int)$row['date_until'];
$row['email'] = strtolower($row['email']);
// not yet
if($ts_start != -1 && $ts_start > $ts_now) continue;
// already ended
if($ts_end != -1 && $ts_end < $ts_now) continue;
// setup mail-path (e.g. /var/customers/mail/[loginname]/[user@domain.tld]/new
$path = makeCorrectDir($row['homedir'] . $row['maildir'] . "new/");
// if the directory does not exist, inform syslog
if (!is_dir($path)) {
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Error accessing maildir: " . $path);
continue;
}
// get all files
$its = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path)
);
$responded_counter = 0;
foreach ($its as $fullFilename => $it ) {
if ($it->getFilename() == '.' || $it->getFilename() == '..') {
continue;
}
/*
* is the time passed between now and
* the time we received the mail lower/equal
* than our cycle-seconds?
*/
$filemtime = $it->getMTime();
if (time() - $filemtime <= $cycle) {
// why not read up to k lines?
// I've been patching this forever, to avoid FATAL ERROR / memory exhausted
// (fgets() is now binary safe, too)
// $content = file($fullFilename);
$lcount = 0; $content = array(); $handle = @fopen($fullFilename, "r");
if ($handle) {
// 1023 lines of an email should be enough to analyze it
while (($lcount++<1023) && (($buffer = fgets($handle)) !== false)) {
$content[]=$buffer;
}
fclose($handle);
}
// error reading mail contents or just empty
if (count($content) == 0) {
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Unable to read mail from maildir: " . dirname($fullFilename));
continue;
}
$match = array();
$from = '';
$to = '';
$sender = '';
$spam = false;
foreach ($content as $line) {
// header ends on first empty line, skip rest of mail
if (strlen(rtrim($line)) == 0) {
break;
}
//fetching from field
if (!strlen($from)
&& preg_match("/^From:(.+)<(.*)>$/", $line, $match)
) {
$from = strtolower($match[2]);
}
elseif (!strlen($from)
&& preg_match("/^From:\s+(.*@.*)$/", $line, $match)
) {
$from = strtolower($match[1]);
}
//fetching to field
if ((!strlen($to) || $to != $row['email'])
&& preg_match("/^To:(.+)<(.*)>$/", $line, $match)
) {
$to = strtolower($match[2]);
}
elseif ((!strlen($to) || $to != $row['email'])
&& preg_match("/^To:\s+(.*@.*)$/", $line, $match)
) {
$to = strtolower($match[1]);
}
/*
* if we still don't have a To:-address
* OR even worse, the $to is NOT the mail-address
* of the customer which autoresponder this is
* we have to check for CC too, #476
*/
elseif ((!strlen($to) || $to != $row['email'])
&& preg_match("/^Cc:(.+)<(.*)>$/", $line, $match)
) {
$to = strtolower($match[2]);
}
elseif ((!strlen($to) || $to != $row['email'])
&& preg_match("/^Cc:\s+(.*@.*)$/", $line, $match)
) {
$to = strtolower($match[1]);
}
// fetching sender field
if (!strlen($sender)
&& preg_match("/^Sender:(.+)<(.*)>$/", $line, $match)
) {
$sender = strtolower($match[2]);
}
elseif (!strlen($sender)
&& preg_match("/Sender:\s+(.*@.*)$/", $line, $match)
) {
$sender = strtolower($match[1]);
}
//check for amavis/spamassassin spam headers
if (preg_match("/^X-Spam-Status: (Yes|No)(.*)$/", $line, $match)) {
if(strtolower($match[1]) == 'yes') {
$spam = true;
}
}
//check for precedence header
if (preg_match("/^Precedence: (bulk|list|junk)(.*)$/", $line, $match)) {
// use the spam flag to skip reply
$spam = true;
}
}
// check if the receiver is really the one
// with the autoresponder
if (!strlen($to) || $to != $row['email']) {
$to = '';
}
//skip mail when marked as spam
if ($spam == true) {
continue;
}
//error while parsing mail
if ($to == '' || $from == '') {
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "No valid headers found in mail to parse");
continue;
}
//important! prevent mailbombs when mail comes from a maildaemon/mailrobot
//robot/daemon mails must go to Sender: field in envelope header
//refers to "Das Postfix-Buch" / RFC 2822
if ($sender != '') {
$from = $sender;
}
//make message valid to email format
$message = str_replace("\r\n", "\n", $row['message']);
//check if mail is already an answer
$fullcontent = implode("", $content);
if (strstr($fullcontent, $message) || $from == $to) {
continue;
}
$_mailerror = false;
try {
$mail->CharSet = "UTF-8";
$mail->SetFrom($to, $to);
$mail->AddReplyTo($to, $to);
$mail->Subject = $row['subject'];
$mail->AltBody = $message;
$html_message = str_replace("\n", "<br />", $message);
$mail->MsgHTML(html_entity_decode($html_message));
$mail->AddAddress($from, $from);
$mail->AddCustomHeader('Precedence: bulk');
$mail->Send();
} catch(phpmailerException $e) {
$mailerr_msg = $e->errorMessage();
$_mailerror = true;
} catch (Exception $e) {
$mailerr_msg = $e->getMessage();
$_mailerror = true;
}
if ($_mailerror) {
$cronlog->logAction(CRON_ACTION, LOG_WARNING, "Error sending autoresponder mail: " . $mailerr_msg);
}
$mail->ClearAddresses();
$responded_counter++;
}
}
$cronlog->logAction(CRON_ACTION, LOG_INFO, "Responded to '" . $responded_counter . "' mails from '".$path."'");
}
}

View File

@@ -1,158 +0,0 @@
<?php if (!defined('MASTER_CRONJOB')) die('You cannot access this file directly!');
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Cron
*
*/
/**
* Backup
*/
if ($settings['system']['backup_enabled'] == '1') {
fwrite($debugHandler, 'backup customers started...' . "\n");
// get sql-root access data for mysqldump
Database::needRoot(true);
Database::needSqlData();
$sql_root = Database::getSqlData();
Database::needRoot(false);
$result_stmt = Database::query("
SELECT customerid, loginname, guid, documentroot, backup_allowed, backup_enabled
FROM `" . TABLE_PANEL_CUSTOMERS . "` ORDER BY `customerid` ASC;
");
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
fwrite($debugHandler, 'backup for ' . $row['loginname'] . ' started...' . "\n");
// backup
if ($row['backup_allowed'] == '1'
&& $row['backup_enabled'] == '1'
) {
// get uid & gid from ftp table
$ftp_result_stmt = Database::prepare("
SELECT uid, gid FROM `" . TABLE_FTP_USERS . "`
WHERE `username` = :loginname
");
$ftp_row = Database::pexecute_first($ftp_result_stmt, array('loginname' => $row['loginname']));
// create backup dir an set rights
$_backupdir = makeCorrectDir($settings['system']['backup_dir'] . $row['loginname']);
if (!file_exists($_backupdir)) {
safe_exec('install -d ' . escapeshellarg($_backupdir) . ' -o ' . escapeshellarg($ftp_row['uid']) . ' -g ' . escapeshellarg($ftp_row['gid']) . ' -m ' . '0500');
}
// create customers html backup
safe_exec('tar -C ' . escapeshellarg($row['documentroot']) . ' -c -z -f ' . escapeshellarg($_backupdir) . '/' . escapeshellarg($row['loginname']) . 'html.tar.gz .');
// get customer dbs
$dbs_result_stmt = Database::prepare("
SELECT `databasename` FROM `" . TABLE_PANEL_DATABASES . "`
WHERE `customerid` = :customerid
");
Database::pexecute($dbs_result_stmt, array('customerid' => $row['customerid']));
while ($dbs_row = $dbs_result_stmt->fetch(PDO::FETCH_ASSOC)){
// create customers sql backup
safe_exec(escapeshellcmd($settings['system']['backup_mysqldump_path']) . ' --opt --force --allow-keywords -u ' . escapeshellarg($sql_root['user']) . ' -p' . escapeshellarg($sql_root['passwd']) . ' -h ' . $sql_root['host'] . ' -B ' . escapeshellarg($dbs_row['databasename']) . ' -r ' . escapeshellarg($_backupdir) . '/' . escapeshellarg($dbs_row['databasename']) . '.sql' );
// compress sql backup
safe_exec('tar -C ' . escapeshellarg($_backupdir) . ' -c -z -f ' . escapeshellarg($settings['system']['backup_dir']) . $row['loginname'] . '/' . escapeshellarg($dbs_row['databasename']) . '.tar.gz ' . escapeshellarg($dbs_row['databasename']) . '.sql');
// remove uncompresed sql files
safe_exec('rm ' . escapeshellarg($_backupdir) . '/' . escapeshellarg($dbs_row['databasename']) . '.sql');
}
// create 1 big file with html & db
if ($settings['system']['backup_bigfile'] == 1) {
safe_exec('tar -C ' . escapeshellarg($_backupdir) . '/' . ' --exclude=' . escapeshellarg($row['loginname']) . '.tar.gz -c -z -f ' . escapeshellarg($_backupdir) . '/' . escapeshellarg($row['loginname']) . '.tar.gz .');
// remove separated files
$tmp_files = scandir($_backupdir);
foreach ($tmp_files as $tmp_file) {
if (preg_match('/.*(html|sql|aps).*\.tar\.gz$/', $tmp_file) && !preg_match('/^' . $row['loginname'] . '\.tar\.gz$/', $tmp_file)) {
safe_exec('rm ' . escapeshellarg($_backupdir) . '/' . escapeshellarg($tmp_file));
}
}
} else {
//remove big file if separated backups are used
if (file_exists(makeCorrectFile($_backupdir . '/' . $row['loginname'] . '.tar.gz'))) {
safe_exec('rm ' . escapeshellarg($_backupdir) . '/' . escapeshellarg($row['loginname']) . '.tar.gz');
}
}
// chown & chmod files to prevent manipulation
safe_exec('chown ' . escapeshellarg($row['guid']) . ':' . escapeshellarg($row['guid']) . ' ' . escapeshellarg($_backupdir) . '/*');
safe_exec('chmod 0400 ' . escapeshellarg($_backupdir) . '/*');
// create ftp backup user
$user_result_stmt = Database::prepare("
SELECT username, password FROM `" . TABLE_FTP_USERS . "`
WHERE `customerid` = :customerid AND `username` = :username;
");
$user_row = Database::pexecute_first($user_result_stmt, array('customerid' => $row['customerid'], 'username' => $row['loginname']));
$ins_stmt = Database::prepare("
REPLACE INTO `" . TABLE_FTP_USERS . "`
(`customerid`, `username`, `password`, `homedir`, `login_enabled`, `uid`, `gid`)
VALUES
(:customerid, :username, :password, :homedir, 'y', :guid, :guid)
");
$ins_data = array(
'customerid' => $row['customerid'],
'username' => $row['loginname']."_backup",
'password' => $user_row['password'],
'homedir' => makeCorrectDir($settings['system']['backup_dir'].'/'.$row['loginname'].'/'),
'guid' => $row['guid']
);
Database::pexecute($ins_stmt, $ins_data);
if ($settings['system']['backup_ftp_enabled'] == '1') {
// upload backup to customers ftp server
$_ftpdir = makeCorrectDir($settings['system']['backup_dir'].'/'.$row['loginname'].'/');
$ftp_files = scandir($_ftpdir);
foreach ($ftp_files as $ftp_file) {
if (preg_match('/.*\.tar\.gz$/', $ftp_file)) {
$ftp_con = ftp_connect($settings['system']['backup_ftp_server']);
$ftp_login = ftp_login($ftp_con, $settings['system']['backup_ftp_user'], $settings['system']['backup_ftp_pass']);
// Check whether to use passive mode or not
if ($settings['system']['backup_ftp_passive'] == 1) {
ftp_pasv($ftp_con, true);
} else {
ftp_pasv($ftp_con, false);
}
$_file = makeCorrectFile($_ftpdir.'/'.$ftp_file);
$ftp_upload = ftp_put($ftp_con, $ftp_file, $_file, FTP_BINARY);
}
}
}
fwrite($debugHandler, 'backup for ' . $row['loginname'] . ' finished...' . "\n");
}
// delete old backup data (deletes backup if customer or admin disables backup)
elseif ($row['backup_allowed'] == '0' || $row['backup_enabled'] == '0') {
$_ftpdir = makeCorrectDir($settings['system']['backup_dir'].'/'.$row['loginname'].'/');
if (file_exists($_ftpdir)){
$files = scandir($_ftpdir);
foreach ($files as $file) {
if (preg_match('/.*\.tar\.gz$/', $file)){
$_file = makeCorrectFile($_ftpdir.'/'.$file);
safe_exec('rm -f ' . escapeshellarg($_file));
}
}
}
}
}
fwrite($debugHandler, 'backup customers finished...' . "\n");
}