bridgedb.captcha

This module implements various methods for obtaining or creating CAPTCHAs.

Inheritance diagram of CaptchaExpired, CaptchaKeyError, GimpCaptchaError, Captcha, ReCaptcha, GimpCaptcha

Module Overview:

bridgedb.captcha
 |- CaptchaExpired - Raised if a solution is given for a stale CAPTCHA.
 |- CaptchaKeyError - Raised if a CAPTCHA system's keys are invalid/missing.
 |- GimpCaptchaError - Raised when a Gimp CAPTCHA can't be retrieved.
 |
 \_ ICaptcha - Zope Interface specification for a generic CAPTCHA.
      |
    Captcha - Generic base class implementation for obtaining a CAPTCHA.
    |  |- image - The CAPTCHA image.
    |  |- challenge - A unique string associated with this CAPTCHA image.
    |  |- publicKey - The public key for this CAPTCHA system.
    |  |- secretKey - The secret key for this CAPTCHA system.
    |   \_ get() - Get a new pair of CAPTCHA image and challenge strings.
    |
    |- ReCaptcha - Obtain reCaptcha images and challenge strings.
    |   \_ get() - Request an image and challenge from a reCaptcha API server.
    |
    \_ GimpCaptcha - Class for obtaining a CAPTCHA from a local cache.
        |- hmacKey - A client-specific key for HMAC generation.
        |- cacheDir - The path to the local CAPTCHA cache directory.
        |- sched - A class for timing out CAPTCHAs after an interval.
        \_ get() - Get a CAPTCHA image from the cache and create a challenge.

There are two types of CAPTCHAs which BridgeDB knows how to serve: those obtained by from a reCaptcha API server with Raptcha, and those which have been generated with gimp-captcha and then cached locally.

exception CaptchaExpired[source]

Bases: exceptions.ValueError

Raised when a client’s CAPTCHA is too stale.

exception CaptchaKeyError[source]

Bases: exceptions.Exception

Raised if a CAPTCHA system’s keys are invalid or missing.

exception GimpCaptchaError[source]

Bases: exceptions.Exception

General exception raised when a Gimp CAPTCHA cannot be retrieved.

interface ICaptcha[source]

Interface specification for CAPTCHAs.

image

A string containing the contents of a CAPTCHA image file.

challenge

A unique string associated with the dispursal of this CAPTCHA.

publicKey

A public key used for encrypting CAPTCHA challenge strings.

secretKey

A private key used for decrypting challenge strings during CAPTCHAsolution verification.

get()

Retrieve a new CAPTCHA image.

class Captcha(publicKey=None, secretKey=None)[source]

Bases: object

A generic CAPTCHA base class.

Variables:
  • image (str) – The CAPTCHA image.
  • challenge (str) – A challenge string which should permit checking of the client’s CAPTCHA solution in some manner. In stateless protocols such as HTTP, this should be passed along to the client with the CAPTCHA image.
  • publicKey (str) – A public key used for encrypting CAPTCHA challenge strings.
  • secretKey (str) – A private key used for decrypting challenge strings during CAPTCHA solution verification.

Obtain a new CAPTCHA for a client.

get()[source]

Retrieve a new CAPTCHA image and its associated challenge string.

The image and challenge will be stored as image and challenge, respectively.

class ReCaptcha(publicKey=None, secretKey=None)[source]

Bases: bridgedb.captcha.Captcha

A CAPTCHA obtained from a remote reCaptcha API server.

Variables:
  • image (str) – The CAPTCHA image.
  • challenge (str) – The 'recaptcha_challenge_response' HTTP form field to pass to the client, along with the CAPTCHA image. See BridgeDB's captcha.html Mako template for an example usage.
  • publicKey (str) – The public reCaptcha API key.
  • secretKey (str) – The private reCaptcha API key.

Create a new ReCaptcha CAPTCHA.

Parameters:
  • publicKey (str) – The public reCaptcha API key.
  • secretKey (str) – The private reCaptcha API key.
get()[source]

Retrieve a CAPTCHA from the reCaptcha API server.

This simply requests a new CAPTCHA from recaptcha.client.captcha.API_SSL_SERVER and parses the returned HTML to extract the CAPTCHA image and challenge string. The image is stored at ReCaptcha.image and the challenge string at ReCaptcha.challenge.

Raises:
  • CaptchaKeyError – If either the publicKey or secretKey are missing.
  • HTTPError – If the server returned any HTTP error status code.
class GimpCaptcha(publicKey=None, secretKey=None, hmacKey=None, cacheDir=None)[source]

Bases: bridgedb.captcha.Captcha

A locally cached CAPTCHA image which was created with gimp-captcha.

Variables:
  • publicKey (str) – A PKCS#1 OAEP-padded, public RSA key. This is used to hide the correct CAPTCHA solution within the captcha_challenge_field HTML form field. That form field is given to the a client along with the image during the initial CAPTCHA request, and the client should give it back to us later during the CAPTCHA solution verification step.
  • secretKey (str) – A PKCS#1 OAEP-padded, private RSA key, used for verifying the client’s solution to the CAPTCHA.
  • hmacKey (bytes) – A client-specific HMAC secret key.
  • cacheDir (str) – The local directory which pre-generated CAPTCHA images have been stored in. This can be set via the GIMP_CAPTCHA_DIR setting in the config file.
  • sched (bridgedb.schedule.ScheduledInterval) – A time interval. After this amount time has passed, the CAPTCHA is considered stale, and all solutions are considered invalid regardless of their correctness.

Create a GimpCaptcha which retrieves images from cacheDir.

Parameters:
  • publicKey (str) – A PKCS#1 OAEP-padded, public RSA key, used for creating the captcha_challenge_field string to give to a client.
  • secretKey (str) – A PKCS#1 OAEP-padded, private RSA key, used for verifying the client’s solution to the CAPTCHA.
  • hmacKey (bytes) – A client-specific HMAC secret key.
  • cacheDir (str) – The local directory which pre-generated CAPTCHA images have been stored in. This can be set via the GIMP_CAPTCHA_DIR setting in the config file.
Raises:
  • GimpCaptchaError – if cacheDir is not a directory.
  • CaptchaKeyError – if any of secretKey, publicKey, or hmacKey are invalid or missing.
sched = <bridgedb.schedule.ScheduledInterval object>
classmethod check(challenge, solution, secretKey, hmacKey)[source]

Check a client’s CAPTCHA solution against the challenge.

Parameters:
  • challenge (str) – The contents of the 'captcha_challenge_field' HTTP form field.
  • solution (str) – The client’s proposed solution to the CAPTCHA that they were presented with.
  • secretKey (str) – A PKCS#1 OAEP-padded, private RSA key, used for verifying the client’s solution to the CAPTCHA.
  • hmacKey (bytes) – A private key for generating HMACs.
Raises CaptchaExpired:
 

if the solution was for a stale CAPTCHA.

Return type:

bool

Returns:

True if the CAPTCHA solution was correct and not stale. False otherwise.

createChallenge(answer)[source]

Encrypt-then-HMAC a timestamp plus the CAPTCHA answer.

A challenge string consists of a URL-safe, base64-encoded string which contains an HMAC concatenated with an ENC_BLOB, in the following form:

CHALLENGE := B64( HMAC | ENC_BLOB )
ENC_BLOB := RSA_ENC( ANSWER_BLOB )
ANSWER_BLOB := ( TIMESTAMP | ANSWER )
where
  • B64 is a URL-safe base64-encode function,
  • RSA_ENC is the PKCS#1 RSA-OAEP encryption function,
  • and the remaining feilds are specified as follows:
Field Description Length
HMAC An HMAC of the ENC_BLOB, created with the client-specific hmacKey, by applying getHMAC() to the ENC_BLOB. 20 bytes
ENC_BLOB An encrypted ANSWER_BLOB, created with a PKCS#1 OAEP-padded RSA publicKey. varies
ANSWER_BLOB Contains the concatenated TIMESTAMP and ANSWER. varies
TIMESTAMP A Unix Epoch timestamp, in seconds, left-padded with “0”s. 12 bytes
ANSWER A string containing answer to this CAPTCHA image. 8 bytes

The steps taken to produce a CHALLENGE are then:

  1. Create a TIMESTAMP, and pad it on the left with ``0``s to 12 bytes in length.
  2. Next, take the answer to this CAPTCHA image and concatenate the padded TIMESTAMP and the ANSWER, forming an ANSWER_BLOB.
  3. Encrypt the resulting ANSWER_BLOB to publicKey to create the ENC_BLOB.
  4. Use the client-specific hmacKey to apply the getHMAC() function to the ENC_BLOB, obtaining an HMAC.
  5. Create the final CHALLENGE string by concatenating the HMAC and ENC_BLOB, then base64-encoding the result.
Parameters:answer (str) – The answer to a CAPTCHA.
Return type:str
Returns:A challenge string.
get()[source]

Get a random CAPTCHA from the cache directory.

This chooses a random CAPTCHA image file from the cache directory, and reads the contents of the image into a string. Next, it creates a challenge string for the CAPTCHA, via createChallenge().

Raises GimpCaptchaError:
 if the chosen CAPTCHA image file could not be read, or if the cacheDir is empty.
Return type:tuple
Returns:A 2-tuple containing the image file contents as a string, and a challenge string (used for checking the client’s solution).