"g-configure-recaptcha-form")); $group = $form->group("configure_recaptcha") ->label(t("Configure reCAPTCHA")); $group->input("public_key") ->label(t("Public Key")) ->value(module::get_var("recaptcha", "public_key")) ->rules("required") ->error_messages("required", t("You must enter a public key")) ->error_messages("invalid", t("This public key is invalid")); $group->input("private_key") ->label(t("Private Key")) ->value(module::get_var("recaptcha", "private_key")) ->callback("recaptcha::verify_key") ->error_messages("required", t("You must enter a private key")) ->error_messages("invalid", t("This private key is invalid")); $group->submit("")->value(t("Save")); $site_domain = urlencode(stripslashes($_SERVER["HTTP_HOST"])); $form->get_key_url = "http://www.google.com/recaptcha/admin/create?domains=$site_domain&app=Gallery3"; return $form; } static function check_config() { $public_key = module::get_var("recaptcha", "public_key"); $private_key = module::get_var("recaptcha", "private_key"); if (empty($public_key) || empty($private_key)) { site_status::warning( t("reCAPTCHA is not quite ready! Please configure the reCAPTCHA Keys", array("url" => html::mark_clean(url::site("admin/recaptcha")))), "recaptcha_config"); } else { site_status::clear("recaptcha_config"); } } /** * Verify that the recaptcha key is valid. * @param string $private_key * @return boolean */ static function verify_key($private_key_input) { if (!$private_key_input->value) { $private_key_input->add_error("required", 1); return; } $remote_ip = Input::instance()->server("REMOTE_ADDR"); $response = self::_http_post("api-verify.recaptcha.net", "/verify", array("privatekey" => $private_key_input->value, "remoteip" => $remote_ip, "challenge" => "right", "response" => "wrong")); if ($response[1] == "false\ninvalid-site-private-key") { // This is the only thing I can figure out how to verify. // See http://recaptcha.net/apidocs/captcha for possible return values $private_key_input->add_error("invalid", 1); } } /** * Form validation call back for captcha validation * @param string $form * @return string error message or null */ static function is_recaptcha_valid($challenge, $response, $private_key) { $input = Input::instance(); $remote_ip = $input->server("REMOTE_ADDR"); // discard spam submissions if (empty($challenge) || empty($response)) { return "incorrect-captcha-sol"; } $response = self::_http_post("api-verify.recaptcha.net", "/verify", array("privatekey" => $private_key, "remoteip" => $remote_ip, "challenge" => $challenge, "response" => $response)); $answers = explode ("\n", $response [1]); if (trim ($answers [0]) == "true") { return null; } else { return $answers[1]; } } /** * Encodes the given data into a query string format * @param $data - array of string elements to be encoded * @return string - encoded request */ private static function _encode(array $data){ $req = array(); foreach ($data as $key => $value){ $req[] = "$key=" . urlencode(stripslashes($value)); } return implode("&", $req); } /** * Submits an HTTP POST to a reCAPTCHA server * @param string $host * @param string $path * @param array $data * @param int port * @return array response */ private static function _http_post($host, $path, $data, $port = 80) { $req = self::_encode($data); $http_request = "POST $path HTTP/1.0\r\n"; $http_request .= "Host: $host\r\n"; $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; $http_request .= "Content-Length: " . strlen($req) . "\r\n"; $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; $http_request .= "\r\n"; $http_request .= $req; $response = ""; if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { throw new Exception("@todo COULD NOT OPEN SOCKET"); } fwrite($fs, $http_request); while (!feof($fs)) { $response .= fgets($fs, 1160); // One TCP-IP packet } fclose($fs); $response = explode("\r\n\r\n", $response, 2); return $response; } }