| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1 | <?php
 | 
 | 2 | /*
 | 
 | 3 |    see /api
 | 
 | 4 | */
 | 
 | 5 | 
 | 
 | 6 | header('Content-Type: application/json');
 | 
 | 7 | require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
 | 
 | 8 | error_reporting(0);
 | 
 | 9 | 
 | 
 | 10 | function api_log($_data) {
 | 
 | 11 |   global $redis;
 | 
 | 12 |   $data_var = array();
 | 
 | 13 |   foreach ($_data as $data => &$value) {
 | 
 | 14 |     if ($data == 'csrf_token') {
 | 
 | 15 |       continue;
 | 
 | 16 |     }
 | 
 | 17 |     if ($value = json_decode($value, true)) {
 | 
 | 18 |       unset($value["csrf_token"]);
 | 
 | 19 |       foreach ($value as $key => &$val) {
 | 
 | 20 |         if(preg_match("/pass/i", $key)) {
 | 
 | 21 |           $val = '*';
 | 
 | 22 |         }
 | 
 | 23 |       }
 | 
 | 24 |       $value = json_encode($value);
 | 
 | 25 |     }
 | 
 | 26 |     $data_var[] = $data . "='" . $value . "'";
 | 
 | 27 |   }
 | 
 | 28 |   try {
 | 
 | 29 |     $log_line = array(
 | 
 | 30 |       'time' => time(),
 | 
 | 31 |       'uri' => $_SERVER['REQUEST_URI'],
 | 
 | 32 |       'method' => $_SERVER['REQUEST_METHOD'],
 | 
 | 33 |       'remote' => get_remote_ip(),
 | 
 | 34 |       'data' => implode(', ', $data_var)
 | 
 | 35 |     );
 | 
 | 36 |     $redis->lPush('API_LOG', json_encode($log_line));
 | 
 | 37 |   }
 | 
 | 38 |   catch (RedisException $e) {
 | 
 | 39 |     $_SESSION['return'][] = array(
 | 
 | 40 |       'type' => 'danger',
 | 
 | 41 |       'msg' => 'Redis: '.$e
 | 
 | 42 |     );
 | 
 | 43 |     return false;
 | 
 | 44 |   }
 | 
 | 45 | }
 | 
 | 46 | 
 | 
 | 47 | if (isset($_GET['query'])) {
 | 
 | 48 | 
 | 
 | 49 |   $query = explode('/', $_GET['query']);
 | 
 | 50 |   $action =     (isset($query[0])) ? $query[0] : null;
 | 
 | 51 |   $category =   (isset($query[1])) ? $query[1] : null;
 | 
 | 52 |   $object =     (isset($query[2])) ? $query[2] : null;
 | 
 | 53 |   $extra =      (isset($query[3])) ? $query[3] : null;
 | 
 | 54 | 
 | 
 | 55 |   // accept json in request body
 | 
 | 56 |   if(strpos($_SERVER['HTTP_CONTENT_TYPE'], 'application/json') !== false) {
 | 
 | 57 |     $request = file_get_contents('php://input');
 | 
 | 58 |     $requestDecoded = json_decode($request, true);
 | 
 | 59 | 
 | 
 | 60 |     // check for valid json
 | 
 | 61 |     if ($action != 'get' && $requestDecoded === null) {
 | 
 | 62 |       http_response_code(400);
 | 
 | 63 |       echo json_encode(array(
 | 
 | 64 |           'type' => 'error',
 | 
 | 65 |           'msg' => 'Request body doesn\'t contain valid json!'
 | 
 | 66 |       ));
 | 
 | 67 |       exit;
 | 
 | 68 |     }
 | 
 | 69 | 
 | 
 | 70 |     // add
 | 
 | 71 |     if ($action == 'add') {
 | 
 | 72 |       $_POST['attr'] = $request;
 | 
 | 73 |     }
 | 
 | 74 | 
 | 
 | 75 |     // edit
 | 
 | 76 |     if ($action == 'edit') {
 | 
 | 77 |       $_POST['attr']  = json_encode($requestDecoded['attr']);
 | 
 | 78 |       $_POST['items'] = json_encode($requestDecoded['items']);
 | 
 | 79 |     }
 | 
 | 80 | 
 | 
 | 81 |     // delete
 | 
 | 82 |     if ($action == 'delete') {
 | 
 | 83 |       $_POST['items'] = $request;
 | 
 | 84 |     }
 | 
 | 85 | 
 | 
 | 86 |   }
 | 
 | 87 |   api_log($_POST);
 | 
 | 88 | 
 | 
 | 89 |   $request_incomplete = json_encode(array(
 | 
 | 90 |     'type' => 'error',
 | 
 | 91 |     'msg' => 'Cannot find attributes in post data'
 | 
 | 92 |   ));
 | 
 | 93 | 
 | 
 | 94 |   switch ($action) {
 | 
 | 95 |     case "add":
 | 
 | 96 |       if ($_SESSION['mailcow_cc_api_access'] == 'ro' || isset($_SESSION['pending_mailcow_cc_username'])) {
 | 
 | 97 |         http_response_code(403);
 | 
 | 98 |         echo json_encode(array(
 | 
 | 99 |             'type' => 'error',
 | 
 | 100 |             'msg' => 'API read/write access denied'
 | 
 | 101 |         ));
 | 
 | 102 |         exit();
 | 
 | 103 |       }
 | 
 | 104 |       function process_add_return($return) {
 | 
 | 105 |         $generic_failure = json_encode(array(
 | 
 | 106 |           'type' => 'error',
 | 
 | 107 |           'msg' => 'Cannot add item'
 | 
 | 108 |         ));
 | 
 | 109 |         $generic_success = json_encode(array(
 | 
 | 110 |           'type' => 'success',
 | 
 | 111 |           'msg' => 'Task completed'
 | 
 | 112 |         ));
 | 
 | 113 |         if ($return === false) {
 | 
 | 114 |           echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_failure;
 | 
 | 115 |         }
 | 
 | 116 |         else {
 | 
 | 117 |           echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_success;
 | 
 | 118 |         }
 | 
 | 119 |       }
 | 
 | 120 |       if (!isset($_POST['attr']) && $category != "fido2-registration") {
 | 
 | 121 |         echo $request_incomplete;
 | 
 | 122 |         exit;
 | 
 | 123 |       }
 | 
 | 124 |       else {
 | 
 | 125 |         if ($category != "fido2-registration") {
 | 
 | 126 |           $attr = (array)json_decode($_POST['attr'], true);
 | 
 | 127 |         }
 | 
 | 128 |         unset($attr['csrf_token']);
 | 
 | 129 |       }
 | 
 | 130 |       // only allow POST requests to POST API endpoints
 | 
 | 131 |       if ($_SERVER['REQUEST_METHOD'] != 'POST') {
 | 
 | 132 |         http_response_code(405);
 | 
 | 133 |         echo json_encode(array(
 | 
 | 134 |             'type' => 'error',
 | 
 | 135 |             'msg' => 'only POST method is allowed'
 | 
 | 136 |         ));
 | 
 | 137 |         exit();
 | 
 | 138 |       }
 | 
 | 139 | 
 | 
 | 140 |       switch ($category) {
 | 
 | 141 |         // fido2-registration via POST
 | 
 | 142 |         case "fido2-registration":
 | 
 | 143 |           header('Content-Type: application/json');
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 144 |           if (isset($_SESSION["mailcow_cc_role"])) {
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 145 |             $post = trim(file_get_contents('php://input'));
 | 
 | 146 |             if ($post) {
 | 
 | 147 |               $post = json_decode($post);
 | 
 | 148 |             }
 | 
 | 149 |             $clientDataJSON = base64_decode($post->clientDataJSON);
 | 
 | 150 |             $attestationObject = base64_decode($post->attestationObject);
 | 
 | 151 |             $challenge = $_SESSION['challenge'];
 | 
 | 152 |             try {
 | 
 | 153 |               $data = $WebAuthn->processCreate($clientDataJSON, $attestationObject, $challenge, $GLOBALS['FIDO2_UV_FLAG_REGISTER'], $GLOBALS['FIDO2_USER_PRESENT_FLAG']);
 | 
 | 154 |             }
 | 
 | 155 |             catch (Throwable $ex) {
 | 
 | 156 |               $return = new stdClass();
 | 
 | 157 |               $return->success = false;
 | 
 | 158 |               $return->msg = $ex->getMessage();
 | 
 | 159 |               echo json_encode($return);
 | 
 | 160 |               exit;
 | 
 | 161 |             }
 | 
 | 162 |             fido2(array("action" => "register", "registration" => $data));
 | 
 | 163 |             $return = new stdClass();
 | 
 | 164 |             $return->success = true;
 | 
 | 165 |             echo json_encode($return);
 | 
 | 166 |             exit;
 | 
 | 167 |           }
 | 
 | 168 |           else {
 | 
 | 169 |             echo $request_incomplete;
 | 
 | 170 |             exit;
 | 
 | 171 |           }
 | 
 | 172 |         break;
 | 
 | 173 |         case "time_limited_alias":
 | 
 | 174 |           process_add_return(mailbox('add', 'time_limited_alias', $attr));
 | 
 | 175 |         break;
 | 
 | 176 |         case "relayhost":
 | 
 | 177 |           process_add_return(relayhost('add', $attr));
 | 
 | 178 |         break;
 | 
 | 179 |         case "transport":
 | 
 | 180 |           process_add_return(transport('add', $attr));
 | 
 | 181 |         break;
 | 
 | 182 |         case "rsetting":
 | 
 | 183 |           process_add_return(rsettings('add', $attr));
 | 
 | 184 |         break;
 | 
 | 185 |         case "mailbox":
 | 
 | 186 |           process_add_return(mailbox('add', 'mailbox', $attr));
 | 
 | 187 |         break;
 | 
 | 188 |         case "oauth2-client":
 | 
 | 189 |           process_add_return(oauth2('add', 'client', $attr));
 | 
 | 190 |         break;
 | 
 | 191 |         case "domain":
 | 
 | 192 |           process_add_return(mailbox('add', 'domain', $attr));
 | 
 | 193 |         break;
 | 
 | 194 |         case "resource":
 | 
 | 195 |           process_add_return(mailbox('add', 'resource', $attr));
 | 
 | 196 |         break;
 | 
 | 197 |         case "alias":
 | 
 | 198 |           process_add_return(mailbox('add', 'alias', $attr));
 | 
 | 199 |         break;
 | 
 | 200 |         case "filter":
 | 
 | 201 |           process_add_return(mailbox('add', 'filter', $attr));
 | 
 | 202 |         break;
 | 
 | 203 |         case "global-filter":
 | 
 | 204 |           process_add_return(mailbox('add', 'global_filter', $attr));
 | 
 | 205 |         break;
 | 
 | 206 |         case "domain-policy":
 | 
 | 207 |           process_add_return(policy('add', 'domain', $attr));
 | 
 | 208 |         break;
 | 
 | 209 |         case "mailbox-policy":
 | 
 | 210 |           process_add_return(policy('add', 'mailbox', $attr));
 | 
 | 211 |         break;
 | 
 | 212 |         case "alias-domain":
 | 
 | 213 |           process_add_return(mailbox('add', 'alias_domain', $attr));
 | 
 | 214 |         break;
 | 
 | 215 |         case "fwdhost":
 | 
 | 216 |           process_add_return(fwdhost('add', $attr));
 | 
 | 217 |         break;
 | 
 | 218 |         case "dkim":
 | 
 | 219 |           process_add_return(dkim('add', $attr));
 | 
 | 220 |         break;
 | 
 | 221 |         case "dkim_duplicate":
 | 
 | 222 |           process_add_return(dkim('duplicate', $attr));
 | 
 | 223 |         break;
 | 
 | 224 |         case "dkim_import":
 | 
 | 225 |           process_add_return(dkim('import', $attr));
 | 
 | 226 |         break;
 | 
 | 227 |         case "domain-admin":
 | 
 | 228 |           process_add_return(domain_admin('add', $attr));
 | 
 | 229 |         break;
 | 
 | 230 |         case "admin":
 | 
 | 231 |           process_add_return(admin('add', $attr));
 | 
 | 232 |         break;
 | 
 | 233 |         case "syncjob":
 | 
 | 234 |           process_add_return(mailbox('add', 'syncjob', $attr));
 | 
 | 235 |         break;
 | 
 | 236 |         case "bcc":
 | 
 | 237 |           process_add_return(bcc('add', $attr));
 | 
 | 238 |         break;
 | 
 | 239 |         case "recipient_map":
 | 
 | 240 |           process_add_return(recipient_map('add', $attr));
 | 
 | 241 |         break;
 | 
 | 242 |         case "tls-policy-map":
 | 
 | 243 |           process_add_return(tls_policy_maps('add', $attr));
 | 
 | 244 |         break;
 | 
 | 245 |         case "app-passwd":
 | 
 | 246 |           process_add_return(app_passwd('add', $attr));
 | 
 | 247 |         break;
 | 
 | 248 |         // return no route found if no case is matched
 | 
 | 249 |         default:
 | 
 | 250 |           http_response_code(404);
 | 
 | 251 |           echo json_encode(array(
 | 
 | 252 |             'type' => 'error',
 | 
 | 253 |             'msg' => 'route not found'
 | 
 | 254 |           ));
 | 
 | 255 |           exit();
 | 
 | 256 |       }
 | 
 | 257 |     break;
 | 
 | 258 |     case "process":
 | 
 | 259 |       // only allow POST requests to process API endpoints
 | 
 | 260 |       if ($_SERVER['REQUEST_METHOD'] != 'POST') {
 | 
 | 261 |         http_response_code(405);
 | 
 | 262 |         echo json_encode(array(
 | 
 | 263 |             'type' => 'error',
 | 
 | 264 |             'msg' => 'only POST method is allowed'
 | 
 | 265 |         ));
 | 
 | 266 |         exit();
 | 
 | 267 |       }
 | 
 | 268 |       switch ($category) {
 | 
 | 269 |         case "fido2-args":
 | 
 | 270 |           header('Content-Type: application/json');
 | 
 | 271 |           $post = trim(file_get_contents('php://input'));
 | 
 | 272 |           if ($post) {
 | 
 | 273 |             $post = json_decode($post);
 | 
 | 274 |           }
 | 
 | 275 |           $clientDataJSON = base64_decode($post->clientDataJSON);
 | 
 | 276 |           $authenticatorData = base64_decode($post->authenticatorData);
 | 
 | 277 |           $signature = base64_decode($post->signature);
 | 
 | 278 |           $id = base64_decode($post->id);
 | 
 | 279 |           $challenge = $_SESSION['challenge'];
 | 
 | 280 |           $process_fido2 = fido2(array("action" => "get_by_b64cid", "cid" => $post->id));
 | 
 | 281 |           if ($process_fido2['pub_key'] === false) {
 | 
 | 282 |             $return = new stdClass();
 | 
 | 283 |             $return->success = false;
 | 
 | 284 |             echo json_encode($return);
 | 
 | 285 |             exit;
 | 
 | 286 |           }
 | 
 | 287 |           try {
 | 
 | 288 |             $WebAuthn->processGet($clientDataJSON, $authenticatorData, $signature, $process_fido2['pub_key'], $challenge, null, $GLOBALS['FIDO2_UV_FLAG_LOGIN'], $GLOBALS['FIDO2_USER_PRESENT_FLAG']);
 | 
 | 289 |           }
 | 
 | 290 |           catch (Throwable $ex) {
 | 
 | 291 |             unset($process_fido2);
 | 
 | 292 |             $return = new stdClass();
 | 
 | 293 |             $return->success = false;
 | 
 | 294 |             echo json_encode($return);
 | 
 | 295 |             exit;
 | 
 | 296 |           }
 | 
 | 297 |           $return = new stdClass();
 | 
 | 298 |           $return->success = true;
 | 
 | 299 |           $stmt = $pdo->prepare("SELECT `superadmin` FROM `admin` WHERE `username` = :username");
 | 
 | 300 |           $stmt->execute(array(':username' => $process_fido2['username']));
 | 
 | 301 |           $obj_props = $stmt->fetch(PDO::FETCH_ASSOC);
 | 
 | 302 |           if ($obj_props['superadmin'] === 1) {
 | 
 | 303 |             $_SESSION["mailcow_cc_role"] = "admin";
 | 
 | 304 |           }
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 305 |           elseif ($obj_props['superadmin'] === 0) {
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 306 |             $_SESSION["mailcow_cc_role"] = "domainadmin";
 | 
 | 307 |           }
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 308 |           else {
 | 
 | 309 |             $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :username");
 | 
 | 310 |             $stmt->execute(array(':username' => $process_fido2['username']));
 | 
 | 311 |             $row = $stmt->fetch(PDO::FETCH_ASSOC);
 | 
 | 312 |             if ($row['username'] == $process_fido2['username']) {
 | 
 | 313 |               $_SESSION["mailcow_cc_role"] = "user";
 | 
 | 314 |             }
 | 
 | 315 |           }
 | 
 | 316 |           if (empty($_SESSION["mailcow_cc_role"])) {
 | 
 | 317 |             session_unset();
 | 
 | 318 |             session_destroy();
 | 
 | 319 |             exit;
 | 
 | 320 |           }
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 321 |           $_SESSION["mailcow_cc_username"] = $process_fido2['username'];
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 322 |           $_SESSION["fido2_cid"] = $process_fido2['cid'];
 | 
 | 323 |           unset($_SESSION["challenge"]);
 | 
 | 324 |           $_SESSION['return'][] =  array(
 | 
 | 325 |             'type' => 'success',
 | 
 | 326 |             'log' => array("fido2_login"),
 | 
 | 327 |             'msg' => array('logged_in_as', $process_fido2['username'])
 | 
 | 328 |           );
 | 
 | 329 |           echo json_encode($return);
 | 
 | 330 |         break;
 | 
 | 331 |       }
 | 
 | 332 |     break;
 | 
 | 333 |     case "get":
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 334 |       function process_get_return($data, $object = true) {
 | 
 | 335 |         if ($object === true) {
 | 
 | 336 |           $ret_str = '{}';
 | 
 | 337 |         }
 | 
 | 338 |         else {
 | 
 | 339 |           $ret_str = '[]';
 | 
 | 340 |         }
 | 
 | 341 |         echo (!isset($data) || empty($data)) ? $ret_str : json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 342 |       }
 | 
 | 343 |       // only allow GET requests to GET API endpoints
 | 
 | 344 |       if ($_SERVER['REQUEST_METHOD'] != 'GET') {
 | 
 | 345 |         http_response_code(405);
 | 
 | 346 |         echo json_encode(array(
 | 
 | 347 |             'type' => 'error',
 | 
 | 348 |             'msg' => 'only GET method is allowed'
 | 
 | 349 |         ));
 | 
 | 350 |         exit();
 | 
 | 351 |       }
 | 
 | 352 |       switch ($category) {
 | 
 | 353 |         case "u2f-registration":
 | 
 | 354 |           header('Content-Type: application/javascript');
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 355 |           if (isset($_SESSION["mailcow_cc_role"]) && $_SESSION["mailcow_cc_username"] == $object) {
 | 
 | 356 |             list($req, $sigs) = $u2f->getRegisterData(get_u2f_registrations($object));
 | 
 | 357 |             $_SESSION['regReq'] = json_encode($req);
 | 
 | 358 |             $_SESSION['regSigs'] = json_encode($sigs);
 | 
 | 359 |             echo 'var req = ' . json_encode($req) . ';';
 | 
 | 360 |             echo 'var registeredKeys = ' . json_encode($sigs) . ';';
 | 
 | 361 |             echo 'var appId = req.appId;';
 | 
 | 362 |             echo 'var registerRequests = [{version: req.version, challenge: req.challenge}];';
 | 
 | 363 |             return;
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 364 |           }
 | 
 | 365 |           else {
 | 
 | 366 |             return;
 | 
 | 367 |           }
 | 
 | 368 |         break;
 | 
 | 369 |         // fido2-registration via GET
 | 
 | 370 |         case "fido2-registration":
 | 
 | 371 |           header('Content-Type: application/json');
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 372 |           if (isset($_SESSION["mailcow_cc_role"])) {
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 373 |               // Exclude existing CredentialIds, if any
 | 
 | 374 |               $excludeCredentialIds = fido2(array("action" => "get_user_cids"));
 | 
 | 375 |               $createArgs = $WebAuthn->getCreateArgs($_SESSION["mailcow_cc_username"], $_SESSION["mailcow_cc_username"], $_SESSION["mailcow_cc_username"], 30, true, $GLOBALS['FIDO2_UV_FLAG_REGISTER'], $excludeCredentialIds);
 | 
 | 376 |               print(json_encode($createArgs));
 | 
 | 377 |               $_SESSION['challenge'] = $WebAuthn->getChallenge();
 | 
 | 378 |               return;
 | 
 | 379 |           }
 | 
 | 380 |           else {
 | 
 | 381 |             return;
 | 
 | 382 |           }
 | 
 | 383 |         break;
 | 
 | 384 |         case "u2f-authentication":
 | 
 | 385 |           header('Content-Type: application/javascript');
 | 
 | 386 |           if (isset($_SESSION['pending_mailcow_cc_username']) && $_SESSION['pending_mailcow_cc_username'] == $object) {
 | 
 | 387 |             $auth_data = $u2f->getAuthenticateData(get_u2f_registrations($object));
 | 
 | 388 |             $challenge = $auth_data[0]->challenge;
 | 
 | 389 |             $appId = $auth_data[0]->appId;
 | 
 | 390 |             foreach ($auth_data as $each) {
 | 
 | 391 |               $key = array(); // Empty array
 | 
 | 392 |               $key['version']   = $each->version;
 | 
 | 393 |               $key['keyHandle'] = $each->keyHandle;
 | 
 | 394 |               $registeredKey[]  = $key;
 | 
 | 395 |             }
 | 
 | 396 |             $_SESSION['authReq']  = json_encode($auth_data);
 | 
 | 397 |             echo 'var appId = "' . $appId . '";';
 | 
 | 398 |             echo 'var challenge = ' . json_encode($challenge) . ';';
 | 
 | 399 |             echo 'var registeredKeys = ' . json_encode($registeredKey) . ';';
 | 
 | 400 |             return;
 | 
 | 401 |           }
 | 
 | 402 |           else {
 | 
 | 403 |             return;
 | 
 | 404 |           }
 | 
 | 405 |         break;
 | 
 | 406 |         case "fido2-get-args":
 | 
 | 407 |           header('Content-Type: application/json');
 | 
 | 408 |           // Login without username, no ids!
 | 
 | 409 |           // $ids = fido2(array("action" => "get_all_cids"));
 | 
 | 410 |           // if (count($ids) == 0) {
 | 
 | 411 |             // return;
 | 
 | 412 |           // }
 | 
 | 413 |           $ids = NULL;
 | 
 | 414 |           $getArgs = $WebAuthn->getGetArgs($ids, 30, true, true, true, true, $GLOBALS['FIDO2_UV_FLAG_LOGIN']);
 | 
 | 415 |           print(json_encode($getArgs));
 | 
 | 416 |           $_SESSION['challenge'] = $WebAuthn->getChallenge();
 | 
 | 417 |           return;
 | 
 | 418 |         break;
 | 
 | 419 |       }
 | 
 | 420 |       if (isset($_SESSION['mailcow_cc_role'])) {
 | 
 | 421 |         switch ($category) {
 | 
 | 422 |           case "rspamd":
 | 
 | 423 |             switch ($object) {
 | 
 | 424 |               case "actions":
 | 
 | 425 |                 $data = rspamd_actions();
 | 
 | 426 |                 if ($data) {
 | 
 | 427 |                   echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
 | 
 | 428 |                 }
 | 
 | 429 |                 else {
 | 
 | 430 |                   echo '{}';
 | 
 | 431 |                 }
 | 
 | 432 |               break;
 | 
 | 433 |             }
 | 
 | 434 |           break;
 | 
 | 435 | 
 | 
 | 436 |           case "domain":
 | 
 | 437 |             switch ($object) {
 | 
 | 438 |               case "all":
 | 
 | 439 |                 $domains = mailbox('get', 'domains');
 | 
 | 440 |                 if (!empty($domains)) {
 | 
 | 441 |                   foreach ($domains as $domain) {
 | 
 | 442 |                     if ($details = mailbox('get', 'domain_details', $domain)) {
 | 
 | 443 |                       $data[] = $details;
 | 
 | 444 |                     }
 | 
 | 445 |                     else {
 | 
 | 446 |                       continue;
 | 
 | 447 |                     }
 | 
 | 448 |                   }
 | 
 | 449 |                   process_get_return($data);
 | 
 | 450 |                 }
 | 
 | 451 |                 else {
 | 
 | 452 |                   echo '{}';
 | 
 | 453 |                 }
 | 
 | 454 |               break;
 | 
 | 455 | 
 | 
 | 456 |               default:
 | 
 | 457 |                 $data = mailbox('get', 'domain_details', $object);
 | 
 | 458 |                 process_get_return($data);
 | 
 | 459 |               break;
 | 
 | 460 |             }
 | 
 | 461 |           break;
 | 
 | 462 | 
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 463 |           case "passwordpolicy":
 | 
 | 464 |             switch ($object) {
 | 
 | 465 |               case "html":
 | 
 | 466 |                 $password_complexity_rules = password_complexity('html');
 | 
 | 467 |                 if ($password_complexity_rules !== false) {
 | 
 | 468 |                   process_get_return($password_complexity_rules);
 | 
 | 469 |                 }
 | 
 | 470 |                 else {
 | 
 | 471 |                   echo '{}';
 | 
 | 472 |                 }
 | 
 | 473 |               break;
 | 
 | 474 |             }
 | 
 | 475 |           break;
 | 
 | 476 | 
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 477 |           case "app-passwd":
 | 
 | 478 |             switch ($object) {
 | 
 | 479 |               case "all":
 | 
 | 480 |                 if (empty($extra)) {
 | 
 | 481 |                   $app_passwds = app_passwd('get');
 | 
 | 482 |                 }
 | 
 | 483 |                 else {
 | 
 | 484 |                   $app_passwds = app_passwd('get', array('username' => $extra));
 | 
 | 485 |                 }
 | 
 | 486 |                 if (!empty($app_passwds)) {
 | 
 | 487 |                   foreach ($app_passwds as $app_passwd) {
 | 
 | 488 |                     $details = app_passwd('details', array('id' => $app_passwd['id']));
 | 
 | 489 |                     if ($details !== false) {
 | 
 | 490 |                       $data[] = $details;
 | 
 | 491 |                     }
 | 
 | 492 |                     else {
 | 
 | 493 |                       continue;
 | 
 | 494 |                     }
 | 
 | 495 |                   }
 | 
 | 496 |                   process_get_return($data);
 | 
 | 497 |                 }
 | 
 | 498 |                 else {
 | 
 | 499 |                   echo '{}';
 | 
 | 500 |                 }
 | 
 | 501 |               break;
 | 
 | 502 | 
 | 
 | 503 |               default:
 | 
 | 504 |                 $data = app_passwd('details', array('id' => $object['id']));
 | 
 | 505 |                 process_get_return($data);
 | 
 | 506 |               break;
 | 
 | 507 |             }
 | 
 | 508 |           break;
 | 
 | 509 | 
 | 
 | 510 |           case "mailq":
 | 
 | 511 |             switch ($object) {
 | 
 | 512 |               case "all":
 | 
 | 513 |                 $mailq = mailq('get');
 | 
 | 514 |                 if (!empty($mailq)) {
 | 
 | 515 |                   echo $mailq;
 | 
 | 516 |                 }
 | 
 | 517 |                 else {
 | 
 | 518 |                   echo '[]';
 | 
 | 519 |                 }
 | 
 | 520 |               break;
 | 
 | 521 |             }
 | 
 | 522 |           break;
 | 
 | 523 |           
 | 
 | 524 |           case "postcat":
 | 
 | 525 |             switch ($object) {
 | 
 | 526 |               default:
 | 
 | 527 |                 $data = mailq('cat', array('qid' => $object));
 | 
 | 528 |                 echo $data;
 | 
 | 529 |               break;
 | 
 | 530 |             }
 | 
 | 531 |           break;
 | 
 | 532 | 
 | 
 | 533 |           case "global_filters":
 | 
 | 534 |             $global_filters = mailbox('get', 'global_filter_details');
 | 
 | 535 |             switch ($object) {
 | 
 | 536 |               case "all":
 | 
 | 537 |                 if (!empty($global_filters)) {
 | 
 | 538 |                   process_get_return($global_filters);
 | 
 | 539 |                 }
 | 
 | 540 |                 else {
 | 
 | 541 |                   echo '{}';
 | 
 | 542 |                 }
 | 
 | 543 |               break;
 | 
 | 544 |               case "prefilter":
 | 
 | 545 |                 if (!empty($global_filters['prefilter'])) {
 | 
 | 546 |                   process_get_return($global_filters['prefilter']);
 | 
 | 547 |                 }
 | 
 | 548 |                 else {
 | 
 | 549 |                   echo '{}';
 | 
 | 550 |                 }
 | 
 | 551 |               break;
 | 
 | 552 |               case "postfilter":
 | 
 | 553 |                 if (!empty($global_filters['postfilter'])) {
 | 
 | 554 |                   process_get_return($global_filters['postfilter']);
 | 
 | 555 |                 }
 | 
 | 556 |                 else {
 | 
 | 557 |                   echo '{}';
 | 
 | 558 |                 }
 | 
 | 559 |               break;
 | 
 | 560 |             }
 | 
 | 561 |           break;
 | 
 | 562 | 
 | 
 | 563 |           case "rl-domain":
 | 
 | 564 |             switch ($object) {
 | 
 | 565 |               case "all":
 | 
 | 566 |                 $domains = array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains'));
 | 
 | 567 |                 if (!empty($domains)) {
 | 
 | 568 |                   foreach ($domains as $domain) {
 | 
 | 569 |                     if ($details = ratelimit('get', 'domain', $domain)) {
 | 
 | 570 |                       $details['domain'] = $domain;
 | 
 | 571 |                       $data[] = $details;
 | 
 | 572 |                     }
 | 
 | 573 |                     else {
 | 
 | 574 |                       continue;
 | 
 | 575 |                     }
 | 
 | 576 |                   }
 | 
 | 577 |                   process_get_return($data);
 | 
 | 578 |                 }
 | 
 | 579 |                 else {
 | 
 | 580 |                   echo '{}';
 | 
 | 581 |                 }
 | 
 | 582 |               break;
 | 
 | 583 | 
 | 
 | 584 |               default:
 | 
 | 585 |                 $data = ratelimit('get', 'domain', $object);
 | 
 | 586 |                 process_get_return($data);
 | 
 | 587 |               break;
 | 
 | 588 |             }
 | 
 | 589 |           break;
 | 
 | 590 | 
 | 
 | 591 |           case "rl-mbox":
 | 
 | 592 |             switch ($object) {
 | 
 | 593 |               case "all":
 | 
 | 594 |                 $domains = mailbox('get', 'domains');
 | 
 | 595 |                 if (!empty($domains)) {
 | 
 | 596 |                   foreach ($domains as $domain) {
 | 
 | 597 |                     $mailboxes = mailbox('get', 'mailboxes', $domain);
 | 
 | 598 |                     if (!empty($mailboxes)) {
 | 
 | 599 |                       foreach ($mailboxes as $mailbox) {
 | 
 | 600 |                         if ($details = ratelimit('get', 'mailbox', $mailbox)) {
 | 
 | 601 |                           $details['mailbox'] = $mailbox;
 | 
 | 602 |                           $data[] = $details;
 | 
 | 603 |                         }
 | 
 | 604 |                         else {
 | 
 | 605 |                           continue;
 | 
 | 606 |                         }
 | 
 | 607 |                       }
 | 
 | 608 |                     }
 | 
 | 609 |                   }
 | 
 | 610 |                   process_get_return($data);
 | 
 | 611 |                 }
 | 
 | 612 |                 else {
 | 
 | 613 |                   echo '{}';
 | 
 | 614 |                 }
 | 
 | 615 |               break;
 | 
 | 616 | 
 | 
 | 617 |               default:
 | 
 | 618 |                 $data = ratelimit('get', 'mailbox', $object);
 | 
 | 619 |                 process_get_return($data);
 | 
 | 620 |               break;
 | 
 | 621 |             }
 | 
 | 622 |           break;
 | 
 | 623 | 
 | 
 | 624 |           case "relayhost":
 | 
 | 625 |             switch ($object) {
 | 
 | 626 |               case "all":
 | 
 | 627 |                 $relayhosts = relayhost('get');
 | 
 | 628 |                 if (!empty($relayhosts)) {
 | 
 | 629 |                   foreach ($relayhosts as $relayhost) {
 | 
 | 630 |                     if ($details = relayhost('details', $relayhost['id'])) {
 | 
 | 631 |                       $data[] = $details;
 | 
 | 632 |                     }
 | 
 | 633 |                     else {
 | 
 | 634 |                       continue;
 | 
 | 635 |                     }
 | 
 | 636 |                   }
 | 
 | 637 |                   process_get_return($data);
 | 
 | 638 |                 }
 | 
 | 639 |                 else {
 | 
 | 640 |                   echo '{}';
 | 
 | 641 |                 }
 | 
 | 642 |               break;
 | 
 | 643 | 
 | 
 | 644 |               default:
 | 
 | 645 |                 $data = relayhost('details', $object);
 | 
 | 646 |                 process_get_return($data);
 | 
 | 647 |               break;
 | 
 | 648 |             }
 | 
 | 649 |           break;
 | 
 | 650 | 
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 651 |           case "last-login":
 | 
 | 652 |             if ($object) {
 | 
 | 653 |               // extra == days
 | 
 | 654 |               if (isset($extra) && intval($extra) >= 1) {
 | 
 | 655 |                 $data = last_login('get', $object, intval($extra));
 | 
 | 656 |               }
 | 
 | 657 |               else {
 | 
 | 658 |                 $data = last_login('get', $object);
 | 
 | 659 |               }
 | 
 | 660 |               process_get_return($data);
 | 
 | 661 |             }
 | 
 | 662 |           break;
 | 
 | 663 | 
 | 
 | 664 |           // Todo: move to delete
 | 
 | 665 |           case "reset-last-login":
 | 
 | 666 |             if ($object) {
 | 
 | 667 |               $data = last_login('reset', $object);
 | 
 | 668 |               process_get_return($data);
 | 
 | 669 |             }
 | 
 | 670 |           break;
 | 
 | 671 | 
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 672 |           case "transport":
 | 
 | 673 |             switch ($object) {
 | 
 | 674 |               case "all":
 | 
 | 675 |                 $transports = transport('get');
 | 
 | 676 |                 if (!empty($transports)) {
 | 
 | 677 |                   foreach ($transports as $transport) {
 | 
 | 678 |                     if ($details = transport('details', $transport['id'])) {
 | 
 | 679 |                       $data[] = $details;
 | 
 | 680 |                     }
 | 
 | 681 |                     else {
 | 
 | 682 |                       continue;
 | 
 | 683 |                     }
 | 
 | 684 |                   }
 | 
 | 685 |                   process_get_return($data);
 | 
 | 686 |                 }
 | 
 | 687 |                 else {
 | 
 | 688 |                   echo '{}';
 | 
 | 689 |                 }
 | 
 | 690 |               break;
 | 
 | 691 | 
 | 
 | 692 |               default:
 | 
 | 693 |                 $data = transport('details', $object);
 | 
 | 694 |                 process_get_return($data);
 | 
 | 695 |               break;
 | 
 | 696 |             }
 | 
 | 697 |           break;
 | 
 | 698 | 
 | 
 | 699 |           case "rsetting":
 | 
 | 700 |             switch ($object) {
 | 
 | 701 |               case "all":
 | 
 | 702 |                 $rsettings = rsettings('get');
 | 
 | 703 |                 if (!empty($rsettings)) {
 | 
 | 704 |                   foreach ($rsettings as $rsetting) {
 | 
 | 705 |                     if ($details = rsettings('details', $rsetting['id'])) {
 | 
 | 706 |                       $data[] = $details;
 | 
 | 707 |                     }
 | 
 | 708 |                     else {
 | 
 | 709 |                       continue;
 | 
 | 710 |                     }
 | 
 | 711 |                   }
 | 
 | 712 |                   process_get_return($data);
 | 
 | 713 |                 }
 | 
 | 714 |                 else {
 | 
 | 715 |                   echo '{}';
 | 
 | 716 |                 }
 | 
 | 717 |               break;
 | 
 | 718 | 
 | 
 | 719 |               default:
 | 
 | 720 |                 $data = rsettings('details', $object);
 | 
 | 721 |                 process_get_return($data);
 | 
 | 722 |               break;
 | 
 | 723 |             }
 | 
 | 724 |           break;
 | 
 | 725 | 
 | 
 | 726 |           case "oauth2-client":
 | 
 | 727 |             switch ($object) {
 | 
 | 728 |               case "all":
 | 
 | 729 |                 $clients = oauth2('get', 'clients');
 | 
 | 730 |                 if (!empty($clients)) {
 | 
 | 731 |                   foreach ($clients as $client) {
 | 
 | 732 |                     if ($details = oauth2('details', 'client', $client)) {
 | 
 | 733 |                       $data[] = $details;
 | 
 | 734 |                     }
 | 
 | 735 |                     else {
 | 
 | 736 |                       continue;
 | 
 | 737 |                     }
 | 
 | 738 |                   }
 | 
 | 739 |                   process_get_return($data);
 | 
 | 740 |                 }
 | 
 | 741 |                 else {
 | 
 | 742 |                   echo '{}';
 | 
 | 743 |                 }
 | 
 | 744 |               break;
 | 
 | 745 | 
 | 
 | 746 |               default:
 | 
 | 747 |                 $data = oauth2('details', 'client', $object);
 | 
 | 748 |                 process_get_return($data);
 | 
 | 749 |               break;
 | 
 | 750 |             }
 | 
 | 751 |           break;
 | 
 | 752 | 
 | 
 | 753 |           case "logs":
 | 
 | 754 |             switch ($object) {
 | 
 | 755 |               case "dovecot":
 | 
 | 756 |                 // 0 is first record, so empty is fine
 | 
 | 757 |                 if (isset($extra)) {
 | 
 | 758 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 759 |                   $logs = get_logs('dovecot-mailcow', $extra);
 | 
 | 760 |                 }
 | 
 | 761 |                 else {
 | 
 | 762 |                   $logs = get_logs('dovecot-mailcow');
 | 
 | 763 |                 }
 | 
 | 764 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 765 |               break;
 | 
 | 766 |               case "ratelimited":
 | 
 | 767 |                 // 0 is first record, so empty is fine
 | 
 | 768 |                 if (isset($extra)) {
 | 
 | 769 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 770 |                   $logs = get_logs('ratelimited', $extra);
 | 
 | 771 |                 }
 | 
 | 772 |                 else {
 | 
 | 773 |                   $logs = get_logs('ratelimited');
 | 
 | 774 |                 }
 | 
 | 775 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 776 |               break;
 | 
 | 777 |               case "netfilter":
 | 
 | 778 |                 // 0 is first record, so empty is fine
 | 
 | 779 |                 if (isset($extra)) {
 | 
 | 780 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 781 |                   $logs = get_logs('netfilter-mailcow', $extra);
 | 
 | 782 |                 }
 | 
 | 783 |                 else {
 | 
 | 784 |                   $logs = get_logs('netfilter-mailcow');
 | 
 | 785 |                 }
 | 
 | 786 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 787 |               break;
 | 
 | 788 |               case "postfix":
 | 
 | 789 |                 // 0 is first record, so empty is fine
 | 
 | 790 |                 if (isset($extra)) {
 | 
 | 791 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 792 |                   $logs = get_logs('postfix-mailcow', $extra);
 | 
 | 793 |                 }
 | 
 | 794 |                 else {
 | 
 | 795 |                   $logs = get_logs('postfix-mailcow');
 | 
 | 796 |                 }
 | 
 | 797 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 798 |               break;
 | 
 | 799 |               case "autodiscover":
 | 
 | 800 |                 // 0 is first record, so empty is fine
 | 
 | 801 |                 if (isset($extra)) {
 | 
 | 802 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 803 |                   $logs = get_logs('autodiscover-mailcow', $extra);
 | 
 | 804 |                 }
 | 
 | 805 |                 else {
 | 
 | 806 |                   $logs = get_logs('autodiscover-mailcow');
 | 
 | 807 |                 }
 | 
 | 808 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 809 |               break;
 | 
 | 810 |               case "sogo":
 | 
 | 811 |                 // 0 is first record, so empty is fine
 | 
 | 812 |                 if (isset($extra)) {
 | 
 | 813 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 814 |                   $logs = get_logs('sogo-mailcow', $extra);
 | 
 | 815 |                 }
 | 
 | 816 |                 else {
 | 
 | 817 |                   $logs = get_logs('sogo-mailcow');
 | 
 | 818 |                 }
 | 
 | 819 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 820 |               break;
 | 
 | 821 |               case "ui":
 | 
 | 822 |                 // 0 is first record, so empty is fine
 | 
 | 823 |                 if (isset($extra)) {
 | 
 | 824 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 825 |                   $logs = get_logs('mailcow-ui', $extra);
 | 
 | 826 |                 }
 | 
 | 827 |                 else {
 | 
 | 828 |                   $logs = get_logs('mailcow-ui');
 | 
 | 829 |                 }
 | 
 | 830 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 831 |               break;
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 832 |               case "sasl":
 | 
 | 833 |                 // 0 is first record, so empty is fine
 | 
 | 834 |                 if (isset($extra)) {
 | 
 | 835 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 836 |                   $logs = get_logs('sasl', $extra);
 | 
 | 837 |                 }
 | 
 | 838 |                 else {
 | 
 | 839 |                   $logs = get_logs('sasl');
 | 
 | 840 |                 }
 | 
 | 841 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 842 |               break;
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 843 |               case "watchdog":
 | 
 | 844 |                 // 0 is first record, so empty is fine
 | 
 | 845 |                 if (isset($extra)) {
 | 
 | 846 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 847 |                   $logs = get_logs('watchdog-mailcow', $extra);
 | 
 | 848 |                 }
 | 
 | 849 |                 else {
 | 
 | 850 |                   $logs = get_logs('watchdog-mailcow');
 | 
 | 851 |                 }
 | 
 | 852 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 853 |               break;
 | 
 | 854 |               case "acme":
 | 
 | 855 |                 // 0 is first record, so empty is fine
 | 
 | 856 |                 if (isset($extra)) {
 | 
 | 857 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 858 |                   $logs = get_logs('acme-mailcow', $extra);
 | 
 | 859 |                 }
 | 
 | 860 |                 else {
 | 
 | 861 |                   $logs = get_logs('acme-mailcow');
 | 
 | 862 |                 }
 | 
 | 863 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 864 |               break;
 | 
 | 865 |               case "api":
 | 
 | 866 |                 // 0 is first record, so empty is fine
 | 
 | 867 |                 if (isset($extra)) {
 | 
 | 868 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 869 |                   $logs = get_logs('api-mailcow', $extra);
 | 
 | 870 |                 }
 | 
 | 871 |                 else {
 | 
 | 872 |                   $logs = get_logs('api-mailcow');
 | 
 | 873 |                 }
 | 
 | 874 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 875 |               break;
 | 
 | 876 |               case "rspamd-history":
 | 
 | 877 |                 // 0 is first record, so empty is fine
 | 
 | 878 |                 if (isset($extra)) {
 | 
 | 879 |                   $extra = preg_replace('/[^\d\-]/i', '', $extra);
 | 
 | 880 |                   $logs = get_logs('rspamd-history', $extra);
 | 
 | 881 |                 }
 | 
 | 882 |                 else {
 | 
 | 883 |                   $logs = get_logs('rspamd-history');
 | 
 | 884 |                 }
 | 
 | 885 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 886 |               break;
 | 
 | 887 |               case "rspamd-stats":
 | 
 | 888 |                 $logs = get_logs('rspamd-stats');
 | 
 | 889 |                 echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
 | 
 | 890 |               break;
 | 
 | 891 |               // return no route found if no case is matched
 | 
 | 892 |               default:
 | 
 | 893 |                 http_response_code(404);
 | 
 | 894 |                 echo json_encode(array(
 | 
 | 895 |                   'type' => 'error',
 | 
 | 896 |                   'msg' => 'route not found'
 | 
 | 897 |                 ));
 | 
 | 898 |                 exit();
 | 
 | 899 |             }
 | 
 | 900 |           break;
 | 
 | 901 |           case "mailbox":
 | 
 | 902 |             switch ($object) {
 | 
 | 903 |               case "all":
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 904 |               case "reduced":
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 905 |                 if (empty($extra)) {
 | 
 | 906 |                   $domains = mailbox('get', 'domains');
 | 
 | 907 |                 }
 | 
 | 908 |                 else {
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 909 |                   $domains = explode(',', $extra);
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 910 |                 }
 | 
 | 911 |                 if (!empty($domains)) {
 | 
 | 912 |                   foreach ($domains as $domain) {
 | 
 | 913 |                     $mailboxes = mailbox('get', 'mailboxes', $domain);
 | 
 | 914 |                     if (!empty($mailboxes)) {
 | 
 | 915 |                       foreach ($mailboxes as $mailbox) {
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 916 |                         if ($details = mailbox('get', 'mailbox_details', $mailbox, $object)) {
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 917 |                           $data[] = $details;
 | 
 | 918 |                         }
 | 
 | 919 |                         else {
 | 
 | 920 |                           continue;
 | 
 | 921 |                         }
 | 
 | 922 |                       }
 | 
 | 923 |                     }
 | 
 | 924 |                   }
 | 
 | 925 |                   process_get_return($data);
 | 
 | 926 |                 }
 | 
 | 927 |                 else {
 | 
 | 928 |                   echo '{}';
 | 
 | 929 |                 }
 | 
 | 930 |               break;
 | 
 | 931 | 
 | 
 | 932 |               default:
 | 
 | 933 |                 $data = mailbox('get', 'mailbox_details', $object);
 | 
 | 934 |                 process_get_return($data);
 | 
 | 935 |               break;
 | 
 | 936 |             }
 | 
 | 937 |           break;
 | 
 | 938 |           case "syncjobs":
 | 
 | 939 |             switch ($object) {
 | 
 | 940 |               case "all":
 | 
 | 941 |                 $domains = mailbox('get', 'domains');
 | 
 | 942 |                 if (!empty($domains)) {
 | 
 | 943 |                   foreach ($domains as $domain) {
 | 
 | 944 |                     $mailboxes = mailbox('get', 'mailboxes', $domain);
 | 
 | 945 |                     if (!empty($mailboxes)) {
 | 
 | 946 |                       foreach ($mailboxes as $mailbox) {
 | 
 | 947 |                         $syncjobs = mailbox('get', 'syncjobs', $mailbox);
 | 
 | 948 |                         if (!empty($syncjobs)) {
 | 
 | 949 |                           foreach ($syncjobs as $syncjob) {
 | 
 | 950 |                             if (isset($extra)) {
 | 
 | 951 |                               $details = mailbox('get', 'syncjob_details', $syncjob, explode(',', $extra));
 | 
 | 952 |                             }
 | 
 | 953 |                             else {
 | 
 | 954 |                               $details = mailbox('get', 'syncjob_details', $syncjob);
 | 
 | 955 |                             }
 | 
 | 956 |                             if ($details) {
 | 
 | 957 |                               $data[] = $details;
 | 
 | 958 |                             }
 | 
 | 959 |                             else {
 | 
 | 960 |                               continue;
 | 
 | 961 |                             }
 | 
 | 962 |                           }
 | 
 | 963 |                         }
 | 
 | 964 |                       }
 | 
 | 965 |                     }
 | 
 | 966 |                   }
 | 
 | 967 |                   process_get_return($data);
 | 
 | 968 |                 }
 | 
 | 969 |                 else {
 | 
 | 970 |                   echo '{}';
 | 
 | 971 |                 }
 | 
 | 972 |               break;
 | 
 | 973 | 
 | 
 | 974 |               default:
 | 
 | 975 |                 $syncjobs = mailbox('get', 'syncjobs', $object);
 | 
 | 976 |                 if (!empty($syncjobs)) {
 | 
 | 977 |                   foreach ($syncjobs as $syncjob) {
 | 
 | 978 |                     if (isset($extra)) {
 | 
 | 979 |                       $details = mailbox('get', 'syncjob_details', $syncjob, explode(',', $extra));
 | 
 | 980 |                     }
 | 
 | 981 |                     else {
 | 
 | 982 |                       $details = mailbox('get', 'syncjob_details', $syncjob);
 | 
 | 983 |                     }
 | 
 | 984 |                     if ($details) {
 | 
 | 985 |                       $data[] = $details;
 | 
 | 986 |                     }
 | 
 | 987 |                     else {
 | 
 | 988 |                       continue;
 | 
 | 989 |                     }
 | 
 | 990 |                   }
 | 
 | 991 |                 }
 | 
 | 992 |                 process_get_return($data);
 | 
 | 993 |               break;
 | 
 | 994 |             }
 | 
 | 995 |           break;
 | 
 | 996 |           case "active-user-sieve":
 | 
 | 997 |             if (isset($object)) {
 | 
 | 998 |               $sieve_filter = mailbox('get', 'active_user_sieve', $object);
 | 
 | 999 |               if (!empty($sieve_filter)) {
 | 
 | 1000 |                 $data[] = $sieve_filter;
 | 
 | 1001 |               }
 | 
 | 1002 |             }
 | 
 | 1003 |             process_get_return($data);
 | 
 | 1004 |           break;
 | 
 | 1005 |           case "filters":
 | 
 | 1006 |             switch ($object) {
 | 
 | 1007 |               case "all":
 | 
 | 1008 |                 $domains = mailbox('get', 'domains');
 | 
 | 1009 |                 if (!empty($domains)) {
 | 
 | 1010 |                   foreach ($domains as $domain) {
 | 
 | 1011 |                     $mailboxes = mailbox('get', 'mailboxes', $domain);
 | 
 | 1012 |                     if (!empty($mailboxes)) {
 | 
 | 1013 |                       foreach ($mailboxes as $mailbox) {
 | 
 | 1014 |                         $filters = mailbox('get', 'filters', $mailbox);
 | 
 | 1015 |                         if (!empty($filters)) {
 | 
 | 1016 |                           foreach ($filters as $filter) {
 | 
 | 1017 |                             if ($details = mailbox('get', 'filter_details', $filter)) {
 | 
 | 1018 |                               $data[] = $details;
 | 
 | 1019 |                             }
 | 
 | 1020 |                             else {
 | 
 | 1021 |                               continue;
 | 
 | 1022 |                             }
 | 
 | 1023 |                           }
 | 
 | 1024 |                         }
 | 
 | 1025 |                       }
 | 
 | 1026 |                     }
 | 
 | 1027 |                   }
 | 
 | 1028 |                   process_get_return($data);
 | 
 | 1029 |                 }
 | 
 | 1030 |                 else {
 | 
 | 1031 |                   echo '{}';
 | 
 | 1032 |                 }
 | 
 | 1033 |               break;
 | 
 | 1034 | 
 | 
 | 1035 |               default:
 | 
 | 1036 |                 $filters = mailbox('get', 'filters', $object);
 | 
 | 1037 |                 if (!empty($filters)) {
 | 
 | 1038 |                   foreach ($filters as $filter) {
 | 
 | 1039 |                     if ($details = mailbox('get', 'filter_details', $filter)) {
 | 
 | 1040 |                       $data[] = $details;
 | 
 | 1041 |                     }
 | 
 | 1042 |                     else {
 | 
 | 1043 |                       continue;
 | 
 | 1044 |                     }
 | 
 | 1045 |                   }
 | 
 | 1046 |                 }
 | 
 | 1047 |                 process_get_return($data);
 | 
 | 1048 |               break;
 | 
 | 1049 |             }
 | 
 | 1050 |           break;
 | 
 | 1051 |           case "bcc":
 | 
 | 1052 |             switch ($object) {
 | 
 | 1053 |               case "all":
 | 
 | 1054 |                 $bcc_items = bcc('get');
 | 
 | 1055 |                 if (!empty($bcc_items)) {
 | 
 | 1056 |                   foreach ($bcc_items as $bcc_item) {
 | 
 | 1057 |                     if ($details = bcc('details', $bcc_item)) {
 | 
 | 1058 |                       $data[] = $details;
 | 
 | 1059 |                     }
 | 
 | 1060 |                     else {
 | 
 | 1061 |                       continue;
 | 
 | 1062 |                     }
 | 
 | 1063 |                   }
 | 
 | 1064 |                 }
 | 
 | 1065 |                 process_get_return($data);
 | 
 | 1066 |               break;
 | 
 | 1067 |               default:
 | 
 | 1068 |                 $data = bcc('details', $object);
 | 
 | 1069 |                 if (!empty($data)) {
 | 
 | 1070 |                   $data[] = $details;
 | 
 | 1071 |                 }
 | 
 | 1072 |                 process_get_return($data);
 | 
 | 1073 |               break;
 | 
 | 1074 |             }
 | 
 | 1075 |           break;
 | 
 | 1076 |           case "recipient_map":
 | 
 | 1077 |             switch ($object) {
 | 
 | 1078 |               case "all":
 | 
 | 1079 |                 $recipient_map_items = recipient_map('get');
 | 
 | 1080 |                 if (!empty($recipient_map_items)) {
 | 
 | 1081 |                   foreach ($recipient_map_items as $recipient_map_item) {
 | 
 | 1082 |                     if ($details = recipient_map('details', $recipient_map_item)) {
 | 
 | 1083 |                       $data[] = $details;
 | 
 | 1084 |                     }
 | 
 | 1085 |                     else {
 | 
 | 1086 |                       continue;
 | 
 | 1087 |                     }
 | 
 | 1088 |                   }
 | 
 | 1089 |                 }
 | 
 | 1090 |                 process_get_return($data);
 | 
 | 1091 |               break;
 | 
 | 1092 |               default:
 | 
 | 1093 |                 $data = recipient_map('details', $object);
 | 
 | 1094 |                 if (!empty($data)) {
 | 
 | 1095 |                   $data[] = $details;
 | 
 | 1096 |                 }
 | 
 | 1097 |                 process_get_return($data);
 | 
 | 1098 |               break;
 | 
 | 1099 |             }
 | 
 | 1100 |           break;
 | 
 | 1101 |           case "tls-policy-map":
 | 
 | 1102 |             switch ($object) {
 | 
 | 1103 |               case "all":
 | 
 | 1104 |                 $tls_policy_maps_items = tls_policy_maps('get');
 | 
 | 1105 |                 if (!empty($tls_policy_maps_items)) {
 | 
 | 1106 |                   foreach ($tls_policy_maps_items as $tls_policy_maps_item) {
 | 
 | 1107 |                     if ($details = tls_policy_maps('details', $tls_policy_maps_item)) {
 | 
 | 1108 |                       $data[] = $details;
 | 
 | 1109 |                     }
 | 
 | 1110 |                     else {
 | 
 | 1111 |                       continue;
 | 
 | 1112 |                     }
 | 
 | 1113 |                   }
 | 
 | 1114 |                 }
 | 
 | 1115 |                 process_get_return($data);
 | 
 | 1116 |               break;
 | 
 | 1117 |               default:
 | 
 | 1118 |                 $data = tls_policy_maps('details', $object);
 | 
 | 1119 |                 if (!empty($data)) {
 | 
 | 1120 |                   $data[] = $details;
 | 
 | 1121 |                 }
 | 
 | 1122 |                 process_get_return($data);
 | 
 | 1123 |               break;
 | 
 | 1124 |             }
 | 
 | 1125 |           break;
 | 
 | 1126 |           case "policy_wl_mailbox":
 | 
 | 1127 |             switch ($object) {
 | 
 | 1128 |               default:
 | 
 | 1129 |                 $data = policy('get', 'mailbox', $object)['whitelist'];
 | 
 | 1130 |                 process_get_return($data);
 | 
 | 1131 |               break;
 | 
 | 1132 |             }
 | 
 | 1133 |           break;
 | 
 | 1134 |           case "policy_bl_mailbox":
 | 
 | 1135 |             switch ($object) {
 | 
 | 1136 |               default:
 | 
 | 1137 |                 $data = policy('get', 'mailbox', $object)['blacklist'];
 | 
 | 1138 |                 process_get_return($data);
 | 
 | 1139 |               break;
 | 
 | 1140 |             }
 | 
 | 1141 |           break;
 | 
 | 1142 |           case "policy_wl_domain":
 | 
 | 1143 |             switch ($object) {
 | 
 | 1144 |               default:
 | 
 | 1145 |                 $data = policy('get', 'domain', $object)['whitelist'];
 | 
 | 1146 |                 process_get_return($data);
 | 
 | 1147 |               break;
 | 
 | 1148 |             }
 | 
 | 1149 |           break;
 | 
 | 1150 |           case "policy_bl_domain":
 | 
 | 1151 |             switch ($object) {
 | 
 | 1152 |               default:
 | 
 | 1153 |                 $data = policy('get', 'domain', $object)['blacklist'];
 | 
 | 1154 |                 process_get_return($data);
 | 
 | 1155 |               break;
 | 
 | 1156 |             }
 | 
 | 1157 |           break;
 | 
 | 1158 |           case "time_limited_aliases":
 | 
 | 1159 |             switch ($object) {
 | 
 | 1160 |               default:
 | 
 | 1161 |                 $data = mailbox('get', 'time_limited_aliases', $object);
 | 
 | 1162 |                 process_get_return($data);
 | 
 | 1163 |               break;
 | 
 | 1164 |             }
 | 
 | 1165 |           break;
 | 
 | 1166 |           case "fail2ban":
 | 
 | 1167 |             switch ($object) {
 | 
 | 1168 |               default:
 | 
 | 1169 |                 $data = fail2ban('get');
 | 
 | 1170 |                 process_get_return($data);
 | 
 | 1171 |               break;
 | 
 | 1172 |             }
 | 
 | 1173 |           break;
 | 
 | 1174 |           case "resource":
 | 
 | 1175 |             switch ($object) {
 | 
 | 1176 |               case "all":
 | 
 | 1177 |                 $domains = mailbox('get', 'domains');
 | 
 | 1178 |                 if (!empty($domains)) {
 | 
 | 1179 |                   foreach ($domains as $domain) {
 | 
 | 1180 |                     $resources = mailbox('get', 'resources', $domain);
 | 
 | 1181 |                     if (!empty($resources)) {
 | 
 | 1182 |                       foreach ($resources as $resource) {
 | 
 | 1183 |                         if ($details = mailbox('get', 'resource_details', $resource)) {
 | 
 | 1184 |                           $data[] = $details;
 | 
 | 1185 |                         }
 | 
 | 1186 |                         else {
 | 
 | 1187 |                           continue;
 | 
 | 1188 |                         }
 | 
 | 1189 |                       }
 | 
 | 1190 |                     }
 | 
 | 1191 |                   }
 | 
 | 1192 |                   process_get_return($data);
 | 
 | 1193 |                 }
 | 
 | 1194 |                 else {
 | 
 | 1195 |                   echo '{}';
 | 
 | 1196 |                 }
 | 
 | 1197 |               break;
 | 
 | 1198 |               default:
 | 
 | 1199 |                 $data = mailbox('get', 'resource_details', $object);
 | 
 | 1200 |                 process_get_return($data);
 | 
 | 1201 |               break;
 | 
 | 1202 |             }
 | 
 | 1203 |           break;
 | 
 | 1204 |           case "fwdhost":
 | 
 | 1205 |             switch ($object) {
 | 
 | 1206 |               case "all":
 | 
 | 1207 |                 process_get_return(fwdhost('get'));
 | 
 | 1208 |               break;
 | 
 | 1209 |               default:
 | 
 | 1210 |                 process_get_return(fwdhost('details', $object));
 | 
 | 1211 |               break;
 | 
 | 1212 |             }
 | 
 | 1213 |           break;
 | 
 | 1214 |           case "quarantine":
 | 
 | 1215 |             // "all" will not print details
 | 
 | 1216 |             switch ($object) {
 | 
 | 1217 |               case "all":
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 1218 |                 process_get_return(quarantine('get'), false);
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1219 |               break;
 | 
 | 1220 |               default:
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 1221 |                 process_get_return(quarantine('details', $object), false);
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1222 |               break;
 | 
 | 1223 |             }
 | 
 | 1224 |           break;
 | 
 | 1225 |           case "alias-domain":
 | 
 | 1226 |             switch ($object) {
 | 
 | 1227 |               case "all":
 | 
 | 1228 |                 $alias_domains = mailbox('get', 'alias_domains');
 | 
 | 1229 |                 if (!empty($alias_domains)) {
 | 
 | 1230 |                   foreach ($alias_domains as $alias_domain) {
 | 
 | 1231 |                     if ($details = mailbox('get', 'alias_domain_details', $alias_domain)) {
 | 
 | 1232 |                       $data[] = $details;
 | 
 | 1233 |                     }
 | 
 | 1234 |                     else {
 | 
 | 1235 |                       continue;
 | 
 | 1236 |                     }
 | 
 | 1237 |                   }
 | 
 | 1238 |                 }
 | 
 | 1239 |                 process_get_return($data);
 | 
 | 1240 |               break;
 | 
 | 1241 |               default:
 | 
 | 1242 |                 process_get_return(mailbox('get', 'alias_domain_details', $object));
 | 
 | 1243 |               break;
 | 
 | 1244 |             }
 | 
 | 1245 |           break;
 | 
 | 1246 |           case "alias":
 | 
 | 1247 |             switch ($object) {
 | 
 | 1248 |               case "all":
 | 
 | 1249 |                 if (empty($extra)) {
 | 
 | 1250 |                   $domains = array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains'));
 | 
 | 1251 |                 }
 | 
 | 1252 |                 else {
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 1253 |                   $domains = explode(',', $extra);
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1254 |                 }
 | 
 | 1255 |                 if (!empty($domains)) {
 | 
 | 1256 |                   foreach ($domains as $domain) {
 | 
 | 1257 |                     $aliases = mailbox('get', 'aliases', $domain);
 | 
 | 1258 |                     if (!empty($aliases)) {
 | 
 | 1259 |                       foreach ($aliases as $alias) {
 | 
 | 1260 |                         if ($details = mailbox('get', 'alias_details', $alias)) {
 | 
 | 1261 |                           $data[] = $details;
 | 
 | 1262 |                         }
 | 
 | 1263 |                         else {
 | 
 | 1264 |                           continue;
 | 
 | 1265 |                         }
 | 
 | 1266 |                       }
 | 
 | 1267 |                     }
 | 
 | 1268 |                   }
 | 
 | 1269 |                   process_get_return($data);
 | 
 | 1270 |                 }
 | 
 | 1271 |                 else {
 | 
 | 1272 |                   echo '{}';
 | 
 | 1273 |                 }
 | 
 | 1274 |               break;
 | 
 | 1275 | 
 | 
 | 1276 |               default:
 | 
 | 1277 |                 process_get_return(mailbox('get', 'alias_details', $object));
 | 
 | 1278 |               break;
 | 
 | 1279 |             }
 | 
 | 1280 |           break;
 | 
 | 1281 |           case "domain-admin":
 | 
 | 1282 |             switch ($object) {
 | 
 | 1283 |               case "all":
 | 
 | 1284 |                 $domain_admins = domain_admin('get');
 | 
 | 1285 |                 if (!empty($domain_admins)) {
 | 
 | 1286 |                   foreach ($domain_admins as $domain_admin) {
 | 
 | 1287 |                     if ($details = domain_admin('details', $domain_admin)) {
 | 
 | 1288 |                       $data[] = $details;
 | 
 | 1289 |                     }
 | 
 | 1290 |                     else {
 | 
 | 1291 |                       continue;
 | 
 | 1292 |                     }
 | 
 | 1293 |                   }
 | 
 | 1294 |                   process_get_return($data);
 | 
 | 1295 |                 }
 | 
 | 1296 |                 else {
 | 
 | 1297 |                   echo '{}';
 | 
 | 1298 |                 }
 | 
 | 1299 |               break;
 | 
 | 1300 | 
 | 
 | 1301 |               default:
 | 
 | 1302 |                 process_get_return(domain_admin('details', $object));
 | 
 | 1303 |               break;
 | 
 | 1304 |             }
 | 
 | 1305 |           break;
 | 
 | 1306 |           case "admin":
 | 
 | 1307 |             switch ($object) {
 | 
 | 1308 |               case "all":
 | 
 | 1309 |                 $admins = admin('get');
 | 
 | 1310 |                 if (!empty($admins)) {
 | 
 | 1311 |                   foreach ($admins as $admin) {
 | 
 | 1312 |                     if ($details = admin('details', $admin)) {
 | 
 | 1313 |                       $data[] = $details;
 | 
 | 1314 |                     }
 | 
 | 1315 |                     else {
 | 
 | 1316 |                       continue;
 | 
 | 1317 |                     }
 | 
 | 1318 |                   }
 | 
 | 1319 |                   process_get_return($data);
 | 
 | 1320 |                 }
 | 
 | 1321 |                 else {
 | 
 | 1322 |                   echo '{}';
 | 
 | 1323 |                 }
 | 
 | 1324 |               break;
 | 
 | 1325 | 
 | 
 | 1326 |               default:
 | 
 | 1327 |                 process_get_return(admin('details', $object));
 | 
 | 1328 |               break;
 | 
 | 1329 |             }
 | 
 | 1330 |           break;
 | 
 | 1331 |           case "dkim":
 | 
 | 1332 |             switch ($object) {
 | 
 | 1333 |               default:
 | 
 | 1334 |                 $data = dkim('details', $object);
 | 
 | 1335 |                 process_get_return($data);
 | 
 | 1336 |                 break;
 | 
 | 1337 |             }
 | 
 | 1338 |           break;
 | 
 | 1339 |           case "presets":
 | 
 | 1340 |             switch ($object) {
 | 
 | 1341 |               case "rspamd":
 | 
 | 1342 |                 process_get_return(presets('get', 'rspamd'));
 | 
 | 1343 |               break;
 | 
 | 1344 |               case "sieve":
 | 
 | 1345 |                 process_get_return(presets('get', 'sieve'));
 | 
 | 1346 |               break;
 | 
 | 1347 |             }
 | 
 | 1348 |           break;
 | 
 | 1349 |           case "status":
 | 
 | 1350 |             if ($_SESSION['mailcow_cc_role'] == "admin") {
 | 
 | 1351 |               switch ($object) {
 | 
 | 1352 |                 case "containers":
 | 
 | 1353 |                   $containers = (docker('info'));
 | 
 | 1354 |                   foreach ($containers as $container => $container_info) {
 | 
 | 1355 |                     $container . ' (' . $container_info['Config']['Image'] . ')';
 | 
 | 1356 |                     $containerstarttime = ($container_info['State']['StartedAt']);
 | 
 | 1357 |                     $containerstate = ($container_info['State']['Status']);
 | 
 | 1358 |                     $containerimage = ($container_info['Config']['Image']);
 | 
 | 1359 |                     $temp[$container] = array(
 | 
 | 1360 |                       'type' => 'info',
 | 
 | 1361 |                       'container' => $container,
 | 
 | 1362 |                       'state' => $containerstate,
 | 
 | 1363 |                       'started_at' => $containerstarttime,
 | 
 | 1364 |                       'image' => $containerimage
 | 
 | 1365 |                     );
 | 
 | 1366 |                   }
 | 
 | 1367 |                   echo json_encode($temp, JSON_UNESCAPED_SLASHES);
 | 
 | 1368 |                 break;
 | 
 | 1369 |                 case "vmail":
 | 
 | 1370 |                   $exec_fields_vmail = array('cmd' => 'system', 'task' => 'df', 'dir' => '/var/vmail');
 | 
 | 1371 |                   $vmail_df = explode(',', json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields_vmail), true));
 | 
 | 1372 |                   $temp = array(
 | 
 | 1373 |                     'type' => 'info',
 | 
 | 1374 |                     'disk' => $vmail_df[0],
 | 
 | 1375 |                     'used' => $vmail_df[2],
 | 
 | 1376 |                     'total'=> $vmail_df[1],
 | 
 | 1377 |                     'used_percent' => $vmail_df[4]
 | 
 | 1378 |                   );
 | 
 | 1379 |                   echo json_encode($temp, JSON_UNESCAPED_SLASHES);
 | 
 | 1380 |               break;
 | 
 | 1381 |               case "solr":
 | 
 | 1382 |                 $solr_status = solr_status();
 | 
 | 1383 |                 $solr_size = ($solr_status['status']['dovecot-fts']['index']['size']);
 | 
 | 1384 |                 $solr_documents = ($solr_status['status']['dovecot-fts']['index']['numDocs']);
 | 
 | 1385 |                 if (strtolower(getenv('SKIP_SOLR')) != 'n') {
 | 
 | 1386 |                   $solr_enabled = false;
 | 
 | 1387 |                 }
 | 
 | 1388 |                 else {
 | 
 | 1389 |                   $solr_enabled = true;
 | 
 | 1390 |                 }
 | 
 | 1391 |                 echo json_encode(array(
 | 
 | 1392 |                   'type' => 'info',
 | 
 | 1393 |                   'solr_enabled' => $solr_enabled,
 | 
 | 1394 |                   'solr_size' => $solr_size,
 | 
 | 1395 |                   'solr_documents' => $solr_documents
 | 
 | 1396 |                 ));
 | 
 | 1397 |               break;
 | 
 | 1398 |               }
 | 
 | 1399 |             }
 | 
 | 1400 |           break;
 | 
 | 1401 |         break;
 | 
 | 1402 |         // return no route found if no case is matched
 | 
 | 1403 |         default:
 | 
 | 1404 |           http_response_code(404);
 | 
 | 1405 |           echo json_encode(array(
 | 
 | 1406 |             'type' => 'error',
 | 
 | 1407 |             'msg' => 'route not found'
 | 
 | 1408 |           ));
 | 
 | 1409 |           exit();
 | 
 | 1410 |         }
 | 
 | 1411 |       }
 | 
 | 1412 |     break;
 | 
 | 1413 |     case "delete":
 | 
 | 1414 |       if ($_SESSION['mailcow_cc_api_access'] == 'ro' || isset($_SESSION['pending_mailcow_cc_username']) || !isset($_SESSION["mailcow_cc_username"])) {
 | 
 | 1415 |         http_response_code(403);
 | 
 | 1416 |         echo json_encode(array(
 | 
 | 1417 |             'type' => 'error',
 | 
 | 1418 |             'msg' => 'API read/write access denied'
 | 
 | 1419 |         ));
 | 
 | 1420 |         exit();
 | 
 | 1421 |       }
 | 
 | 1422 |       function process_delete_return($return) {
 | 
 | 1423 |         $generic_failure = json_encode(array(
 | 
 | 1424 |           'type' => 'error',
 | 
 | 1425 |           'msg' => 'Cannot delete item'
 | 
 | 1426 |         ));
 | 
 | 1427 |         $generic_success = json_encode(array(
 | 
 | 1428 |           'type' => 'success',
 | 
 | 1429 |           'msg' => 'Task completed'
 | 
 | 1430 |         ));
 | 
 | 1431 |         if ($return === false) {
 | 
 | 1432 |           echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_failure;
 | 
 | 1433 |         }
 | 
 | 1434 |         else {
 | 
 | 1435 |           echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_success;
 | 
 | 1436 |         }
 | 
 | 1437 |       }
 | 
 | 1438 |       if (!isset($_POST['items'])) {
 | 
 | 1439 |         echo $request_incomplete;
 | 
 | 1440 |         exit;
 | 
 | 1441 |       }
 | 
 | 1442 |       else {
 | 
 | 1443 |         $items = (array)json_decode($_POST['items'], true);
 | 
 | 1444 |       }
 | 
 | 1445 |       // only allow POST requests to POST API endpoints
 | 
 | 1446 |       if ($_SERVER['REQUEST_METHOD'] != 'POST') {
 | 
 | 1447 |         http_response_code(405);
 | 
 | 1448 |         echo json_encode(array(
 | 
 | 1449 |             'type' => 'error',
 | 
 | 1450 |             'msg' => 'only POST method is allowed'
 | 
 | 1451 |         ));
 | 
 | 1452 |         exit();
 | 
 | 1453 |       }
 | 
 | 1454 |       switch ($category) {
 | 
 | 1455 |         case "alias":
 | 
 | 1456 |           process_delete_return(mailbox('delete', 'alias', array('id' => $items)));
 | 
 | 1457 |         break;
 | 
 | 1458 |         case "oauth2-client":
 | 
 | 1459 |           process_delete_return(oauth2('delete', 'client', array('id' => $items)));
 | 
 | 1460 |         break;
 | 
 | 1461 |         case "app-passwd":
 | 
 | 1462 |           process_delete_return(app_passwd('delete', array('id' => $items)));
 | 
 | 1463 |         break;
 | 
 | 1464 |         case "relayhost":
 | 
 | 1465 |           process_delete_return(relayhost('delete', array('id' => $items)));
 | 
 | 1466 |         break;
 | 
 | 1467 |         case "transport":
 | 
 | 1468 |           process_delete_return(transport('delete', array('id' => $items)));
 | 
 | 1469 |         break;
 | 
 | 1470 |         case "rsetting":
 | 
 | 1471 |           process_delete_return(rsettings('delete', array('id' => $items)));
 | 
 | 1472 |         break;
 | 
 | 1473 |         case "syncjob":
 | 
 | 1474 |           process_delete_return(mailbox('delete', 'syncjob', array('id' => $items)));
 | 
 | 1475 |         break;
 | 
 | 1476 |         case "filter":
 | 
 | 1477 |           process_delete_return(mailbox('delete', 'filter', array('id' => $items)));
 | 
 | 1478 |         break;
 | 
 | 1479 |         case "mailq":
 | 
 | 1480 |           process_delete_return(mailq('delete', array('qid' => $items)));
 | 
 | 1481 |         break;
 | 
 | 1482 |         case "qitem":
 | 
 | 1483 |           process_delete_return(quarantine('delete', array('id' => $items)));
 | 
 | 1484 |         break;
 | 
 | 1485 |         case "bcc":
 | 
 | 1486 |           process_delete_return(bcc('delete', array('id' => $items)));
 | 
 | 1487 |         break;
 | 
 | 1488 |         case "recipient_map":
 | 
 | 1489 |           process_delete_return(recipient_map('delete', array('id' => $items)));
 | 
 | 1490 |         break;
 | 
 | 1491 |         case "tls-policy-map":
 | 
 | 1492 |           process_delete_return(tls_policy_maps('delete', array('id' => $items)));
 | 
 | 1493 |         break;
 | 
 | 1494 |         case "fwdhost":
 | 
 | 1495 |           process_delete_return(fwdhost('delete', array('forwardinghost' => $items)));
 | 
 | 1496 |         break;
 | 
 | 1497 |         case "dkim":
 | 
 | 1498 |           process_delete_return(dkim('delete', array('domains' => $items)));
 | 
 | 1499 |         break;
 | 
 | 1500 |         case "domain":
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1501 |           process_delete_return(mailbox('delete', 'domain', array('domain' => $items)));
 | 
 | 1502 |         break;
 | 
 | 1503 |         case "alias-domain":
 | 
 | 1504 |           process_delete_return(mailbox('delete', 'alias_domain', array('alias_domain' => $items)));
 | 
 | 1505 |         break;
 | 
 | 1506 |         case "mailbox":
 | 
 | 1507 |           process_delete_return(mailbox('delete', 'mailbox', array('username' => $items)));
 | 
 | 1508 |         break;
 | 
 | 1509 |         case "resource":
 | 
 | 1510 |           process_delete_return(mailbox('delete', 'resource', array('name' => $items)));
 | 
 | 1511 |         break;
 | 
 | 1512 |         case "mailbox-policy":
 | 
 | 1513 |           process_delete_return(policy('delete', 'mailbox', array('prefid' => $items)));
 | 
 | 1514 |         break;
 | 
 | 1515 |         case "domain-policy":
 | 
 | 1516 |           process_delete_return(policy('delete', 'domain', array('prefid' => $items)));
 | 
 | 1517 |         break;
 | 
 | 1518 |         case "time_limited_alias":
 | 
 | 1519 |           process_delete_return(mailbox('delete', 'time_limited_alias', array('address' => $items)));
 | 
 | 1520 |         break;
 | 
 | 1521 |         case "eas_cache":
 | 
 | 1522 |           process_delete_return(mailbox('delete', 'eas_cache', array('username' => $items)));
 | 
 | 1523 |         break;
 | 
 | 1524 |         case "sogo_profile":
 | 
 | 1525 |           process_delete_return(mailbox('delete', 'sogo_profile', array('username' => $items)));
 | 
 | 1526 |         break;
 | 
 | 1527 |         case "domain-admin":
 | 
 | 1528 |           process_delete_return(domain_admin('delete', array('username' => $items)));
 | 
 | 1529 |         break;
 | 
 | 1530 |         case "admin":
 | 
 | 1531 |           process_delete_return(admin('delete', array('username' => $items)));
 | 
 | 1532 |         break;
 | 
 | 1533 |         case "rlhash":
 | 
 | 1534 |           echo ratelimit('delete', null, implode($items));
 | 
 | 1535 |         break;
 | 
 | 1536 |         // return no route found if no case is matched
 | 
 | 1537 |         default:
 | 
 | 1538 |           http_response_code(404);
 | 
 | 1539 |           echo json_encode(array(
 | 
 | 1540 |             'type' => 'error',
 | 
 | 1541 |             'msg' => 'route not found'
 | 
 | 1542 |           ));
 | 
 | 1543 |           exit();
 | 
 | 1544 |       }
 | 
 | 1545 |     break;
 | 
 | 1546 |     case "edit":
 | 
 | 1547 |       if ($_SESSION['mailcow_cc_api_access'] == 'ro' || isset($_SESSION['pending_mailcow_cc_username']) || !isset($_SESSION["mailcow_cc_username"])) {
 | 
 | 1548 |         http_response_code(403);
 | 
 | 1549 |         echo json_encode(array(
 | 
 | 1550 |             'type' => 'error',
 | 
 | 1551 |             'msg' => 'API read/write access denied'
 | 
 | 1552 |         ));
 | 
 | 1553 |         exit();
 | 
 | 1554 |       }
 | 
 | 1555 |       function process_edit_return($return) {
 | 
 | 1556 |         $generic_failure = json_encode(array(
 | 
 | 1557 |           'type' => 'error',
 | 
 | 1558 |           'msg' => 'Cannot edit item'
 | 
 | 1559 |         ));
 | 
 | 1560 |         $generic_success = json_encode(array(
 | 
 | 1561 |           'type' => 'success',
 | 
 | 1562 |           'msg' => 'Task completed'
 | 
 | 1563 |         ));
 | 
 | 1564 |         if ($return === false) {
 | 
 | 1565 |           echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_failure;
 | 
 | 1566 |         }
 | 
 | 1567 |         else {
 | 
 | 1568 |           echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_success;
 | 
 | 1569 |         }
 | 
 | 1570 |       }
 | 
 | 1571 |       if (!isset($_POST['attr'])) {
 | 
 | 1572 |         echo $request_incomplete;
 | 
 | 1573 |         exit;
 | 
 | 1574 |       }
 | 
 | 1575 |       else {
 | 
 | 1576 |         $attr = (array)json_decode($_POST['attr'], true);
 | 
 | 1577 |         unset($attr['csrf_token']);
 | 
 | 1578 |         $items = isset($_POST['items']) ? (array)json_decode($_POST['items'], true) : null;
 | 
 | 1579 |       }
 | 
 | 1580 |       // only allow POST requests to POST API endpoints
 | 
 | 1581 |       if ($_SERVER['REQUEST_METHOD'] != 'POST') {
 | 
 | 1582 |         http_response_code(405);
 | 
 | 1583 |         echo json_encode(array(
 | 
 | 1584 |             'type' => 'error',
 | 
 | 1585 |             'msg' => 'only POST method is allowed'
 | 
 | 1586 |         ));
 | 
 | 1587 |         exit();
 | 
 | 1588 |       }
 | 
 | 1589 |       switch ($category) {
 | 
 | 1590 |         case "bcc":
 | 
 | 1591 |           process_edit_return(bcc('edit', array_merge(array('id' => $items), $attr)));
 | 
 | 1592 |         break;
 | 
 | 1593 |         case "pushover":
 | 
 | 1594 |           process_edit_return(pushover('edit', array_merge(array('username' => $items), $attr)));
 | 
 | 1595 |         break;
 | 
 | 1596 |         case "pushover-test":
 | 
 | 1597 |           process_edit_return(pushover('test', array_merge(array('username' => $items), $attr)));
 | 
 | 1598 |         break;
 | 
 | 1599 |         case "oauth2-client":
 | 
 | 1600 |           process_edit_return(oauth2('edit', 'client', array_merge(array('id' => $items), $attr)));
 | 
 | 1601 |         break;
 | 
 | 1602 |         case "recipient_map":
 | 
 | 1603 |           process_edit_return(recipient_map('edit', array_merge(array('id' => $items), $attr)));
 | 
 | 1604 |         break;
 | 
 | 1605 |         case "app-passwd":
 | 
 | 1606 |           process_edit_return(app_passwd('edit', array_merge(array('id' => $items), $attr)));
 | 
 | 1607 |         break;
 | 
 | 1608 |         case "tls-policy-map":
 | 
 | 1609 |           process_edit_return(tls_policy_maps('edit', array_merge(array('id' => $items), $attr)));
 | 
 | 1610 |         break;
 | 
 | 1611 |         case "alias":
 | 
 | 1612 |           process_edit_return(mailbox('edit', 'alias', array_merge(array('id' => $items), $attr)));
 | 
 | 1613 |         break;
 | 
 | 1614 |         case "rspamd-map":
 | 
 | 1615 |           process_edit_return(rspamd_maps('edit', array_merge(array('map' => $items), $attr)));
 | 
 | 1616 |         break;
 | 
 | 1617 |         case "fido2-fn":
 | 
 | 1618 |           process_edit_return(fido2(array('action' => 'edit_fn', 'fido2_attrs' => $attr)));
 | 
 | 1619 |         break;
 | 
 | 1620 |         case "app_links":
 | 
 | 1621 |           process_edit_return(customize('edit', 'app_links', $attr));
 | 
 | 1622 |         break;
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 1623 |         case "passwordpolicy":
 | 
 | 1624 |           process_edit_return(password_complexity('edit', $attr));
 | 
 | 1625 |         break;
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1626 |         case "relayhost":
 | 
 | 1627 |           process_edit_return(relayhost('edit', array_merge(array('id' => $items), $attr)));
 | 
 | 1628 |         break;
 | 
 | 1629 |         case "transport":
 | 
 | 1630 |           process_edit_return(transport('edit', array_merge(array('id' => $items), $attr)));
 | 
 | 1631 |         break;
 | 
 | 1632 |         case "rsetting":
 | 
 | 1633 |           process_edit_return(rsettings('edit', array_merge(array('id' => $items), $attr)));
 | 
 | 1634 |         break;
 | 
 | 1635 |         case "delimiter_action":
 | 
 | 1636 |           process_edit_return(mailbox('edit', 'delimiter_action', array_merge(array('username' => $items), $attr)));
 | 
 | 1637 |         break;
 | 
 | 1638 |         case "tls_policy":
 | 
 | 1639 |           process_edit_return(mailbox('edit', 'tls_policy', array_merge(array('username' => $items), $attr)));
 | 
 | 1640 |         break;
 | 
 | 1641 |         case "quarantine_notification":
 | 
 | 1642 |           process_edit_return(mailbox('edit', 'quarantine_notification', array_merge(array('username' => $items), $attr)));
 | 
 | 1643 |         break;
 | 
 | 1644 |         case "quarantine_category":
 | 
 | 1645 |           process_edit_return(mailbox('edit', 'quarantine_category', array_merge(array('username' => $items), $attr)));
 | 
 | 1646 |         break;
 | 
 | 1647 |         case "qitem":
 | 
 | 1648 |           process_edit_return(quarantine('edit', array_merge(array('id' => $items), $attr)));
 | 
 | 1649 |         break;
 | 
 | 1650 |         case "quarantine":
 | 
 | 1651 |           process_edit_return(quarantine('edit', $attr));
 | 
 | 1652 |         break;
 | 
 | 1653 |         case "quota_notification":
 | 
 | 1654 |           process_edit_return(quota_notification('edit', $attr));
 | 
 | 1655 |         break;
 | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 1656 |         case "quota_notification_bcc":
 | 
 | 1657 |           process_edit_return(quota_notification_bcc('edit', $attr));
 | 
 | 1658 |         break;
 | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1659 |         case "mailq":
 | 
 | 1660 |           process_edit_return(mailq('edit', array_merge(array('qid' => $items), $attr)));
 | 
 | 1661 |         break;
 | 
 | 1662 |         case "time_limited_alias":
 | 
 | 1663 |           process_edit_return(mailbox('edit', 'time_limited_alias', array_merge(array('address' => $items), $attr)));
 | 
 | 1664 |         break;
 | 
 | 1665 |         case "mailbox":
 | 
 | 1666 |           process_edit_return(mailbox('edit', 'mailbox', array_merge(array('username' => $items), $attr)));
 | 
 | 1667 |         break;
 | 
 | 1668 |         case "syncjob":
 | 
 | 1669 |           process_edit_return(mailbox('edit', 'syncjob', array_merge(array('id' => $items), $attr)));
 | 
 | 1670 |         break;
 | 
 | 1671 |         case "filter":
 | 
 | 1672 |           process_edit_return(mailbox('edit', 'filter', array_merge(array('id' => $items), $attr)));
 | 
 | 1673 |         break;
 | 
 | 1674 |         case "resource":
 | 
 | 1675 |           process_edit_return(mailbox('edit', 'resource', array_merge(array('name' => $items), $attr)));
 | 
 | 1676 |         break;
 | 
 | 1677 |         case "domain":
 | 
 | 1678 |           process_edit_return(mailbox('edit', 'domain', array_merge(array('domain' => $items), $attr)));
 | 
 | 1679 |         break;
 | 
 | 1680 |         case "rl-domain":
 | 
 | 1681 |           process_edit_return(ratelimit('edit', 'domain', array_merge(array('object' => $items), $attr)));
 | 
 | 1682 |         break;
 | 
 | 1683 |         case "rl-mbox":
 | 
 | 1684 |           process_edit_return(ratelimit('edit', 'mailbox', array_merge(array('object' => $items), $attr)));
 | 
 | 1685 |         break;
 | 
 | 1686 |         case "user-acl":
 | 
 | 1687 |           process_edit_return(acl('edit', 'user', array_merge(array('username' => $items), $attr)));
 | 
 | 1688 |         break;
 | 
 | 1689 |         case "da-acl":
 | 
 | 1690 |           process_edit_return(acl('edit', 'domainadmin', array_merge(array('username' => $items), $attr)));
 | 
 | 1691 |         break;
 | 
 | 1692 |         case "alias-domain":
 | 
 | 1693 |           process_edit_return(mailbox('edit', 'alias_domain', array_merge(array('alias_domain' => $items), $attr)));
 | 
 | 1694 |         break;
 | 
 | 1695 |         case "spam-score":
 | 
 | 1696 |           process_edit_return(mailbox('edit', 'spam_score', array_merge(array('username' => $items), $attr)));
 | 
 | 1697 |         break;
 | 
 | 1698 |         case "domain-admin":
 | 
 | 1699 |           process_edit_return(domain_admin('edit', array_merge(array('username' => $items), $attr)));
 | 
 | 1700 |         break;
 | 
 | 1701 |         case "admin":
 | 
 | 1702 |           process_edit_return(admin('edit', array_merge(array('username' => $items), $attr)));
 | 
 | 1703 |         break;
 | 
 | 1704 |         case "fwdhost":
 | 
 | 1705 |           process_edit_return(fwdhost('edit', array_merge(array('fwdhost' => $items), $attr)));
 | 
 | 1706 |         break;
 | 
 | 1707 |         case "fail2ban":
 | 
 | 1708 |           process_edit_return(fail2ban('edit', array_merge(array('network' => $items), $attr)));
 | 
 | 1709 |         break;
 | 
 | 1710 |         case "ui_texts":
 | 
 | 1711 |           process_edit_return(customize('edit', 'ui_texts', $attr));
 | 
 | 1712 |         break;
 | 
 | 1713 |         case "self":
 | 
 | 1714 |           if ($_SESSION['mailcow_cc_role'] == "domainadmin") {
 | 
 | 1715 |             process_edit_return(domain_admin('edit', $attr));
 | 
 | 1716 |           }
 | 
 | 1717 |           elseif ($_SESSION['mailcow_cc_role'] == "user") {
 | 
 | 1718 |             process_edit_return(edit_user_account($attr));
 | 
 | 1719 |           }
 | 
 | 1720 |         break;
 | 
 | 1721 |         // return no route found if no case is matched
 | 
 | 1722 |         default:
 | 
 | 1723 |           http_response_code(404);
 | 
 | 1724 |           echo json_encode(array(
 | 
 | 1725 |             'type' => 'error',
 | 
 | 1726 |             'msg' => 'route not found'
 | 
 | 1727 |           ));
 | 
 | 1728 |           exit();
 | 
 | 1729 |       }
 | 
 | 1730 |     break;
 | 
 | 1731 |     // return no route found if no case is matched
 | 
 | 1732 |     default:
 | 
 | 1733 |       http_response_code(404);
 | 
 | 1734 |       echo json_encode(array(
 | 
 | 1735 |         'type' => 'error',
 | 
 | 1736 |         'msg' => 'route not found'
 | 
 | 1737 |       ));
 | 
 | 1738 |       exit();
 | 
 | 1739 |   }
 | 
 | 1740 | }
 | 
 | 1741 | if ($_SESSION['mailcow_cc_api'] === true) {
 | 
 | 1742 |   if (isset($_SESSION['mailcow_cc_api']) && $_SESSION['mailcow_cc_api'] === true) {
 | 
 | 1743 |     unset($_SESSION['return']);
 | 
 | 1744 |   }
 | 
 | 1745 | }
 |