1: <?php
2: 3: 4: 5: 6: 7: 8:
9:
10:
11: $plugin_is_filter = 5 | CLASS_PLUGIN;
12: $plugin_description = gettext("Zenphoto captcha handler.");
13: $plugin_author = "Stephen Billard (sbillard)";
14: $plugin_disable = ($_zp_captcha->name && $_zp_captcha->name != 'zpCaptcha') ? sprintf(gettext('Only one Captcha handler plugin may be enabled. <a href="#%1$s"><code>%1$s</code></a> is already enabled.'), $_zp_captcha->name) : '';
15:
16: $option_interface = 'zpCaptcha';
17:
18: class zpCaptcha extends _zp_captcha {
19:
20: var $name = 'zpCaptcha';
21:
22: 23: 24: 25: 26:
27: function __construct() {
28: global $plugin_is_filter;
29: if (OFFSET_PATH == 2) {
30: setOptionDefault('zp_plugin_zpCaptcha', $plugin_is_filter);
31: setOptionDefault('zenphoto_captcha_length', 5);
32: setOptionDefault('zenphoto_captcha_font_size', 18);
33: setOptionDefault('zenphoto_captcha_key', sha1($_SERVER['HTTP_HOST'] . 'a9606420399a77387af2a4b541414ee5' . getUserIP()));
34: setOptionDefault('zenphoto_captcha_string', 'abcdefghijkmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWXYZ');
35: }
36: }
37:
38: 39: 40: 41: 42:
43: function getOptionsSupported() {
44: $fontlist = zp_getFonts();
45: $options = array(
46: gettext('Hash key') => array('key' => 'zenphoto_captcha_key', 'type' => OPTION_TYPE_TEXTBOX,
47: 'order' => 2,
48: 'desc' => gettext('The key used in hashing the CAPTCHA string. Note: this key will change with each successful CAPTCHA verification.')),
49: gettext('Allowed characters') => array('key' => 'zenphoto_captcha_string', 'type' => OPTION_TYPE_TEXTBOX,
50: 'order' => 1,
51: 'desc' => gettext('The characters which may appear in the CAPTCHA string.')),
52: gettext('CAPTCHA length') => array('key' => 'zenphoto_captcha_length', 'type' => OPTION_TYPE_RADIO,
53: 'order' => 0,
54: 'buttons' => array(gettext('3') => 3, gettext('4') => 4, gettext('5') => 5, gettext('6') => 6),
55: 'desc' => gettext('The number of characters in the CAPTCHA.')),
56: gettext('CAPTCHA font') => array('key' => 'zenphoto_captcha_font', 'type' => OPTION_TYPE_SELECTOR,
57: 'order' => 3,
58: 'selections' => array_merge(array('*' . gettext('random') . '*' => '*'), $fontlist),
59: 'desc' => gettext('The font to use for CAPTCHA characters.')),
60: gettext('CAPTCHA font size') => array('key' => 'zenphoto_captcha_font_size', 'type' => OPTION_TYPE_CLEARTEXT,
61: 'order' => 3.5,
62: 'desc' => gettext('The size to use if the font is scalable (<em>TTF</em> and <em>Imagick</em> fonts.)')),
63: '' => array('key' => 'zenphoto_captcha_image', 'type' => OPTION_TYPE_CUSTOM,
64: 'order' => 4,
65: 'desc' => gettext('Sample CAPTCHA image'))
66: );
67: return $options;
68: }
69:
70: function handleOption($key, $cv) {
71: $captcha = $this->getCaptcha(NULL);
72: ?>
73: <span id="zenphoto_captcha_image_loc"><?php echo $captcha['html']; ?></span>
74: <script type="text/javascript">
75:
76: $(document).ready(function() {
77: $('#zenphoto_captcha_font').change(function() {
78: var base = $('#zenphoto_captcha_image_loc').html();
79: var match = base.match(/src=".*"\s/gi) + '%';
80: if ((i = match.indexOf('&')) <= 0) {
81: i = match.indexOf('" %');
82: }
83: var path = match.substr(0, i);
84: var nbase = base.replace(path, path + '&f=' + $('#zenphoto_captcha_font').val());
85: $('#zenphoto_captcha_image_loc').html(nbase);
86: });
87: });
88:
89: </script>
90: <?php
91: }
92:
93: 94: 95: 96: 97:
98: function getCaptchaKey() {
99: global $_zp_authority;
100: $key = getOption('zenphoto_captcha_key');
101: if (empty($key)) {
102: $admin = $_zp_authority->getMasterUser();
103: if (is_object($admin)) {
104: $key = $admin->getPass();
105: } else {
106: $key = 'No admin set';
107: }
108: $key = sha1('zenphoto' . $key . 'captcha key');
109: setOption('zenphoto_captcha_key', $key);
110: }
111: return $key;
112: }
113:
114: 115: 116: 117: 118: 119: 120: 121:
122: function checkCaptcha($code, $code_ok) {
123: $captcha_len = getOption('zenphoto_captcha_length');
124: $key = $this->getCaptchaKey();
125: $code_cypher = sha1(bin2hex(rc4($key, trim($code))));
126: $code_ok = trim($code_ok);
127: if ($code_cypher != $code_ok || strlen($code) != $captcha_len) {
128: return false;
129: }
130: query('DELETE FROM ' . prefix('captcha') . ' WHERE `ptime`<' . (time() - 3600));
131: $result = query('DELETE FROM ' . prefix('captcha') . ' WHERE `hash`="' . $code_cypher . '"');
132: if ($result && db_affected_rows() == 1) {
133: $len = rand(0, strlen($key) - 1);
134: $key = sha1(substr($key, 0, $len) . $code . substr($key, $len));
135: setOption('zenphoto_captcha_key', $key);
136: return true;
137: }
138: return false;
139: }
140:
141: 142: 143: 144: 145:
146: function getCaptcha($prompt) {
147: global $_zp_HTML_cache;
148: $_zp_HTML_cache->disable();
149: $captcha_len = getOption('zenphoto_captcha_length');
150: $key = $this->getCaptchaKey();
151: $lettre = getOption('zenphoto_captcha_string');
152: $numlettre = strlen($lettre) - 1;
153:
154: $string = '';
155: for ($i = 0; $i < $captcha_len; $i++) {
156: $string .= $lettre[rand(0, $numlettre)];
157: }
158: $cypher = bin2hex(rc4($key, $string));
159: $code = sha1($cypher);
160: query('DELETE FROM ' . prefix('captcha') . ' WHERE `ptime`<' . (time() - 3600), false);
161: query("INSERT INTO " . prefix('captcha') . " (ptime, hash) VALUES (" . db_quote(time()) . "," . db_quote($code) . ")", false);
162: $html = '<label for="code" class="captcha_label">' . $prompt . '</label><img id="captcha" src="' . WEBPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/zpCaptcha/c.php?i=' . $cypher . '" alt="Code" />';
163: $input = '<input type="text" id="code" name="code" class="captchainputbox" />';
164: $hidden = '<input type="hidden" name="code_h" value="' . $code . '" />';
165: return array('input' => $input, 'html' => $html, 'hidden' => $hidden);
166: }
167:
168: }
169:
170: if ($plugin_disable) {
171: enableExtension('zpCaptcha', 0);
172: } else {
173: $_zp_captcha = new zpCaptcha();
174: }
175: ?>
176: