patchcablemgr/includes/Security.class.php
2020-11-22 22:50:42 +00:00

550 lines
16 KiB
PHP
Executable File
Raw Blame History

<?php
/*** *** *** *** *** ***
* @package Quadodo Login Script
* @file Security.class.php
* @start July 24th, 2007
* @author Douglas Rennehan
* @license http://www.opensource.org/licenses/gpl-license.php
* @version 1.0.3
* @link http://www.quadodo.net
*** *** *** *** *** ***
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*** *** *** *** *** ***
* Comments are always before the code they are commenting.
*** *** *** *** *** ***/
if (!defined('QUADODO_IN_SYSTEM')) {
exit;
}
/**
* Contains all necessary security functions
*/
class Security {
/**
* @var object $qls - Will contain everything else
*/
var $qls;
/**
* Construct class and clean input
* @param object $qls - Contains all other classes
* @return void
*/
function __construct(&$qls) {
// Check register_globals
if (@ini_get('register_globals') == 1 || strtoupper(@ini_get('register_globals')) == 'ON') {
die(REGISTER_GLOBALS_ON);
}
$this->qls = &$qls;
// Get rid of the slashes if it's turned on
if (get_magic_quotes_gpc()) {
// POST Method
foreach ($_POST as $key => $value) {
if (is_array($value)) {
foreach ($value as $key2 => $value2) {
if (is_array($value2)) {
foreach ($value2 as $key3 => $value3) {
if (is_array($value3)) {
foreach ($value3 as $key4 => $value4) {
// Can't go any deeper
if (is_array($value4)) {
$_POST[$key][$key2][$key3][$key4] = $value4;
}
else {
$_POST[$key][$key2][$key3][$key4] = stripslashes($value4);
}
}
}
else {
$_POST[$key][$key2][$key3] = stripslashes($value3);
}
}
}
else {
$_POST[$key][$key2] = stripslashes($value2);
}
}
}
else {
$_POST[$key] = stripslashes($value);
}
}
// GET Method
foreach ($_GET as $key => $value) {
if (is_array($value)) {
foreach ($value as $key2 => $value2) {
if (is_array($value2)) {
foreach ($value2 as $key3 => $value3) {
if (is_array($value3)) {
foreach ($value3 as $key4 => $value4) {
// Can't go any deeper
if (is_array($value4)) {
$_GET[$key][$key2][$key3][$key4] = $value4;
}
else {
$_GET[$key][$key2][$key3][$key4] = stripslashes($value4);
}
}
}
else {
$_GET[$key][$key2][$key3] = stripslashes($value3);
}
}
}
else {
$_GET[$key][$key2] = stripslashes($value2);
}
}
}
else {
$_GET[$key] = stripslashes($value);
}
}
// COOKIE Method
foreach ($_COOKIE as $key => $value) {
if (is_array($value)) {
foreach ($value as $key2 => $value2) {
if (is_array($value2)) {
foreach ($value2 as $key3 => $value3) {
if (is_array($value3)) {
foreach ($value3 as $key4 => $value4) {
// Can't go any deeper
if (is_array($value4)) {
$_COOKIE[$key][$key2][$key3][$key4] = $value4;
}
else {
$_COOKIE[$key][$key2][$key3][$key4] = stripslashes($value4);
}
}
}
else {
$_COOKIE[$key][$key2][$key3] = stripslashes($value3);
}
}
}
else {
$_COOKIE[$key][$key2] = stripslashes($value2);
}
}
}
else {
$_COOKIE[$key] = stripslashes($value);
}
}
}
}
/**
* Quotes strings for insertion in database
* @param mixed $input - Can be an array of values or just a string
* @optional bool $html - Whether or not to use htmlentities()
* @return string of cleaned input
*/
function make_safe($input, $html = true) {
if (is_array($input)) {
/**
* Loops to a depth of 3, and it will add slashes to each of
* the $value{num} at each depth. If the htmlentities() is chosen
* via the $html variable, it will be used.
*/
foreach ($input as $key => $value) {
if (is_array($value)) {
foreach ($value as $key2 => $value2) {
if (is_array($value2)) {
foreach ($value2 as $key3 => $value3) {
if (is_array($value3)) {
foreach ($value3 as $key4 => $value4) {
if ($html === false) {
$input[$key][$key2][$key3][$key4] = addslashes($value4);
}
else {
$input[$key][$key2][$key3][$key4] = htmlentities($value4, ENT_QUOTES);
}
}
}
else {
if ($html === false) {
$input[$key][$key2][$key3] = addslashes($value3);
}
else {
$input[$key][$key2][$key3] = htmlentities($value3, ENT_QUOTES);
}
}
}
}
else {
if ($html === false) {
$input[$key][$key2] = addslashes($value2);
}
else {
$input[$key][$key2] = htmlentities($value2, ENT_QUOTES);
}
}
}
}
else {
if ($html === false) {
$input[$key] = addslashes($value);
}
else {
$input[$key] = htmlentities($value, ENT_QUOTES);
}
}
}
return $input;
}
else {
if ($html === false) {
return addslashes($input);
}
else {
return htmlentities($input, ENT_QUOTES);
}
}
}
/**
* Check the security image and user inputted code
* @param string $random_id - Random id of the image
* @param string $input - Input text from the user
* @return bool
*/
function check_security_image($random_id, $input) {
// Get info from database
$result = $this->qls->SQL->select('*',
'security_image',
array('random_id' =>
array(
'=',
$random_id
)
)
);
$row = $this->qls->SQL->fetch_array($result);
// Is the text equal?
if ($row['real_text'] == $input) {
return true;
}
else {
return false;
}
}
/**
* Remove any old login attempts from the database
* @return void
*/
function remove_old_tries() {
// Find the time minus 12 hours
$time_minus_12_hours = time() - ((60 * 60) * 12);
$this->qls->SQL->update('users',
array(
'tries' => 0,
'last_try' => time()
),
array('last_try' =>
array(
'<',
$time_minus_12_hours
)
)
);
}
/**
* Generates a random text string for the security image
* @return string
*/
function generate_text_string() {
// List of characters to include on security image
$characters = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9');
$num_chars = rand(5, 8);
$real_text = '';
for ($x = 0; $x < $num_chars; $x++) {
$real_text .= $characters[array_rand($characters)];
}
return $real_text;
}
/**
* Removes old image records from the database (15 minutes)
* @return void
*/
function delete_old_images() {
// Run the delete query
$this->qls->SQL->delete('security_image',
array('date' =>
array(
'<',
time() - 900
)
)
);
}
/**
* Generates a random id and inserts text and random id in the database
* @return the random id string or false on failure
*/
function generate_random_id() {
// Do we even have to do it?
if ($this->qls->config['security_image'] == 'yes') {
$this->delete_old_images();
$hash[] = md5(md5(time() + time()) . sha1(time()));
$hash[] = sha1($hash[0] . $hash[0] . time());
$hash[] = sha1(rand() . rand() . (time() * rand()) . rand(1, 100));
$final = sha1($hash[0] . $hash[1] . $hash[2] . time());
// Run insert query
$this->qls->SQL->insert('security_image',
array(
'random_id',
'real_text',
'date'
),
array(
$final,
$this->generate_text_string(),
time()
)
);
return $final;
}
else {
return false;
}
}
/**
* Checks to see whether the registration page is available
* @return void, but will kill the script if not allowed
*/
function check_auth_registration() {
if ($this->qls->config['auth_registration'] == 0) {
// See if the code is set
if(isset($_GET['code'])) {
$code = $_GET['code'];
} else if(isset($_POST['code'])) {
$code = $_POST['code'];
} else {
$code = false;
}
$code = (isset($code) && strlen($code) == 40 && preg_match('/^[a-fA-F0-9]{40}$/', $code)) ? $this->make_safe($code) : false;
if($code) {
$result = $this->qls->SQL->query("SELECT `used` FROM `{$this->qls->config['sql_prefix']}invitations` WHERE `code`='{$code}'");
$row = $this->qls->SQL->fetch_array($result);
if ($row['used'] == 1 || $row['used'] == '') {
die(REGISTER_CODE_INVALID);
}
} else {
die(REGISTER_CODE_INVALID);
}
}
}
/**
* Checks to see whether the user can access the
* page and will update the hit counter.
* @param string $page_name - The page to check (must have extension)
* @return void
*/
function check_auth_page($page_name) {
$page_name = $this->make_safe($page_name);
$result = $this->qls->SQL->select('*',
'pages',
array('name' =>
array(
'=',
$page_name
)
)
);
$row = $this->qls->SQL->fetch_array($result);
$hash = sha1($row['id']);
if ($this->qls->user_info['auth_' . $hash] == 0) {
die(NO_AUTHORIZATION);
}
// Update the hit counter
$this->qls->SQL->update('pages',
array('hits' => $row['hits'] + 1),
array('id' =>
array(
'=',
$row['id']
)
)
);
}
/**
* This outputs a security image (no text can be output before it is called)
* @return void
*/
function security_image() {
$ext_prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : '';
// Is the GD extension installed?
if (!extension_loaded('gd') && !@dl($ext_prefix . 'gd.' . PHP_SHLIB_SUFFIX) && !extension_loaded('gd2') && !@dl($ext_prefix . 'gd2.' . PHP_SHLIB_SUFFIX)) {
die(NO_GD);
}
// Send the header information
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0', false);
header('Pragma: no-cache');
header('Expires: Thursday, 21 June 2007 05:00:00 GMT');
header('Content-Type: image/png', true);
// Height and width of the image
$height = rand(100, 150);
$width = rand(300, 350);
$random_id = (isset($_GET['id']) && strlen($_GET['id']) == 40 && preg_match('/[a-fA-F0-9]{40}/', $_GET['id'])) ? $this->make_safe($_GET['id']) : '';
if ($random_id == '') {
$text_string = 'Quadodo';
}
else {
// Get the information from the database
$result = $this->qls->SQL->select('*',
'security_image',
array('random_id' =>
array(
'=',
$random_id
)
)
);
$row = $this->qls->SQL->fetch_array($result);
if ($row['real_text'] == '') {
$text_string = 'Quadodo';
}
else {
$text_string = $row['real_text'];
}
}
// Create a true color image
$image = imagecreatetruecolor($width, $height);
// Allocate some colors
$colors = array(
imagecolorallocate($image, 255, 255, 255),
imagecolorallocate($image, 255, 0, 0),
imagecolorallocate($image, 0, 255, 0),
imagecolorallocate($image, 0, 0, 255),
imagecolorallocate($image, 255, 255, 0),
imagecolorallocate($image, 255, 0, 255),
imagecolorallocate($image, 0, 255, 255)
);
// Place those dots all over the place
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
// Totally random color
$random_color = imagecolorallocate($image, rand(rand(100, 120), 255), rand(rand(100, 120), 255), rand(rand(100, 120), 255));
imagesetpixel($image, $x, $y, $random_color);
}
}
// Put some lines on there!
$random_increment = array(rand(rand(4, 5), rand(5, 10)), rand(rand(5, 6), rand(7, 15)));
for ($x = 0; $x < $width; $x++) {
// If it's on the increment line, draw it
if (($x % $random_increment[0]) == 0) {
imagesetthickness($image, rand(1, 2));
imageline($image, $x, 0, $x, $height, $colors[array_rand($colors)]);
}
}
// Put some more lines
for ($x = 0; $x < $height; $x++) {
if (($x % $random_increment[1]) == 0) {
imagesetthickness($image, rand(1, 2));
imageline($image, 0, $x, $width, $x, $colors[array_rand($colors)]);
}
}
// Search through the fonts directory
foreach (glob(dirname(__FILE__) . '/fonts/*.ttf') as $file_name) {
$fonts[] = $file_name;
}
$font = $fonts[array_rand($fonts)];
// Place random characters all over the place
$chars = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '<27>', '<27>', '<27>');
for ($x = 0; $x < rand(200, 250); $x++) {
$font_size = rand(5, 10);
$font_angle = rand(-30, 40);
$font_color = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
$random_char = $chars[array_rand($chars)];
$text = imagettfbbox($font_size, $font_angle, $font, $random_char);
$text_width = abs($text[2] - $text[0]);
$text_height = abs($text[5] - $text[3]);
$text_x = rand(0, $width);
$text_y = rand(0, $height);
imagettftext($image, $font_size, $font_angle, $text_x, $text_y, $font_color, $font, $random_char);
}
// Put ellipses everywhere! :O
for ($x = 0; $x < rand(10, 20); $x++) {
$ellipse_height = rand(0, ($height / 2));
$ellipse_width = rand(0, ($width / 2));
$ellipse_y = rand($ellipse_height, $height);
$ellipse_x = rand($ellipse_width, $width);
$ellipse_color = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
imagesetthickness($image, rand(1, 10));
imageellipse($image, $ellipse_x, $ellipse_y, $ellipse_width, $ellipse_height, $ellipse_color);
}
// Generate the text and randomly position it
$font_color = imagecolorallocate($image, rand(0, 10), rand(0, 10), rand(0, 10));
$font_size = rand(30, 40);
$font_angle = rand(-6, 6);
$text = imagettfbbox($font_size, $font_angle, $font, $text_string);
$text_width = abs($text[2] - $text[0]);
$text_height = abs($text[5] - $text[3]);
$text_x = ($width / 2) - ($text_width / 2) + rand(-10, 10);
if ($font_angle > 4 || $font_angle < -4) {
$text_y = (($height / 2) - ($text_height / 2));
}
else {
$text_y = (($height / 1.5) - ($text_height / 2));
}
// Place text on image, output image and then destroy the image
imagettftext($image, $font_size, $font_angle, $text_x, $text_y, $font_color, $font, $text_string);
imagepng($image);
imagedestroy($image);
}
}