Adding files from the ReCAPTCHA extension, with minor modifications
authorYaron Koren <yaron@users.mediawiki.org>
Mon, 31 Jan 2011 05:40:06 +0000 (05:40 +0000)
committerYaron Koren <yaron@users.mediawiki.org>
Mon, 31 Jan 2011 05:40:06 +0000 (05:40 +0000)
ReCaptcha.i18n.php [new file with mode: 0644]
ReCaptcha.php [new file with mode: 0644]
recaptchalib.php [new file with mode: 0644]

diff --git a/ReCaptcha.i18n.php b/ReCaptcha.i18n.php
new file mode 100644 (file)
index 0000000..c568e09
--- /dev/null
@@ -0,0 +1,120 @@
+<?php\r
+/**\r
+ * Internationalisation file for the ReCaptcha module of the ConfirmEdit\r
+ * extension.\r
+ *\r
+ * @addtogroup Extensions\r
+*/\r
+\r
+$messages = array();\r
+\r
+/* English */\r
+$messages['en'] = array(\r
+        'recaptcha-edit' => 'To help protect against automated edit spam, please type the two words you see in the box below:', \r
+        'recaptcha-addurl' => 'Your edit includes new external links. To help protect against automated\r
+spam, please type the two words you see in the box below:',\r
+    'recaptcha-badpass' => 'To help protect against automated password cracking, please type the two words you see in the box below:',\r
+       'recaptcha-createaccount' => 'To help protect against automated account creation, please type the two words you see in the box below:',\r
+       'recaptcha-createaccount-fail' => "Incorrect or missing reCAPTCHA answer.",\r
+       'recaptcha-create' => 'To help protect against automated page creation, please type the two words you see in the box below:', \r
+\r
+);\r
+\r
+/* French */\r
+$messages['fr'] = array(\r
+     'recaptcha-edit' => "Pour nous protéger des robots, merci d'écrire les deux mots visibles dans le cadre qui suit:", \r
+     'recaptcha-addurl' => "Votre contribution contient des liens vers un site externe. Pour nous protéger des robots, merci d'écrire les deux mots visibles dans le cadre qui suit:",\r
+     'recaptcha-badpass' => "Pour nous protéger des essais automatiques de cassage de mot de passe, merci d'écrire les deux mots visibles dans le cadre qui suit:",\r
+       'recaptcha-createaccount' => "Pour nous protéger des créations automatiques de compte, merci d'écrire les deux mots visibles dans le cadre qui suit:",\r
+       'recaptcha-createaccount-fail' => "Réponse de reCAPTCHA fausse ou manquante.",\r
+       'recaptcha-create' => "Pour nous protéger des créations automatiques de pages, merci d'écrire les deux mots visibles dans le cadre qui suit:",\r
+);\r
+\r
+/* Spanish */\r
+$message['es'] = array(\r
+     'recaptcha-edit' => 'Para protegernos de los robots, escribid por favor las dos palabras visibles en el cuadro abajo:', \r
+     'recaptcha-addurl' => 'Su aportación contiene enlaces externos. Para protegernos de los robots, escribid por favor las dos palabras visibles en el cuadro abajo:',\r
+     'recaptcha-badpass' => 'Para protegernos de los robots que intentan adivinar contraseñas, escribid por favor las dos palabras visibles en el cuadro abajo:',\r
+       'recaptcha-createaccount' => 'Para protegernos de la creación automática de cuentas, escribid por favor las dos palabras visibles en el cuadro abajo:',\r
+       'recaptcha-createaccount-fail' => "La respuesta al reCAPTCHA esta falsa o faltante.",\r
+       'recaptcha-create' => 'Para protegernos de la creación automática de páginas, escribid por favor las dos palabras visibles en el cuadro abajo:', \r
+);\r
+\r
+/* Polish */\r
+$messages['pl'] = array(\r
+     'recaptcha-edit' => 'Aby uchronić nas przed robotami, proszę wpisać dwa widoczne słowa w poniższym polu:', \r
+     'recaptcha-addurl' => 'Twoja edycja zawiera linki zewnętrzne. Aby uchronić nas przed robotami, proszę wpisać dwa widoczne słowa w poniższym polu:',\r
+     'recaptcha-badpass' => 'Aby uchronić nas przed złamaniem automatycznym haseł, proszę wpisać dwa widoczne słowa w poniższym polu:',\r
+       'recaptcha-createaccount' => 'Aby uchronić nas przed automatycznym stworzeniem użytkowników, proszę wpisać dwa widoczne słowa w poniższym polu:',\r
+       'recaptcha-createaccount-fail' => "Odpowiedź na reCAPTCHA jest fałszywa lub brakująca.",\r
+       'recaptcha-create' => 'Aby uchronić nas przed tworzeniem stron przez robotów, proszę wpisać dwa widoczne słowa w poniższym polu:', \r
+);\r
+\r
+/* German */\r
+$messages['de'] = array(\r
+     'recaptcha-edit' => 'Zum Schutz vor automatisiertem Spam, gib bitte die beiden folgenden Wörter in das untenstehende Feld ein:', \r
+     'recaptcha-addurl' => 'Deine Bearbeitung enthält neue externe Links. Zum Schutz vor automatisiertem Spam gebe bitte die beiden folgenden Wörter in das untenstehende Feld ein:',\r
+     'recaptcha-badpass' => 'Zum Schutz gegen automatisiertes Knacken von Passwörtern, gebe bitte die beiden folgenden Wörter in das untenstehende Feld ein:',\r
+       'recaptcha-createaccount' => 'Zum Schutz gegen automatisierte Erstellung von Benutzerkonten gebe bitte die beiden folgenden Wörter in das untenstehende Feld ein:',\r
+       'recaptcha-createaccount-fail' => "Fehlerhafte oder fehlende reCAPTCHA Antwort.",\r
+       'recaptcha-create' => 'Zum Schutz gegen automatisierte Erstellung von Seiten gebe bitte die beiden folgenden Wörter in das untenstehende Feld ein:', \r
+);\r
+\r
+/* Portuguese */\r
+$messages['pt'] = array(\r
+     'recaptcha-edit' => 'Para proteger-nos de spam, por favor escreva  as duas palavras visíveis abaixo:',\r
+     'recaptcha-addurl' => 'A sua edição contem ligações externas. Para proteger-nos de spam, por favor escreva  as duas palavras visíveis abaixo:',\r
+     'recaptcha-badpass' => 'Para proteger-nos de robots que tentam adivinhar senhas, por favor escreva  as duas palavras visíveis abaixo:',\r
+        'recaptcha-createaccount' => 'Para proteger-nos de criação automática de contas, por favor escreva  as duas palavras visíveis abaixo:',\r
+        'recaptcha-createaccount-fail' => "A resposta ao reCAPTCHA é errada.",\r
+        'recaptcha-create' => 'Para proteger-nos da criação automática de páginas, por favor escreva  as duas palavras visíveis abaixo:',\r
+);\r
+\r
+/* Brazilian Portuguese */\r
+$messages['pt_br'] = array(\r
+        'recaptcha-edit' => 'Para ajudar a prevenir contra vandalismos, por favor digite as duas palavras que voc&amp;ecirc; v&amp;ecirc; na caixa abaixo:', \r
+        'recaptcha-addurl' => 'A sua edi&amp;ccedil;&amp;atilde;o inclui liga&amp;ccedil;&amp;otilde;es externas. Para ajudar a prevenir contra vandalismos, por favor digite as duas palavras que voc&amp;ecirc; v&amp;ecirc; na caixa abaixo:',\r
+    'recaptcha-badpass' => 'Para ajudar a prevenir contra tentativas de desbloquear senhas, por favor digite as duas palavras que voc&amp;ecirc; v&amp;ecirc; na caixa abaixo:',\r
+       'recaptcha-createaccount' => 'Para ajudar a prevenir contra cria&amp;ccedil;&amp;atilde;o automatizada de usu&amp;aacute;rios, por favor digite as duas palavras que voc&amp;ecirc; v&amp;ecirc; na caixa abaixo:',\r
+       'recaptcha-createaccount-fail' => "Resposta incorreta ao reCAPTCHA.",\r
+       'recaptcha-create' => 'Para ajudar a prevenir contra cria&amp;ccedil;&amp;atilde;o automatizada de p&amp;aacute;ginas, por favor digite as duas palavras que voc&amp;ecirc; v&amp;ecirc; na caixa abaixo:', \r
+);\r
+\r
+/* Swedish */\r
+$messages['sv'] = array(\r
+     'recaptcha-edit' => 'Den här sidan skyddas mot spam-robotar, bevisa att du är en människa genom att skriva de två orden du ser i boxen nedan:', \r
+     'recaptcha-addurl' => 'Din förändring av sidan innehåller nya externa länkar, vilket är typiskt för spam. Bevisa att du är en människa genom att skriva de två orden du ser i boxen nedan:',\r
+     'recaptcha-badpass' => 'För att skydda wikin mot robotar som gissar användares lösenord behöver användare bevisa att de är människor. Skriv ner de två orden som du ser i boxen nedan:',\r
+       'recaptcha-createaccount' => 'För att skydda wikin mot robotar som skapar konton behöver användare bevisa att de är människor. Var vänlig och skriv ner de två orden du ser i boxen nedan:',\r
+       'recaptcha-createaccount-fail' => "Du har angivit ett felaktig svar för reCAPTCHA.",\r
+       'recaptcha-create' => 'För att skydda wikin mot robotar som skapar nya artiklar. Var vänlig och skriv ner de två orden som finns i boxen nedan:', \r
+);\r
+\r
+/* Vietnamese */\r
+$messages['vi'] = array(\r
+     'recaptcha-edit' => 'Để giúp tránh các sửa đổi rác tự động, xin hãy gõ hai từ mà bạn nhìn thấy vào ô dưới đây:', \r
+     'recaptcha-addurl' => 'Sửa đổi của bạn có chứa liên kết ngoài mới. Để giúp tránh các sửa đổi rác tự động, xin hãy gõ hai từ mà bạn nhìn vào ô dưới đây:',\r
+     'recaptcha-badpass' => 'Để giúp tránh bẻ khóa mật khẩu tự động, xin hãy gõ hai từ mà bạn nhìn vào ô dưới đây:',\r
+       'recaptcha-createaccount' => 'Để giúp tránh việc mở tài khoản tự động, xin hãy gõ hai từ mà bạn nhìn vào ô dưới đây:',\r
+       'recaptcha-createaccount-fail' => "Thiếu câu trả lời reCAPTCHA hoặc câu trả lời không đúng.",\r
+       'recaptcha-create' => 'Để giúp tránh việc tạo trang tự động, xin hãy gõ hai từ mà bạn nhìn vào ô dưới đây:', \r
+);\r
+\r
+$messages['he'] = array(\r
+         'recaptcha-edit' => 'אינכם משתמש רשום.כהגנה מפני ספאם אוטומטי, אנא הקלידו את שתי המילים שלהלן. תודה.',\r
+         'recaptcha-addurl' => 'אינכם משתמש רשום.כהגנה מפני ספאם אוטומטי, אנא הקלידו את שתי המילים שלהלן. תודה.',\r
+         'recaptcha-badpass' => 'כהגנה מפני מפצחי סיסמאות אוטומטיים אנא הקלידו את שתי המילים שלהלן:',\r
+       'recaptcha-createaccount' => 'כהגנה מפני יצירת חשבונות פיקטיביים ע"י אוטומטים אנא הקלידו את שתי המילים שלהלן:',\r
+       'recaptcha-createaccount-fail' => 'לא הוקלדו מילות האישור, או שהוקלדו מילים לא נכונות. נסו שנית.',\r
+       'recaptcha-create' => 'אינכם משתמש רשום.כהגנה מפני ספאם אוטומטי, אנא הקלידו את שתי המילים שלהלן. תודה.',\r
+);\r
+\r
+/* Japanese - 日本語 */\r
+$messages['ja'] = array(\r
+        'recaptcha-edit' => '自動編集スパムからの保護のため、下の画像に表示されている2つの言葉を入力 してください。', \r
+        'recaptcha-addurl' => 'あなたの編集は新しい外部リンクを含んでいます。自動スパムからの保護のた め、下の画像に表示されている2つの言葉を入力してください。',\r
+    'recaptcha-badpass' => '自動パスワードクラッキングからの保護のために、下の画像に表示されている2 つの言葉を入力してください。',\r
+       'recaptcha-createaccount' => '自動アカウント登録からの保護のために、下の画像に表示されている2つの言葉 を入力してください。',\r
+       'recaptcha-createaccount-fail' => '入力された文字列が正しくありません。',\r
+       'recaptcha-create' => '自動ページ作成からの保護のために、下の画像に表示されている2つの言葉を入 力してください。', \r
+);\r
diff --git a/ReCaptcha.php b/ReCaptcha.php
new file mode 100644 (file)
index 0000000..4d65700
--- /dev/null
@@ -0,0 +1,139 @@
+<?php\r
+\r
+/**\r
+ * Captcha class using the reCAPTCHA widget. \r
+ * Stop Spam. Read Books.  \r
+ *\r
+ * @addtogroup Extensions\r
+ * @author Mike Crawford <mike.crawford@gmail.com>\r
+ * @copyright Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net\r
+ * @licence MIT/X11\r
+ */\r
+\r
+if( !defined( 'MEDIAWIKI' ) ) {\r
+       exit;\r
+}\r
+\r
+$wgExtensionMessagesFiles['ReCaptcha'] = dirname( __FILE__ ) . '/ReCaptcha.i18n.php';\r
+\r
+require_once( 'recaptchalib.php' );\r
+\r
+// Set these in LocalSettings.php\r
+$wgReCaptchaPublicKey = '';\r
+$wgReCaptchaPrivateKey = '';\r
+// For backwards compatibility\r
+$recaptcha_public_key = '';\r
+$recaptcha_private_key = '';\r
+\r
+\r
+/**\r
+ * Make sure the keys are defined.\r
+ */\r
+function efReCaptcha() {\r
+       global $wgReCaptchaPublicKey, $wgReCaptchaPrivateKey;\r
+       global $recaptcha_public_key, $recaptcha_private_key;\r
+       global $wgServerName;\r
+\r
+       // Backwards compatibility\r
+       $wgReCaptchaPublicKey == '' ) {\r
+               $wgReCaptchaPublicKey = $recaptcha_public_key;\r
+       }\r
+       if ( $wgReCaptchaPrivateKey == '' ) {\r
+               $wgReCaptchaPrivateKey = $recaptcha_private_key;\r
+       }\r
+\r
+       if ($wgReCaptchaPublicKey == '' || $wgReCaptchaPrivateKey == '') {\r
+               die ('You need to set $wgReCaptchaPrivateKey and $wgReCaptchaPublicKey in LocalSettings.php to ' .\r
+                    "use the reCAPTCHA plugin. You can sign up for a key <a href='" .\r
+                    htmlentities(recaptcha_get_signup_url ($wgServerName, "mediawiki")) . "'>here</a>.");\r
+       }       \r
+}\r
+\r
+\r
+class ReCaptcha extends SimpleCaptcha {\r
+               \r
+       //reCAPTHCA error code returned from recaptcha_check_answer\r
+       private $recaptcha_error = null;\r
+\r
+               \r
+       /** \r
+        * Displays the reCAPTCHA widget.  \r
+         * If $this->recaptcha_error is set, it will display an error in the widget.\r
+        *\r
+         */\r
+       function getForm() {\r
+               global $wgReCaptchaPublicKey;\r
+               return "<script>var RecaptchaOptions = { tabindex : 1 }; </script> " .\r
+               recaptcha_get_html($wgReCaptchaPublicKey, $this->recaptcha_error);\r
+       }\r
+\r
+\r
+               \r
+       /**\r
+        * Calls the library function recaptcha_check_answer to verify the users input.\r
+        * Sets $this->recaptcha_error if the user is incorrect.\r
+         * @return boolean \r
+         *\r
+         */\r
+       function passCaptcha() {\r
+               global $wgReCaptchaPrivateKey;\r
+               $recaptcha_response = recaptcha_check_answer ($wgReCaptchaPrivateKey,\r
+                                                             wfGetIP (),\r
+                                                             $_POST['recaptcha_challenge_field'],\r
+                                                             $_POST['recaptcha_response_field']);\r
+                if (!$recaptcha_response->is_valid) {\r
+                       $this->recaptcha_error = $recaptcha_response->error;\r
+                       return false;\r
+                }\r
+               $recaptcha_error = null;\r
+                return true;\r
+\r
+       }\r
+\r
+\r
+\r
+        /**\r
+         * Called on all edit page saves. (EditFilter events)\r
+         * @return boolean - true if page save should continue, false if should display Captcha widget.\r
+         */\r
+        function confirmEdit( $editPage, $newtext, $section ) {\r
+                if( $this->shouldCheck( $editPage, $newtext, $section ) ) {\r
+\r
+                        if (!isset($_POST['recaptcha_response_field'])) {\r
+                                //User has not yet been presented with Captcha, show the widget.\r
+                                $editPage->showEditForm( array( &$this, 'editCallback' ) );\r
+                                return false;\r
+                        }\r
+\r
+                        if( $this->passCaptcha() ) {\r
+                                return true;\r
+                        } else {\r
+                                //Try again - show the widget\r
+                                $editPage->showEditForm( array( &$this, 'editCallback' ) );\r
+                                return false;\r
+                        }\r
+\r
+                } else {\r
+                        wfDebug( "ConfirmEdit: no need to show captcha.\n" );\r
+                        return true;\r
+                }\r
+        }\r
+\r
+       \r
+\r
+       /**\r
+        * Show a message asking the user to enter a captcha on edit\r
+        * The result will be treated as wiki text\r
+        *\r
+        * @param $action Action being performed\r
+        * @return string\r
+        */\r
+       function getMessage( $action ) {\r
+               $name = 'recaptcha-' . $action;\r
+               $text = wfMsg( $name );\r
+               # Obtain a more tailored message, if possible, otherwise, fall back to\r
+               # the default for edits\r
+               return wfEmptyMsg( $name, $text ) ? wfMsg( 'recaptcha-edit' ) : $text;\r
+       }\r
+\r
+}\r
diff --git a/recaptchalib.php b/recaptchalib.php
new file mode 100644 (file)
index 0000000..b8ac453
--- /dev/null
@@ -0,0 +1,275 @@
+<?php\r
+/*\r
+ * This is a PHP library that handles calling reCAPTCHA.\r
+ *    - Documentation and latest version\r
+ *          http://recaptcha.net/plugins/php/\r
+ *    - Get a reCAPTCHA API Key\r
+ *          http://recaptcha.net/api/getkey\r
+ *    - Discussion group\r
+ *          http://groups.google.com/group/recaptcha\r
+ *\r
+ * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net\r
+ * AUTHORS:\r
+ *   Mike Crawford\r
+ *   Ben Maurer\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+ * THE SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * The reCAPTCHA server URL's\r
+ */\r
+$recaptcha_api_server = 'http://api.recaptcha.net';\r
+$recaptcha_api_secure_server = 'https://api-secure.recaptcha.net';\r
+$recaptcha_verify_server = 'api-verify.recaptcha.net';\r
+\r
+\r
+/**\r
+ * Encodes the given data into a query string format\r
+ * @param $data - array of string elements to be encoded\r
+ * @return string - encoded request\r
+ */\r
+function _recaptcha_qsencode ($data) {\r
+        $req = "";\r
+        foreach ( $data as $key => $value )\r
+                $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';\r
+\r
+        // Cut the last '&'\r
+        $req=substr($req,0,strlen($req)-1);\r
+        return $req;\r
+}\r
+\r
+\r
+\r
+/**\r
+ * Submits an HTTP POST to a reCAPTCHA server\r
+ * @param string $host\r
+ * @param string $path\r
+ * @param array $data\r
+ * @param int port\r
+ * @return array response\r
+ */\r
+function _recaptcha_http_post($host, $path, $data, $port = 80) {\r
+\r
+        $req = _recaptcha_qsencode ($data);\r
+\r
+        $http_request  = "POST $path HTTP/1.0\r\n";\r
+        $http_request .= "Host: $host\r\n";\r
+        $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";\r
+        $http_request .= "Content-Length: " . strlen($req) . "\r\n";\r
+        $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";\r
+        $http_request .= "\r\n";\r
+        $http_request .= $req;\r
+\r
+        $response = '';\r
+        if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {\r
+                die ('Could not open socket');\r
+        }\r
+\r
+        fwrite($fs, $http_request);\r
+\r
+        while ( !feof($fs) )\r
+                $response .= fgets($fs, 1160); // One TCP-IP packet\r
+        fclose($fs);\r
+        $response = explode("\r\n\r\n", $response, 2);\r
+\r
+        return $response;\r
+}\r
+\r
+\r
+\r
+/**\r
+ * Gets the challenge HTML (javascript and non-javascript version).\r
+ * This is called from the browser, and the resulting reCAPTCHA HTML widget\r
+ * is embedded within the HTML form it was called from.\r
+ * @param string $pubkey A public key for reCAPTCHA\r
+ * @param string $error The error given by reCAPTCHA (optional, default is null)\r
+ * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)\r
+\r
+ * @return string - The HTML to be embedded in the user's form.\r
+ */\r
+function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)\r
+{\r
+        global $recaptcha_api_server, $recaptcha_api_ssl_server;\r
+\r
+       if ($pubkey == null || $pubkey == '') {\r
+               die ("To use reCAPTCHA you must get an API key from <a href='http://recaptcha.net/api/getkey'>http://recaptcha.net/api/getkey</a>");\r
+       }\r
+       \r
+       if ($use_ssl) {\r
+           $server = $recaptcha_api_ssl_server;\r
+        } else {\r
+           $server = $recaptcha_api_server;\r
+        }\r
+        $errorpart = "";\r
+        if ($error) {\r
+           $errorpart = "&amp;error=" . $error;\r
+        }\r
+        return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>\r
+\r
+       <noscript>\r
+               <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br>\r
+               <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>\r
+               <input type="hidden" name="recaptcha_response_field" value="manual_challenge">\r
+       </noscript>';\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * A ReCaptchaResponse is returned from recaptcha_check_answer()\r
+ */\r
+class ReCaptchaResponse {\r
+        var $is_valid;\r
+        var $error;\r
+}\r
+\r
+\r
+/**\r
+  * Calls an HTTP POST function to verify if the user's guess was correct\r
+  * @param string $privkey\r
+  * @param string $remoteip\r
+  * @param string $challenge\r
+  * @param string $response\r
+  * @return ReCaptchaResponse\r
+  */\r
+function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response)\r
+{\r
+       if ($privkey == null || $privkey == '') {\r
+               die ("To use reCAPTCHA you must get an API key from <a href='http://recaptcha.net/api/getkey'>http://recaptcha.net/api/getkey</a>");\r
+       }\r
+\r
+       if ($remoteip == null || $remoteip == '') {\r
+               die ("For security reasons, you must pass the remote ip to reCAPTCHA");\r
+       }\r
+\r
+       \r
+       \r
+        //discard spam submissions\r
+        if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {\r
+                $recaptcha_response = new ReCaptchaResponse();\r
+                $recaptcha_response->is_valid = false;\r
+                $recaptcha_response->error = 'incorrect-captcha-sol';\r
+                return $recaptcha_response;\r
+        }\r
+\r
+        global $recaptcha_verify_server;\r
+        $response = _recaptcha_http_post ($recaptcha_verify_server, "/verify",\r
+                                          array (\r
+                                                 'privatekey' => $privkey,\r
+                                                 'remoteip' => $remoteip,\r
+                                                 'challenge' => $challenge,\r
+                                                 'response' => $response\r
+                                                 )\r
+                                          );\r
+\r
+        $answers = explode ("\n", $response [1]);\r
+        $recaptcha_response = new ReCaptchaResponse();\r
+\r
+        if (trim ($answers [0]) == 'true') {\r
+                $recaptcha_response->is_valid = true;\r
+        }\r
+        else {\r
+                $recaptcha_response->is_valid = false;\r
+                $recaptcha_response->error = $answers [1];\r
+        }\r
+        return $recaptcha_response;\r
+\r
+}\r
+\r
+/**\r
+ * gets a URL where the user can sign up for reCAPTCHA. If your application\r
+ * has a configuration page where you enter a key, you should provide a link\r
+ * using this function.\r
+ * @param string $domain The domain where the page is hosted\r
+ * @param string $appname The name of your application\r
+ */\r
+function recaptcha_get_signup_url ($domain = null, $appname = null) {\r
+       return "http://recaptcha.net/api/getkey?" .  _recaptcha_qsencode (array ('domain' => $domain, 'app' => $appname));\r
+}\r
+\r
+\r
+\r
+/* Mailhide related code */\r
+\r
+function _recaptcha_aes_encrypt($val,$ky) {\r
+       if (! function_exists ("mcrypt_encrypt")) {\r
+               die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");\r
+       }\r
+       $mode=MCRYPT_MODE_CBC;   \r
+       $enc=MCRYPT_RIJNDAEL_128;\r
+       $val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));\r
+       return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");\r
+}\r
+\r
+\r
+function _recaptcha_mailhide_urlbase64 ($x) {\r
+       return strtr(base64_encode ($x), '+/', '-_');\r
+}\r
+\r
+/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */\r
+function recaptcha_mailhide_url($pubkey, $privkey, $email) {\r
+       if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {\r
+               die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .\r
+                    "you can do so at <a href='http://mailhide.recaptcha.net/apikey'>http://mailhide.recaptcha.net/apikey</a>");\r
+       }\r
+       \r
+\r
+       $ky = pack('H*', $privkey);\r
+       $cryptmail = _recaptcha_aes_encrypt ($email, $ky);\r
+       \r
+       return "http://mailhide.recaptcha.net/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);\r
+}\r
+\r
+/**\r
+ * gets the parts of the email to expose to the user.\r
+ * eg, given johndoe@example,com return ["john", "example.com"].\r
+ * the email is then displayed as john...@example.com\r
+ */\r
+function _recaptcha_mailhide_email_parts ($email) {\r
+       $arr = preg_split("/@/", $email );\r
+\r
+       if (strlen ($arr[0]) <= 4) {\r
+               $arr[0] = substr ($arr[0], 0, 1);\r
+       } else if (strlen ($arr[0]) <= 6) {\r
+               $arr[0] = substr ($arr[0], 0, 3);\r
+       } else {\r
+               $arr[0] = substr ($arr[0], 0, 4);\r
+       }\r
+       return $arr;\r
+}\r
+\r
+/**\r
+ * Gets html to display an email address given a public an private key.\r
+ * to get a key, go to:\r
+ *\r
+ * http://mailhide.recaptcha.net/apikey\r
+ */\r
+function recaptcha_mailhide_html($pubkey, $privkey, $email) {\r
+       $emailparts = _recaptcha_mailhide_email_parts ($email);\r
+       $url = recaptcha_mailhide_url ($pubkey, $privkey, $email);\r
+       \r
+       return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .\r
+               "' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);\r
+\r
+}\r
+\r
+\r
+?>\r