| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,709 @@ |
| 1 |
+<?php |
|
| 2 |
+/** |
|
| 3 |
+ * @copyright 2024 Double Bastion LLC <www.doublebastion.com> |
|
| 4 |
+ * |
|
| 5 |
+ * @author Double Bastion LLC |
|
| 6 |
+ * |
|
| 7 |
+ * @license GNU AGPL version 3 or any later version |
|
| 8 |
+ * |
|
| 9 |
+ * This program is free software; you can redistribute it and/or |
|
| 10 |
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|
| 11 |
+ * License as published by the Free Software Foundation; either |
|
| 12 |
+ * version 3 of the License, or any later version. |
|
| 13 |
+ * |
|
| 14 |
+ * This program is distributed in the hope that it will be useful, |
|
| 15 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 16 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 17 |
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details. |
|
| 18 |
+ * |
|
| 19 |
+ * You should have received a copy of the GNU Affero General Public |
|
| 20 |
+ * License along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
| 21 |
+ * |
|
| 22 |
+ */ |
|
| 23 |
+ |
|
| 24 |
+define('ACCESSCONST', TRUE);
|
|
| 25 |
+ |
|
| 26 |
+require('db-connect.php');
|
|
| 27 |
+ |
|
| 28 |
+foreach (glob("version-scripts/*.php") as $scriptname) {
|
|
| 29 |
+ include $scriptname; |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+session_start(); |
|
| 33 |
+ |
|
| 34 |
+if ($_SESSION['loggedtorspanel'] == true) {
|
|
| 35 |
+ |
|
| 36 |
+?> |
|
| 37 |
+ |
|
| 38 |
+<!doctype html> |
|
| 39 |
+<head> |
|
| 40 |
+ <meta charset="utf-8"> |
|
| 41 |
+ <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|
| 42 |
+ <title>RED SCARF Suite Panel</title> |
|
| 43 |
+ <meta name="description" content="RED SCARF Suite Panel dashboard"> |
|
| 44 |
+ <meta name="viewport" content="width=device-width, initial-scale=1"> |
|
| 45 |
+ |
|
| 46 |
+ <link rel="shortcut icon" type="image/png" href="images/favicon.png" /> |
|
| 47 |
+ <link rel="stylesheet" href="assets/css/normalize.min.css"> |
|
| 48 |
+ <link rel="stylesheet" href="assets/css/bootstrap.min.css"> |
|
| 49 |
+ <link rel="stylesheet" href="assets/css/font-awesome-4.7.0/css/font-awesome.min.css"> |
|
| 50 |
+ <link rel="stylesheet" href="assets/css/themify-icons/themify-icons.css"> |
|
| 51 |
+ <link rel="stylesheet" href="assets/css/cs-skin-elastic.css"> |
|
| 52 |
+ <link rel="stylesheet" href="assets/css/style.css"> |
|
| 53 |
+ |
|
| 54 |
+ <script type="text/javascript" src="assets/js/jquery-3.3.1.min.js"></script> |
|
| 55 |
+ |
|
| 56 |
+ <script type="text/javascript" src="assets/js/jquery.flot.min.js"></script> |
|
| 57 |
+ <script type="text/javascript" src="assets/js/jquery.flot.pie.min.js"></script> |
|
| 58 |
+ <script type="text/javascript" src="assets/js/jquery.flot.tooltip.min.js"></script> |
|
| 59 |
+ |
|
| 60 |
+ <script type="text/javascript" src="assets/js/jquery.flot.time.js"></script> |
|
| 61 |
+ <script type="text/javascript" src="assets/js/jquery.flot.symbol.js"></script> |
|
| 62 |
+ <script type="text/javascript" src="assets/js/jquery.flot.axislabels.js"></script> |
|
| 63 |
+ |
|
| 64 |
+ <script type="text/javascript" src="assets/js/jquery.min.js"></script> |
|
| 65 |
+ <script type="text/javascript" src="assets/js/popper.min.js"></script> |
|
| 66 |
+ <script type="text/javascript" src="assets/js/bootstrap.min.js"></script> |
|
| 67 |
+ <script type="text/javascript" src="assets/js/jquery.matchHeight.min.js"></script> |
|
| 68 |
+ <script type="text/javascript" src="assets/js/main.js"></script> |
|
| 69 |
+ <script type="text/javascript" src="assets/js/moment.min.js"></script> |
|
| 70 |
+ |
|
| 71 |
+ <script type="text/javascript" src="assets/js/settingsmenu.js"></script> |
|
| 72 |
+ <script type="text/javascript" src="assets/js/index.js"></script> |
|
| 73 |
+ <script type="text/javascript" src="assets/js/arrow-up.js"></script> |
|
| 74 |
+ |
|
| 75 |
+</head> |
|
| 76 |
+ |
|
| 77 |
+<body> |
|
| 78 |
+ |
|
| 79 |
+<?php include 'panels.php'; ?> |
|
| 80 |
+ |
|
| 81 |
+ <!-- Content --> |
|
| 82 |
+ |
|
| 83 |
+<div class="content"> |
|
| 84 |
+ |
|
| 85 |
+ |
|
| 86 |
+<!-- Sample Announcement that can be displayed on the Dashboard. When you want to make an announcement you can edit the text below and remove the comment signs. --> |
|
| 87 |
+ |
|
| 88 |
+<!-- |
|
| 89 |
+ <div class="row"> |
|
| 90 |
+ <div class="announcement">Announcement</div> |
|
| 91 |
+ <div class="col-lg-12"> |
|
| 92 |
+ <div class="card"> |
|
| 93 |
+ <div class="card-body"> |
|
| 94 |
+ <div id="announcetext"> |
|
| 95 |
+ Please be adviced that Saturday, May 29, 2025, at 3:00 AM we will conduct periodic system maintenance. All the websites |
|
| 96 |
+ hosted on the server will become inaccessible for 20 minutes, between 3:00 AM - 3:20 AM. Thank you for your understanding ! |
|
| 97 |
+ </div> |
|
| 98 |
+ </div> |
|
| 99 |
+ </div> |
|
| 100 |
+ </div> |
|
| 101 |
+ </div> |
|
| 102 |
+--> |
|
| 103 |
+ |
|
| 104 |
+ <div class="row"> |
|
| 105 |
+ <div class="col-lg-6"> |
|
| 106 |
+ <div class="card"> |
|
| 107 |
+ <div class="card-body"> |
|
| 108 |
+ <h4 class="cardheader">Services Status</h4> |
|
| 109 |
+ <div class="flot-container"> |
|
| 110 |
+ |
|
| 111 |
+ <div class="hostnamerow"> |
|
| 112 |
+ <?php |
|
| 113 |
+ $nameofhost = exec("hostname");
|
|
| 114 |
+ |
|
| 115 |
+ // Get the system uptime |
|
| 116 |
+ $uptimeinit = exec("uptime | awk '{print $3,$4}'");
|
|
| 117 |
+ $uptimesplit = explode(" ", $uptimeinit);
|
|
| 118 |
+ |
|
| 119 |
+ if ($uptimesplit[1] == 'days,') {
|
|
| 120 |
+ $uptimefin = $uptimesplit[0] . " days"; |
|
| 121 |
+ } elseif ($uptimesplit[1] == 'min,') {
|
|
| 122 |
+ $uptimefin = $uptimesplit[0] . " min"; |
|
| 123 |
+ } elseif ($uptimesplit[1] == 'day,') {
|
|
| 124 |
+ $uptimefin = $uptimesplit[0] . " day"; |
|
| 125 |
+ } elseif (strpos($uptimeinit, ':') !== false) {
|
|
| 126 |
+ $uptimesec = explode(":", $uptimesplit[0]);
|
|
| 127 |
+ $uptimefin = $uptimesec[0] . " hours"; |
|
| 128 |
+ } |
|
| 129 |
+ |
|
| 130 |
+ if (!file_exists('/var/run/reboot-required')) {
|
|
| 131 |
+ $needsrestart = "<font style='color:#06699b;'> No</font>"; |
|
| 132 |
+ } else { $needsrestart = "<font style='color:#cc2c52; font-weight:900;'> Security updates were automatically installed and THE SERVER NEEDS TO BE RESTARTED.</font>"; }
|
|
| 133 |
+ |
|
| 134 |
+ $hostdomain = gethostname(); |
|
| 135 |
+ $hostip = gethostbyname($hostdomain); |
|
| 136 |
+ |
|
| 137 |
+ print_r("Host: <font color='#06699b'>" . $nameofhost . "</font> • Uptime: <font color='#06699b'>" . $uptimefin .
|
|
| 138 |
+ "</font> • Needs restart: " . $needsrestart . "<br> IP: <div id='hostIP'>" . $hostip . "</div> • |
|
| 139 |
+ <span class='reputationcheck'> |
|
| 140 |
+ <span class='inforeputation'>Check IP reputation</span> |
|
| 141 |
+ <span class='checkreppopup-text'> |
|
| 142 |
+ <input type='submit' id='checkIPmxtoolbox' name='checkipreputation' value='Check IP reputation on mxtoolbox.com'> |
|
| 143 |
+ <input type='submit' id='checkIPabuseipdb' name='checkipreputation' value='Check IP reputation on abuseipdb.com'> |
|
| 144 |
+ </span> |
|
| 145 |
+ </span>"); |
|
| 146 |
+ |
|
| 147 |
+ ?> |
|
| 148 |
+ </div> |
|
| 149 |
+ |
|
| 150 |
+ <div id="failed-processes"> |
|
| 151 |
+ <?php |
|
| 152 |
+ |
|
| 153 |
+ // Search for failed processes and format the data |
|
| 154 |
+ $getfailedservinit = shell_exec('systemctl --failed --all');
|
|
| 155 |
+ $getfailedservsec = str_replace("To show all installed unit files use 'systemctl list-unit-files'.", "", $getfailedservinit);
|
|
| 156 |
+ $failedservsplit = explode("\n", $getfailedservsec);
|
|
| 157 |
+ $countlines = count($failedservsplit); |
|
| 158 |
+ $getfailedservbr = implode("<br>", $failedservsplit);
|
|
| 159 |
+ $getfailedservtert = $failedservsplit[$countlines - 3]; |
|
| 160 |
+ |
|
| 161 |
+ $getfailedlines = []; |
|
| 162 |
+ |
|
| 163 |
+ foreach ($failedservsplit as $failedkey => $failedvalue) {
|
|
| 164 |
+ if (strpos($failedvalue, "●") !== false) {
|
|
| 165 |
+ $getfailedlines[] = str_replace("● ", "", $failedvalue);
|
|
| 166 |
+ } |
|
| 167 |
+ } |
|
| 168 |
+ |
|
| 169 |
+ $tablerows = []; |
|
| 170 |
+ foreach ($getfailedlines as $tablelines) {
|
|
| 171 |
+ $valuesplit = explode(" ", $tablelines);
|
|
| 172 |
+ $getdatainit = array_filter(array_map('trim', $valuesplit));
|
|
| 173 |
+ $getwords = array_values($getdatainit); |
|
| 174 |
+ |
|
| 175 |
+ $getremaininginit = array_slice($getwords, 4); |
|
| 176 |
+ $getremaining = implode(" ", $getremaininginit);
|
|
| 177 |
+ |
|
| 178 |
+ $tablerows[] = "<tr><td class='unitcolumn'>".$getwords[0]."</td><td>".$getwords[1]."</td><td class='activesubcolumns'>".$getwords[2]."</td><td class='activesubcolumns'>".$getwords[3]."</td><td>".$getremaining."</td></tr>"; |
|
| 179 |
+ } |
|
| 180 |
+ |
|
| 181 |
+ $finaltablehead = "<table id='failed-services'><tr><th>UNIT</th><th>LOAD</th><th>ACTIVE</th><th>SUB</th><th>DESCRIPTION</th></tr>"; |
|
| 182 |
+ |
|
| 183 |
+ array_unshift($tablerows, $finaltablehead); |
|
| 184 |
+ array_push($tablerows, "</table>"); |
|
| 185 |
+ $finaltablerows = implode("", $tablerows);
|
|
| 186 |
+ |
|
| 187 |
+ // If there are failed processes, list them in a table |
|
| 188 |
+ if ($getfailedservtert[0] != 0){
|
|
| 189 |
+ echo "<b>The following ".$getfailedservtert[0]." services are in failed state:</b>".$finaltablerows." |
|
| 190 |
+ LOAD = Reflects whether the unit definition was properly loaded.<br> |
|
| 191 |
+ ACTIVE = The high-level unit activation state, i.e. generalization of SUB.<br> |
|
| 192 |
+ SUB = The low-level unit activation state, values depend on unit type."; |
|
| 193 |
+ } else echo "<p id='nofailedservices'>There are no services in failed state !</p><img id='ok-sign-image' src='images/ok_sign.svg' alt='' />"; |
|
| 194 |
+ |
|
| 195 |
+ ?> |
|
| 196 |
+ </div> |
|
| 197 |
+ </div> |
|
| 198 |
+ </div> |
|
| 199 |
+ </div><!-- /# card --> |
|
| 200 |
+ </div><!-- /# column --> |
|
| 201 |
+ |
|
| 202 |
+ <div class="col-lg-6"> |
|
| 203 |
+ <div class="card"> |
|
| 204 |
+ <div class="card-body"> |
|
| 205 |
+ <h4 class="cardheader">ClamAV Detections by Periodic Scanning</h4> |
|
| 206 |
+ <div class="flot-container"> |
|
| 207 |
+ <div class="clamavdirrow"> |
|
| 208 |
+ <?php |
|
| 209 |
+ $detectresult = $mysqli->query("SELECT id, detdir FROM detectionsdir WHERE id = 1");
|
|
| 210 |
+ $clamavdet = $detectresult->fetch_array(); |
|
| 211 |
+ $clamavreportdir = $clamavdet[1]; |
|
| 212 |
+ echo "ClamAV detections directory: <font color='#06699b'>" . $clamavreportdir . "</font>"; |
|
| 213 |
+ ?> |
|
| 214 |
+ </div> |
|
| 215 |
+ <div id="clamav-detections"> |
|
| 216 |
+ |
|
| 217 |
+ |
|
| 218 |
+<?php |
|
| 219 |
+ |
|
| 220 |
+ $maildetectrep = $clamavreportdir . "/clamav_mail_report"; |
|
| 221 |
+ $nextdetectrep = $clamavreportdir . "/clamav_nextcloud_report"; |
|
| 222 |
+ $targetstr = "Infected files: "; |
|
| 223 |
+ |
|
| 224 |
+ $maildetlnbr = ""; |
|
| 225 |
+ $nextdetlnbr = ""; |
|
| 226 |
+ |
|
| 227 |
+ // Search for the infected files lines in the mail scan report |
|
| 228 |
+ if (is_file($maildetectrep)) {
|
|
| 229 |
+ $mailfilecheck = true; |
|
| 230 |
+ $readmaildetrep = file_get_contents($maildetectrep); |
|
| 231 |
+ $infectedfl = strstr($readmaildetrep, $targetstr); |
|
| 232 |
+ $txtbreakline = explode("\n", $infectedfl);
|
|
| 233 |
+ $nbofinfectfls = explode("Infected files: ", $txtbreakline[0]);
|
|
| 234 |
+ $nbinfctdflsmail = $nbofinfectfls[1]; |
|
| 235 |
+ |
|
| 236 |
+ if ($nbinfctdflsmail != 0) {
|
|
| 237 |
+ $getdetlines = file($maildetectrep); |
|
| 238 |
+ |
|
| 239 |
+ $getdetmaillnarr = array(); |
|
| 240 |
+ $gosel = false; |
|
| 241 |
+ $p = 0; |
|
| 242 |
+ foreach ($getdetlines as $lnkey => $lnvalue) {
|
|
| 243 |
+ |
|
| 244 |
+ if (strpos($lnvalue, "SCAN SUMMARY") !== false) {
|
|
| 245 |
+ $gosel = false; |
|
| 246 |
+ } |
|
| 247 |
+ if (trim($lnvalue) == '') { $gosel = false; }
|
|
| 248 |
+ if ($gosel) {
|
|
| 249 |
+ $lnsplit = explode(":", $lnvalue);
|
|
| 250 |
+ $lnsplitreminit = array_slice($lnsplit, 2); |
|
| 251 |
+ $lnsplitrem = implode(":", $lnsplitreminit);
|
|
| 252 |
+ $lndircolor = $lnsplit[0] . ":" . $lnsplit[1]; |
|
| 253 |
+ $lndirsplit = explode("/", $lndircolor);
|
|
| 254 |
+ $lndirlast = end($lndirsplit); |
|
| 255 |
+ reset($lndirsplit); |
|
| 256 |
+ $lndirproc = array_pop($lndirsplit); |
|
| 257 |
+ $lndirprocfin = implode("/", $lndirsplit);
|
|
| 258 |
+ $lncolored = "<font style='color:#008e61;font-weight:600;'>" . $lndirprocfin . "/</font><font style='color:#ff0000;'>" . $lndirlast . "</font> :" . $lnsplitrem; |
|
| 259 |
+ $getdetmaillnarr[$p] = $lncolored; |
|
| 260 |
+ |
|
| 261 |
+ $p++; |
|
| 262 |
+ } |
|
| 263 |
+ if (strpos($lnvalue, "---------------------------") !== false) {
|
|
| 264 |
+ $gosel = true; |
|
| 265 |
+ } |
|
| 266 |
+ |
|
| 267 |
+ } |
|
| 268 |
+ $maildetlnbr = implode("<br><br>", $getdetmaillnarr);
|
|
| 269 |
+ } |
|
| 270 |
+ |
|
| 271 |
+ } else { $mailfilecheck = false; }
|
|
| 272 |
+ |
|
| 273 |
+ // Search for the infected files lines in the Nextcloud scan report |
|
| 274 |
+ if (is_file($nextdetectrep)) {
|
|
| 275 |
+ $nextfilecheck = true; |
|
| 276 |
+ $readnextdetrep = file_get_contents($nextdetectrep); |
|
| 277 |
+ $infectedfltxt = strstr($readnextdetrep, $targetstr); |
|
| 278 |
+ $txtbreakln = explode("\n", $infectedfltxt);
|
|
| 279 |
+ $nbofinfectedinit = explode("Infected files: ", $txtbreakln[0]);
|
|
| 280 |
+ $nbinfctdflsnext = $nbofinfectedinit[1]; |
|
| 281 |
+ |
|
| 282 |
+ if ($nbinfctdflsnext != 0) {
|
|
| 283 |
+ $getdetnextlines = file($nextdetectrep); |
|
| 284 |
+ |
|
| 285 |
+ $getdetnextlinesarr = array(); |
|
| 286 |
+ $goselnext = false; |
|
| 287 |
+ $b = 0; |
|
| 288 |
+ foreach ($getdetnextlines as $lnextkey => $lnextvalue) {
|
|
| 289 |
+ |
|
| 290 |
+ if (strpos($lnextvalue, "SCAN SUMMARY") !== false) {
|
|
| 291 |
+ $goselnext = false; |
|
| 292 |
+ } |
|
| 293 |
+ if (trim($lnextvalue) == '') { $goselnext = false; }
|
|
| 294 |
+ if ($goselnext) {
|
|
| 295 |
+ $lnextsplit = explode(":", $lnextvalue);
|
|
| 296 |
+ $lnextreminit = array_slice($lnextsplit, 1); |
|
| 297 |
+ $lnextsplitrem = implode(":", $lnextreminit);
|
|
| 298 |
+ $lnextdirsplit = explode("/", $lnextsplit[0]);
|
|
| 299 |
+ $lnextend = end($lnextdirsplit); |
|
| 300 |
+ reset($lnextdirsplit); |
|
| 301 |
+ $lnextproc = array_pop($lnextdirsplit); |
|
| 302 |
+ $lnextprocfin = implode("/", $lnextdirsplit);
|
|
| 303 |
+ $lnextcolored = "<font style='color:#008e61;font-weight:600;'>" . $lnextprocfin . "/</font><font style='color:#ff0000;'>" . $lnextend . "</font> :" . $lnextsplitrem; |
|
| 304 |
+ $getdetnextlinesarr[$b] = $lnextcolored; |
|
| 305 |
+ |
|
| 306 |
+ $b++; |
|
| 307 |
+ } |
|
| 308 |
+ if (strpos($lnextvalue, "---------------------------") !== false) {
|
|
| 309 |
+ $goselnext = true; |
|
| 310 |
+ } |
|
| 311 |
+ } |
|
| 312 |
+ $nextdetlnbr = implode("<br><br>", $getdetnextlinesarr);
|
|
| 313 |
+ } |
|
| 314 |
+ |
|
| 315 |
+ } else { $nextfilecheck = false; }
|
|
| 316 |
+ |
|
| 317 |
+ |
|
| 318 |
+ if ($mailfilecheck == false && $nextfilecheck == false) {
|
|
| 319 |
+ $clamdetfilesmissing = "<div class='clamavnodir'>Error! The files containing the ClamAV antivirus detections weren't found ! Please verify that the detections directory |
|
| 320 |
+ set up in 'Settings > Detections Directory' is correct and that the crontab jobs for ClamAV periodic scanning are correct.</div>"; |
|
| 321 |
+ } elseif ($mailfilecheck == false && $nextfilecheck == true) {
|
|
| 322 |
+ $clamdetfilesmissing = "<div class='clamavnodir'>Error! The file containing the detections made by ClamAV in the '/var/vmail' directory wasn't found ! Please verify ClamAV |
|
| 323 |
+ status and the crontab jobs for ClamAV periodic scanning.</div>"; |
|
| 324 |
+ } elseif ($mailfilecheck == true && $nextfilecheck == false) {
|
|
| 325 |
+ $clamdetfilesmissing = "<div class='clamavnodir'>Error! The file containing the detections made by ClamAV in the '/var/www/cloud.example.com/data' directory wasn't |
|
| 326 |
+ found ! Please verify ClamAV status and the crontab jobs for ClamAV periodic scanning.</div>"; |
|
| 327 |
+ } else $clamdetfilesmissing = ""; |
|
| 328 |
+ |
|
| 329 |
+ |
|
| 330 |
+ if (($maildetlnbr != "") && ($nextdetlnbr != "")) {
|
|
| 331 |
+ $clamavperiodicdetect = "<div id='clamavpozitive'><div class='clamavsectext'>ClamAV antivirus has made the following detections by periodic scanning:</div><br> |
|
| 332 |
+ <ul><li class='virusesline'>Viruses detected in received emails directories (You should remove them manually):</li><br>" . $maildetlnbr . "</ul><br> |
|
| 333 |
+ <ul><li class='virusesline'>Viruses detected in Nextcloud upload directories (You should remove them manually):</li><br>" . $nextdetlnbr . "</ul> |
|
| 334 |
+ </div>"; |
|
| 335 |
+ } elseif (($maildetlnbr != "") && ($nextdetlnbr == "")) {
|
|
| 336 |
+ $clamavperiodicdetect = "<div id='clamavpozitive'><div class='clamavsectext'>ClamAV antivirus has made the following detections by periodic scanning:</div><br> |
|
| 337 |
+ <ul><li class='virusesline'>Viruses detected in received emails directories (You should remove them manually):</li><br>" . $maildetlnbr . "</ul> |
|
| 338 |
+ </div>" . $clamdetfilesmissing; |
|
| 339 |
+ } elseif (($maildetlnbr == "") && ($nextdetlnbr != "")) {
|
|
| 340 |
+ $clamavperiodicdetect = "<div id='clamavpozitive'><div class='clamavsectext'>ClamAV antivirus has made the following detections by periodic scanning:</div><br> |
|
| 341 |
+ <ul><li class='virusesline'>Viruses detected in Nextcloud upload directories (You should remove them manually):</li><br>" . $nextdetlnbr . "</ul> |
|
| 342 |
+ </div>" . $clamdetfilesmissing; |
|
| 343 |
+ } elseif ((($maildetlnbr == "") && ($nextdetlnbr == "")) && ($mailfilecheck == true && $nextfilecheck == true)) {
|
|
| 344 |
+ $clamavperiodicdetect = "<div class='clamavperdetect'><div id='clamavnodet'>ClamAV didn't detect any problems by periodic scanning !</div><img id='ok-sign-clamav' |
|
| 345 |
+ src='images/ok_sign.svg' alt=''></div>"; |
|
| 346 |
+ } elseif ((($maildetlnbr == "") && ($nextdetlnbr == "")) && ($mailfilecheck == false && $nextfilecheck == false)) {
|
|
| 347 |
+ $clamavperiodicdetect = $clamdetfilesmissing; |
|
| 348 |
+ } elseif ((($maildetlnbr == "") && ($nextdetlnbr == "")) && ($mailfilecheck == false && $nextfilecheck == true)) {
|
|
| 349 |
+ $clamavperiodicdetect = "<div class='clamavnodir'>Error! The file containing the detections made by ClamAV in the '/var/vmail' directory wasn't found ! Please verify ClamAV |
|
| 350 |
+ status and the crontab jobs for ClamAV periodic scanning.</div>"; |
|
| 351 |
+ } elseif ((($maildetlnbr == "") && ($nextdetlnbr == "")) && ($mailfilecheck == true && $nextfilecheck == false)) {
|
|
| 352 |
+ $clamavperiodicdetect = "<div class='clamavnodir'>Error! The file containing the detections made by ClamAV in the '/var/www/cloud.example.com/data' directory wasn't |
|
| 353 |
+ found ! Please verify ClamAV status and the crontab jobs for ClamAV periodic scanning.</div>"; |
|
| 354 |
+ } |
|
| 355 |
+ |
|
| 356 |
+ echo $clamavperiodicdetect; |
|
| 357 |
+ |
|
| 358 |
+?> |
|
| 359 |
+ </div> |
|
| 360 |
+ </div> |
|
| 361 |
+ </div> |
|
| 362 |
+ </div> <!-- /# card --> |
|
| 363 |
+ </div> <!-- /# column --> |
|
| 364 |
+ </div> <!-- /# row --> |
|
| 365 |
+ |
|
| 366 |
+ |
|
| 367 |
+ <div class="row"> |
|
| 368 |
+ <div class="col-lg-6"> |
|
| 369 |
+ <div class="card"> |
|
| 370 |
+ <div class="card-body"> |
|
| 371 |
+ <h4 class="cardheader">Storage</h4> |
|
| 372 |
+ <div class="flot-container"> |
|
| 373 |
+ <div id="useddiskspace"> |
|
| 374 |
+ |
|
| 375 |
+ <div id="pie-placeholder" class="flot"></div> |
|
| 376 |
+ <div id="freediskspace"> |
|
| 377 |
+ <?php |
|
| 378 |
+ |
|
| 379 |
+ // Get the total free storage space (in kibibytes) and if it is below the threashold of 3 GiB, display a warning |
|
| 380 |
+ $diskthreshold = 3145728; |
|
| 381 |
+ $freedisk = exec("df -x tmpfs --total | awk '{print $4}' | tail -1");
|
|
| 382 |
+ $totalspace = exec("df -x tmpfs --total | awk '{print $2}' | tail -1");
|
|
| 383 |
+ $freediskgb = round($freedisk / 1048576); |
|
| 384 |
+ $totaldiskgb = round($totalspace / 1048576); |
|
| 385 |
+ $totalusedspace = $totaldiskgb - $freediskgb; |
|
| 386 |
+ |
|
| 387 |
+ if ($freedisk <= $diskthreshold){
|
|
| 388 |
+ $diskwarn = "You may consider removing unnecessary files, optimize data storage processes, upgrade your server, or your server's storage."; |
|
| 389 |
+ } else $diskwarn = null; |
|
| 390 |
+ |
|
| 391 |
+ // Include an info line about the free storage space |
|
| 392 |
+ $infodisk = "The total free storage space on all partitions of this system is approximately<font style='color: #0082cd; font-weight: bold;'> ".$freediskgb." </font><a style='color: #0082cd; font-weight: bold; text-decoration: underline;' href='https://en.wikipedia.org/wiki/Gibibyte' target='_blank'>gibibytes</a> from a total of <font style='color: #00a859; font-weight: bold;'> ".$totaldiskgb." gibibytes.</font></b>"; |
|
| 393 |
+ |
|
| 394 |
+ echo $infodisk . "<br><br>" . $diskwarn; |
|
| 395 |
+ |
|
| 396 |
+ ?> |
|
| 397 |
+ |
|
| 398 |
+ </div> |
|
| 399 |
+ </div> |
|
| 400 |
+ </div> |
|
| 401 |
+ </div> |
|
| 402 |
+ </div> <!-- /# card --> |
|
| 403 |
+ </div> <!-- /# column --> |
|
| 404 |
+ |
|
| 405 |
+ <div class="col-lg-6"> |
|
| 406 |
+ <div class="card"> |
|
| 407 |
+ <div class="card-body"> |
|
| 408 |
+ <h4 class="cardheader">Network Usage</h4> |
|
| 409 |
+ |
|
| 410 |
+ <div class="flot-container"> |
|
| 411 |
+ |
|
| 412 |
+ <div class="totalnetrow"> |
|
| 413 |
+ <?php |
|
| 414 |
+ |
|
| 415 |
+ $int = exec("ip addr | awk '/state UP/ {print $2}' | sed 's/.$//'");
|
|
| 416 |
+ |
|
| 417 |
+ $transmitted = file_get_contents("/sys/class/net/".$int."/statistics/tx_bytes");
|
|
| 418 |
+ $received = file_get_contents("/sys/class/net/".$int."/statistics/rx_bytes");
|
|
| 419 |
+ $transDropped = file_get_contents("/sys/class/net/".$int."/statistics/tx_dropped");
|
|
| 420 |
+ $recDropped = file_get_contents("/sys/class/net/".$int."/statistics/rx_dropped");
|
|
| 421 |
+ $txErrors = file_get_contents("/sys/class/net/".$int."/statistics/tx_errors");
|
|
| 422 |
+ $rxErrors = file_get_contents("/sys/class/net/".$int."/statistics/rx_errors");
|
|
| 423 |
+ $totalSent = round(intval($transmitted)/1073741824, 2); |
|
| 424 |
+ $totalReceived = round(intval($received)/1073741824, 2); |
|
| 425 |
+ $txDropped = round(intval($transDropped)/1048576, 2); |
|
| 426 |
+ $rxDropped = round(intval($recDropped)/1048576, 2); |
|
| 427 |
+ print_r("<div class='networkinfo' >Total Sent: <font color='#06699b'>" . $totalSent . " GiB</font> • Total Received: <font color='#06699b'>" . $totalReceived . " GiB</font></br>TX Dropped: <font color='#06699b'>" . $txDropped . " MiB</font> • RX Dropped: <font color='#06699b'>" . $rxDropped . " MiB</font> • TX Errors: <font color='#06699b'>" . $txErrors . "</font> • RX Errors: <font color='#06699b'>" . $rxErrors . "</font></div>");
|
|
| 428 |
+ ?> |
|
| 429 |
+ </div> |
|
| 430 |
+ |
|
| 431 |
+ <div id="net-usage-placeholder"></div> |
|
| 432 |
+ |
|
| 433 |
+ </div> |
|
| 434 |
+ </div> |
|
| 435 |
+ </div> |
|
| 436 |
+ </div> |
|
| 437 |
+ </div> <!-- /# row --> |
|
| 438 |
+ |
|
| 439 |
+ |
|
| 440 |
+ <script type="text/javascript"> |
|
| 441 |
+ |
|
| 442 |
+ var usedspace = "<?php print_r($totalusedspace); ?>"; |
|
| 443 |
+ var freespace = "<?php print_r($freediskgb); ?>"; |
|
| 444 |
+ |
|
| 445 |
+ var data = [{
|
|
| 446 |
+ label: "Used Space", |
|
| 447 |
+ data: usedspace, |
|
| 448 |
+ color: '#cc2c52' |
|
| 449 |
+ }, {
|
|
| 450 |
+ label: "Free Space", |
|
| 451 |
+ data: freespace, |
|
| 452 |
+ color: '#0895e0' |
|
| 453 |
+ }]; |
|
| 454 |
+ |
|
| 455 |
+ function labelFormatter(label, series) {
|
|
| 456 |
+ return "<div style='font-size:13px; text-align: center; color: white; font-weight: bold;'>" + series.data[0][1] + " GiB <br>" + label + "</div>"; |
|
| 457 |
+ } |
|
| 458 |
+ |
|
| 459 |
+ var options = {
|
|
| 460 |
+ series: {
|
|
| 461 |
+ pie: {
|
|
| 462 |
+ show: true, |
|
| 463 |
+ radius: 1, |
|
| 464 |
+ label: {
|
|
| 465 |
+ show: true, |
|
| 466 |
+ radius: 0.52, |
|
| 467 |
+ threshold: 0.1, |
|
| 468 |
+ formatter: labelFormatter |
|
| 469 |
+ } |
|
| 470 |
+ } |
|
| 471 |
+ }, |
|
| 472 |
+ grid: {
|
|
| 473 |
+ hoverable: true, |
|
| 474 |
+ clickable: true |
|
| 475 |
+ }, |
|
| 476 |
+ tooltip: true, |
|
| 477 |
+ tooltipOpts: {
|
|
| 478 |
+ cssClass: "flotTip", |
|
| 479 |
+ content: function(label, xval, yval) {
|
|
| 480 |
+ var content = yval +" GiB %s (%p.0%)"; |
|
| 481 |
+ return content; |
|
| 482 |
+ }, |
|
| 483 |
+ shifts: {
|
|
| 484 |
+ x: 15, |
|
| 485 |
+ y: 0 |
|
| 486 |
+ }, |
|
| 487 |
+ defaultTheme: false |
|
| 488 |
+ } |
|
| 489 |
+ }; |
|
| 490 |
+ |
|
| 491 |
+ $.plot($("#pie-placeholder"), data, options);
|
|
| 492 |
+ |
|
| 493 |
+ </script> |
|
| 494 |
+ |
|
| 495 |
+ <div class="row"> |
|
| 496 |
+ <div class="col-lg-6"> |
|
| 497 |
+ <div class="card"> |
|
| 498 |
+ <div class="card-body"> |
|
| 499 |
+ <h4 class="cardheader">CPU Usage</h4> |
|
| 500 |
+ |
|
| 501 |
+ <div class="flot-container"> |
|
| 502 |
+ |
|
| 503 |
+ <div class="totalcpurow"> |
|
| 504 |
+ <?php |
|
| 505 |
+ $resultcpu = shell_exec("cat /proc/cpuinfo | grep MHz | head -n 1");
|
|
| 506 |
+ $resultproc = explode(":", $resultcpu);
|
|
| 507 |
+ |
|
| 508 |
+ $resultprocfourth = str_replace(" ", "", $resultproc[1]);
|
|
| 509 |
+ $resultfin = "<font color='#06699b'>" . $resultprocfourth . "</font>"; |
|
| 510 |
+ $cpucores = exec("nproc");
|
|
| 511 |
+ $infocpu = "CPU MHz: " . $resultfin . " • CPU Cores: <font color='#06699b'>" . $cpucores . "</font>"; |
|
| 512 |
+ print_r($infocpu); |
|
| 513 |
+ ?> |
|
| 514 |
+ </div> |
|
| 515 |
+ |
|
| 516 |
+ <div id="cpu-usage-placeholder"></div> |
|
| 517 |
+ |
|
| 518 |
+ </div> |
|
| 519 |
+ </div> |
|
| 520 |
+ </div> |
|
| 521 |
+ </div> |
|
| 522 |
+ |
|
| 523 |
+ <div class="col-lg-6"> |
|
| 524 |
+ <div class="card"> |
|
| 525 |
+ <div class="card-body"> |
|
| 526 |
+ <h4 class="cardheader">RAM Usage</h4> |
|
| 527 |
+ <div class="flot-container"> |
|
| 528 |
+ |
|
| 529 |
+ <div class="totalramrow"> |
|
| 530 |
+ <?php |
|
| 531 |
+ |
|
| 532 |
+ $stat1_init = shell_exec("free");
|
|
| 533 |
+ $stat1 = explode("\n", $stat1_init);
|
|
| 534 |
+ |
|
| 535 |
+ $ram1_init = explode(" ", $stat1[1]);
|
|
| 536 |
+ $getnonemptyram1 = array_filter(array_map('trim', $ram1_init));
|
|
| 537 |
+ $ram1 = array_values($getnonemptyram1); |
|
| 538 |
+ |
|
| 539 |
+ $swap1_init = explode(" ", $stat1[2]);
|
|
| 540 |
+ $getnonemptyswap1 = array_filter(array_map('trim', $swap1_init));
|
|
| 541 |
+ $swap1 = array_values($getnonemptyswap1); |
|
| 542 |
+ |
|
| 543 |
+ $ramtotal = $ram1[1]; |
|
| 544 |
+ $swaptotal = $swap1[1]; |
|
| 545 |
+ |
|
| 546 |
+ $totalRam = round($ramtotal / 1048576, 2); |
|
| 547 |
+ $totalSwap = round($swaptotal / 1048576, 2); |
|
| 548 |
+ |
|
| 549 |
+ print_r("Total RAM: <font color='#06699b'>" . $totalRam . " GiB</font> • Total SWAP: <font color='#06699b'>" . $totalSwap . " GiB</font>");
|
|
| 550 |
+ ?> |
|
| 551 |
+ </div> |
|
| 552 |
+ |
|
| 553 |
+ <div id="ram-usage-placeholder"></div> |
|
| 554 |
+ |
|
| 555 |
+ </div> |
|
| 556 |
+ </div> |
|
| 557 |
+ </div> |
|
| 558 |
+ </div> <!-- /# column --> |
|
| 559 |
+ </div> <!-- /# row --> |
|
| 560 |
+ |
|
| 561 |
+ |
|
| 562 |
+ <div class="row"> |
|
| 563 |
+ <div class="col-lg-6"> |
|
| 564 |
+ <div class="card"> |
|
| 565 |
+ <div class="card-header"> |
|
| 566 |
+ <strong class="card-title">Components</strong> |
|
| 567 |
+ </div> |
|
| 568 |
+ <div class="card-body"> |
|
| 569 |
+ <table class="table"> |
|
| 570 |
+ <thead> |
|
| 571 |
+ <tr> |
|
| 572 |
+ <th scope="col">No</th> |
|
| 573 |
+ <th scope="col">Component</th> |
|
| 574 |
+ </tr> |
|
| 575 |
+ </thead> |
|
| 576 |
+ <tbody id="buttonTableTbody"> |
|
| 577 |
+ |
|
| 578 |
+ <?php |
|
| 579 |
+ |
|
| 580 |
+ $sqlquery = $mysqli->query("SELECT id, orderno, component, componentrole, componentplace, imagename, versionscript, info
|
|
| 581 |
+ FROM components"); |
|
| 582 |
+ |
|
| 583 |
+ $getcompname = []; |
|
| 584 |
+ while ($result_fetch = $sqlquery->fetch_row()) {
|
|
| 585 |
+ $inddbid = $result_fetch[0]; |
|
| 586 |
+ $comporderno = $result_fetch[1]; |
|
| 587 |
+ $componentname = $result_fetch[2]; |
|
| 588 |
+ $componentrole = $result_fetch[3]; |
|
| 589 |
+ $componentplace = $result_fetch[4]; |
|
| 590 |
+ $indimagename = $result_fetch[5]; |
|
| 591 |
+ $versionscript = $result_fetch[6]; |
|
| 592 |
+ $popupinfo = htmlspecialchars_decode($result_fetch[7]); |
|
| 593 |
+ $getcompname[] = [$inddbid, $comporderno, $componentname, $componentrole, $componentplace, $indimagename, |
|
| 594 |
+ $versionscript, $popupinfo]; |
|
| 595 |
+ } |
|
| 596 |
+ |
|
| 597 |
+ $sqlquery->close(); |
|
| 598 |
+ |
|
| 599 |
+ $comptablerowsinit = []; |
|
| 600 |
+ for ($r = 0; $r < count($getcompname); $r++) {
|
|
| 601 |
+ $compPlace = str_replace(" ","", $getcompname[$r][4]);
|
|
| 602 |
+ $compRole = str_replace(" ","", $getcompname[$r][3]);
|
|
| 603 |
+ |
|
| 604 |
+ if ($getcompname[$r][6] != '') {
|
|
| 605 |
+ if (strpos($getcompname[$r][6], ".php") !== false) {
|
|
| 606 |
+ $currentFunction = str_replace(".php", "", $getcompname[$r][6]);
|
|
| 607 |
+ $compVersion = $currentFunction(); |
|
| 608 |
+ } else { $compVersion = $getcompname[$r][6]; }
|
|
| 609 |
+ } else $compVersion = ''; |
|
| 610 |
+ |
|
| 611 |
+ $currentorderno = $getcompname[$r][1]; |
|
| 612 |
+ $comptablerowsinit[$currentorderno] = '<td class="componentOrder">'.$getcompname[$r][1].'</td><td><span class="'.$compPlace.' '.$compRole.'"><span class="componentLogo"><img src="images/components/'.$getcompname[$r][5].'" /></span><span class="componentName">'.$getcompname[$r][2].'</span><span class="versionData">'.$compVersion.'</span><span class="componentInfo"><img class="infopic" src="images/info-popup.svg"/><span class="popup-text">'.$getcompname[$r][7].'</span></span></span></td></tr>'; |
|
| 613 |
+ } |
|
| 614 |
+ |
|
| 615 |
+ ksort($comptablerowsinit); |
|
| 616 |
+ $comptablerows = array_combine(range(1, count($comptablerowsinit)), array_values($comptablerowsinit)); |
|
| 617 |
+ |
|
| 618 |
+ for ($n = 1; $n <= count($comptablerows); $n++) {
|
|
| 619 |
+ echo '<tr class="compTableRow"><td class="currentNmbr">'.$n.'</td>' . $comptablerows[$n]; |
|
| 620 |
+ } |
|
| 621 |
+ |
|
| 622 |
+ ?> |
|
| 623 |
+ |
|
| 624 |
+ </tbody> |
|
| 625 |
+ </table> |
|
| 626 |
+ <table class="legendTable"><thead><tr><th class="headerBckgrnd">Color</th><th class="headerBckgrnd"></th><th class="headerBckgrnd">Indentation</th><th class="headerBckgrnd"></th></tr></thead><tbody><tr><td class="firstHalf"><img src="images/blue-square.png" class="legendColors" alt="blue square" /></td><td class="firstHalf">Kernel Component</td><td class="indentLevel secondHalf">First Level</td><td class="secondHalf">Operating system</td></tr><tr><td class="firstHalf"><img src="images/purple-square.png" class="legendColors" alt="purple square" /></td><td class="firstHalf">Shell Component</td><td class="indentLevel secondHalf">Second Level</td><td class="secondHalf">Applications installed inside the operating system</td></tr><tr><td class="firstHalf"><img src="images/green-square.png" class="legendColors" alt="green square" /></td><td class="firstHalf">Hull Component</td><td class="indentLevel secondHalf">Third Level</td><td class="secondHalf">Applications installed inside the preceding second level applications</td></tr></tbody></table> |
|
| 627 |
+ |
|
| 628 |
+ </div> |
|
| 629 |
+ </div> |
|
| 630 |
+ </div> |
|
| 631 |
+ |
|
| 632 |
+ <div class="col-lg-6"> |
|
| 633 |
+ <div class="card"> |
|
| 634 |
+ <div class="card-header"> |
|
| 635 |
+ <strong class="card-title">Launch Application</strong> |
|
| 636 |
+ </div> |
|
| 637 |
+ <div class="card-body"> |
|
| 638 |
+ <table id="dashboardButtons" class="table "> |
|
| 639 |
+ <thead> |
|
| 640 |
+ <tr> |
|
| 641 |
+ <th scope="col">No</th> |
|
| 642 |
+ <th scope="col">Application</th> |
|
| 643 |
+ </tr> |
|
| 644 |
+ </thead> |
|
| 645 |
+ |
|
| 646 |
+ <tbody id="buttonTbody"> |
|
| 647 |
+ |
|
| 648 |
+ <?php |
|
| 649 |
+ |
|
| 650 |
+ $buttonquery = $mysqli->query("SELECT orderno, nameonbutton, buttonurl, imgname FROM buttons");
|
|
| 651 |
+ |
|
| 652 |
+ $buttondata = []; |
|
| 653 |
+ while ($results = $buttonquery->fetch_row()) {
|
|
| 654 |
+ $indorderno = $results[0]; |
|
| 655 |
+ $indnameonbutton = $results[1]; |
|
| 656 |
+ $indbuttonurl = $results[2]; |
|
| 657 |
+ $indimgname = $results[3]; |
|
| 658 |
+ $buttondata[] = [$indorderno, $indnameonbutton, $indbuttonurl, $indimgname]; |
|
| 659 |
+ } |
|
| 660 |
+ |
|
| 661 |
+ $buttonquery->close(); |
|
| 662 |
+ |
|
| 663 |
+ $buttontablerowsinit = []; |
|
| 664 |
+ |
|
| 665 |
+ for ($r = 0; $r < count($buttondata); $r++) {
|
|
| 666 |
+ |
|
| 667 |
+ $currentbuttonno = $buttondata[$r][0]; |
|
| 668 |
+ $buttontablerowsinit[$currentbuttonno] = '<td class="buttonOrder">'.$buttondata[$r][0].'</td><td><a class="appButton" href="'.$buttondata[$r][2].'" role="button" target="_blank"><img class="buttonImage" src="images/buttons/'.$buttondata[$r][3].'" />'.$buttondata[$r][1].'</a></td></tr>'; |
|
| 669 |
+ } |
|
| 670 |
+ |
|
| 671 |
+ ksort($buttontablerowsinit); |
|
| 672 |
+ $buttontablerows = array_combine(range(1, count($buttontablerowsinit)), array_values($buttontablerowsinit)); |
|
| 673 |
+ |
|
| 674 |
+ for ($b = 1; $b <= count($buttontablerows); $b++) {
|
|
| 675 |
+ echo '<tr class="btnTableRow"><td class="currentbtnNo">'.$b.'</td>' . $buttontablerows[$b]; |
|
| 676 |
+ } |
|
| 677 |
+ |
|
| 678 |
+ ?> |
|
| 679 |
+ |
|
| 680 |
+ </tbody> |
|
| 681 |
+ </table> |
|
| 682 |
+ </div> |
|
| 683 |
+ </div> |
|
| 684 |
+ </div> |
|
| 685 |
+ </div> <!-- /# row --> |
|
| 686 |
+ |
|
| 687 |
+<?php include 'about.php'; ?> |
|
| 688 |
+ |
|
| 689 |
+</div> |
|
| 690 |
+ <!-- /.content --> |
|
| 691 |
+ <div class="clearfix"></div> |
|
| 692 |
+ |
|
| 693 |
+<?php include 'footer.php'; ?> |
|
| 694 |
+ |
|
| 695 |
+ </div> |
|
| 696 |
+ <!-- /#right-panel --> |
|
| 697 |
+ |
|
| 698 |
+ <button id="upBttn"></button> |
|
| 699 |
+ |
|
| 700 |
+</body> |
|
| 701 |
+</html> |
|
| 702 |
+ |
|
| 703 |
+<?php |
|
| 704 |
+ |
|
| 705 |
+} else {
|
|
| 706 |
+ header("Location: panel-login.php");
|
|
| 707 |
+ } |
|
| 708 |
+ |
|
| 709 |
+?> |