1
0
mirror of https://github.com/mailcow/mailcow-dockerized.git synced 2026-06-03 13:13:11 +00:00

Merge branch 'staging' into nightly

This commit is contained in:
DerLinkman
2026-01-19 12:17:11 +01:00
51 changed files with 2982 additions and 481 deletions
+10 -1
View File
@@ -129,7 +129,16 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
);
}
$mta_sts = mailbox('get', 'mta_sts', $domain);
// Check if domain is an alias domain and get target domain's MTA-STS
$alias_domain_details = mailbox('get', 'alias_domain_details', $domain);
$mta_sts_domain = $domain;
if ($alias_domain_details !== false && !empty($alias_domain_details['target_domain'])) {
// This is an alias domain, check target domain for MTA-STS
$mta_sts_domain = $alias_domain_details['target_domain'];
}
$mta_sts = mailbox('get', 'mta_sts', $mta_sts_domain);
if (count($mta_sts) > 0 && $mta_sts['active'] == 1) {
if (!in_array($domain, $alias_domains)) {
$records[] = array(
+26
View File
@@ -824,6 +824,32 @@ function verify_hash($hash, $password) {
$hash = $components[4];
return hash_equals(hash_pbkdf2('sha1', $password, $salt, $rounds), $hash);
case "PBKDF2-SHA512":
// Handle FreeIPA-style hash: {PBKDF2-SHA512}10000$<base64_salt>$<base64_hash>
$components = explode('$', $hash);
if (count($components) !== 3) return false;
// 1st part: iteration count (integer)
$iterations = intval($components[0]);
if ($iterations <= 0) return false;
// 2nd part: salt (base64-encoded)
$salt = $components[1];
// 3rd part: hash (base64-encoded)
$stored_hash_b64 = $components[2];
// Decode salt and hash from base64
$salt_bin = base64_decode($salt, true);
$hash_bin = base64_decode($stored_hash_b64, true);
if ($salt_bin === false || $hash_bin === false) return false;
// Get length of hash in bytes
$hash_len = strlen($hash_bin);
if ($hash_len === 0) return false;
// Calculate PBKDF2-SHA512 hash for provided password
$test_hash = hash_pbkdf2('sha512', $password, $salt_bin, $iterations, $hash_len, true);
return hash_equals($hash_bin, $test_hash);
case "PLAIN-MD4":
return hash_equals(hash('md4', $password), $hash);
+27 -10
View File
@@ -49,6 +49,12 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
// Default to 1 yr
$_data["validity"] = 8760;
}
if (isset($_data["permanent"]) && filter_var($_data["permanent"], FILTER_VALIDATE_BOOL)) {
$permanent = 1;
}
else {
$permanent = 0;
}
$domain = $_data['domain'];
$description = $_data['description'];
$valid_domains[] = mailbox('get', 'mailbox_details', $username)['domain'];
@@ -65,13 +71,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
return false;
}
$validity = strtotime("+" . $_data["validity"] . " hour");
$stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `description`, `goto`, `validity`) VALUES
(:address, :description, :goto, :validity)");
$stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `description`, `goto`, `validity`, `permanent`) VALUES
(:address, :description, :goto, :validity, :permanent)");
$stmt->execute(array(
':address' => readable_random_string(rand(rand(3, 9), rand(3, 9))) . '.' . readable_random_string(rand(rand(3, 9), rand(3, 9))) . '@' . $domain,
':description' => $description,
':goto' => $username,
':validity' => $validity
':validity' => $validity,
':permanent' => $permanent
));
$_SESSION['return'][] = array(
'type' => 'success',
@@ -2104,15 +2111,23 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
continue;
}
if (empty($_data['validity'])) {
if (empty($_data['validity']) && empty($_data['permanent'])) {
continue;
}
$validity = round((int)time() + ($_data['validity'] * 3600));
$stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = :validity WHERE
if (isset($_data['permanent']) && filter_var($_data['permanent'], FILTER_VALIDATE_BOOL)) {
$permanent = 1;
$validity = 0;
}
else if (isset($_data['validity'])) {
$permanent = 0;
$validity = round((int)time() + ($_data['validity'] * 3600));
}
$stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = :validity, `permanent` = :permanent WHERE
`address` = :address");
$stmt->execute(array(
':address' => $address,
':validity' => $validity
':validity' => $validity,
':permanent' => $permanent
));
$_SESSION['return'][] = array(
'type' => 'success',
@@ -4585,10 +4600,12 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
`description`,
`validity`,
`created`,
`modified`
`modified`,
`permanent`
FROM `spamalias`
WHERE `goto` = :username
AND `validity` >= :unixnow");
AND (`validity` >= :unixnow
OR `permanent` != 0)");
$stmt->execute(array(':username' => $_data, ':unixnow' => time()));
$tladata = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $tladata;
@@ -5163,7 +5180,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$stmt = $pdo->prepare("SELECT COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE (`kind` = '' OR `kind` = NULL) AND `domain` = :domain AND `username` != :username");
$stmt->execute(array(':domain' => $row['domain'], ':username' => $_data));
$MailboxUsage = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT IFNULL(COUNT(`address`), 0) AS `sa_count` FROM `spamalias` WHERE `goto` = :address AND `validity` >= :unixnow");
$stmt = $pdo->prepare("SELECT IFNULL(COUNT(`address`), 0) AS `sa_count` FROM `spamalias` WHERE `goto` = :address AND (`validity` >= :unixnow OR `permanent` != 0)");
$stmt->execute(array(':address' => $_data, ':unixnow' => time()));
$SpamaliasUsage = $stmt->fetch(PDO::FETCH_ASSOC);
$mailboxdata['max_new_quota'] = ($DomainQuota['quota'] * 1048576) - $MailboxUsage['in_use'];
+3 -2
View File
@@ -4,7 +4,7 @@ function init_db_schema()
try {
global $pdo;
$db_version = "15102025_1115";
$db_version = "10312025_0525";
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
@@ -554,7 +554,8 @@ function init_db_schema()
"description" => "TEXT NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"validity" => "INT(11)"
"validity" => "INT(11)",
"permanent" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
+2 -1
View File
@@ -85,7 +85,7 @@ $AVAILABLE_LANGUAGES = array(
// 'ca-es' => 'Català (Catalan)',
'bg-bg' => 'Български (Bulgarian)',
'cs-cz' => 'Čeština (Czech)',
'da-dk' => 'Danish (Dansk)',
'da-dk' => 'Dansk (Danish)',
'de-de' => 'Deutsch (German)',
'en-gb' => 'English',
'es-es' => 'Español (Spanish)',
@@ -110,6 +110,7 @@ $AVAILABLE_LANGUAGES = array(
'sv-se' => 'Svenska (Swedish)',
'tr-tr' => 'Türkçe (Turkish)',
'uk-ua' => 'Українська (Ukrainian)',
'vi-vn' => 'Tiếng Việt (Vietnamese)',
'zh-cn' => '简体中文 (Simplified Chinese)',
'zh-tw' => '繁體中文 (Traditional Chinese)',
);