Version Description
Download this release
Release Info
Developer | furkan811 |
Plugin | Cloudflare |
Version | 1.3.24 |
Comparing to | |
See all releases |
Version 1.3.24
- IpRange.php +210 -0
- IpRewrite.php +109 -0
- cloudflare.php +623 -0
- composer.json +27 -0
- readme.txt +196 -0
IpRange.php
ADDED
@@ -0,0 +1,210 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* ip_in_range.php - Function to determine if an IP is located in a
|
4 |
+
* specific range as specified via several alternative
|
5 |
+
* formats.
|
6 |
+
*
|
7 |
+
* Network ranges can be specified as:
|
8 |
+
* 1. Wildcard format: 1.2.3.*
|
9 |
+
* 2. CIDR format: 1.2.3/24 OR 1.2.3.4/255.255.255.0
|
10 |
+
* 3. Start-End IP format: 1.2.3.0-1.2.3.255
|
11 |
+
*
|
12 |
+
* Return value BOOLEAN : ip_in_range($ip, $range);
|
13 |
+
*
|
14 |
+
* Copyright 2008: Paul Gregg <pgregg@pgregg.com>
|
15 |
+
* 10 January 2008
|
16 |
+
* Version: 1.2
|
17 |
+
*
|
18 |
+
* Source website: http://www.pgregg.com/projects/php/ip_in_range/
|
19 |
+
* Version 1.2
|
20 |
+
*
|
21 |
+
* This software is Donationware - if you feel you have benefited from
|
22 |
+
* the use of this tool then please consider a donation. The value of
|
23 |
+
* which is entirely left up to your discretion.
|
24 |
+
* http://www.pgregg.com/donate/
|
25 |
+
*
|
26 |
+
* Please do not remove this header, or source attibution from this file.
|
27 |
+
*/
|
28 |
+
|
29 |
+
/*
|
30 |
+
* Modified by James Greene <james@cloudflare.com> to include IPV6 support
|
31 |
+
* (original version only supported IPV4).
|
32 |
+
* 21 May 2012
|
33 |
+
*/
|
34 |
+
|
35 |
+
namespace CloudFlare;
|
36 |
+
|
37 |
+
class IpRange
|
38 |
+
{
|
39 |
+
// ipv4_in_range
|
40 |
+
// This function takes 2 arguments, an IP address and a "range" in several
|
41 |
+
// different formats.
|
42 |
+
// Network ranges can be specified as:
|
43 |
+
// 1. Wildcard format: 1.2.3.*
|
44 |
+
// 2. CIDR format: 1.2.3/24 OR 1.2.3.4/255.255.255.0
|
45 |
+
// 3. Start-End IP format: 1.2.3.0-1.2.3.255
|
46 |
+
// The function will return true if the supplied IP is within the range.
|
47 |
+
// Note little validation is done on the range inputs - it expects you to
|
48 |
+
// use one of the above 3 formats.
|
49 |
+
public static function ipv4_in_range($ip, $range) {
|
50 |
+
if (strpos($range, '/') !== false) {
|
51 |
+
// $range is in IP/NETMASK format
|
52 |
+
list($range, $netmask) = explode('/', $range, 2);
|
53 |
+
if (strpos($netmask, '.') !== false) {
|
54 |
+
// $netmask is a 255.255.0.0 format
|
55 |
+
$netmask = str_replace('*', '0', $netmask);
|
56 |
+
$netmask_dec = ip2long($netmask);
|
57 |
+
return ( (ip2long($ip) & $netmask_dec) == (ip2long($range) & $netmask_dec) );
|
58 |
+
} else {
|
59 |
+
// $netmask is a CIDR size block
|
60 |
+
// fix the range argument
|
61 |
+
$x = explode('.', $range);
|
62 |
+
while(count($x)<4) $x[] = '0';
|
63 |
+
list($a,$b,$c,$d) = $x;
|
64 |
+
$range = sprintf("%u.%u.%u.%u", empty($a)?'0':$a, empty($b)?'0':$b,empty($c)?'0':$c,empty($d)?'0':$d);
|
65 |
+
$range_dec = ip2long($range);
|
66 |
+
$ip_dec = ip2long($ip);
|
67 |
+
|
68 |
+
# Strategy 1 - Create the netmask with 'netmask' 1s and then fill it to 32 with 0s
|
69 |
+
#$netmask_dec = bindec(str_pad('', $netmask, '1') . str_pad('', 32-$netmask, '0'));
|
70 |
+
|
71 |
+
# Strategy 2 - Use math to create it
|
72 |
+
$wildcard_dec = pow(2, (32-$netmask)) - 1;
|
73 |
+
$netmask_dec = ~ $wildcard_dec;
|
74 |
+
|
75 |
+
return (($ip_dec & $netmask_dec) == ($range_dec & $netmask_dec));
|
76 |
+
}
|
77 |
+
} else {
|
78 |
+
// range might be 255.255.*.* or 1.2.3.0-1.2.3.255
|
79 |
+
if (strpos($range, '*') !==false) { // a.b.*.* format
|
80 |
+
// Just convert to A-B format by setting * to 0 for A and 255 for B
|
81 |
+
$lower = str_replace('*', '0', $range);
|
82 |
+
$upper = str_replace('*', '255', $range);
|
83 |
+
$range = "$lower-$upper";
|
84 |
+
}
|
85 |
+
|
86 |
+
if (strpos($range, '-')!==false) { // A-B format
|
87 |
+
list($lower, $upper) = explode('-', $range, 2);
|
88 |
+
$lower_dec = (float)sprintf("%u",ip2long($lower));
|
89 |
+
$upper_dec = (float)sprintf("%u",ip2long($upper));
|
90 |
+
$ip_dec = (float)sprintf("%u",ip2long($ip));
|
91 |
+
return ( ($ip_dec>=$lower_dec) && ($ip_dec<=$upper_dec) );
|
92 |
+
}
|
93 |
+
return false;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
public static function ip2long6($ip) {
|
98 |
+
if (substr_count($ip, '::')) {
|
99 |
+
$ip = str_replace('::', str_repeat(':0000', 8 - substr_count($ip, ':')) . ':', $ip);
|
100 |
+
}
|
101 |
+
|
102 |
+
$ip = explode(':', $ip);
|
103 |
+
$r_ip = '';
|
104 |
+
foreach ($ip as $v) {
|
105 |
+
$r_ip .= str_pad(base_convert($v, 16, 2), 16, 0, STR_PAD_LEFT);
|
106 |
+
}
|
107 |
+
|
108 |
+
return base_convert($r_ip, 2, 10);
|
109 |
+
}
|
110 |
+
|
111 |
+
// Get the ipv6 full format and return it as a decimal value.
|
112 |
+
public static function get_ipv6_full($ip)
|
113 |
+
{
|
114 |
+
$pieces = explode ("/", $ip, 2);
|
115 |
+
$left_piece = $pieces[0];
|
116 |
+
$right_piece = null;
|
117 |
+
if (count($pieces) > 1) $right_piece = $pieces[1];
|
118 |
+
|
119 |
+
// Extract out the main IP pieces
|
120 |
+
$ip_pieces = explode("::", $left_piece, 2);
|
121 |
+
$main_ip_piece = $ip_pieces[0];
|
122 |
+
$last_ip_piece = null;
|
123 |
+
if (count($ip_pieces) > 1) $last_ip_piece = $ip_pieces[1];
|
124 |
+
|
125 |
+
// Pad out the shorthand entries.
|
126 |
+
$main_ip_pieces = explode(":", $main_ip_piece);
|
127 |
+
foreach($main_ip_pieces as $key=>$val) {
|
128 |
+
$main_ip_pieces[$key] = str_pad($main_ip_pieces[$key], 4, "0", STR_PAD_LEFT);
|
129 |
+
}
|
130 |
+
|
131 |
+
// Check to see if the last IP block (part after ::) is set
|
132 |
+
$last_piece = "";
|
133 |
+
$size = count($main_ip_pieces);
|
134 |
+
if (trim($last_ip_piece) != "") {
|
135 |
+
$last_piece = str_pad($last_ip_piece, 4, "0", STR_PAD_LEFT);
|
136 |
+
|
137 |
+
// Build the full form of the IPV6 address considering the last IP block set
|
138 |
+
for ($i = $size; $i < 7; $i++) {
|
139 |
+
$main_ip_pieces[$i] = "0000";
|
140 |
+
}
|
141 |
+
$main_ip_pieces[7] = $last_piece;
|
142 |
+
}
|
143 |
+
else {
|
144 |
+
// Build the full form of the IPV6 address
|
145 |
+
for ($i = $size; $i < 8; $i++) {
|
146 |
+
$main_ip_pieces[$i] = "0000";
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
// Rebuild the final long form IPV6 address
|
151 |
+
$final_ip = implode(":", $main_ip_pieces);
|
152 |
+
|
153 |
+
return self::ip2long6($final_ip);
|
154 |
+
}
|
155 |
+
|
156 |
+
|
157 |
+
// Determine whether the IPV6 address is within range.
|
158 |
+
// $ip is the IPV6 address in decimal format to check if its within the IP range created by the cloudflare IPV6 address, $range_ip.
|
159 |
+
// $ip and $range_ip are converted to full IPV6 format.
|
160 |
+
// Returns true if the IPV6 address, $ip, is within the range from $range_ip. False otherwise.
|
161 |
+
public static function ipv6_in_range($ip, $range_ip)
|
162 |
+
{
|
163 |
+
$pieces = explode ("/", $range_ip, 2);
|
164 |
+
$left_piece = $pieces[0];
|
165 |
+
$right_piece = $pieces[1];
|
166 |
+
|
167 |
+
// Extract out the main IP pieces
|
168 |
+
$ip_pieces = explode("::", $left_piece, 2);
|
169 |
+
$main_ip_piece = $ip_pieces[0];
|
170 |
+
$last_ip_piece = $ip_pieces[1];
|
171 |
+
|
172 |
+
// Pad out the shorthand entries.
|
173 |
+
$main_ip_pieces = explode(":", $main_ip_piece);
|
174 |
+
foreach($main_ip_pieces as $key=>$val) {
|
175 |
+
$main_ip_pieces[$key] = str_pad($main_ip_pieces[$key], 4, "0", STR_PAD_LEFT);
|
176 |
+
}
|
177 |
+
|
178 |
+
// Create the first and last pieces that will denote the IPV6 range.
|
179 |
+
$first = $main_ip_pieces;
|
180 |
+
$last = $main_ip_pieces;
|
181 |
+
|
182 |
+
// Check to see if the last IP block (part after ::) is set
|
183 |
+
$last_piece = "";
|
184 |
+
$size = count($main_ip_pieces);
|
185 |
+
if (trim($last_ip_piece) != "") {
|
186 |
+
$last_piece = str_pad($last_ip_piece, 4, "0", STR_PAD_LEFT);
|
187 |
+
|
188 |
+
// Build the full form of the IPV6 address considering the last IP block set
|
189 |
+
for ($i = $size; $i < 7; $i++) {
|
190 |
+
$first[$i] = "0000";
|
191 |
+
$last[$i] = "ffff";
|
192 |
+
}
|
193 |
+
$main_ip_pieces[7] = $last_piece;
|
194 |
+
}
|
195 |
+
else {
|
196 |
+
// Build the full form of the IPV6 address
|
197 |
+
for ($i = $size; $i < 8; $i++) {
|
198 |
+
$first[$i] = "0000";
|
199 |
+
$last[$i] = "ffff";
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
// Rebuild the final long form IPV6 address
|
204 |
+
$first = self::ip2long6(implode(":", $first));
|
205 |
+
$last = self::ip2long6(implode(":", $last));
|
206 |
+
$in_range = ($ip >= $first && $ip <= $last);
|
207 |
+
|
208 |
+
return $in_range;
|
209 |
+
}
|
210 |
+
}
|
IpRewrite.php
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace CloudFlare;
|
4 |
+
|
5 |
+
class IpRewrite {
|
6 |
+
static protected $is_cf = NULL;
|
7 |
+
static protected $original_ip = FALSE;
|
8 |
+
static protected $rewritten_ip = FALSE;
|
9 |
+
|
10 |
+
static protected $cf_ipv4 = array(
|
11 |
+
"199.27.128.0/21",
|
12 |
+
"173.245.48.0/20",
|
13 |
+
"103.21.244.0/22",
|
14 |
+
"103.22.200.0/22",
|
15 |
+
"103.31.4.0/22",
|
16 |
+
"141.101.64.0/18",
|
17 |
+
"108.162.192.0/18",
|
18 |
+
"190.93.240.0/20",
|
19 |
+
"188.114.96.0/20",
|
20 |
+
"197.234.240.0/22",
|
21 |
+
"198.41.128.0/17",
|
22 |
+
"162.158.0.0/15",
|
23 |
+
"104.16.0.0/12",
|
24 |
+
"172.64.0.0/13"
|
25 |
+
);
|
26 |
+
|
27 |
+
static protected $cf_ipv6 = array(
|
28 |
+
"2400:cb00::/32",
|
29 |
+
"2606:4700::/32",
|
30 |
+
"2803:f800::/32",
|
31 |
+
"2405:b500::/32",
|
32 |
+
"2405:8100::/32"
|
33 |
+
);
|
34 |
+
|
35 |
+
// Returns boolean
|
36 |
+
public static function isCloudFlare()
|
37 |
+
{
|
38 |
+
self::rewrite();
|
39 |
+
return self::$is_cf;
|
40 |
+
}
|
41 |
+
|
42 |
+
// Returns IP Address or false on error
|
43 |
+
public static function getRewrittenIP()
|
44 |
+
{
|
45 |
+
self::rewrite();
|
46 |
+
return self::$rewritten_ip;
|
47 |
+
}
|
48 |
+
|
49 |
+
// Returns IP Address or false on error
|
50 |
+
public static function getOriginalIP()
|
51 |
+
{
|
52 |
+
self::rewrite();
|
53 |
+
return self::$original_ip;
|
54 |
+
}
|
55 |
+
|
56 |
+
// Helper method for testing, should not be used in production
|
57 |
+
public static function reset()
|
58 |
+
{
|
59 |
+
self::$is_cf = NULL;
|
60 |
+
self::$original_ip = FALSE;
|
61 |
+
self::$rewritten_ip = FALSE;
|
62 |
+
}
|
63 |
+
|
64 |
+
/*
|
65 |
+
* Protected function to handle the rewriting of CloudFlare IP Addresses to end-user IP Addresses
|
66 |
+
*
|
67 |
+
* ** NOTE: This function will ultimately rewrite $_SERVER["REMOTE_ADDR"] if the site is on CloudFlare
|
68 |
+
*/
|
69 |
+
protected static function rewrite()
|
70 |
+
{
|
71 |
+
// only should be run once per page load
|
72 |
+
if (self::$is_cf !== NULL) {
|
73 |
+
return;
|
74 |
+
}
|
75 |
+
|
76 |
+
// Set this based on the presence of the header, so it is true even if IP has already been rewritten
|
77 |
+
self::$is_cf = isset($_SERVER["HTTP_CF_CONNECTING_IP"]) ? TRUE : FALSE;
|
78 |
+
|
79 |
+
// Store original remote address in $original_ip
|
80 |
+
self::$original_ip = isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : FALSE;
|
81 |
+
|
82 |
+
// Process original_ip if on cloudflare
|
83 |
+
if (self::$is_cf && self::$original_ip) {
|
84 |
+
// Check for IPv4 v. IPv6
|
85 |
+
if (strpos(self::$original_ip, ":") === FALSE) {
|
86 |
+
foreach (self::$cf_ipv4 as $range) {
|
87 |
+
if (IpRange::ipv4_in_range(self::$original_ip, $range)) {
|
88 |
+
if (self::$is_cf) {
|
89 |
+
self::$rewritten_ip = $_SERVER["REMOTE_ADDR"] =
|
90 |
+
$_SERVER["HTTP_CF_CONNECTING_IP"];
|
91 |
+
}
|
92 |
+
break;
|
93 |
+
}
|
94 |
+
}
|
95 |
+
} else {
|
96 |
+
$ipv6 = IpRange::get_ipv6_full(self::$original_ip);
|
97 |
+
foreach (self::$cf_ipv6 as $range) {
|
98 |
+
if (IpRange::ipv6_in_range($ipv6, $range)) {
|
99 |
+
if (self::$is_cf) {
|
100 |
+
self::$rewritten_ip = $_SERVER["REMOTE_ADDR"] =
|
101 |
+
$_SERVER["HTTP_CF_CONNECTING_IP"];
|
102 |
+
}
|
103 |
+
break;
|
104 |
+
}
|
105 |
+
}
|
106 |
+
}
|
107 |
+
}
|
108 |
+
}
|
109 |
+
}
|
cloudflare.php
ADDED
@@ -0,0 +1,623 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: CloudFlare
|
4 |
+
Plugin URI: http://www.cloudflare.com/wiki/CloudFlareWordPressPlugin
|
5 |
+
Description: CloudFlare integrates your blog with the CloudFlare platform.
|
6 |
+
Version: 1.3.24
|
7 |
+
Author: Ian Pye, Jerome Chen, James Greene, Simon Moore, David Fritsch, John Wineman (CloudFlare Team)
|
8 |
+
License: GPLv2
|
9 |
+
*/
|
10 |
+
|
11 |
+
/*
|
12 |
+
This program is free software; you can redistribute it and/or modify
|
13 |
+
it under the terms of the GNU General Public License as published by
|
14 |
+
the Free Software Foundation; version 2 of the License.
|
15 |
+
|
16 |
+
This program is distributed in the hope that it will be useful,
|
17 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 |
+
GNU General Public License for more details.
|
20 |
+
|
21 |
+
You should have received a copy of the GNU General Public License
|
22 |
+
along with this program; if not, write to the Free Software
|
23 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
24 |
+
|
25 |
+
Plugin adapted from the Akismet WP plugin.
|
26 |
+
|
27 |
+
*/
|
28 |
+
|
29 |
+
define('CLOUDFLARE_VERSION', '1.3.24');
|
30 |
+
define('CLOUDFLARE_API_URL', 'https://www.cloudflare.com/api_json.html');
|
31 |
+
define('CLOUDFLARE_SPAM_URL', 'https://www.cloudflare.com/ajax/external-event.html');
|
32 |
+
|
33 |
+
require_once("IpRewrite.php");
|
34 |
+
require_once("IpRange.php");
|
35 |
+
|
36 |
+
use CloudFlare\IpRewrite;
|
37 |
+
|
38 |
+
$cfPostKeys = array("cloudflare_zone_name", "cf_key", "cf_email", "dev_mode", "protocol_rewrite");
|
39 |
+
|
40 |
+
foreach($_POST as $key => $value) {
|
41 |
+
if(in_array($key, $cfPostKeys)) {
|
42 |
+
$_POST[$key] = cloudflare_filter_xss($_POST[$key]);
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
function cloudflare_filter_xss($input) {
|
47 |
+
return htmlentities($input, ENT_QUOTES | ENT_HTML5, "UTF-8");
|
48 |
+
}
|
49 |
+
|
50 |
+
|
51 |
+
// Make sure we don't expose any info if called directly
|
52 |
+
if ( !function_exists( 'add_action' ) ) {
|
53 |
+
echo "Hi there! I'm just a plugin, not much I can do when called directly.";
|
54 |
+
exit;
|
55 |
+
}
|
56 |
+
|
57 |
+
function cloudflare_init() {
|
58 |
+
global $is_cf;
|
59 |
+
|
60 |
+
$is_cf = IpRewrite::isCloudFlare();
|
61 |
+
|
62 |
+
add_action('admin_menu', 'cloudflare_config_page');
|
63 |
+
}
|
64 |
+
add_action('init', 'cloudflare_init',1);
|
65 |
+
|
66 |
+
function cloudflare_admin_init() {
|
67 |
+
|
68 |
+
}
|
69 |
+
|
70 |
+
add_action('admin_init', 'cloudflare_admin_init');
|
71 |
+
|
72 |
+
function cloudflare_plugin_action_links( $links ) {
|
73 |
+
$links[] = '<a href="'. get_admin_url(null, 'options-general.php?page=cloudflare') .'">Settings</a>';
|
74 |
+
return $links;
|
75 |
+
}
|
76 |
+
|
77 |
+
add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'cloudflare_plugin_action_links' );
|
78 |
+
|
79 |
+
function cloudflare_config_page() {
|
80 |
+
if (function_exists('add_options_page')) {
|
81 |
+
add_options_page(__('CloudFlare Configuration'), __('CloudFlare'), 'manage_options', 'cloudflare', 'cloudflare_conf');
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
function load_cloudflare_keys () {
|
86 |
+
global $cloudflare_api_key, $cloudflare_api_email, $cloudflare_zone_name, $cloudflare_protocol_rewrite;
|
87 |
+
$cloudflare_api_key = get_option('cloudflare_api_key');
|
88 |
+
$cloudflare_api_email = get_option('cloudflare_api_email');
|
89 |
+
$cloudflare_zone_name = get_option('cloudflare_zone_name');
|
90 |
+
$cloudflare_protocol_rewrite = load_protocol_rewrite();
|
91 |
+
}
|
92 |
+
|
93 |
+
function load_protocol_rewrite() {
|
94 |
+
return get_option('cloudflare_protocol_rewrite', 1);
|
95 |
+
}
|
96 |
+
|
97 |
+
function cloudflare_conf() {
|
98 |
+
|
99 |
+
if ( function_exists('current_user_can') && !current_user_can('manage_options') )
|
100 |
+
die(__('Cheatin’ uh?'));
|
101 |
+
global $cloudflare_zone_name, $cloudflare_api_key, $cloudflare_api_email, $cloudflare_protocol_rewrite, $is_cf;
|
102 |
+
global $wpdb;
|
103 |
+
|
104 |
+
load_cloudflare_keys();
|
105 |
+
|
106 |
+
$messages = array(
|
107 |
+
'ip_restore_on' => array('text' => __('Plugin Status: True visitor IP is being restored')),
|
108 |
+
'comment_spam_on' => array('text' => __('Plugin Status: CloudFlare will be notified when you mark comments as spam')),
|
109 |
+
'comment_spam_off' => array('text' => __('Plugin Status: CloudFlare will NOT be notified when you mark comments as spam, enter your API details below')),
|
110 |
+
'dev_mode_on' => array('text' => __('Development mode is On. Happy blogging!')),
|
111 |
+
'dev_mode_off' => array('text' => __('Development mode is Off. Happy blogging!')),
|
112 |
+
'protocol_rewrite_on' => array('text' => __('Protocol rewriting is On. Happy blogging!')),
|
113 |
+
'protocol_rewrite_off' => array('text' => __('Protocol rewriting is Off. Happy blogging!')),
|
114 |
+
'manual_entry' => array('text' => __('Enter your CloudFlare domain name, e-mail address and API key below')),
|
115 |
+
'options_saved' => array('text' => __('Options Saved')),
|
116 |
+
);
|
117 |
+
|
118 |
+
$notices = array();
|
119 |
+
$warnings = array();
|
120 |
+
$errors = array();
|
121 |
+
|
122 |
+
$notices[] = 'ip_restore_on';
|
123 |
+
|
124 |
+
// get raw domain - may include www.
|
125 |
+
$urlparts = parse_url(site_url());
|
126 |
+
$raw_domain = $urlparts["host"];
|
127 |
+
|
128 |
+
// if we don't have a domain name already populated
|
129 |
+
if (empty($cloudflare_zone_name)) {
|
130 |
+
|
131 |
+
if (!empty($cloudflare_api_key) && !empty($cloudflare_api_email)) {
|
132 |
+
// Attempt to get the matching host from CF
|
133 |
+
$getDomain = get_domain($cloudflare_api_key, $cloudflare_api_email, $raw_domain);
|
134 |
+
|
135 |
+
// If not found, default to pulling the domain via client side.
|
136 |
+
if (is_wp_error($getDomain)) {
|
137 |
+
$messages['get_domain_failed'] = array('text' => __('Unable to automatically get domain - ' . $getDomain->get_error_message() . ' - please tell us your domain in the form below'));
|
138 |
+
$warnings[] = 'get_domain_failed';
|
139 |
+
}
|
140 |
+
else {
|
141 |
+
update_option('cloudflare_zone_name', esc_sql($getDomain));
|
142 |
+
update_option('cloudflare_zone_name_set_once', "TRUE");
|
143 |
+
load_cloudflare_keys();
|
144 |
+
}
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
$db_results = array();
|
149 |
+
|
150 |
+
if ( isset($_POST['submit'])
|
151 |
+
&& check_admin_referer('cloudflare-db-api','cloudflare-db-api-nonce') ) {
|
152 |
+
|
153 |
+
if ( function_exists('current_user_can') && !current_user_can('manage_options') ) {
|
154 |
+
die(__('Cheatin’ uh?'));
|
155 |
+
}
|
156 |
+
|
157 |
+
$zone_name = $_POST['cloudflare_zone_name'];
|
158 |
+
|
159 |
+
$zone_name = str_replace(".",".",$zone_name);
|
160 |
+
|
161 |
+
$key = $_POST['cf_key'];
|
162 |
+
$email = $_POST['cf_email'];
|
163 |
+
|
164 |
+
$allowedCharacters = array(
|
165 |
+
"." => ".",
|
166 |
+
"@" => "@",
|
167 |
+
"+" => "+"
|
168 |
+
);
|
169 |
+
|
170 |
+
foreach($allowedCharacters as $arrayKey => $value) {
|
171 |
+
$email = str_replace($arrayKey, $value, $email);
|
172 |
+
}
|
173 |
+
|
174 |
+
$dev_mode = esc_sql($_POST["dev_mode"]);
|
175 |
+
$protocol_rewrite = esc_sql($_POST["protocol_rewrite"]);
|
176 |
+
|
177 |
+
if ( empty($zone_name) ) {
|
178 |
+
$zone_status = 'empty';
|
179 |
+
$zone_message = 'Your domain name has been cleared.';
|
180 |
+
delete_option('cloudflare_zone_name');
|
181 |
+
} else {
|
182 |
+
$zone_message = 'Your domain name has been saved.';
|
183 |
+
update_option('cloudflare_zone_name', esc_sql($zone_name));
|
184 |
+
update_option('cloudflare_zone_name_set_once', "TRUE");
|
185 |
+
}
|
186 |
+
|
187 |
+
if ( empty($key) ) {
|
188 |
+
$key_status = 'empty';
|
189 |
+
$key_message = 'Your key has been cleared.';
|
190 |
+
delete_option('cloudflare_api_key');
|
191 |
+
} else {
|
192 |
+
$key_message = 'Your key has been verified.';
|
193 |
+
update_option('cloudflare_api_key', esc_sql($key));
|
194 |
+
update_option('cloudflare_api_key_set_once', "TRUE");
|
195 |
+
}
|
196 |
+
|
197 |
+
if ( empty($email) || !is_email($email) ) {
|
198 |
+
$email_status = 'empty';
|
199 |
+
$email_message = 'Your email has been cleared.';
|
200 |
+
delete_option('cloudflare_api_email');
|
201 |
+
} else {
|
202 |
+
$email_message = 'Your email has been verified.';
|
203 |
+
update_option('cloudflare_api_email', esc_sql($email));
|
204 |
+
update_option('cloudflare_api_email_set_once', "TRUE");
|
205 |
+
}
|
206 |
+
|
207 |
+
if (in_array($protocol_rewrite, array("0","1")) === TRUE) {
|
208 |
+
update_option('cloudflare_protocol_rewrite', $protocol_rewrite);
|
209 |
+
}
|
210 |
+
|
211 |
+
// update the values
|
212 |
+
load_cloudflare_keys();
|
213 |
+
|
214 |
+
if ($cloudflare_api_key != "" && $cloudflare_api_email != "" && $cloudflare_zone_name != "" && $dev_mode != "") {
|
215 |
+
|
216 |
+
$result = set_dev_mode(esc_sql($cloudflare_api_key), esc_sql($cloudflare_api_email), $cloudflare_zone_name, $dev_mode);
|
217 |
+
|
218 |
+
if (is_wp_error($result)) {
|
219 |
+
trigger_error($result->get_error_message(), E_USER_WARNING);
|
220 |
+
$messages['set_dev_mode_failed'] = array('text' => __('Unable to set development mode - ' . $result->get_error_message() . ' - try logging into cloudflare.com to set development mode'));
|
221 |
+
$errors[] = 'set_dev_mode_failed';
|
222 |
+
}
|
223 |
+
else {
|
224 |
+
if ($dev_mode && $result->result == 'success') {
|
225 |
+
$notices[] = 'dev_mode_on';
|
226 |
+
}
|
227 |
+
else if (!$dev_mode && $result->result == 'success') {
|
228 |
+
$notices[] = 'dev_mode_off';
|
229 |
+
}
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
$notices[] = 'options_saved';
|
234 |
+
}
|
235 |
+
|
236 |
+
if (!empty($cloudflare_api_key) && !empty($cloudflare_api_email) && !empty($cloudflare_zone_name)) {
|
237 |
+
$dev_mode = get_dev_mode_status($cloudflare_api_key, $cloudflare_api_email, $cloudflare_zone_name);
|
238 |
+
|
239 |
+
if (is_wp_error($dev_mode)) {
|
240 |
+
$messages['get_dev_mode_failed'] = array('text' => __('Unable to get current development mode status - ' . $dev_mode->get_error_message()));
|
241 |
+
$errors[] = 'get_dev_mode_failed';
|
242 |
+
}
|
243 |
+
}
|
244 |
+
else {
|
245 |
+
$warnings[] = 'manual_entry';
|
246 |
+
}
|
247 |
+
|
248 |
+
if (!empty($cloudflare_api_key) && !empty($cloudflare_api_email)) $notices[] = 'comment_spam_on';
|
249 |
+
else $warnings[] = 'comment_spam_off';
|
250 |
+
|
251 |
+
?>
|
252 |
+
<div class="wrap">
|
253 |
+
|
254 |
+
<?php if ($is_cf) { ?>
|
255 |
+
<h3>You are currently using CloudFlare!</h3>
|
256 |
+
<?php } ?>
|
257 |
+
|
258 |
+
<?php if ($notices) { foreach ( $notices as $m ) { ?>
|
259 |
+
<div class="updated" style="border-left-color: #7ad03a; padding: 10px;"><?php echo $messages[$m]['text']; ?></div>
|
260 |
+
<?php } } ?>
|
261 |
+
|
262 |
+
<?php if ($warnings) { foreach ( $warnings as $m ) { ?>
|
263 |
+
<div class="updated" style="border-left-color: #ffba00; padding: 10px;"><em><?php echo $messages[$m]['text']; ?></em></div>
|
264 |
+
<?php } } ?>
|
265 |
+
|
266 |
+
<?php if ($errors) { foreach ( $errors as $m ) { ?>
|
267 |
+
<div class="updated" style="border-left-color: #dd3d36; padding: 10px;"><b><?php echo $messages[$m]['text']; ?></b></div>
|
268 |
+
<?php } } ?>
|
269 |
+
|
270 |
+
<h4><?php _e('CLOUDFLARE WORDPRESS PLUGIN:'); ?></h4>
|
271 |
+
|
272 |
+
CloudFlare has developed a plugin for WordPress. By using the CloudFlare WordPress Plugin, you receive:
|
273 |
+
<ol>
|
274 |
+
<li>Correct IP Address information for comments posted to your site</li>
|
275 |
+
<li>Better protection as spammers from your WordPress blog get reported to CloudFlare</li>
|
276 |
+
<li>If cURL is installed, you can enter your CloudFlare API details so you can toggle <a href="https://support.cloudflare.com/hc/en-us/articles/200168246-What-does-CloudFlare-Development-mode-mean-" target="_blank">Development mode</a> on/off using the form below</li>
|
277 |
+
</ol>
|
278 |
+
|
279 |
+
<h4>VERSION COMPATIBILITY:</h4>
|
280 |
+
|
281 |
+
The plugin is compatible with WordPress version 2.8.6 and later. The plugin will not install unless you have a compatible platform.
|
282 |
+
|
283 |
+
<h4>THINGS YOU NEED TO KNOW:</h4>
|
284 |
+
|
285 |
+
<ol>
|
286 |
+
<li>The main purpose of this plugin is to ensure you have no change to your originating IPs when using CloudFlare. Since CloudFlare acts a reverse proxy, connecting IPs now come from CloudFlare's range. This plugin will ensure you can continue to see the originating IP. Once you install the plugin, the IP benefit will be activated.</li>
|
287 |
+
|
288 |
+
<li>Every time you click the 'spam' button on your blog, this threat information is sent to CloudFlare to ensure you are constantly getting the best site protection.</li>
|
289 |
+
|
290 |
+
<li>We recommend that any user on CloudFlare with WordPress use this plugin. </li>
|
291 |
+
|
292 |
+
<li>NOTE: This plugin is complementary to Akismet and W3 Total Cache. We recommend that you continue to use those services.</li>
|
293 |
+
|
294 |
+
</ol>
|
295 |
+
|
296 |
+
<h4>MORE INFORMATION ON CLOUDFLARE:</h4>
|
297 |
+
|
298 |
+
CloudFlare is a service that makes websites load faster and protects sites from online spammers and hackers. Any website with a root domain (ie www.mydomain.com) can use CloudFlare. On average, it takes less than 5 minutes to sign up. You can learn more here: <a href="http://www.cloudflare.com/" target="_blank">CloudFlare.com</a>.
|
299 |
+
|
300 |
+
<hr />
|
301 |
+
|
302 |
+
<form action="" method="post" id="cloudflare-conf">
|
303 |
+
<?php wp_nonce_field('cloudflare-db-api','cloudflare-db-api-nonce'); ?>
|
304 |
+
<?php if (get_option('cloudflare_api_key') && get_option('cloudflare_api_email')) { ?>
|
305 |
+
<?php } else { ?>
|
306 |
+
<p><?php printf(__('Input your API key from your CloudFlare Accounts Settings page here. To find your API key, log in to <a href="%1$s">CloudFlare</a> and go to \'Account\'.'), 'https://www.cloudflare.com/a/account/my-account'); ?></p>
|
307 |
+
<?php } ?>
|
308 |
+
<h3><label for="cloudflare_zone_name"><?php _e('CloudFlare Domain Name'); ?></label></h3>
|
309 |
+
<p>
|
310 |
+
<input id="cloudflare_zone_name" name="cloudflare_zone_name" type="text" size="50" maxlength="255" value="<?php echo $cloudflare_zone_name; ?>" style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;" /> (<?php _e('<a href="https://www.cloudflare.com/a/overview" target="_blank">Get this?</a>'); ?>)
|
311 |
+
</p>
|
312 |
+
<p>E.g. Enter domain.com not www.domain.com / blog.domain.com</p>
|
313 |
+
<?php if (isset($zone_message)) echo sprintf('<p>%s</p>', $zone_message); ?>
|
314 |
+
<h3><label for="key"><?php _e('CloudFlare API Key'); ?></label></h3>
|
315 |
+
<p>
|
316 |
+
<input id="key" name="cf_key" type="text" size="50" maxlength="48" value="<?php echo get_option('cloudflare_api_key'); ?>" style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;" /> (<?php _e('<a href="https://www.cloudflare.com/a/account/my-account" target="_blank">Get this?</a>'); ?>)
|
317 |
+
</p>
|
318 |
+
<?php if (isset($key_message)) echo sprintf('<p>%s</p>', $key_message); ?>
|
319 |
+
|
320 |
+
<h3><label for="email"><?php _e('CloudFlare API Email'); ?></label></h3>
|
321 |
+
<p>
|
322 |
+
<input id="email" name="cf_email" type="text" size="50" maxlength="48" value="<?php echo get_option('cloudflare_api_email'); ?>" style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;" /> (<?php _e('<a href="https://www.cloudflare.com/a/account/my-account" target="_blank">Get this?</a>'); ?>)
|
323 |
+
</p>
|
324 |
+
<?php if (isset($key_message)) echo sprintf('<p>%s</p>', $key_message); ?>
|
325 |
+
|
326 |
+
<h3><label for="dev_mode"><?php _e('Development Mode'); ?></label> <span style="font-size:9pt;">(<a href="https://support.cloudflare.com/hc/en-us/articles/200168246-What-does-CloudFlare-Development-mode-mean-" target="_blank">What is this?</a>)</span></h3>
|
327 |
+
|
328 |
+
<div style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;">
|
329 |
+
<input type="radio" name="dev_mode" value="0" <?php if ($dev_mode == "off") echo "checked"; ?>> Off
|
330 |
+
<input type="radio" name="dev_mode" value="1" <?php if ($dev_mode == "on") echo "checked"; ?>> On
|
331 |
+
</div>
|
332 |
+
|
333 |
+
<h3><label for="protocol_rewrite"><?php _e('HTTPS Protocol Rewriting'); ?></label> <span style="font-size:9pt;">(<a href="https://support.cloudflare.com/hc/en-us/articles/203652674" target="_blank">What is this?</a>)</span></h3>
|
334 |
+
|
335 |
+
<div style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;">
|
336 |
+
<input type="radio" name="protocol_rewrite" value="0" <?php if ($cloudflare_protocol_rewrite == 0) echo "checked"; ?>> Off
|
337 |
+
<input type="radio" name="protocol_rewrite" value="1" <?php if ($cloudflare_protocol_rewrite == 1) echo "checked"; ?>> On
|
338 |
+
</div>
|
339 |
+
|
340 |
+
<p class="submit"><input type="submit" name="submit" value="<?php _e('Update options »'); ?>" /></p>
|
341 |
+
</form>
|
342 |
+
|
343 |
+
<?php // </div> ?>
|
344 |
+
</div>
|
345 |
+
<?php
|
346 |
+
}
|
347 |
+
|
348 |
+
// Now actually allow CF to see when a comment is approved/not-approved.
|
349 |
+
function cloudflare_set_comment_status($id, $status) {
|
350 |
+
|
351 |
+
if ($status == 'spam') {
|
352 |
+
|
353 |
+
global $cloudflare_api_key, $cloudflare_api_email;
|
354 |
+
|
355 |
+
load_cloudflare_keys();
|
356 |
+
|
357 |
+
if (!$cloudflare_api_key || !$cloudflare_api_email) {
|
358 |
+
return;
|
359 |
+
}
|
360 |
+
|
361 |
+
$comment = get_comment($id);
|
362 |
+
|
363 |
+
// make sure we have a comment
|
364 |
+
if (!is_null($comment)) {
|
365 |
+
|
366 |
+
$payload = array(
|
367 |
+
"a" => $comment->comment_author,
|
368 |
+
"am" => $comment->comment_author_email,
|
369 |
+
"ip" => $comment->comment_author_IP,
|
370 |
+
"con" => substr($comment->comment_content, 0, 100)
|
371 |
+
);
|
372 |
+
|
373 |
+
$payload = urlencode(json_encode($payload));
|
374 |
+
|
375 |
+
$args = array(
|
376 |
+
'method' => 'GET',
|
377 |
+
'timeout' => 20,
|
378 |
+
'sslverify' => true,
|
379 |
+
'user-agent' => 'CloudFlare/WordPress/'.CLOUDFLARE_VERSION,
|
380 |
+
);
|
381 |
+
|
382 |
+
$url = sprintf('%s?evnt_v=%s&u=%s&tkn=%s&evnt_t=%s', CLOUDFLARE_SPAM_URL, $payload, $cloudflare_api_email, $cloudflare_api_key, 'WP_SPAM');
|
383 |
+
|
384 |
+
// fire and forget here, for better or worse
|
385 |
+
wp_remote_get($url, $args);
|
386 |
+
}
|
387 |
+
|
388 |
+
// ajax/external-event.html?email=ian@cloudflare.com&t=94606855d7e42adf3b9e2fd004c7660b941b8e55aa42d&evnt_v={%22dd%22:%22d%22}&evnt_t=WP_SPAM
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
add_action('wp_set_comment_status', 'cloudflare_set_comment_status', 1, 2);
|
393 |
+
|
394 |
+
function get_dev_mode_status($token, $email, $zone) {
|
395 |
+
|
396 |
+
$fields = array(
|
397 |
+
'a'=>"zone_load",
|
398 |
+
'tkn'=>$token,
|
399 |
+
'email'=>$email,
|
400 |
+
'z'=>$zone
|
401 |
+
);
|
402 |
+
|
403 |
+
$result = cloudflare_curl(CLOUDFLARE_API_URL, $fields, true);
|
404 |
+
|
405 |
+
if (is_wp_error($result)) {
|
406 |
+
trigger_error($result->get_error_message(), E_USER_WARNING);
|
407 |
+
return $result;
|
408 |
+
}
|
409 |
+
|
410 |
+
if ($result->response->zone->obj->zone_status_class == "status-dev-mode") {
|
411 |
+
return "on";
|
412 |
+
}
|
413 |
+
|
414 |
+
return "off";
|
415 |
+
}
|
416 |
+
|
417 |
+
function set_dev_mode($token, $email, $zone, $value) {
|
418 |
+
|
419 |
+
$fields = array(
|
420 |
+
'a'=>"devmode",
|
421 |
+
'tkn'=>$token,
|
422 |
+
'email'=>$email,
|
423 |
+
'z'=>$zone,
|
424 |
+
'v'=>$value
|
425 |
+
);
|
426 |
+
|
427 |
+
$result = cloudflare_curl(CLOUDFLARE_API_URL, $fields, true);
|
428 |
+
|
429 |
+
if (is_wp_error($result)) {
|
430 |
+
trigger_error($result->get_error_message(), E_USER_WARNING);
|
431 |
+
return $result;
|
432 |
+
}
|
433 |
+
|
434 |
+
return $result;
|
435 |
+
}
|
436 |
+
|
437 |
+
function get_domain($token, $email, $raw_domain) {
|
438 |
+
|
439 |
+
$fields = array(
|
440 |
+
'a'=>"zone_load_multi",
|
441 |
+
'tkn'=>$token,
|
442 |
+
'email'=>$email
|
443 |
+
);
|
444 |
+
|
445 |
+
$result = cloudflare_curl(CLOUDFLARE_API_URL, $fields, true);
|
446 |
+
|
447 |
+
if (is_wp_error($result)) {
|
448 |
+
trigger_error($result->get_error_message(), E_USER_WARNING);
|
449 |
+
return $result;
|
450 |
+
}
|
451 |
+
|
452 |
+
$zone_count = $result->response->zones->count;
|
453 |
+
$zone_names = array();
|
454 |
+
|
455 |
+
if ($zone_count < 1) {
|
456 |
+
return new WP_Error('match_domain', 'API did not return any domains');
|
457 |
+
}
|
458 |
+
else {
|
459 |
+
for ($i = 0; $i < $zone_count; $i++) {
|
460 |
+
$zone_names[] = $result->response->zones->objs[$i]->zone_name;
|
461 |
+
}
|
462 |
+
|
463 |
+
$match = match_domain_to_zone($raw_domain, $zone_names);
|
464 |
+
|
465 |
+
if (is_null($match)) {
|
466 |
+
return new WP_Error('match_domain', 'Unable to automatically find your domain (no match)');
|
467 |
+
}
|
468 |
+
else {
|
469 |
+
return $match;
|
470 |
+
}
|
471 |
+
}
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* @param $domain string the domain portion of the WP URL
|
476 |
+
* @param $zone_names array an array of zone_names to compare against
|
477 |
+
*
|
478 |
+
* @returns null|string null in the case of a failure, string in the case of a match
|
479 |
+
*/
|
480 |
+
function match_domain_to_zone($domain, $zones) {
|
481 |
+
|
482 |
+
$splitDomain = explode('.', $domain);
|
483 |
+
$totalParts = count($splitDomain);
|
484 |
+
|
485 |
+
// minimum parts for a complete zone match will be 2, e.g. blah.com
|
486 |
+
for ($i = 0; $i <= ($totalParts - 2); $i++) {
|
487 |
+
$copy = $splitDomain;
|
488 |
+
$currentDomain = implode('.', array_splice($copy, $i));
|
489 |
+
foreach ($zones as $zone_name) {
|
490 |
+
if (strtolower($currentDomain) == strtolower($zone_name)) {
|
491 |
+
return $zone_name;
|
492 |
+
}
|
493 |
+
}
|
494 |
+
}
|
495 |
+
|
496 |
+
return null;
|
497 |
+
}
|
498 |
+
|
499 |
+
/**
|
500 |
+
* @param $url string the URL to curl
|
501 |
+
* @param $fields array an associative array of arguments for POSTing
|
502 |
+
* @param $json boolean attempt to decode response as JSON
|
503 |
+
*
|
504 |
+
* @returns WP_ERROR|string|object in the case of an error, otherwise a $result string or JSON object
|
505 |
+
*/
|
506 |
+
function cloudflare_curl($url, $fields = array(), $json = true) {
|
507 |
+
|
508 |
+
$args = array(
|
509 |
+
'method' => 'GET',
|
510 |
+
'timeout' => 20,
|
511 |
+
'sslverify' => true,
|
512 |
+
'user-agent' => 'CloudFlare/WordPress/'.CLOUDFLARE_VERSION,
|
513 |
+
);
|
514 |
+
|
515 |
+
if (!empty($fields)) {
|
516 |
+
$args['method'] = 'POST';
|
517 |
+
$args['body'] = $fields;
|
518 |
+
}
|
519 |
+
|
520 |
+
$response = wp_remote_request($url, $args);
|
521 |
+
|
522 |
+
// if we have an array, we have a HTTP Response
|
523 |
+
if (is_array($response)) {
|
524 |
+
// Always expect a HTTP 200 from the API
|
525 |
+
|
526 |
+
// HERE BE DRAGONS
|
527 |
+
// WP_HTTP does not return conistent types - cURL seems to return an int for the reponse code, streams returns a string.
|
528 |
+
if (intval($response['response']['code']) !== 200) {
|
529 |
+
// Invalid response code
|
530 |
+
return new WP_Error('cloudflare', sprintf('CloudFlare API returned a HTTP Error: %s - %s', $response['response']['code'], $response['response']['message']));
|
531 |
+
}
|
532 |
+
else {
|
533 |
+
if ($json == true) {
|
534 |
+
$result = json_decode($response['body']);
|
535 |
+
// not a perfect test, but better than nothing perhaps
|
536 |
+
if ($result == null) {
|
537 |
+
return new WP_Error('json_decode', sprintf('Unable to decode JSON response'), $result);
|
538 |
+
}
|
539 |
+
|
540 |
+
// check for the CloudFlare API failure response
|
541 |
+
if (property_exists($result, 'result') && $result->result !== 'success') {
|
542 |
+
$msg = 'Unknown Error';
|
543 |
+
if (property_exists($result, 'msg') && !empty($result->msg)) $msg = $result->msg;
|
544 |
+
return new WP_Error('cloudflare', $msg);
|
545 |
+
}
|
546 |
+
|
547 |
+
return $result;
|
548 |
+
}
|
549 |
+
else {
|
550 |
+
return $response['body'];
|
551 |
+
}
|
552 |
+
}
|
553 |
+
}
|
554 |
+
else if (is_wp_error($response)) {
|
555 |
+
return $response;
|
556 |
+
}
|
557 |
+
|
558 |
+
// Should never happen!
|
559 |
+
return new WP_Error('unknown_wp_http_error', sprintf('Unknown response from wp_remote_request - unable to contact CloudFlare API'));
|
560 |
+
}
|
561 |
+
|
562 |
+
function cloudflare_buffer_wrapup($buffer) {
|
563 |
+
// Check for a Content-Type header. Currently only apply rewriting to "text/html" or undefined
|
564 |
+
$headers = headers_list();
|
565 |
+
$content_type = null;
|
566 |
+
|
567 |
+
foreach ($headers as $header) {
|
568 |
+
if (strpos(strtolower($header), 'content-type:') === 0) {
|
569 |
+
$pieces = explode(':', strtolower($header));
|
570 |
+
$content_type = trim($pieces[1]);
|
571 |
+
break;
|
572 |
+
}
|
573 |
+
}
|
574 |
+
|
575 |
+
if (is_null($content_type) || substr($content_type, 0, 9) === 'text/html') {
|
576 |
+
// replace href or src attributes within script, link, base, and img tags with just "//" for protocol
|
577 |
+
$re = "/(<(script|link|base|img|form)([^>]*)(href|src|action)=[\"'])https?:\\/\\//i";
|
578 |
+
$subst = "$1//";
|
579 |
+
$return = preg_replace($re, $subst, $buffer);
|
580 |
+
|
581 |
+
// on regex error, skip overwriting buffer
|
582 |
+
if ($return) {
|
583 |
+
$buffer = $return;
|
584 |
+
}
|
585 |
+
}
|
586 |
+
|
587 |
+
return $buffer;
|
588 |
+
}
|
589 |
+
|
590 |
+
function cloudflare_buffer_init() {
|
591 |
+
// load just the single option, defaulting to on
|
592 |
+
$cloudflare_protocol_rewrite = load_protocol_rewrite();
|
593 |
+
|
594 |
+
if ($cloudflare_protocol_rewrite == 1) {
|
595 |
+
ob_start('cloudflare_buffer_wrapup');
|
596 |
+
}
|
597 |
+
}
|
598 |
+
|
599 |
+
add_action('plugins_loaded', 'cloudflare_buffer_init');
|
600 |
+
|
601 |
+
// wordpress 4.4 srcset ssl fix
|
602 |
+
// Shoutout to @bhubbard: https://wordpress.org/support/topic/44-https-rewritte-aint-working-with-images?replies=12
|
603 |
+
function cloudflare_ssl_srcset( $sources ) {
|
604 |
+
$cloudflare_protocol_rewrite = load_protocol_rewrite();
|
605 |
+
|
606 |
+
if ($cloudflare_protocol_rewrite == 1) {
|
607 |
+
foreach ( $sources as &$source ) {
|
608 |
+
$re = "/https?:\\/\\//i";
|
609 |
+
$subst = "//";
|
610 |
+
$return = preg_replace($re, $subst, $source['url']);
|
611 |
+
|
612 |
+
if ($return) {
|
613 |
+
$source['url'] = $return;
|
614 |
+
}
|
615 |
+
}
|
616 |
+
|
617 |
+
return $sources;
|
618 |
+
}
|
619 |
+
|
620 |
+
return $sources;
|
621 |
+
}
|
622 |
+
|
623 |
+
add_filter( 'wp_calculate_image_srcset', 'cloudflare_ssl_srcset' );
|
composer.json
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "cloudflare/wordpress-plugin111",
|
3 |
+
"license": "BSD-3-Clause",
|
4 |
+
"require": {
|
5 |
+
"cloudflare/cloudflare-plugin-backend": "^1.1",
|
6 |
+
"cloudflare/cf-ip-rewrite": "^1.0.0",
|
7 |
+
"symfony/yaml": "~2.6",
|
8 |
+
"guzzle/guzzle": "~3.9"
|
9 |
+
},
|
10 |
+
"autoload": {
|
11 |
+
"psr-4": {
|
12 |
+
"CF\\": "src/"
|
13 |
+
}
|
14 |
+
},
|
15 |
+
"version": "1.3.24",
|
16 |
+
"scripts": {
|
17 |
+
"test": "echo \"Test Success\"",
|
18 |
+
"format": "echo \"Format Success\""
|
19 |
+
},
|
20 |
+
"require-dev": {
|
21 |
+
"squizlabs/php_codesniffer": "2.*",
|
22 |
+
"phpunit/phpunit": "4.8.*",
|
23 |
+
"johnkary/phpunit-speedtrap": "^1.0",
|
24 |
+
"php-mock/php-mock-phpunit": "^1.1"
|
25 |
+
},
|
26 |
+
"description": "A CloudFlare plugin for WordPress"
|
27 |
+
}
|
readme.txt
ADDED
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== CloudFlare ===
|
2 |
+
Contributors: i3149, jchen329, jamescf, simon-says, dfritsch
|
3 |
+
Tags: cloudflare, comments, spam, cdn, free, website, performance, speed
|
4 |
+
Requires at least: 2.8
|
5 |
+
Tested up to: 4.1
|
6 |
+
Stable tag: 1.3.24
|
7 |
+
License: GPLv2
|
8 |
+
|
9 |
+
The CloudFlare WordPress Plugin ensures your WordPress blog is running optimally on the CloudFlare platform.
|
10 |
+
|
11 |
+
== Description ==
|
12 |
+
|
13 |
+
* CloudFlare has developed a plugin for WordPress. By using the CloudFlare WordPress Plugin, you receive:
|
14 |
+
|
15 |
+
* Correct IP Address information for comments posted to your site
|
16 |
+
|
17 |
+
* Better protection as spammers from your WordPress blog get reported to CloudFlare
|
18 |
+
|
19 |
+
THINGS YOU NEED TO KNOW:
|
20 |
+
|
21 |
+
* The main purpose of this plugin is to ensure you have no change to your originating IPs when using CloudFlare. Since CloudFlare acts a reverse proxy, connecting IPs now come from CloudFlare's range. This plugin will ensure you can continue to see the originating IP.
|
22 |
+
|
23 |
+
* Every time you click the 'spam' button on your blog, this threat information is sent to CloudFlare to ensure you are constantly getting the best site protection.
|
24 |
+
|
25 |
+
* We recommend any WordPress and CloudFlare user use this plugin. For more best practices around using WordPress and CloudFlare, see: https://support.cloudflare.com/hc/en-us/articles/201717894-Using-CloudFlare-and-WordPress-Five-Easy-First-Steps
|
26 |
+
|
27 |
+
MORE INFORMATION ON CLOUDFLARE:
|
28 |
+
|
29 |
+
CloudFlare is a service that makes websites load faster and protects sites from online spammers and hackers. Any website with a root domain (ie www.mydomain.com) can use CloudFlare. On average, it takes less than 5 minutes to sign up. You can learn more here: [CloudFlare.com](https://www.cloudflare.com/overview.html).
|
30 |
+
|
31 |
+
== Installation ==
|
32 |
+
|
33 |
+
Upload the CloudFlare plugin to your blog, Activate it, and you're done!
|
34 |
+
|
35 |
+
You will also want to sign up your blog with CloudFlare.com
|
36 |
+
|
37 |
+
[Read more](http://blog.cloudflare.com/introducing-the-cloudflare-wordpress-plugin) on why we created this plugin.
|
38 |
+
|
39 |
+
== Changelog ==
|
40 |
+
|
41 |
+
= 1.3.23 =
|
42 |
+
|
43 |
+
Fixed bug that was preventing spam comments from being sent to CloudFlare
|
44 |
+
|
45 |
+
= 1.3.22 =
|
46 |
+
|
47 |
+
* Fixing bug which prevented a user from activating/deactivating the plugin
|
48 |
+
|
49 |
+
= 1.3.21 =
|
50 |
+
|
51 |
+
* Added input sanitization.
|
52 |
+
|
53 |
+
= 1.3.20 =
|
54 |
+
|
55 |
+
* Updated the method to restore visitor IPs
|
56 |
+
* Updated the URL rewrite to be compatible with WordPress 4.4
|
57 |
+
|
58 |
+
= 1.3.18 =
|
59 |
+
|
60 |
+
* Bug: Clean up headers debugging message that can be displayed in some cases
|
61 |
+
|
62 |
+
= 1.3.17 =
|
63 |
+
|
64 |
+
* Limit http protocol rewriting to text/html Content-Type
|
65 |
+
|
66 |
+
= 1.3.16 =
|
67 |
+
|
68 |
+
* Update regex to not alter the canonical url
|
69 |
+
|
70 |
+
= 1.3.15 =
|
71 |
+
|
72 |
+
* Plugin settings are now found under Settings -> CloudFlare
|
73 |
+
* Plugin is now using the WordPress HTTP_API - this will give better support to those in hosting environments without cURL or an up to date CA cert bundle
|
74 |
+
* Fixes to squash some PHP Warnings. Relocated error logging to only happen in WP_DEBUG mode
|
75 |
+
* Added Protocol Rewriting option to support Flexible SSL
|
76 |
+
|
77 |
+
= 1.3.14 =
|
78 |
+
|
79 |
+
* Improved logic to detect the customer domain, with added option for a manual override
|
80 |
+
* Standardised error display
|
81 |
+
* Updated CloudFlare IP Ranges
|
82 |
+
|
83 |
+
= 1.3.13 =
|
84 |
+
|
85 |
+
* Clarified error messaging in the plugin further
|
86 |
+
* Added cURL error detection to explain issues with server installed cert bundles
|
87 |
+
|
88 |
+
= 1.3.12 =
|
89 |
+
|
90 |
+
* Removed use of php short-code in a couple of places
|
91 |
+
* Added some cURL / json_decode error handling to output to the screen any failures
|
92 |
+
* Reformatted error / notice display slightly
|
93 |
+
|
94 |
+
= 1.3.11 =
|
95 |
+
|
96 |
+
* Adjusted a line syntax to account for differing PHP configurations.
|
97 |
+
|
98 |
+
= 1.3.10 =
|
99 |
+
|
100 |
+
* Added IP ranges.
|
101 |
+
|
102 |
+
= 1.3.9 =
|
103 |
+
* Made adjustment to syntax surrounding cURL detection for PHP installations that do not have short_open_tag enabled.
|
104 |
+
|
105 |
+
= 1.3.8 =
|
106 |
+
* Fixed issue with invalid header.
|
107 |
+
* Updated IP ranges
|
108 |
+
* Fixed support link
|
109 |
+
|
110 |
+
= 1.3.7 =
|
111 |
+
* Remove Database Optimizer related text.
|
112 |
+
|
113 |
+
= 1.3.6 =
|
114 |
+
* Remove Database Optimizer.
|
115 |
+
|
116 |
+
= 1.3.5 =
|
117 |
+
* Disable Development Mode option if cURL not installed. Will Use JSONP in future release to allow domains without cURL to use Development Mode.
|
118 |
+
|
119 |
+
= 1.3.4 =
|
120 |
+
* Add in IPV6 support and Development Mode option to wordpress plugin settings page. Remove cached IP range text file.
|
121 |
+
|
122 |
+
= 1.3.3 =
|
123 |
+
* Bump stable version number.
|
124 |
+
|
125 |
+
= 1.3.2.Beta =
|
126 |
+
* BETA RELEASE: IPv6 support - Pull the IPv6 range from https://www.cloudflare.com/ips-v6. Added Development Mode option to wordpress plugin settings page.
|
127 |
+
|
128 |
+
= 1.2.4 =
|
129 |
+
* Pull the IP range from https://www.cloudflare.com/ips-v4. Modified to keep all files within cloudflare plugin directory.
|
130 |
+
|
131 |
+
= 1.2.3 =
|
132 |
+
* Updated with new IP range
|
133 |
+
|
134 |
+
= 1.2.2 =
|
135 |
+
* Restricted database optimization to administrators
|
136 |
+
|
137 |
+
= 1.2.1 =
|
138 |
+
* Increased load priority to avoid conflicts with other plugins
|
139 |
+
|
140 |
+
= 1.2.0 =
|
141 |
+
|
142 |
+
* WP 3.3 compatibility.
|
143 |
+
|
144 |
+
= 1.1.9 =
|
145 |
+
|
146 |
+
* Includes latest CloudFlare IP allocation -- 108.162.192.0/18.
|
147 |
+
|
148 |
+
= 1.1.8 =
|
149 |
+
|
150 |
+
* WP 3.2 compatibility.
|
151 |
+
|
152 |
+
= 1.1.7 =
|
153 |
+
|
154 |
+
* Implements several security updates.
|
155 |
+
|
156 |
+
= 1.1.6 =
|
157 |
+
|
158 |
+
* Includes latest CloudFlare IP allocation -- 141.101.64.0/18.
|
159 |
+
|
160 |
+
= 1.1.5 =
|
161 |
+
|
162 |
+
* Includes latest CloudFlare IP allocation -- 103.22.200.0/22.
|
163 |
+
|
164 |
+
= 1.1.4 =
|
165 |
+
|
166 |
+
* Updated messaging.
|
167 |
+
|
168 |
+
= 1.1.3 =
|
169 |
+
|
170 |
+
* Better permission checking for DB optimizer.
|
171 |
+
* Added CloudFlare's latest /20 to the list of CloudFlare IP ranges.
|
172 |
+
|
173 |
+
= 1.1.2 =
|
174 |
+
|
175 |
+
* Fixed several broken help links.
|
176 |
+
* Fixed confusing error message.
|
177 |
+
|
178 |
+
= 1.1.1 =
|
179 |
+
|
180 |
+
* Fix for Admin menus which are breaking when page variable contains '-'.
|
181 |
+
|
182 |
+
= 1.1.0 =
|
183 |
+
|
184 |
+
* Added a box to input CloudFlare API credentials.
|
185 |
+
* Added a call to CloudFlare's report spam API when a comment is marked as spam.
|
186 |
+
|
187 |
+
= 1.0.1 =
|
188 |
+
|
189 |
+
* Fix to check that it is OK to add a header before adding one.
|
190 |
+
|
191 |
+
= 1.0.0 =
|
192 |
+
|
193 |
+
* Initial feature set
|
194 |
+
* Set RemoteIP header correctly.
|
195 |
+
* On comment spam, send the offending IP to CloudFlare.
|
196 |
+
* Clean up DB on load.
|