aboutsummaryrefslogtreecommitdiff
path: root/mod/captcha/start.php
blob: ec97d96b62d33cd04c28e950107c0845a6335f03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<?php
/**
 * Elgg captcha plugin
 *
 * @package captcha
 */

function captcha_init() {
	global $CONFIG;

	// Register page handler for captcha functionality
	register_page_handler('captcha','captcha_page_handler');

	// Extend CSS
	elgg_extend_view('css/screen','captcha/css');

	// Number of background images
	$CONFIG->captcha_num_bg = 5;

	// Default length
	$CONFIG->captcha_length = 5;

	// Register a function that provides some default override actions
	elgg_register_plugin_hook_handler('actionlist', 'captcha', 'captcha_actionlist_hook');

	// Register actions to intercept
	$actions = array();
	$actions = elgg_trigger_plugin_hook('actionlist', 'captcha', NULL, $actions);

	if (($actions) && (is_array($actions))) {
		foreach ($actions as $action) {
			elgg_register_plugin_hook_handler("action", $action, "captcha_verify_action_hook");
		}
	}
}

function captcha_page_handler($page) {
	global $CONFIG;

	if (isset($page[0])) {
		set_input('captcha_token', $page[0]);
	}

	include($CONFIG->pluginspath . "captcha/captcha.php");
}

/**
 * Generate a token to act as a seed value for the captcha algorithm.
 */
function captcha_generate_token() {
	// Use action token plus some random for uniqueness
	return md5(generate_action_token(time()) . rand());
}

/**
 * Generate a captcha based on the given seed value and length.
 *
 * @param string $seed_token
 * @return string
 */
function captcha_generate_captcha($seed_token) {
	global $CONFIG;

	/*
	 * We generate a token out of the random seed value + some session data,
	 * this means that solving via pr0n site or indian cube farm becomes
	 * significantly more tricky (we hope).
	 * 
	 * We also add the site secret, which is unavailable to the client and so should
	 * make it very very hard to guess values before hand.
	 * 
	 */

	return strtolower(substr(md5(generate_action_token(0) . $seed_token), 0, $CONFIG->captcha_length));
}

/**
 * Verify a captcha based on the input value entered by the user and the seed token passed.
 *
 * @param string $input_value
 * @param string $seed_token
 * @return bool
 */
function captcha_verify_captcha($input_value, $seed_token) {
	if (strcasecmp($input_value, captcha_generate_captcha($seed_token)) == 0) {
		return TRUE;
	}

	return FALSE;
}

/**
 * Listen to the action plugin hook and check the captcha.
 *
 * @param string $hook
 * @param string $entity_type
 * @param mixed $returnvalue
 * @param array $params
 */
function captcha_verify_action_hook($hook, $entity_type, $returnvalue, $params) {
	$token = get_input('captcha_token');
	$input = get_input('captcha_input');

	if (($token) && (captcha_verify_captcha($input, $token))) {
		return TRUE;
	}

	register_error(elgg_echo('captcha:captchafail'));

	// forward to referrer or else action code sends to front page
	forward(REFERER);

	return FALSE;
}

/**
 * This function returns an array of actions the captcha will expect a captcha for.
 * Other plugins may add their own to this list thereby extending the use.
 *
 * @param string $hook
 * @param string $entity_type
 * @param mixed $returnvalue
 * @param array $params
 */
function captcha_actionlist_hook($hook, $entity_type, $returnvalue, $params) {
	if (!is_array($returnvalue)) {
		$returnvalue = array();
	}

	$returnvalue[] = 'register';
	$returnvalue[] = 'user/requestnewpassword';

	return $returnvalue;
}

elgg_register_event_handler('init', 'system', 'captcha_init');