63 public static function check_key_status( $key, $ip = null ) { |
63 public static function check_key_status( $key, $ip = null ) { |
64 return self::http_post( Akismet::build_query( array( 'key' => $key, 'blog' => get_option( 'home' ) ) ), 'verify-key', $ip ); |
64 return self::http_post( Akismet::build_query( array( 'key' => $key, 'blog' => get_option( 'home' ) ) ), 'verify-key', $ip ); |
65 } |
65 } |
66 |
66 |
67 public static function verify_key( $key, $ip = null ) { |
67 public static function verify_key( $key, $ip = null ) { |
|
68 // Shortcut for obviously invalid keys. |
|
69 if ( strlen( $key ) != 12 ) { |
|
70 return 'invalid'; |
|
71 } |
|
72 |
68 $response = self::check_key_status( $key, $ip ); |
73 $response = self::check_key_status( $key, $ip ); |
69 |
74 |
70 if ( $response[1] != 'valid' && $response[1] != 'invalid' ) |
75 if ( $response[1] != 'valid' && $response[1] != 'invalid' ) |
71 return 'failed'; |
76 return 'failed'; |
72 |
77 |
573 public static function transition_comment_status( $new_status, $old_status, $comment ) { |
578 public static function transition_comment_status( $new_status, $old_status, $comment ) { |
574 |
579 |
575 if ( $new_status == $old_status ) |
580 if ( $new_status == $old_status ) |
576 return; |
581 return; |
577 |
582 |
|
583 if ( 'spam' === $new_status || 'spam' === $old_status ) { |
|
584 // Clear the cache of the "X comments in your spam queue" count on the dashboard. |
|
585 wp_cache_delete( 'akismet_spam_count', 'widget' ); |
|
586 } |
|
587 |
578 # we don't need to record a history item for deleted comments |
588 # we don't need to record a history item for deleted comments |
579 if ( $new_status == 'delete' ) |
589 if ( $new_status == 'delete' ) |
580 return; |
590 return; |
581 |
591 |
582 if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) ) |
592 if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) ) |
1327 $args = $wp_xmlrpc_server->message->params; |
1340 $args = $wp_xmlrpc_server->message->params; |
1328 |
1341 |
1329 if ( !empty( $args[1] ) ) { |
1342 if ( !empty( $args[1] ) ) { |
1330 $post_id = url_to_postid( $args[1] ); |
1343 $post_id = url_to_postid( $args[1] ); |
1331 |
1344 |
1332 // If this gets through the pre-check, make sure we properly identify the outbound request as a pingback verification |
1345 // If pingbacks aren't open on this post, we'll still check whether this request is part of a potential DDOS, |
1333 Akismet::pingback_forwarded_for( null, $args[0] ); |
1346 // but indicate to the server that pingbacks are indeed closed so we don't include this request in the user's stats, |
1334 add_filter( 'http_request_args', array( 'Akismet', 'pingback_forwarded_for' ), 10, 2 ); |
1347 // since the user has already done their part by disabling pingbacks. |
|
1348 $pingbacks_closed = false; |
|
1349 |
|
1350 $post = get_post( $post_id ); |
|
1351 |
|
1352 if ( ! $post || ! pings_open( $post ) ) { |
|
1353 $pingbacks_closed = true; |
|
1354 } |
1335 |
1355 |
1336 $comment = array( |
1356 $comment = array( |
1337 'comment_author_url' => $args[0], |
1357 'comment_author_url' => $args[0], |
1338 'comment_post_ID' => $post_id, |
1358 'comment_post_ID' => $post_id, |
1339 'comment_author' => '', |
1359 'comment_author' => '', |
1340 'comment_author_email' => '', |
1360 'comment_author_email' => '', |
1341 'comment_content' => '', |
1361 'comment_content' => '', |
1342 'comment_type' => 'pingback', |
1362 'comment_type' => 'pingback', |
1343 'akismet_pre_check' => '1', |
1363 'akismet_pre_check' => '1', |
1344 'comment_pingback_target' => $args[1], |
1364 'comment_pingback_target' => $args[1], |
|
1365 'pingbacks_closed' => $pingbacks_closed ? '1' : '0', |
1345 ); |
1366 ); |
1346 |
1367 |
1347 $comment = Akismet::auto_check_comment( $comment ); |
1368 $comment = Akismet::auto_check_comment( $comment ); |
1348 |
1369 |
1349 if ( isset( $comment['akismet_result'] ) && 'true' == $comment['akismet_result'] ) { |
1370 if ( isset( $comment['akismet_result'] ) && 'true' == $comment['akismet_result'] ) { |
1350 // Lame: tightly coupled with the IXR classes. Unfortunately the action provides no context and no way to return anything. |
1371 // Lame: tightly coupled with the IXR classes. Unfortunately the action provides no context and no way to return anything. |
1351 $wp_xmlrpc_server->error( new IXR_Error( 0, 'Invalid discovery target' ) ); |
1372 $wp_xmlrpc_server->error( new IXR_Error( 0, 'Invalid discovery target' ) ); |
1352 } |
1373 } |
1353 } |
1374 } |
1354 } |
1375 } |
1355 |
1376 |
1356 public static function pingback_forwarded_for( $r, $url ) { |
|
1357 static $urls = array(); |
|
1358 |
|
1359 // Call this with $r == null to prime the callback to add headers on a specific URL |
|
1360 if ( is_null( $r ) && !in_array( $url, $urls ) ) { |
|
1361 $urls[] = $url; |
|
1362 } |
|
1363 |
|
1364 // Add X-Pingback-Forwarded-For header, but only for requests to a specific URL (the apparent pingback source) |
|
1365 if ( is_array( $r ) && is_array( $r['headers'] ) && !isset( $r['headers']['X-Pingback-Forwarded-For'] ) && in_array( $url, $urls ) ) { |
|
1366 $remote_ip = preg_replace( '/[^a-fx0-9:.,]/i', '', $_SERVER['REMOTE_ADDR'] ); |
|
1367 |
|
1368 // Note: this assumes REMOTE_ADDR is correct, and it may not be if a reverse proxy or CDN is in use |
|
1369 $r['headers']['X-Pingback-Forwarded-For'] = $remote_ip; |
|
1370 |
|
1371 // Also identify the request as a pingback verification in the UA string so it appears in logs |
|
1372 $r['user-agent'] .= '; verifying pingback from ' . $remote_ip; |
|
1373 } |
|
1374 |
|
1375 return $r; |
|
1376 } |
|
1377 |
|
1378 /** |
1377 /** |
1379 * Ensure that we are loading expected scalar values from akismet_as_submitted commentmeta. |
1378 * Ensure that we are loading expected scalar values from akismet_as_submitted commentmeta. |
1380 * |
1379 * |
1381 * @param mixed $meta_value |
1380 * @param mixed $meta_value |
1382 * @return mixed |
1381 * @return mixed |