Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Authen::PluggableCaptcUser)Contributed Perl DocumenAuthen::PluggableCaptcha(3)

       Authen::PluggableCaptcha	- A pluggable Captcha framework	for Perl

       IMPORTANT-- the .03 release is incompatible with	earlier	versions.
       Most notably: all external hooks	for hash mangling have been replaced
       with object methods ( ie: $obj->{'__Challenge'} is now $obj->challenge
       ) and keyword arguments expecting a class name have the word '_class'
       as a suffix.

       Authen::PluggableCaptcha	is a framework for creating Captchas , based
       on the idea of creating Captchas	with a plugin architecture.

       The power of this module	is that	it creates Captchas in the sense that
       a programmer writes Perl	modules-- not just in the sense	that a
       programmer calls	a Captcha library for display.

       The essence of a	Captcha	has been broken	down into three	components:
       KeyManager , Challenge and Render -- all	of which programmers now have
       full control over.  Mix and match existing classes or create your own.
       Authen::PluggableCaptcha	helps you make your own	captcha	tests -- and
       it helps	you do it fast.

       The KeyManager component	handles	creating & validatiing keys that are
       later used to uniquely identify a CAPTCHA.  By default the KeyManager
       uses a time-based key system, but it can	be trivially extended to
       integrate with a	database and make single-use keys.

       The Challenge component maps a key to a set of instructions, a user
       prompt ,	and a correct response.

       The render component is used to display the challenge - be it text,
       image or	sound.

	 use Authen::PluggableCaptcha;
	 use Authen::PluggableCaptcha::Challenge::TypeString;
	 use Authen::PluggableCaptcha::Render::Image::Imager;

	 # create a new	captcha	for your form
	 my $captcha= Authen::PluggableCaptcha->new(
	   type=> "new",
	   seed=> $session->user->seed ,
	   site_secret=> $MyApp::Config::site_secret
	 my $captcha_publickey=	$captcha->get_publickey();

	 # image captcha?  create an html link to your captcha script with the public key
	 my $html= qq|<img src="/path/to/${captcha_publickey}"/>|;

	 # image captcha?  render it
	 my $existing_publickey= 'a33d8ce53691848ee1096061dfdd4639_1149624525';
	 my $existing_publickey	= $apr->param('captcha_publickey');
	 my $captcha= Authen::PluggableCaptcha->new(
	   type=> 'existing' ,
	   publickey=> $existing_publickey ,
	   seed=> $session->user->seed ,
	   site_secret=> $MyApp::Config::site_secret

	 # save	it as a	file
	 my $as_string=	$captcha->render(
	   challenge_class=> 'Authen::PluggableCaptcha::Challenge::TypeString',
	   render_class=>'Authen::PluggableCaptcha::Render::Image::Imager' ,
	 open(WRITE, ">test.jpg");
	 print WRITE $as_string;

	 # or serve it yourself
	 $r->add_header('Content Type: image/jpeg');
	 $r->print( $as_string );

	 # wait, what if we want to validate the captcha first?
	 my $captcha= Authen::PluggableCaptcha->new(
	   type=> 'existing' ,
	   publickey=> $apr->param('captcha_publickey'),
	   seed=> $session->user->seed ,
	   site_secret=	$MyApp::Config::site_secret
	 if ( !$captcha->validate_response( user_response=> $apr->param('captcha_response') ) )	{
		 my $reason= $captcha->get_error('validate_response');
		 die "could not	validate captcha because: ${reason}.";

       in the above example, $captcha->new just	configures the captcha.
       $captcha->render	actually renders the image.  if	the captcha is expired
       (too old	by the default configuration) ,	the default expired captcha
       routine from the	plugin will take place better yet, handle all the
       timely and ip/request validation	in the application logic.  the
       timeliness just makes someone answer a captcha 1x every 5minutes, but
       doesn't prevent re/mis use

       render accepts a	'render_class' argument	that will internally dispatch
       the routines to a new instance of that class.

       using this method, multiple renderings and formats can be created using
       a single	key and	challenge.

       Authen::PluggableCaptcha	is a fully modularized and extensible system
       for making Pluggable Catpcha (Completely	Automated Public Turing	Test
       to Tell Computers and Humans Apart) tests.

       Pluggable?  All Captcha objects are instantiated	and interfaced via the
       main module, and	then manipulated to require various submodules as

       Authen::PluggableCaptcha	borrows	from the functionality in

   The Base Modules:

	 Consolidates functionality previously found in	KeyGenerator and KeyValidator

	 Generates , parses and	validates publickeys which are used to validate	and create captchas
	 Default is Authen::PluggableCaptcha::KeyManager , which makes a key %md5%_%time% and performs no additional checking

	 A subclass is highly recommended.
	 Subclasses can	contain	a regex	or a bunch of DB interaction stuff to ensure a key is used only	one time per ip	address


	 simply	put, a challenge is a test.
	 challenges internally require a ref to	a KeyManager instance ,	it then	maps that instance via it's own	facilities into	a test to render or validate
	 a challege generates 3	bits of	text:

	 a visual captcha would	have user_prompt and correct_response as the same.
	 a text	logic puzzle would not.


	 the rendering of a captcha for	presentation to	a user.
	 This could be an image, sound,	block of (obfuscated?) html or just plain text

Reasoning (reinventing the wheel)
       Current CPAN captcha modules all	exhibit	one or more of the following

       - the module is tied heavily into a given image rendering library
       - the module only supports a single style of an image Catpcha
       - the module renders/saves the image to disk

       I wanted	a module that works in a clustered environment,	could be
       easily extended / implemented with the following	design requirements:

       1 challenges are	presented by a public_key
       2 a seed	(sessionID ?) +	a server key (siteSecret) hash together	to
       create a	public key
       3 the public_key	is handled by its own module which can be subclassed
       and replaced as long as it provides the required	methods

       with this method, generating a public key 'your own way'	is very	easy,
       so the module integrates	easily into your app


       o   the public_key creates a captcha test / challenge ( instructions ,
	   user_prompt , correct_repsonse ) for	presentation or	validation

	   - the captcha test is handled by its	own module which can be
	   subclassed as long as it provides the required methods
	   - want to upgrade a test? its right there
	   - want a private test?  create a new	subclass
	   - want to add tests to cpan?	 please	do!
       o   the rendering is then handled by its	own module which can be
	   subclassed as long as it provides the required methods

       o   the rendering doesn't just render a jpg for a visual	captcha... the
	   captcha challenge can then be rendered in any format

	   - image
	   - audio
	   - text

       any single component can	be extended or replaced	- that means you can
       cheaply/easily/quickly create new captchas as older ones	get defeated.
       instead of going	crazy trying to	make the worlds	best captcha, you can
       just make a ton of crappy ones that are faster to make than to break :)

       everything is standardized and made for modular interaction since the
       public_key maps to a captcha test, the same key can create an
       image/audio/text	captcha,

       Note that Render::Image is never	called - it is just a base class.  The
       module ships with Render::Img::Imager, which uses the Imager library.
       Its admittedly not very good- it	is simple a proof-of-concept.

       want gd/imagemagick?  write Render::Img::GD or
       Render::Image::ImageMagick with the appropriate hooks (and submit to

       This functionality exists so that you don't need	to run GD on your box
       if you've got a mod_perl	setup that aready uses Imager.

       Using any of the	image libraries	should be a snap- just write a render
       class that can create an	image with 'user_prompt' text, and returns
       'as_string' Using any of	the audio libraries will work in the same
       manner too.

       Initial support includes	the ability to have Textual logic Catptchas.
       They do silly things like say "What is one plus one ? (as text in
       english)" HTML::Email::Obfuscate	makes these hard to scrape, though a
       better solution is needed and welcome.

       One of the main points of PluggableCaptcha is that even if you create a
       Captcha that is one step	ahead of spammers ( read: assholes ) , they're
       not giving up --	they're	just going to take longer to break the
       Captcha-- and once they do, you're sweating trying to protect yourself

       With PluggableCaptcha, it should	be easier to :

       a- create new captchas cheaply: make a new logic	puzzle , a new way of
       rendering images	, or change the	random character builder into
       something that creates strings that look	like words, so people can
       spell them easier.
       b- customize existing captchas: subclass	captchas from the distribution
       , or others people submit to CPAN. create some site specific changes on
       the way fonts are rendered, etc.
       c- constantly change captchas ON	THE FLY.  mix and match	render and
       challenge classes.  the only thing that would take much work is
       swapping	from a text to an image.  but 1	line of	code controls what is
       in the image, or	how to solve it!

       Under this system, ideally, people can change / adapt / update so fast
       , that spammers never get a break in their efforts to break captcha

       new PARAMS Returns a new	Authen::PluggableCaptcha object	constructed
       according to PARAMS, where PARAMS are name/value	pairs.
	   PARAMS are name/value pairs.

	   Required PARAMS are:

	   "type TYPE"
		   Type	of captcha. Valid options are 'new' or 'existing'

	   "seed TYPE"
		   seed	used for key management.  this could be	a session id,
		   a session id	+ url,	an empty string, or any	other defined

	   "site_secret	TYPE"
		   site_secret used for	key management.	 this could be a
		   shared value	for your website.

	   Optional PARAMS are:

	   "keymanager_args TYPE"
		   The value for the keymanager_args key will be sent to the
		   KeyManager on instantiation as 'keymanager_args'

		   This	is useful if you need to specify a DB connection or
		   something similar to	the keymanager

	   "do_not_validate_key	INT"
		   This	is valid only for 'existing' type captchas.

		   passing this	argument as the	integer	'1'(1) will not
		   validate the	publickey in the keymanager.

		   This	is useful if you are externally	handling the key
		   management, and just	use this package for Render +

       captcha_type TYPE
	   get the captcha type

	   returns an instance of the active keymanager

       challenge_instance TYPE
	   returns an instance of a challenge class TYPE

       render_instance TYPE
	   returns an instance of a render class TYPE

	   calls a die if the captcha is invalid

	   returns a publickey from the	keymanager.

	   instructs the keymanager to expire the publickey. on	success
	   returns 1 and sets the captcha as invalid and expired.  returns 0
	   on failure and -1 on	error.

	   Validates a user response against the key/time for this captcha

	   returns 1 on	sucess,	0 on failure, -1 on error.

       render PARAMS
	   renders the captcha based on	the kw_args submitted in PARAMS

	   returns the rendered	captcha	as a string

	   PARAMS are required name/value pairs.  Required PARAMS are:

	   "challenge_class TYPE" Full name of a
	   Authen::PluggableCaptcha::Challenge derived class
	   "render_class TYPE" Full name of a Authen::PluggableCaptcha::Render
	   derived class

       Set the Following envelope variables for	debugging


       debug messages are sent to STDERR via the ErrorLoggingObject package

       This is an initial alpha	release.

       There are a host	of issues with it.  Most are discussed here:

       To Do:

	       priority	| task
	       +++| clean up how stuff is stored / passed around / accessing defaults.	there's	a lot of messy stuff with in regards to	passing	around default values and redundancy of	vars
	       +++| create a better way	to make	attributes shared stored and accessed
	       ++ | Imager does	not have facilities right now to do a 'sine warp' easily.  figure some sort of text warping for	the imager module.
	       ++ | Port the rendering portions	of cpan	gd/imagemagick captchas	to Img::(GD|ImageMagick)
	       ++ | Img::Imager	make the default font more of a	default
	       ++ | Img::Imager	add in support to render each letter seperately	w/a different font/size
	       +  | Img::Imager	better handle as_string/save + support for png format etc
	       -  | is there a way to make the default font more cross platform?
	       -- | add	a sound	plugin ( text-logic might render that a	trivial	enhancement depending on how obfuscation treats	display	)

       If you make your	own subclasses or patches, please keep this
       information in mind:

	       The '.' and '..'	prefixes are reserved namespaces ( ie: $self->{'.Attributes'} ,	$self->{'..Errors'} )

	       Generally: '.' prefixes a shared	or inherited trait ; '..' prefixes an class private variable

	       If you see a function with _ in the code, its undocumented and unsupported.  Only write code against regular looking functions.	Never write code against _ or __ functions.  Never.

       Many ideas , most notably the approach to creating layered images, came
       from PyCaptcha ,

       Jonathan	Vanasco	,

       Patches,	support, features, additional etc

	       Kjetil Kjernsmo,

       Copyright (C) 2006 by Jonathan Vanasco

       This library is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

       Hey! The	above document had some	coding errors, which are explained

       Around line 294:
	   You forgot a	'=back'	before '=head1'

       Around line 545:
	   =pod	directives shouldn't be	over one line long!  Ignoring all 2
	   lines of content

       Around line 587:
	   =pod	directives shouldn't be	over one line long!  Ignoring all 2
	   lines of content

       Around line 657:
	   =pod	directives shouldn't be	over one line long!  Ignoring all 2
	   lines of content

       Around line 671:
	   =pod	directives shouldn't be	over one line long!  Ignoring all 2
	   lines of content

       Around line 688:
	   =pod	directives shouldn't be	over one line long!  Ignoring all 2
	   lines of content

       Around line 760:
	   =pod	directives shouldn't be	over one line long!  Ignoring all 2
	   lines of content

       Around line 822:
	   =pod	directives shouldn't be	over one line long!  Ignoring all 2
	   lines of content

perl v5.32.1			  2007-02-27	   Authen::PluggableCaptcha(3)


Want to link to this manual page? Use this URL:

home | help