functions.quarantaine.inc.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <?php
  2. function quarantaine($_action, $_data = null) {
  3. global $pdo;
  4. global $redis;
  5. global $lang;
  6. switch ($_action) {
  7. case 'delete':
  8. if (!is_array($_data['id'])) {
  9. $ids = array();
  10. $ids[] = $_data['id'];
  11. }
  12. else {
  13. $ids = $_data['id'];
  14. }
  15. if (!isset($_SESSION['acl']['quarantaine']) || $_SESSION['acl']['quarantaine'] != "1" ) {
  16. $_SESSION['return'] = array(
  17. 'type' => 'danger',
  18. 'msg' => sprintf($lang['danger']['access_denied'])
  19. );
  20. return false;
  21. }
  22. foreach ($ids as $id) {
  23. if (!is_numeric($id)) {
  24. $_SESSION['return'] = array(
  25. 'type' => 'danger',
  26. 'msg' => sprintf($lang['danger']['access_denied'])
  27. );
  28. return false;
  29. }
  30. try {
  31. $stmt = $pdo->prepare('SELECT `rcpt` FROM `quarantaine` WHERE `id` = :id');
  32. $stmt->execute(array(':id' => $id));
  33. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  34. if (hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['rcpt'])) {
  35. try {
  36. $stmt = $pdo->prepare("DELETE FROM `quarantaine` WHERE `id` = :id");
  37. $stmt->execute(array(
  38. ':id' => $id
  39. ));
  40. }
  41. catch (PDOException $e) {
  42. $_SESSION['return'] = array(
  43. 'type' => 'danger',
  44. 'msg' => 'MySQL: '.$e
  45. );
  46. return false;
  47. }
  48. }
  49. else {
  50. $_SESSION['return'] = array(
  51. 'type' => 'danger',
  52. 'msg' => sprintf($lang['danger']['access_denied'])
  53. );
  54. return false;
  55. }
  56. }
  57. catch(PDOException $e) {
  58. $_SESSION['return'] = array(
  59. 'type' => 'danger',
  60. 'msg' => 'MySQL: '.$e
  61. );
  62. }
  63. }
  64. $_SESSION['return'] = array(
  65. 'type' => 'success',
  66. 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', $ids))
  67. );
  68. break;
  69. case 'edit':
  70. if (!isset($_SESSION['acl']['quarantaine']) || $_SESSION['acl']['quarantaine'] != "1" ) {
  71. $_SESSION['return'] = array(
  72. 'type' => 'danger',
  73. 'msg' => sprintf($lang['danger']['access_denied'])
  74. );
  75. return false;
  76. }
  77. // Edit settings
  78. if ($_data['action'] == 'settings') {
  79. if ($_SESSION['mailcow_cc_role'] != "admin") {
  80. $_SESSION['return'] = array(
  81. 'type' => 'danger',
  82. 'msg' => sprintf($lang['danger']['access_denied'])
  83. );
  84. return false;
  85. }
  86. $retention_size = $_data['retention_size'];
  87. $max_size = $_data['max_size'];
  88. $exclude_domains = (array)$_data['exclude_domains'];
  89. try {
  90. $redis->Set('Q_RETENTION_SIZE', intval($retention_size));
  91. $redis->Set('Q_MAX_SIZE', intval($max_size));
  92. $redis->Set('Q_EXCLUDE_DOMAINS', json_encode($exclude_domains));
  93. }
  94. catch (RedisException $e) {
  95. $_SESSION['return'] = array(
  96. 'type' => 'danger',
  97. 'msg' => 'Redis: '.$e
  98. );
  99. return false;
  100. }
  101. $_SESSION['return'] = array(
  102. 'type' => 'success',
  103. 'msg' => 'Saved settings'
  104. );
  105. }
  106. // Release item
  107. elseif ($_data['action'] == 'release') {
  108. if (!is_array($_data['id'])) {
  109. $ids = array();
  110. $ids[] = $_data['id'];
  111. }
  112. else {
  113. $ids = $_data['id'];
  114. }
  115. foreach ($ids as $id) {
  116. if (!is_numeric($id)) {
  117. $_SESSION['return'] = array(
  118. 'type' => 'danger',
  119. 'msg' => sprintf($lang['danger']['access_denied'])
  120. );
  121. return false;
  122. }
  123. try {
  124. $stmt = $pdo->prepare('SELECT `msg`, `qid`, `sender`, `rcpt` FROM `quarantaine` WHERE `id` = :id');
  125. $stmt->execute(array(':id' => $id));
  126. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  127. if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['rcpt'])) {
  128. $_SESSION['return'] = array(
  129. 'type' => 'danger',
  130. 'msg' => sprintf($lang['danger']['access_denied'])
  131. );
  132. return false;
  133. }
  134. }
  135. catch(PDOException $e) {
  136. $_SESSION['return'] = array(
  137. 'type' => 'danger',
  138. 'msg' => 'MySQL: '.$e
  139. );
  140. }
  141. $sender = (isset($row['sender'])) ? $row['sender'] : 'sender-unknown@rspamd';
  142. try {
  143. $mail = new PHPMailer(true);
  144. $mail->isSMTP();
  145. $mail->SMTPDebug = 0;
  146. $mail->SMTPOptions = array(
  147. 'ssl' => array(
  148. 'verify_peer' => false,
  149. 'verify_peer_name' => false,
  150. 'allow_self_signed' => true
  151. )
  152. );
  153. if (!empty(gethostbynamel('postfix-mailcow'))) {
  154. $postfix = 'apostfix-mailcow';
  155. }
  156. if (!empty(gethostbynamel('postfix'))) {
  157. $postfix = 'postfix';
  158. }
  159. else {
  160. $_SESSION['return'] = array(
  161. 'type' => 'warning',
  162. 'msg' => sprintf($lang['danger']['release_send_failed'], 'Cannot determine Postfix host')
  163. );
  164. return false;
  165. }
  166. $mail->Host = $postfix;
  167. $mail->Port = 590;
  168. $mail->setFrom($sender);
  169. $mail->CharSet = 'UTF-8';
  170. $mail->Subject = sprintf($lang['quarantaine']['release_subject'], $row['qid']);
  171. $mail->addAddress($row['rcpt']);
  172. $mail->IsHTML(false);
  173. $msg_tmpf = tempnam("/tmp", $row['qid']);
  174. file_put_contents($msg_tmpf, $row['msg']);
  175. $mail->addAttachment($msg_tmpf, $row['qid'] . '.eml');
  176. $mail->Body = sprintf($lang['quarantaine']['release_body']);
  177. $mail->send();
  178. unlink($msg_tmpf);
  179. }
  180. catch (phpmailerException $e) {
  181. unlink($msg_tmpf);
  182. $_SESSION['return'] = array(
  183. 'type' => 'warning',
  184. 'msg' => sprintf($lang['danger']['release_send_failed'], $e->errorMessage())
  185. );
  186. return false;
  187. }
  188. try {
  189. $stmt = $pdo->prepare("DELETE FROM `quarantaine` WHERE `id` = :id");
  190. $stmt->execute(array(
  191. ':id' => $id
  192. ));
  193. }
  194. catch (PDOException $e) {
  195. $_SESSION['return'] = array(
  196. 'type' => 'danger',
  197. 'msg' => 'MySQL: '.$e
  198. );
  199. return false;
  200. }
  201. }
  202. $_SESSION['return'] = array(
  203. 'type' => 'success',
  204. 'msg' => $lang['success']['items_released']
  205. );
  206. }
  207. return true;
  208. break;
  209. case 'get':
  210. try {
  211. if ($_SESSION['mailcow_cc_role'] == "user") {
  212. $stmt = $pdo->prepare('SELECT `id`, `qid`, `rcpt`, `sender`, UNIX_TIMESTAMP(`created`) AS `created` FROM `quarantaine` WHERE `rcpt` = :mbox');
  213. $stmt->execute(array(':mbox' => $_SESSION['mailcow_cc_username']));
  214. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  215. while($row = array_shift($rows)) {
  216. $q_meta[] = $row;
  217. }
  218. }
  219. else {
  220. foreach (mailbox('get', 'mailboxes') as $mbox) {
  221. $stmt = $pdo->prepare('SELECT `id`, `qid`, `rcpt`, `sender`, UNIX_TIMESTAMP(`created`) AS `created` FROM `quarantaine` WHERE `rcpt` = :mbox');
  222. $stmt->execute(array(':mbox' => $mbox));
  223. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  224. while($row = array_shift($rows)) {
  225. $q_meta[] = $row;
  226. }
  227. }
  228. }
  229. }
  230. catch(PDOException $e) {
  231. $_SESSION['return'] = array(
  232. 'type' => 'danger',
  233. 'msg' => 'MySQL: '.$e
  234. );
  235. }
  236. return $q_meta;
  237. break;
  238. case 'settings':
  239. if ($_SESSION['mailcow_cc_role'] != "admin") {
  240. $_SESSION['return'] = array(
  241. 'type' => 'danger',
  242. 'msg' => sprintf($lang['danger']['access_denied'])
  243. );
  244. return false;
  245. }
  246. try {
  247. $settings['exclude_domains'] = json_decode($redis->Get('Q_EXCLUDE_DOMAINS'), true);
  248. $settings['max_size'] = $redis->Get('Q_MAX_SIZE');
  249. $settings['retention_size'] = $redis->Get('Q_RETENTION_SIZE');
  250. }
  251. catch (RedisException $e) {
  252. $_SESSION['return'] = array(
  253. 'type' => 'danger',
  254. 'msg' => 'Redis: '.$e
  255. );
  256. return false;
  257. }
  258. return $settings;
  259. break;
  260. case 'details':
  261. if (!is_numeric($_data) || empty($_data)) {
  262. return false;
  263. }
  264. try {
  265. $stmt = $pdo->prepare('SELECT `rcpt`, `symbols`, `msg`, `domain` FROM `quarantaine` WHERE `id`= :id');
  266. $stmt->execute(array(':id' => $_data));
  267. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  268. if (hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $row['rcpt'])) {
  269. return $row;
  270. }
  271. return false;
  272. }
  273. catch(PDOException $e) {
  274. $_SESSION['return'] = array(
  275. 'type' => 'danger',
  276. 'msg' => 'MySQL: '.$e
  277. );
  278. }
  279. return false;
  280. break;
  281. }
  282. }