Class: Turing::CGIHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/turing/cgi_handler.rb

Overview

Generic (Fast)CGI handler to ease integration into current systems

Handles CGI requests using prepared HTML templates and Turing::Challenge object.

Example of use:

#!/usr/bin/ruby
require 'rubygems'
gem 'turing'
require 'turing'
tcgi_config = {
  :imagepath => "/imgs",
  :outdir => '/home/wejn/ap/htdocs/imgs',
  :store => '/home/wejn/ap/data/turing.pstore',
  :redirect_to => 'http://localhost:8000/secured/',
}
tcgi_config[:on_success] = proc do
  out = {}
  out[:headers] = {
      "cookie" => CGI::Cookie.new({
          'name' => 'turing_passed',
          'value' => 'true',
          'path' => '/',
          'expires' => Time.now + 3600*24,
          }),
      "dude" => "you_rock!",
  }
  out
end
Turing::CGIHandler.new(tcgi_config).handle

This CGI script forces user to pass turing challenge. After he passes the test, he's given cookie turing_passed with value true and redirected to http://localhost:8000/secured/.

Please note: Using this script verbatim is like having no turing challenge at all -- any non-braindead attacker will get around it in no time.

Defined Under Namespace

Classes: Template

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ CGIHandler

Configure instance using options hash.

Warning: Keys of this hash must be symbols.

Accepted options:

  • templatedir: directory where templates (challenge.rhtml, error.rhtml, success.rhtml) reside, by default it's set to gem's shared/templates/ directory.
  • on_success: proc object (or any object responding to call) which returns Hash. Recognized keys of the returned hash are headers and variables. Former are used as HTTP response headers, latter are used as variables for success template (if no redirect given).
  • redirect_to: redirect to this location on success. This can be also done by returning Location header in +on_success+'s headers hash.
  • imagepath: path under which generated images are accessible.

Given hash will be also used to initialize Turing::Challenge object.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/turing/cgi_handler.rb', line 65

def initialize(options = {}) # {{{
  @options = options
  base = File.join(File.dirname(__FILE__), '..', '..', 'shared')
  
  if @options[:templatedir].nil?
    @options[:templatedir] = File.join(base, 'templates')
  end

  begin
    td = @options[:templatedir]
    raise "not directory" unless FileTest.directory?(td)
  rescue
    error_response("Templatedir is invalid", $!)
  end
  
  begin
    @tc = Turing::Challenge.new(@options)
  rescue
    error_response("Unable to initialize Turing::Challenge class", $!)
    exit 1
  end
end

Instance Method Details

#handle(cgi = nil) ⇒ Object

Handle incoming CGI request.

If you don't pass one, it will create it using CGI.new



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/turing/cgi_handler.rb', line 91

def handle(cgi = nil) # {{{
  cgi ||= CGI.new

  if "POST" == cgi.request_method
    if @tc.valid_answer?(cgi["id"], cgi["solution"])
      # process on_success
      os = @options[:on_success]
      if os.nil? || ! os.respond_to?(:call)
        extra = verify_extra({}) # assure correct structure
      else
        extra = verify_extra(os.call)
      end

      # is there redir from config or from on_success?
      if @options[:redirect_to] || extra[:headers]["Location"]
        redirect_to(cgi, extra[:headers]["Location"] || \
          @options[:redirect_to], extra)
      else
        success_response(cgi, extra)
      end
    else
      show_challenge(cgi, true)
    end
  else
    show_challenge(cgi)
  end
end