prefix . SCAPTCHA_TABLE ."` SET `conf_val`='". $value ."' WHERE `conf_key`='". $index ."'"); return mysql_query($sql); } function runUpdates() { global $wpdb; $sql = mysql_query("SELECT * FROM `". $wpdb->prefix . SCAPTCHA_TABLE ."`"); while($ary = mysql_fetch_array($sql)) { $key = $ary['conf_key']; if(isset($_POST[$key])) { if($_POST[$key] == 'on') { $_POST[$key] = 'true'; } updateConfigs($key,$_POST[$key]); // $feedback .=('Trying... ' . $_POST[$key] . '
'); } else { updateConfigs($key,''); // $feedback .= ($key . ' failed to update!
'); } } return $feedback; } function restoreDefaults() { global $wpdb; mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='false' WHERE `conf_key`='display::login'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='false' WHERE `conf_key`='display::sgup'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='200' WHERE `conf_key`='demensions::width'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='75' WHERE `conf_key`='demensions::height'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='true' WHERE `conf_key`='type::word'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='ttf' WHERE `conf_key`='font::type'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='./includes/elephant.ttf' WHERE `conf_key`='font::path'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='30' WHERE `conf_key`='format::size'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='30' WHERE `conf_key`='format::spacing'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='50' WHERE `conf_key`='format::angle'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='#e3daed' WHERE `conf_key`='color::background'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='#0a68dd,#f65c47,#8d32fd' WHERE `conf_key`='color::text'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='40' WHERE `conf_key`='color::transparent'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='#80BFFF' WHERE `conf_key`='color::lines'"); mysql_query("UPDATE `". $wpdb->prefix . SCAPTCHA_TABLE ."` SET `conf_val`='#8080ff' WHERE `conf_key`='color::arc'"); } function getConfigVal($index) { global $wpdb; $sql = ("SELECT * FROM `". $wpdb->prefix . SCAPTCHA_TABLE ."` WHERE `conf_key`='". $index ."'"); $ary = mysql_fetch_array(mysql_query($sql)); // /// THE FOLLOWING COMMENT IS A DEBUG LINE, UNCOMMENT THE LINE FOR A FULL LIST OF READ-QUERIES. // // echo('' . $sql . ' :: QUERIES: '. $ary['conf_val'] .'
'); return $ary['conf_val']; } function checkIt($key) { global $wpdb; $sql = ("SELECT * FROM `". $wpdb->prefix . SCAPTCHA_TABLE ."` WHERE `conf_key`='". $key ."'"); $ary = mysql_fetch_array(mysql_query($sql)); if($ary['conf_val'] == 1 || $ary['conf_val'] == 'true') { $ret = (' CHECKED'); } else { $ret = NULL; } return $ret; } function selectIt($key,$val) { global $wpdb; $sql = ("SELECT * FROM `". $wpdb->prefix . SCAPTCHA_TABLE ."` WHERE `conf_key`='". $key ."'"); $ary = mysql_fetch_array(mysql_query($sql)); if($ary['conf_val'] == $val) { $ret = (' SELECTED'); } else { $ret = NULL; } return $ret; } define('SI_IMAGE_JPEG', 1); define('SI_IMAGE_PNG', 2); define('SI_IMAGE_GIF', 3); function GDorTFF($reqtype) { if($reqtype == 'gd') { if(getConfigVal('font::type') == 'gd') { return true; } else { return false; } } else { if(getConfigVal('font::type') == 'ttf') { return true; } else { return false; } } } define('IMG_WIDTH', getConfigVal('demensions::width')); define('IMG_HEIGHT', getConfigVal('demensions::height')); define('WORD_LIST', getConfigVal('type::word')); define('USE_GD_FONT', GDorTFF('gd')); define('FONT_PATH', getConfigVal('font::path')); define('FONT_SIZE', getConfigVal('format::size')); define('ANGLE_MIN', 0-getConfigVal('format::angle')); define('ANGLE_MAX', getConfigVal('format::angle')); define('SPACE_MIN', getConfigVal('format::spacing')); define('SPACE_MAX', getConfigVal('format::spacing')+4); define('BG_COLOR', getConfigVal('color::background')); define('TXT_COLOR', getConfigVal('color::text')); define('TRANS_PCT', getConfigVal('color::transparent')); define('LINE_COLOR', getConfigVal('color::lines')); define('ARC_COLOR', getConfigVal('color::arc')); // Start up the plugin... if(isset($_REQUEST['sid']) && isset($_REQUEST['img']) && !isset($_POST['SpamCode'])) { $img = new securimage(); $img->show(); // alternate use: $img->show('/path/to/background.jpg'); exit; } elseif(isset($_REQUEST['audio']) && !isset($_POST['SpamCode'])) { $img = new Securimage(); header('Content-type: audio/x-wav'); header('Content-Disposition: attachment; name="securimage.wav"'); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Expires: Sun, 1 Jan 2000 12:00:00 GMT'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT'); echo $img->getAudibleCode(); exit; } else { class RandomCaptchaSpam { var $adminOptionsName = "scaptcha_options"; var $db_table_name = ''; function scaptcha(){$this->RandomCaptchaSpam();} // Backwards compatability... function RandomCaptchaSpam() { // This is the main construct... global $wpdb; register_activation_hook(__FILE__,array(&$this,"install_on_activation")); add_action("admin_menu", array(&$this,"configure_pages")); add_action('wp_footer', array(&$this,'copyright_credits')); // REMOVAL OF THIS LINE OF CODE WILL RESULT IN COPYRIGHT VIOLATIONS -- AS YOU ARE ALLOWED TO RETAIN A COPY OF THIS SOFTWARE FROM THE AUTHOR WHILE THIS IS IN TACT. REMOVAL WILL REVOLK THAT PRIVLAGE. if(getConfigVal('display::sgup') == 'true') { add_action('signup_extra_fields', array( &$this, 'signup_form' )); // add image and input field to signup form add_filter('wpmu_validate_user_signup', array( &$this, 'signup_post')); // add post signup post security code check } if(getConfigVal('display::login') == 'true') { add_action('login_form', array( &$this, 'wpmulogin_form' ) ); //add captcha into login form add_filter('wp_authenticate', array( &$this, 'wpmulogin_authenticate')); // add post login security code check } $this->db_table_name = $wpdb->prefix . SCAPTCHA_TABLE; $this->adminOptions = $this->getAdminOptions(); } function configure_pages() { // This adds the pages in the admin panel... If you don't want them there, delete them. add_menu_page('sCAPTCHA', 'sCAPTCHA', 10, __FILE__, array(&$this,"configure_page_1")); add_submenu_page(__FILE__, "Configure", "Configure", 10, "super-captcha/Configure", array(&$this,"configure_page_4")); add_submenu_page(__FILE__, "ReadMe", "ReadMe", 10, "super-captcha/ReadMe", array(&$this,"configure_page_2")); add_submenu_page(__FILE__, "License", "License", 10, "super-captcha/License", array(&$this,"configure_page_3")); } function getAdminOptions() { // This is just for testing right now... $adminOptions = array("optionName" => "Value", "optionName2" => "Value", "optionName3" => "Value"); $savedOptions = get_option($this->adminOptionsName); if (!empty($savedOptions)) { foreach ($savedOptions as $key => $option) { $adminOptions[$key] = $option; } } update_option($this->adminOptionsName, $adminOptions); return $adminOptions; } function configure_page_1() { // Welcome & Configuration Page. ?>

Super-CAPTCHA Dashboard

VERSION:

Thank you for using Super-CAPTCHA! This particular CAPTCHA system was origionally designed to run on the WordPress Multi User edition and may not function properly on the regular WordPress installs. I have tested it, and it seem sto work fine, but there may be some issues I'm not aware of. If you find any bugs, please report them here. Feel free to leave you feature requests, questions, comments, and donations there as well. Note that the automatic upgrades of this software is only supported 2 version releases back. So version 2.0.0 will only be upgradeable to 2.0.2, afterwards you'll have to manually find the older versions to upgrade each version yourself.

DONATE! | Configure Super-CAPTCHA | Support Super-CAPTCHA (Donate) | View README | View LICENSE

Settings Saved!

Defaults Restored!

Configuration

Live View Listen: Audible CAPTCHA
Visual Verification

Display:  
  Login Page: />
  Registration Page: />
   
Demensions:  
  Width:
  Height:
   
Wordize:  
Activate: />
Note: This will deactivate the random code and use words from your word list below.
List:
You can edit this option manually by uploading your own `words.txt` to PATH-TO-WORDPRESS/wp-content/plugins/super-captcha/includes/words/ .
   
Font Config:  
Type:
Path:
This is the relative path from the plugin directory.
Size:
Size of your font - 30 is default.
Spacing & Angels:  
Character Spacing:
Character Angels:
Coloring:  
Background:
Text Colors:
Use more than 1, and seperate with comas (,) .
Text Transparentcy:
Background Noise:
Archs:

Super-CAPTCHA README

Super-CAPTCHA LICENSE

Secured by Super-CAPTCHA © 2009 MLW & Associates, LLP. All rights reserved.

Visual Verification Audible CAPTCHA Reload CAPTCHA


(Letters ARE case-sensitive)

check($_POST['SpamCode']); if($valid == true) { unset( $_POST['SpamCode'] ); } else { $errors['login_captcha'] = __('ERROR: Please enter correct verification.'); } } elseif(!isset($_POST['SpamCode']) && isset($_POST['log'])) { $errors['login_captcha'] = __('ERROR: The verification field is empty.'); } return $errors; } function signup_form( $errors ) { $error = $errors->get_error_message('captcha'); ?> check($_POST['SpamCode']); if($valid == true) { // GOAL! } else { $myerror = "Please enter correct verification."; } } elseif(!isset($_POST['SpamCode']) && isset($_POST['user_name'])) { $errors = "Please enter verification."; } */ if( isset($myerror) ) { echo '

' . $error . '

'; } ?>

Visual Verification Audible CAPTCHA Reload CAPTCHA

check($_POST['SpamCode']); if($valid == true) { unset( $_POST['SpamCode'] ); $_SESSION['capcha'] = 'pass'; } else { $content['errors']->add('captcha', __('Please enter correct verification.')); $_SESSION['capcha'] = 'fail'; } } elseif($_POST['SpamCode'] == '' && isset($_POST['user_name'])) { $content['errors']->add('captcha', __('Please enter verification.')); $_SESSION['capcha'] = 'fail'; } return( $content ); } function install_on_activation() { global $wpdb; chmod(THIS_DIR, 0755); chmod(THIS_DIR . '/super-captcha.php', 0755); chmod(THIS_DIR . '/includes', 0755); chmod(THIS_DIR . '/includes/elephant.ttf', 0755); chmod(THIS_DIR . '/includes/images', 0755); chmod(THIS_DIR . '/includes/images/audio_icon.gif', 0755); chmod(THIS_DIR . '/includes/images/refresh.gif', 0755); chmod(THIS_DIR . '/includes/words/words.txt', 0755); echo('

Chmoded Files... Updating Database....

'); $plugin_db_version = "2.0.1"; $installed_ver = get_option( "scaptcha_db_version" ); //only run installation if not installed or if previous version installed if ($installed_ver === false || $installed_ver != $plugin_db_version) // if ($installed_ver === false) { $sql = "CREATE TABLE " . $this->db_table_name . " ( conf_id mediumint(9) NOT NULL AUTO_INCREMENT, conf_key VARCHAR(255), conf_val VARCHAR(255), UNIQUE KEY conf_id (conf_id), UNIQUE KEY conf_key (conf_key) ); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('display::login', 'false'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('display::sgup', 'false'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('demensions::width', '200'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('demensions::height', '75'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('type::word', '1'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('font::type', 'ttf'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('font::path', './includes/elephant.ttf'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('format::size', '30'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('format::spacing', '30'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('format::angle', '50'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('color::background', '#e3daed'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('color::text', '#0a68dd,#f65c47,#8d32fd'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('color::transparent', '40'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('color::lines', '#80BFFF'); INSERT INTO " . $this->db_table_name . " (`conf_key`, `conf_val`) VALUES ('color::arc', '#8080ff'); "; require_once(ABSPATH . "wp-admin/upgrade-functions.php"); dbDelta($sql); echo('

Database Installed... Install Complete!

'); //add a database version number for future upgrade purposes update_option("scaptcha_db_version", $plugin_db_version); } } } } new RandomCaptchaSpam(); /** * Securimage CAPTCHA Class. * * @package Securimage * @subpackage classes * */ class Securimage { /** * The desired width of the CAPTCHA image. * * @var int */ var $image_width = IMG_WIDTH; /** * The desired width of the CAPTCHA image. * * @var int */ var $image_height = IMG_HEIGHT; /** * The image format for output.
* Valid options: SI_IMAGE_PNG, SI_IMAGE_JPG, SI_IMAGE_GIF * * @var int */ var $image_type = SI_IMAGE_PNG; /** * The length of the code to generate. * * @var int */ var $code_length = 6; /** * The character set for individual characters in the image.
* Letters are converted to uppercase.
* The font must support the letters or there may be problematic substitutions. * * @var string */ var $charset = 'ABCDEFGHKLMNPRSTUVWYZabdefghijklmnpqrt23456789'; //var $charset = '0123456789'; /** * Create codes using this word list * * @var string The path to the word list to use for creating CAPTCHA codes */ var $wordlist_file = 'includes/words/words.txt'; /** * True to use a word list file instead of a random code * * @var bool */ var $use_wordlist = WORD_LIST; /** * Whether to use a GD font instead of a TTF font.
* TTF offers more support and options, but use this if your PHP doesn't support TTF.
* * @var boolean */ var $use_gd_font = USE_GD_FONT; /** * The GD font to use.
* Internal gd fonts can be loaded by their number.
* Alternatively, a file path can be given and the font will be loaded from file. * * @var mixed */ var $gd_font_file = FONT_PATH; /** * The approximate size of the font in pixels.
* This does not control the size of the font because that is determined by the GD font itself.
* This is used to aid the calculations of positioning used by this class.
* * @var int */ var $gd_font_size = FONT_SIZE; // Note: These font options below do not apply if you set $use_gd_font to true with the exception of $text_color /** * The path to the TTF font file to load. * * @var string */ var $ttf_file = FONT_PATH; /** * The font size.
* Depending on your version of GD, this should be specified as the pixel size (GD1) or point size (GD2)
* * @var int */ var $font_size = FONT_SIZE; /** * The minimum angle in degrees, with 0 degrees being left-to-right reading text.
* Higher values represent a counter-clockwise rotation.
* For example, a value of 90 would result in bottom-to-top reading text. * * @var int */ var $text_angle_minimum = ANGLE_MIN; /** * The minimum angle in degrees, with 0 degrees being left-to-right reading text.
* Higher values represent a counter-clockwise rotation.
* For example, a value of 90 would result in bottom-to-top reading text. * * @var int */ var $text_angle_maximum = ANGLE_MAX; /** * The X-Position on the image where letter drawing will begin.
* This value is in pixels from the left side of the image. * * @var int */ var $text_x_start = 8; /** * Letters can be spaced apart at random distances.
* This is the minimum distance between two letters.
* This should be at least as wide as a font character.
* Small values can cause letters to be drawn over eachother.
* * @var int */ var $text_minimum_distance = SPACE_MIN; /** * Letters can be spaced apart at random distances.
* This is the maximum distance between two letters.
* This should be at least as wide as a font character.
* Small values can cause letters to be drawn over eachother.
* * @var int */ var $text_maximum_distance = SPACE_MAX; /** * The background color for the image.
* This should be specified in HTML hex format.
* Make sure to include the preceding # sign! * * @var string */ var $image_bg_color = BG_COLOR; /** * The text color to use for drawing characters.
* This value is ignored if $use_multi_text is set to true.
* Make sure this contrasts well with the background color.
* Specify the color in HTML hex format with preceding # sign * * @see Securimage::$use_multi_text * @var string */ var $text_color = "#ff0000"; /** * Set to true to use multiple colors for each character. * * @see Securimage::$multi_text_color * @var boolean */ var $use_multi_text = true; /** * String of HTML hex colors to use.
* Separate each possible color with commas.
* Be sure to precede each value with the # sign. * * @var string */ var $multi_text_color = TXT_COLOR; /** * Set to true to make the characters appear transparent. * * @see Securimage::$text_transparency_percentage * @var boolean */ var $use_transparent_text = true; /** * The percentage of transparency, 0 to 100.
* A value of 0 is completely opaque, 100 is completely transparent (invisble) * * @see Securimage::$use_transparent_text * @var int */ var $text_transparency_percentage = TRANS_PCT; // Line options /** * Draw vertical and horizontal lines on the image. * * @see Securimage::$line_color * @see Securimage::$line_distance * @see Securimage::$line_thickness * @see Securimage::$draw_lines_over_text * @var boolean */ var $draw_lines = true; /** * The color of the lines drawn on the image.
* Use HTML hex format with preceding # sign. * * @see Securimage::$draw_lines * @var string */ var $line_color = LINE_COLOR; /** * How far apart to space the lines from eachother in pixels. * * @see Securimage::$draw_lines * @var int */ var $line_distance = 10; /** * How thick to draw the lines in pixels.
* 1-3 is ideal depending on distance * * @see Securimage::$draw_lines * @see Securimage::$line_distance * @var int */ var $line_thickness = 2; /** * Set to true to draw angled lines on the image in addition to the horizontal and vertical lines. * * @see Securimage::$draw_lines * @var boolean */ var $draw_angled_lines = false; /** * Draw the lines over the text.
* If fales lines will be drawn before putting the text on the image.
* This can make the image hard for humans to read depending on the line thickness and distance. * * @var boolean */ var $draw_lines_over_text = false; /** * For added security, it is a good idea to draw arced lines over the letters to make it harder for bots to segment the letters.
* Two arced lines will be drawn over the text on each side of the image.
* This is currently expirimental and may be off in certain configurations. * * @var boolean */ var $arc_linethrough = true; /** * The colors or color of the arced lines.
* Use HTML hex notation with preceding # sign, and separate each value with a comma.
* This should be similar to your font color for single color images. * * @var string */ var $arc_line_colors = ARC_COLOR; /** * Full path to the WAV files to use to make the audio files, include trailing /.
* Name Files [A-Z0-9].wav * * @since 1.0.1 * @var string */ var $audio_path = './includes/audio/'; //END USER CONFIGURATION //There should be no need to edit below unless you really know what you are doing. /** * The gd image resource. * * @access private * @var resource */ var $im; /** * The background image resource * * @access private * @var resource */ var $bgimg; /** * The code generated by the script * * @access private * @var string */ var $code; /** * The code that was entered by the user * * @access private * @var string */ var $code_entered; /** * Whether or not the correct code was entered * * @access private * @var boolean */ var $correct_code; /** * Class constructor.
* Because the class uses sessions, this will attempt to start a session if there is no previous one.
* If you do not start a session before calling the class, the constructor must be called before any * output is sent to the browser. * * * $securimage = new Securimage(); * * */ function Securimage() { if ( session_id() == '') { // no session has been started yet, which is needed for validation session_start(); } } /** * Generate a code and output the image to the browser. * * * show('bg.jpg'); * ?> * * * @param string $background_image The path to an image to use as the background for the CAPTCHA */ function show($background_image = "") { if($background_image != "" && is_readable($background_image)) { $this->bgimg = $background_image; } $this->doImage(); } /** * Validate the code entered by the user. * * * $code = $_POST['code']; * if ($securimage->check($code) == false) { * die("Sorry, the code entered did not match."); * } else { * $valid = true; * } * * @param string $code The code the user entered * @return boolean true if the code was correct, false if not */ function check($code) { $this->code_entered = $code; $this->validate(); return $this->correct_code; } /** * Generate and output the image * * @access private * */ function doImage() { if($this->use_transparent_text == true || $this->bgimg != "") { $this->im = imagecreatetruecolor($this->image_width, $this->image_height); $bgcolor = imagecolorallocate($this->im, hexdec(substr($this->image_bg_color, 1, 2)), hexdec(substr($this->image_bg_color, 3, 2)), hexdec(substr($this->image_bg_color, 5, 2))); imagefilledrectangle($this->im, 0, 0, imagesx($this->im), imagesy($this->im), $bgcolor); } else { //no transparency $this->im = imagecreate($this->image_width, $this->image_height); $bgcolor = imagecolorallocate($this->im, hexdec(substr($this->image_bg_color, 1, 2)), hexdec(substr($this->image_bg_color, 3, 2)), hexdec(substr($this->image_bg_color, 5, 2))); } if($this->bgimg != "") { $this->setBackground(); } $this->createCode(); if (!$this->draw_lines_over_text && $this->draw_lines) $this->drawLines(); $this->drawWord(); if ($this->arc_linethrough == true) $this->arcLines(); if ($this->draw_lines_over_text && $this->draw_lines) $this->drawLines(); $this->output(); } /** * Set the background of the CAPTCHA image * * @access private * */ function setBackground() { $dat = @getimagesize($this->bgimg); if($dat == false) { return; } switch($dat[2]) { case 1: $newim = @imagecreatefromgif($this->bgimg); break; case 2: $newim = @imagecreatefromjpeg($this->bgimg); break; case 3: $newim = @imagecreatefrompng($this->bgimg); break; case 15: $newim = @imagecreatefromwbmp($this->bgimg); break; case 16: $newim = @imagecreatefromxbm($this->bgimg); break; default: return; } if(!$newim) return; imagecopy($this->im, $newim, 0, 0, 0, 0, $this->image_width, $this->image_height); } /** * Draw arced lines over the text * * @access private * */ function arcLines() { $colors = explode(',', $this->arc_line_colors); imagesetthickness($this->im, 3); $color = $colors[rand(0, sizeof($colors) - 1)]; $linecolor = imagecolorallocate($this->im, hexdec(substr($color, 1, 2)), hexdec(substr($color, 3, 2)), hexdec(substr($color, 5, 2))); $xpos = $this->text_x_start + ($this->font_size * 2) + rand(-5, 5); $width = $this->image_width / 2.66 + rand(3, 10); $height = $this->font_size * 2.14 - rand(3, 10); if ( rand(0,100) % 2 == 0 ) { $start = rand(0,66); $ypos = $this->image_height / 2 - rand(5, 15); $xpos += rand(5, 15); } else { $start = rand(180, 246); $ypos = $this->image_height / 2 + rand(5, 15); } $end = $start + rand(75, 110); imagearc($this->im, $xpos, $ypos, $width, $height, $start, $end, $linecolor); $color = $colors[rand(0, sizeof($colors) - 1)]; $linecolor = imagecolorallocate($this->im, hexdec(substr($color, 1, 2)), hexdec(substr($color, 3, 2)), hexdec(substr($color, 5, 2))); if ( rand(1,75) % 2 == 0 ) { $start = rand(45, 111); $ypos = $this->image_height / 2 - rand(5, 15); $xpos += rand(5, 15); } else { $start = rand(200, 250); $ypos = $this->image_height / 2 + rand(5, 15); } $end = $start + rand(75, 100); imagearc($this->im, $this->image_width * .75, $ypos, $width, $height, $start, $end, $linecolor); } /** * Draw lines on the image * * @access private * */ function drawLines() { $linecolor = imagecolorallocate($this->im, hexdec(substr($this->line_color, 1, 2)), hexdec(substr($this->line_color, 3, 2)), hexdec(substr($this->line_color, 5, 2))); imagesetthickness($this->im, $this->line_thickness); //vertical lines for($x = 1; $x < $this->image_width; $x += $this->line_distance) { imageline($this->im, $x, 0, $x, $this->image_height, $linecolor); } //horizontal lines for($y = 11; $y < $this->image_height; $y += $this->line_distance) { imageline($this->im, 0, $y, $this->image_width, $y, $linecolor); } if ($this->draw_angled_lines == true) { for ($x = -($this->image_height); $x < $this->image_width; $x += $this->line_distance) { imageline($this->im, $x, 0, $x + $this->image_height, $this->image_height, $linecolor); } for ($x = $this->image_width + $this->image_height; $x > 0; $x -= $this->line_distance) { imageline($this->im, $x, 0, $x - $this->image_height, $this->image_height, $linecolor); } } } /** * Draw the CAPTCHA code over the image * * @access private * */ function drawWord() { if ($this->use_gd_font == true) { if (!is_int($this->gd_font_file)) { //is a file name $font = @imageloadfont($this->gd_font_file); if ($font == false) { trigger_error("Failed to load GD Font file {$this->gd_font_file} ", E_USER_WARNING); return; } } else { //gd font identifier $font = $this->gd_font_file; } $color = imagecolorallocate($this->im, hexdec(substr($this->text_color, 1, 2)), hexdec(substr($this->text_color, 3, 2)), hexdec(substr($this->text_color, 5, 2))); imagestring($this->im, $font, $this->text_x_start, ($this->image_height / 2) - ($this->gd_font_size / 2), $this->code, $color); } else { //ttf font if($this->use_transparent_text == true) { $alpha = intval($this->text_transparency_percentage / 100 * 127); $font_color = imagecolorallocatealpha($this->im, hexdec(substr($this->text_color, 1, 2)), hexdec(substr($this->text_color, 3, 2)), hexdec(substr($this->text_color, 5, 2)), $alpha); } else { //no transparency $font_color = imagecolorallocate($this->im, hexdec(substr($this->text_color, 1, 2)), hexdec(substr($this->text_color, 3, 2)), hexdec(substr($this->text_color, 5, 2))); } $x = $this->text_x_start; $strlen = strlen($this->code); $y_min = ($this->image_height / 2) + ($this->font_size / 2) - 2; $y_max = ($this->image_height / 2) + ($this->font_size / 2) + 2; $colors = explode(',', $this->multi_text_color); for($i = 0; $i < $strlen; ++$i) { $angle = rand($this->text_angle_minimum, $this->text_angle_maximum); $y = rand($y_min, $y_max); if ($this->use_multi_text == true) { $idx = rand(0, sizeof($colors) - 1); $r = substr($colors[$idx], 1, 2); $g = substr($colors[$idx], 3, 2); $b = substr($colors[$idx], 5, 2); if($this->use_transparent_text == true) { $font_color = imagecolorallocatealpha($this->im, "0x$r", "0x$g", "0x$b", $alpha); } else { $font_color = imagecolorallocate($this->im, "0x$r", "0x$g", "0x$b"); } } @imagettftext($this->im, $this->font_size, $angle, $x, $y, $font_color, $this->ttf_file, $this->code{$i}); $x += rand($this->text_minimum_distance, $this->text_maximum_distance); } //for loop } //else ttf font } //function /** * Create a code and save to the session * * @since 1.0.1 * */ function createCode() { $this->code = false; if ($this->use_wordlist && is_readable($this->wordlist_file)) { $this->code = $this->readCodeFromFile(); } if ($this->code == false) { $this->code = $this->generateCode($this->code_length); } $this->saveData(); } /** * Generate a code * * @access private * @param int $len The code length * @return string */ function generateCode($len) { $code = ''; for($i = 1, $cslen = strlen($this->charset); $i <= $len; ++$i) { $code .= strtoupper( $this->charset{rand(0, $cslen - 1)} ); } return $code; } /** * Reads a word list file to get a code * * @access private * @since 1.0.2 * @return mixed false on failure, a word on success */ function readCodeFromFile() { $fp = @fopen($this->wordlist_file, 'rb'); if (!$fp) return false; $fsize = filesize($this->wordlist_file); if ($fsize < 32) return false; // too small of a list to be effective if ($fsize < 128) { $max = $fsize; // still pretty small but changes the range of seeking } else { $max = 128; } fseek($fp, rand(0, $fsize - $max), SEEK_SET); $data = fread($fp, 128); // read a random 128 bytes from file fclose($fp); $data = preg_replace("/\r?\n/", "\n", $data); $start = strpos($data, "\n", rand(0, 100)) + 1; // random start position $end = strpos($data, "\n", $start); // find end of word return strtolower(substr($data, $start, $end - $start)); // return substring in 128 bytes } /** * Output image to the browser * * @access private * */ function output() { header("Expires: Sun, 1 Jan 2000 12:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); switch($this->image_type) { case SI_IMAGE_JPEG: header("Content-Type: image/jpeg"); imagejpeg($this->im, null, 90); break; case SI_IMAGE_GIF: header("Content-Type: image/gif"); imagegif($this->im); break; default: header("Content-Type: image/png"); imagepng($this->im); break; } imagedestroy($this->im); } /** * Get WAV file data of the spoken code.
* This is appropriate for output to the browser as audio/x-wav * * @since 1.0.1 * @return string WAV data * */ function getAudibleCode() { $letters = array(); $code = $this->getCode(); if ($code == '') { $this->createCode(); $code = $this->getCode(); } for($i = 0; $i < strlen($code); ++$i) { $letters[] = $code{$i}; } return $this->generateWAV($letters); } /** * Save the code in the session * * @access private * */ function saveData() { $_SESSION['securimage_code_value'] = strtolower($this->code); } /** * Validate the code to the user code * * @access private * */ function validate() { if ( isset($_SESSION['securimage_code_value']) && !empty($_SESSION['securimage_code_value']) ) { if ( $_SESSION['securimage_code_value'] == strtolower(trim($this->code_entered)) ) { $this->correct_code = true; $_SESSION['securimage_code_value'] = ''; } else { $this->correct_code = false; } } else { $this->correct_code = false; } } /** * Get the captcha code * * @since 1.0.1 * @return string */ function getCode() { if (isset($_SESSION['securimage_code_value']) && !empty($_SESSION['securimage_code_value'])) { return $_SESSION['securimage_code_value']; } else { return ''; } } /** * Check if the user entered code was correct * * @access private * @return boolean */ function checkCode() { return $this->correct_code; } /** * Generate a wav file by concatenating individual files * @since 1.0.1 * @access private * @param array $letters Array of letters to build a file from * @return string WAV file data */ function generateWAV($letters) { $first = true; // use first file to write the header... $data_len = 0; $files = array(); $out_data = ''; foreach ($letters as $letter) { $filename = $this->audio_path . strtoupper($letter) . '.wav'; $fp = fopen($filename, 'rb'); $file = array(); $data = fread($fp, filesize($filename)); // read file in $header = substr($data, 0, 36); $body = substr($data, 44); $data = unpack('NChunkID/VChunkSize/NFormat/NSubChunk1ID/VSubChunk1Size/vAudioFormat/vNumChannels/VSampleRate/VByteRate/vBlockAlign/vBitsPerSample', $header); $file['sub_chunk1_id'] = $data['SubChunk1ID']; $file['bits_per_sample'] = $data['BitsPerSample']; $file['channels'] = $data['NumChannels']; $file['format'] = $data['AudioFormat']; $file['sample_rate'] = $data['SampleRate']; $file['size'] = $data['ChunkSize'] + 8; $file['data'] = $body; if ( ($p = strpos($file['data'], 'LIST')) !== false) { // If the LIST data is not at the end of the file, this will probably break your sound file $info = substr($file['data'], $p + 4, 8); $data = unpack('Vlength/Vjunk', $info); $file['data'] = substr($file['data'], 0, $p); $file['size'] = $file['size'] - (strlen($file['data']) - $p); } $files[] = $file; $data = null; $header = null; $body = null; $data_len += strlen($file['data']); fclose($fp); } $out_data = ''; for($i = 0; $i < sizeof($files); ++$i) { if ($i == 0) { // output header $out_data .= pack('C4VC8', ord('R'), ord('I'), ord('F'), ord('F'), $data_len + 36, ord('W'), ord('A'), ord('V'), ord('E'), ord('f'), ord('m'), ord('t'), ord(' ')); $out_data .= pack('VvvVVvv', 16, $files[$i]['format'], $files[$i]['channels'], $files[$i]['sample_rate'], $files[$i]['sample_rate'] * (($files[$i]['bits_per_sample'] * $files[$i]['channels']) / 8), ($files[$i]['bits_per_sample'] * $files[$i]['channels']) / 8, $files[$i]['bits_per_sample'] ); $out_data .= pack('C4', ord('d'), ord('a'), ord('t'), ord('a')); $out_data .= pack('V', $data_len); } $out_data .= $files[$i]['data']; } return $out_data; } } /* class Securimage */ ?>