0byt3m1n1
Path:
/
data
/
applications
/
aps
/
geeklog
/
1.8.0-0
/
standard
/
htdocs
/
public_html
/
admin
/
[
Home
]
File: sectest.php
<?php /* Reminder: always indent with 4 spaces (no tabs). */ // +---------------------------------------------------------------------------+ // | Geeklog 1.6 | // +---------------------------------------------------------------------------+ // | sectest.php | // | | // | Does a quick security check of the Geeklog install | // +---------------------------------------------------------------------------+ // | Copyright (C) 2002-2009 by the following authors: | // | | // | Authors: Dirk Haun - dirk AT haun-online DOT de | // | Jeffrey Schoolcraft - dream AT dr3amscap3 DOT com | // +---------------------------------------------------------------------------+ // | | // | This program is free software; you can redistribute it and/or | // | modify it under the terms of the GNU General Public License | // | as published by the Free Software Foundation; either version 2 | // | of the License, or (at your option) any later version. | // | | // | This program is distributed in the hope that it will be useful, | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | // | GNU General Public License for more details. | // | | // | You should have received a copy of the GNU General Public License | // | along with this program; if not, write to the Free Software Foundation, | // | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | // | | // +---------------------------------------------------------------------------+ /** * This script does a few quick and simple checks to ensure that you have * installed Geeklog in a (relatively) secure fashion. It also gives tips on * how to fix issues. * */ /** * Geeklog common function library */ require_once '../lib-common.php'; /** * Security check to ensure user even belongs on this page */ require_once 'auth.inc.php'; $display = ''; if (!SEC_inGroup('Root')) { $display .= COM_siteHeader('menu', $MESSAGE[30]) . COM_showMessageText($MESSAGE[29], $MESSAGE[30]) . COM_siteFooter(); COM_accessLog("User {$_USER['username']} tried to illegally access the security check."); COM_output($display); exit; } // ugh, global variable ... $failed_tests = 0; /** * Send an HTTP HEAD request for the given URL * * @param string $url URL to request * @param string &$errmsg error message, if any (on return) * @return int HTTP response code or 777 on error * */ function doHeadRequest($url, &$errmsg) { require_once 'HTTP/Request.php'; $req = new HTTP_Request($url); $req->setMethod(HTTP_REQUEST_METHOD_HEAD); $req->addHeader('User-Agent', 'Geeklog/' . VERSION); $response = $req->sendRequest(); if (PEAR::isError($response)) { $errmsg = $response->getMessage(); return 777; } else { return $req->getResponseCode(); } } /** * Determine the site's base URL to check * * @return string site URL or empty string (= nothing to check) * */ function urlToCheck() { global $_CONF; $url = ''; if ($_CONF['path'] == $_CONF['path_html']) { // not good ... $url = $_CONF['site_url']; } elseif (substr($_CONF['path'], 0, strlen($_CONF['path_html'])) == $_CONF['path_html']) { // "geeklog" dir in the document root $rest = substr($_CONF['path'], -(strlen($_CONF['path']) - strlen($_CONF['path_html']))); $url = $_CONF['site_url'] . '/' . $rest; } else { // check for sites like www.example.com/geeklog $u = $_CONF['site_url']; if (substr($u, -1) == '/') { $u = substr($u, 0, -1); } $pos = strpos($u, ':'); if ($pos !== false) { $u2 = substr($u, $pos + 3); } else { $u2 = $u; } $p = explode('/', $u2); if (count($p) > 1) { $cut = strlen($p[count($p) - 1]) + 1; $url = substr($u, 0, -$cut); } } if (!empty($url) && (substr($url, -1) == '/')) { $url = substr($url, 0, -1); } return $url; } /** * Give an interpretation of the test result * * @param int $retcode HTTP response code of the test * @param string $msg file or directory that was checked * @return string text explaining the result of the test * */ function interpretResult($retcode, $msg) { global $LANG_SECTEST, $failed_tests; $retval = ''; if ($retcode == 200) { $retval .= sprintf($LANG_SECTEST['reachable'], '<strong>' . $msg . '</strong>') . '<br' . XHTML . '><em>' . $LANG_SECTEST['fix_it'] . '</em>'; $failed_tests++; } elseif (($retcode == 401) || ($retcode == 403) || ($retcode == 404)) { $retval .= sprintf($LANG_SECTEST['not_reachable'], $msg); } elseif (is_numeric($retcode)) { $retval .= sprintf($LANG_SECTEST['not_sure'], $retval, $msg); $failed_tests++; } else { $retval .= $retcode; } return $retval; } /** * Create a temporary file * * @param string $file full path of the file to create * @return boolean true: success; false: file creation failed * */ function makeTempfile($file) { $retval = false; $tempfile = @fopen($file, 'w'); if ($tempfile) { $retval = true; fclose($tempfile); } return $retval; } /** * Perform a test * * @param string $baseurl the site's base URL * @param string $urltocheck relative URL to check * @param string $what explanatory text: what is being checked * @return string test result as a list item * */ function doTest($baseurl, $urltocheck, $what) { global $failed_tests; $retval = ''; $retval .= '<li>'; $retcode = doHeadRequest($baseurl . '/' . $urltocheck, $errmsg); if ($retcode == 777) { $retval .= $errmsg; $failed_tests++; } else { $retval .= interpretResult($retcode, $what); } $retval .= '</li>' . LB; return $retval; } /** * Check for the existence of the install directory * * NOTE: This test used to be part of the "Get Bent" block in lib-custom.php * * @return string text explaining the result of the test * */ function checkInstallDir() { global $_CONF, $LANG_SECTEST, $failed_tests; $retval = ''; // we don't have the path to the admin directory, so try to figure it out // from $_CONF['site_admin_url'] $adminurl = $_CONF['site_admin_url']; if (strrpos($adminurl, '/') == strlen($adminurl)) { $adminurl = substr($adminurl, 0, -1); } $pos = strrpos($adminurl, '/'); if ($pos === false) { // only guessing ... $installdir = $_CONF['path_html'] . 'admin/install'; } else { $installdir = $_CONF['path_html'] . substr($adminurl, $pos + 1) . '/install'; } if (is_dir($installdir)) { $retval .= '<li>' . sprintf($LANG_SECTEST['remove_inst'], '<b>' . $installdir . '</b>') . ' ' . $LANG_SECTEST['remove_inst2'] . '</li>'; $failed_tests++; } else { $retval .= '<li>' . $LANG_SECTEST['inst_removed'] . '</li>'; } return $retval; } /** * Check for accounts that still use the default password * * NOTE: If one of our users is also using "password" as their password, this * test will also detect that, as it checks all accounts. * * @return string text explaining the result of the test * */ function checkDefaultPassword() { global $_TABLES, $LANG_SECTEST, $failed_tests; $retval = ''; // check to see if any account still has 'password' as its password. $pwdRoot = 0; $pwdUser = 0; $result = DB_query("SELECT uid FROM {$_TABLES['users']} WHERE passwd='" . SEC_encryptPassword('password') . "'"); $numPwd = DB_numRows($result); if ($numPwd > 0) { for ($i = 0; $i < $numPwd; $i++) { list($uid) = DB_fetchArray($result); if (SEC_inGroup('Root', $uid)) { $pwdRoot++; } else { $pwdUser++; } } } if ($pwdRoot > 0) { $retval .= '<li>' . sprintf($LANG_SECTEST['fix_password'], $pwdRoot) . '</li>'; $failed_tests++; } else { $retval .= '<li>' . $LANG_SECTEST['password_okay'] . '</li>'; } return $retval; } // MAIN $display = COM_siteHeader('menu', $LANG_SECTEST['sectest']); $display .= COM_startBlock($LANG_SECTEST['results']); $url = urlToCheck(); if (!empty($url)) { $display .= '<ol>'; if (strpos($_SERVER['PHP_SELF'], 'public_html') !== false) { $doclang = COM_getLanguageName(); $docs = 'docs/' . $doclang . '/install.html'; if (file_exists($_CONF['path_html'] . $docs)) { $instUrl = $_CONF['site_url'] . '/' . $docs; } else { $instUrl = $_CONF['site_url'] . '/docs/english/install.html'; } $instUrl .= '#public_html'; $display .= '<li>' . sprintf($LANG_SECTEST['public_html'], COM_createLink($LANG_SECTEST['installation'], $instUrl)) . '</li>' . LB; $failed_tests++; } $display .= checkInstallDir(); $urls = array ( array('db-config.php', 'db-config.php'), array('logs/error.log', 'logs ' . $LANG_SECTEST['directory']), array('plugins/staticpages/functions.inc', 'plugins ' . $LANG_SECTEST['directory']), array('system/lib-security.php', 'system ' . $LANG_SECTEST['directory']) ); foreach ($urls as $tocheck) { $display .= doTest($url, $tocheck[0], $tocheck[1]); } // Note: We're not testing the 'sql' and 'language' directories. if (($_CONF['allow_mysqldump'] == 1) && ($_DB_dbms == 'mysql')) { if (makeTempfile($_CONF['backup_path'] . 'test.txt')) { $display .= doTest($url, 'backups/test.txt', 'backups ' . $LANG_SECTEST['directory']); @unlink($_CONF['backup_path'] . 'test.txt'); } else { $display .= '<li>' . sprintf($LANG_SECTEST['failed_tmp'], 'backups') . '</li>'; } } if (makeTempfile($_CONF['path_data'] . 'test.txt')) { $display .= doTest($url, 'data/test.txt', 'data directory'); @unlink($_CONF['path_data'] . 'test.txt'); } else { $display .= '<li>' . sprintf($LANG_SECTEST['failed_tmp'], 'data') . '</li>'; } $display .= checkDefaultPassword(); $display .= '</ol>'; } else { $resultInstallDirCheck = checkInstallDir(); $resultPasswordCheck = checkDefaultPassword(); if ($failed_tests == 0) { $display .= '<p>' . $LANG_SECTEST['okay'] . '</p>'; } else { $display .= '<ol>'; $display .= $resultInstallDirCheck . LB . $resultPasswordCheck; $display .= '</ol>'; } } if ($failed_tests > 0) { $display .= '<p class="warningsmall"><strong>' . $LANG_SECTEST['please_fix'] . '</strong></p>'; DB_save($_TABLES['vars'], 'name,value', "'security_check','0'"); } else { $display .= '<p>' . $LANG_SECTEST['please_note'] . '</p>'; DB_save($_TABLES['vars'], 'name,value', "'security_check','1'"); } $ml = COM_createLink('geeklog-announce', 'http://lists.geeklog.net/mailman/listinfo/geeklog-announce'); $versioncheck = '<strong>' . $LANG01[107] . '</strong>'; $display .= '<p>' . sprintf($LANG_SECTEST['stay_informed'], $ml, $versioncheck) . '</p>'; $display .= COM_endBlock(); $display .= COM_siteFooter(); COM_output($display); ?>