MediaWiki  1.29.1
recaptchalib.php
Go to the documentation of this file.
1 <?php
38 define( "RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api" );
39 define( "RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api" );
40 define( "RECAPTCHA_VERIFY_SERVER", "www.google.com" );
41 
47 function _recaptcha_qsencode ( $data ) {
48  $req = "";
49  foreach ( $data as $key => $value )
50  $req .= $key . '=' . urlencode( stripslashes( $value ) ) . '&';
51 
52  // Cut the last '&'
53  $req = substr( $req, 0, strlen( $req ) -1 );
54  return $req;
55 }
56 
57 
58 
67 function _recaptcha_http_post( $host, $path, $data, $port = 80 ) {
68 
69  $req = _recaptcha_qsencode ( $data );
70 
71  $http_request = "POST $path HTTP/1.0\r\n";
72  $http_request .= "Host: $host\r\n";
73  $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
74  $http_request .= "Content-Length: " . strlen( $req ) . "\r\n";
75  $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
76  $http_request .= "\r\n";
77  $http_request .= $req;
78 
79  $response = '';
80  if ( false == ( $fs = @fsockopen( $host, $port, $errno, $errstr, 10 ) ) ) {
81  die ( 'Could not open socket' );
82  }
83 
84  fwrite( $fs, $http_request );
85 
86  while ( !feof( $fs ) )
87  $response .= fgets( $fs, 1160 ); // One TCP-IP packet
88  fclose( $fs );
89  $response = explode( "\r\n\r\n", $response, 2 );
90 
91  return $response;
92 }
93 
94 
95 
106 function recaptcha_get_html ( $pubkey, $error = null, $use_ssl = false )
107 {
108  if ( $pubkey == null || $pubkey == '' ) {
109  die ( "To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>" );
110  }
111 
112  if ( $use_ssl ) {
113  $server = RECAPTCHA_API_SECURE_SERVER;
114  } else {
115  $server = RECAPTCHA_API_SERVER;
116  }
117 
118  $errorpart = "";
119  if ( $error ) {
120  $errorpart = "&amp;error=" . $error;
121  }
122  return '<script type="text/javascript" src="' . $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>
123 
124  <noscript>
125  <iframe src="' . $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
126  <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
127  <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
128  </noscript>';
129 }
130 
131 
132 
133 
137 class ReCaptchaResponse {
138  public $is_valid;
139  public $error;
140 }
141 
142 
152 function recaptcha_check_answer ( $privkey, $remoteip, $challenge, $response, $extra_params = array() )
153 {
154  if ( $privkey == null || $privkey == '' ) {
155  die ( "To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>" );
156  }
157 
158  if ( $remoteip == null || $remoteip == '' ) {
159  die ( "For security reasons, you must pass the remote ip to reCAPTCHA" );
160  }
161 
162 
163 
164  // discard spam submissions
165  if ( $challenge == null || strlen( $challenge ) == 0 || $response == null || strlen( $response ) == 0 ) {
166  $recaptcha_response = new ReCaptchaResponse();
167  $recaptcha_response->is_valid = false;
168  $recaptcha_response->error = 'incorrect-captcha-sol';
169  return $recaptcha_response;
170  }
171 
172  $response = _recaptcha_http_post ( RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
173  array (
174  'privatekey' => $privkey,
175  'remoteip' => $remoteip,
176  'challenge' => $challenge,
177  'response' => $response
178  ) + $extra_params
179  );
180 
181  $answers = explode ( "\n", $response [1] );
182  $recaptcha_response = new ReCaptchaResponse();
183 
184  if ( trim ( $answers [0] ) == 'true' ) {
185  $recaptcha_response->is_valid = true;
186  }
187  else {
188  $recaptcha_response->is_valid = false;
189  $recaptcha_response->error = $answers [1];
190  }
191  return $recaptcha_response;
192 
193 }
194 
202 function recaptcha_get_signup_url ( $domain = null, $appname = null ) {
203  return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode ( array ( 'domains' => $domain, 'app' => $appname ) );
204 }
205 
206 function _recaptcha_aes_pad( $val ) {
207  $block_size = 16;
208  $numpad = $block_size - ( strlen ( $val ) % $block_size );
209  return str_pad( $val, strlen ( $val ) + $numpad, chr( $numpad ) );
210 }
211 
212 /* Mailhide related code */
213 
214 function _recaptcha_aes_encrypt( $val, $ky ) {
215  if ( ! function_exists ( "mcrypt_encrypt" ) ) {
216  die ( "To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed." );
217  }
218  $mode = MCRYPT_MODE_CBC;
219  $enc = MCRYPT_RIJNDAEL_128;
220  $val = _recaptcha_aes_pad( $val );
221  return mcrypt_encrypt( $enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" );
222 }
223 
224 
225 function _recaptcha_mailhide_urlbase64 ( $x ) {
226  return strtr( base64_encode ( $x ), '+/', '-_' );
227 }
228 
229 /* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
230 function recaptcha_mailhide_url( $pubkey, $privkey, $email ) {
231  if ( $pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null ) {
232  die ( "To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
233  "you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>" );
234  }
235 
236 
237  $ky = pack( 'H*', $privkey );
238  $cryptmail = _recaptcha_aes_encrypt ( $email, $ky );
239 
240  return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ( $cryptmail );
241 }
242 
248 function _recaptcha_mailhide_email_parts ( $email ) {
249  $arr = preg_split( "/@/", $email );
250 
251  if ( strlen ( $arr[0] ) <= 4 ) {
252  $arr[0] = substr ( $arr[0], 0, 1 );
253  } elseif ( strlen ( $arr[0] ) <= 6 ) {
254  $arr[0] = substr ( $arr[0], 0, 3 );
255  } else {
256  $arr[0] = substr ( $arr[0], 0, 4 );
257  }
258  return $arr;
259 }
260 
267 function recaptcha_mailhide_html( $pubkey, $privkey, $email ) {
268  $emailparts = _recaptcha_mailhide_email_parts ( $email );
269  $url = recaptcha_mailhide_url ( $pubkey, $privkey, $email );
270 
271  return htmlentities( $emailparts[0] ) . "<a href='" . htmlentities ( $url ) .
272  "' 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] );
273 
274 }
_recaptcha_qsencode
_recaptcha_qsencode( $data)
Encodes the given data into a query string format.
Definition: recaptchalib.php:47
RECAPTCHA_API_SECURE_SERVER
const RECAPTCHA_API_SECURE_SERVER
Definition: recaptchalib.php:39
$req
this hook is for auditing only $req
Definition: hooks.txt:990
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
RECAPTCHA_VERIFY_SERVER
const RECAPTCHA_VERIFY_SERVER
Definition: recaptchalib.php:40
recaptcha_get_html
recaptcha_get_html( $pubkey, $error=null, $use_ssl=false)
Gets the challenge HTML (javascript and non-javascript version).
Definition: recaptchalib.php:106
_recaptcha_http_post
_recaptcha_http_post( $host, $path, $data, $port=80)
Submits an HTTP POST to a reCAPTCHA server.
Definition: recaptchalib.php:67
RECAPTCHA_API_SERVER
const RECAPTCHA_API_SERVER
This is a PHP library that handles calling reCAPTCHA.
Definition: recaptchalib.php:38
$value
$value
Definition: styleTest.css.php:45
$response
this hook is for auditing only $response
Definition: hooks.txt:783
$path
$path
Definition: NoLocalSettings.php:26
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
array
the array() calling protocol came about after MediaWiki 1.4rc1.