Perl CAPTCHA
File keycaptcha.pm with CAPTCHA API implementation:
package KeyCAPTCHA;
use strict;
use warnings;
use Digest::MD5 qw(md5 md5_hex);
use CGI qw/:standard/;
use LWP::Simple;
# Replace PUT_YOUR_PRIVATE_KEY_HERE and PUT_YOUR_USER_ID_HERE
# with proper values from your keycaptcha.com account
my $kc_private_key='PUT_YOUR_PRIVATE_KEY_HERE';
my $kc_user_id = 'PUT_YOUR_USER_ID_HERE';
sub generate_random_string {
my $res = '';
$res.= chr int rand(26)+96 for 1..8;
return $res;
}
sub get_captcha{
my $self = shift;
my $p_kc_js_code = "<!-- KeyCAPTCHA code (www.keycaptcha.com) -->
<script type='text/javascript'>
var s_s_c_user_id = '$kc_user_id';
var s_s_c_session_id = '#KC_SESSION_ID#';
var s_s_c_captcha_field_id = 'capcode';
var s_s_c_submit_button_id = 'postbut';
var s_s_c_web_server_sign = '#KC_WSIGN#';
var s_s_c_web_server_sign2 = '#KC_WSIGN2#';
</script>
<script language=JavaScript src='http://backs.keycaptcha.com/swfs/cap.js'></script>
<!-- end of KeyCAPTCHA code -->
";
my $p_kc_session_id = generate_random_string();
$p_kc_session_id = md5_hex($p_kc_session_id).'-4.1.0.001';
my $p_kc_web_server_sign = md5_hex($p_kc_session_id . $ENV{'REMOTE_ADDR'} . $kc_private_key);
my $p_kc_web_server_sign2 = md5_hex($p_kc_session_id . $kc_private_key);
my $session_id_str = "#KC_SESSION_ID#";
$session_id_str = quotemeta $session_id_str;
$p_kc_js_code =~ s/$session_id_str/$p_kc_session_id/g;
my $web_server_sign2_str = "#KC_WSIGN2#";
$web_server_sign2_str = quotemeta $web_server_sign2_str;
$p_kc_js_code =~ s/$web_server_sign2_str/$p_kc_web_server_sign2/g;
my $web_server_sign_str = "#KC_WSIGN#";
$web_server_sign_str = quotemeta $web_server_sign_str;
$p_kc_js_code =~ s/$web_server_sign_str/$p_kc_web_server_sign/g;
return $p_kc_js_code;
}
sub validate_captcha {
my ($response) = @_;
unless ( $response ) {
return 0;
}
my @kc_vars = split(/\|/, $response);
if ( scalar(@kc_vars) < 4 ) {
return 0;
}
my $kc_s = md5_hex("accept" . $kc_vars[1] . $kc_private_key . $kc_vars[2]);
if ( $kc_s != $kc_vars[0] ) {
return 0;
}
if ( index($kc_vars[2], "http://") == 0 ) {
my $c = get ($kc_vars[2]);
if ( $c == '1' ) {
return 1;
}
}
return 0;
}
1;
File index.pl for showing and proceeding form protected by CAPTCHA:
#!/usr/bin/perl
use CGI qw/:standard/;
sub populatePostFields {
%postFields = ();
read( STDIN, $tmpStr, $ENV{ "CONTENT_LENGTH" } );
@parts = split( /\&/, $tmpStr );
foreach $part (@parts) {
( $name, $value ) = split( /\=/, $part );
$value =~ ( s/%23/\#/g );
$value =~ ( s/%2F/\//g );
$postFields{ "$name" } = $value;
}
}
print "Content-type: text/html\n\n";
# Replace PATH_TO_KEYCAPTHA with real path to keycaptcha.pm
require ('/PATH_TO_KEYCAPTHA/keycaptcha.pm');
print $ENV{'REMOTE_ADDR'};
print "\n<form method=\"POST\" action=\"\">";
print(KeyCAPTCHA::get_captcha());
print "<input type=hidden id=\"capcode\" name= \"capcode\" value=\"false\">\n";
print "<input name=\"name\">";
print "<input type=submit id=\"postbut\">";
print '</form>';
if(request_method() eq 'POST'){
&populatePostFields;
my $capcode = $postFields{'capcode'};
$capcode =~ s/%([a-f0-9]{2})/pack('C', hex($1))/egi;
my $res = KeyCAPTCHA::validate_captcha($capcode);
if ($res == 1){
print ("right");
}else {
print ("false");
}
}