From 61bced878837f320dbb0d74951e73c98b8d78232 Mon Sep 17 00:00:00 2001 From: "Hahn Axel (hahn)" <axel.hahn@iml.unibe.ch> Date: Thu, 19 May 2022 14:38:47 +0200 Subject: [PATCH] admin: added - detect wrong hosts --- public_html/admin/index.php | 155 +++++++++++++++++++ public_html/admin/main.css | 27 ++++ public_html/classes/redirect.admin.class.php | 8 +- 3 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 public_html/admin/index.php create mode 100644 public_html/admin/main.css diff --git a/public_html/admin/index.php b/public_html/admin/index.php new file mode 100644 index 0000000..ebddf14 --- /dev/null +++ b/public_html/admin/index.php @@ -0,0 +1,155 @@ +<?php +/** + * ---------------------------------------------------------------------- + * _____ __ __ _ _____ _ _ _ + * |_ _| \/ | | | __ \ | (_) | | + * | | | \ / | | | |__) |___ __| |_ _ __ ___ ___| |_ + * | | | |\/| | | | _ // _ \/ _` | | '__/ _ \/ __| __| + * _| |_| | | | |____ | | \ \ __/ (_| | | | | __/ (__| |_ + * |_____|_| |_|______| |_| \_\___|\__,_|_|_| \___|\___|\__| + * + * ---------------------------------------------------------------------- + * admin: list all defined redirections + * ---------------------------------------------------------------------- + * 2022-02-03 v0.1 <axel.hahn@iml.unibe.ch> initial version + * ---------------------------------------------------------------------- + */ + +require_once '../classes/redirect.admin.class.php'; +$oR=new redirectadmin(); +$sHtml=''; + +// ---------------------------------------------------------------------- +// FUNCTIONS +// ---------------------------------------------------------------------- + +function getId($sDomain){ + return 'id_'.md5($sDomain); +} + +// ---------------------------------------------------------------------- +// MAIN +// ---------------------------------------------------------------------- + +if (!$oR->isEnabled()){ + $sHtml.='<div class="error">Admin is disabled.</div>'; +} else { + + $sUrl=(isset($_GET['url']) && $_GET['url']) ? $sUrl=$_GET['url'] : ''; + + // ---------- GET CONFIG DATA + + $aHosts=$oR->getHosts(); + + // ---------- SHOW ERRORS + + if(count($aHosts['_errors'])) { + $sHtml.= '<h2>Found errors</h2>' + .'<ol class="error">' + .'<li>' . implode('</li></li>', $aHosts['_errors']).'</li>' + .'</ol>' + ; + } + unset($aHosts['_errors']); + + // ---------- LOOP OVER ALL ENTRIES + + $sHtml.=' + <form> + 🌐 <input type="text" name="url" size="100" value="'.$sUrl.'" /> + <button>Http HEAD</button> + </form> + <br> + + <h2>Domains and their redirects</h2> + + <table class="mydatatable"><thead> + <tr> + <th>Host</th> + <th>Ip address</th> + <th>Setup</th> + <th>Type</th> + <th>From</th> + <th>Code</th> + <th>Target</th> + </tr> + </thead><tbody>'; + foreach($aHosts as $sHost => $aCfg){ + $sTdFirst='<tr class="cfgtype-'.$aCfg['type'].'">' + .'<td><a href="?url=http://'.$sHost.'/">'.$sHost.'</a></td>' + .'<td>' + .($aCfg['ip'] ? $aCfg['ip'] : '<span class="error">ERROR: unknown host</span>') + .'</td>' + .'<td>'.$aCfg['type'].'</td>' + ; + if (isset($aCfg['redirects'])){ + $iCount=0; + foreach(['direct', 'regex'] as $sType){ + if (count($aCfg['redirects'][$sType])){ + foreach($aCfg['redirects'][$sType] as $sFrom=>$aTo){ + $iCount++; + $sHtml.=$sTdFirst + .'<td class="type-'.$sType.'">'.$sType.'</td>' + .'<td class="type-'.$sType.'">' + .($sType == 'direct' ? '<a href="?url=http://'.$sHost.'/'.$sFrom.'">'.$sFrom.'</a>' : $sFrom) + .'</td>' + .'<td class="http-'.$aTo['code'].'">'.$aTo['code'].'</td>' + .'<td>🌐 <a href="?url='.$aTo['target'].'">'.$aTo['target'].'</a></td>' + .'</tr>'; + } + } + + } + } else { + // type = alias + // $sHtml.='<tr>'.$sTdFirst.'<td></td><td></td><td></td><td>'.(isset($aCfg['target']) ? 'see config for <a href="#'.getId($aCfg['target']).'">'.$aCfg['target'].'</a>' : '').'</td></tr>'; + $sHtml.=$sTdFirst.'<td></td><td></td><td></td><td>'.(isset($aCfg['target']) ? 'see config for <em>'.$aCfg['target'].'</em>' : '').'</td></tr>'; + } + + } + $sHtml.='</tbody></table>' + /* + .'<h2>Config array</h2> + <pre>'.print_r($aHosts, 1).'</pre>' + */ + ; + + // ---------- TEST URL + if ($sUrl){ + $sResult=$oR->httpGet($sUrl.'?debugredirect=1',1); + $sHtml.= '<div class="overlay" onclick="this.style.display=\'none\';"><div>' + . '<h2>🌐 <a href="'.$sUrl.'">'.$sUrl.'</a></h2> (click to open)<br><br>' + . '📄 Http response header:<br><br>'.$oR->renderHttpResponseHeader($sResult, 1) + . '</div></div>' + ; + } + + +} + +// ---------- OUTPUT + +?><!doctype html> +<html> + <head> + <title>Redirects</title> + <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.11.4/datatables.min.css"/> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> + <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.11.4/datatables.min.js"></script> + <link rel="stylesheet" href="main.css"> + </head> + <body> + <h1>⏩ <a href="?">Redirects :: admin</a></h1> + + <?php echo $sHtml; ?> + + <script> + $(document).ready( function () { + $('.mydatatable').DataTable({ + "lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]], + stateSave: true + }); + } ); + </script> + </body> +</html> diff --git a/public_html/admin/main.css b/public_html/admin/main.css new file mode 100644 index 0000000..a24ba6c --- /dev/null +++ b/public_html/admin/main.css @@ -0,0 +1,27 @@ +a{color:royalblue;} +body{background: #f8f8f8; color: #234; font-family: arial;} +h1{background:rgba(0,0,0,0.05); margin: 0 0 1em;; padding: 0.5em;} +h1 a{color:#234; text-decoration: none;} +h2{background:rgba(0,0,0,0.02); color:#458; margin: 0;} +h2 a{color:#458; text-decoration: none; } +pre{background: rgba(0,0,0,0.02);padding: 0.3em 1em; border: 1px solid rgba(0,0,0,0.1); margin-bottom: 2em;} + +.error{background: #fcc;} + +.cfgtype-alias{color:#89a; } +.http-301::after{color:#a55; content: ' (Moved Permanently)'} +.http-307::after{color:#488; content: ' (Temporary Redirect)'} +.http-308::after{color:#a95; content: ' (Permanent Redirect)'} +.type-direct{color:#383; } +.type-regex{color:#838; } + +.status{padding: 0.5em 1em; position: relative;top: -0.8em; border: 2px solid; border-left: 1.5em solid;} +.status-ok{color:#080; background:#cec; } +.status-redirect{color:#651; background:#fec;} +.status-error{color:#800; background:#ecc;} + +.location{background:#fec;} +.debug{color:#197;} + +.overlay{position: fixed; margin: 0; width: 100%; height: 100%; top: 0; left: 0; background: rgba(0,0,0,0.3);overflow: scroll;} +.overlay>div{margin: 3% 10%; background: #fff; padding: 1em;box-shadow: 0 0 3em #000; } diff --git a/public_html/classes/redirect.admin.class.php b/public_html/classes/redirect.admin.class.php index cc609a6..3968a3b 100644 --- a/public_html/classes/redirect.admin.class.php +++ b/public_html/classes/redirect.admin.class.php @@ -107,8 +107,10 @@ class redirectadmin extends redirect { return file_exists($sFile2Enable); } - public function httpHead($sUrl){ + protected function _getIp($sHostname){ + $sIp=gethostbyname($sHostname); + return $sIp===$sHostname ? false : $sIp; } /** @@ -122,7 +124,7 @@ class redirectadmin extends redirect { $aReturn[$sMyHost]=array( 'type'=>'config', 'file'=>$sFilename, - 'ip'=> gethostbyname($sMyHost), + 'ip'=> $this->_getIp($sMyHost), 'aliases'=>array(), 'redirects'=>json_decode(file_get_contents($sFilename), 1), ); @@ -139,7 +141,7 @@ class redirectadmin extends redirect { $aReturn[$sAlias]=array( 'type'=>'alias', 'target'=>$sConfig, - 'ip'=> gethostbyname($sMyHost), + 'ip'=> $this->_getIp($sAlias), ); } } -- GitLab