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 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