These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace StevieRay; |
||
3 | |||
4 | use Mso\IdnaConvert\IdnaConvert; |
||
5 | |||
6 | class Generator |
||
7 | { |
||
8 | private $projectUrl = "https://github.com/Stevie-Ray/referrer-spam-blocker"; |
||
9 | |||
10 | /** @var string string */ |
||
11 | private $outputDir; |
||
12 | |||
13 | /** |
||
14 | * @param string $outputDir |
||
15 | */ |
||
16 | public function __construct($outputDir) |
||
17 | { |
||
18 | $this->outputDir = $outputDir; |
||
19 | } |
||
20 | |||
21 | public function generateFiles() |
||
22 | { |
||
23 | $date = date('Y-m-d H:i:s'); |
||
24 | $lines = $this->domainWorker(); |
||
25 | $this->createApache($date, $lines); |
||
26 | $this->createNginx($date, $lines); |
||
27 | $this->createVarnish($date, $lines); |
||
28 | $this->createIIS($date, $lines); |
||
29 | $this->createuWSGI($date, $lines); |
||
30 | $this->createGoogleExclude($lines); |
||
31 | } |
||
32 | |||
33 | /** |
||
34 | * @return array |
||
35 | */ |
||
36 | public function domainWorker() |
||
37 | { |
||
38 | $domainsFile = __DIR__ . "/domains.txt"; |
||
39 | |||
40 | $handle = fopen($domainsFile, "r"); |
||
41 | if (! $handle) { |
||
42 | throw new \RuntimeException('Error opening file ' . $domainsFile); |
||
43 | } |
||
44 | $lines = array(); |
||
45 | while (($line = fgets($handle)) !== false) { |
||
46 | $line = trim(preg_replace('/\s\s+/', ' ', $line)); |
||
47 | |||
48 | // convert internationalized domain names |
||
49 | if (preg_match('/[А-Яа-яЁёɢ]/u', $line)) { |
||
50 | |||
51 | $IDN = new IdnaConvert(); |
||
52 | |||
53 | $line = $IDN->encode($line); |
||
54 | |||
55 | } |
||
56 | |||
57 | if (empty($line)) { |
||
58 | continue; |
||
59 | } |
||
60 | $lines[] = $line; |
||
61 | } |
||
62 | fclose($handle); |
||
63 | $uniqueLines = array_unique($lines, SORT_STRING); |
||
64 | sort($uniqueLines, SORT_STRING); |
||
65 | if (is_writable($domainsFile)) { |
||
66 | file_put_contents($domainsFile, implode("\n", $uniqueLines)); |
||
67 | } else { |
||
68 | trigger_error("Permission denied"); |
||
69 | } |
||
70 | |||
71 | return $lines; |
||
72 | } |
||
73 | |||
74 | /** |
||
75 | * @param string $filename |
||
76 | * @param string $data |
||
77 | */ |
||
78 | protected function writeToFile($filename, $data) |
||
79 | { |
||
80 | $file = $this->outputDir . '/' . $filename; |
||
81 | if (is_writable($file)) { |
||
82 | file_put_contents($file, $data); |
||
83 | if (! chmod($file, 0644)) { |
||
84 | trigger_error("Couldn't not set " . $filename . " permissions to 644"); |
||
85 | } |
||
86 | } else { |
||
87 | trigger_error("Permission denied"); |
||
88 | } |
||
89 | } |
||
90 | |||
91 | /** |
||
92 | * @param string $date |
||
93 | * @param array $lines |
||
94 | */ |
||
95 | public function createApache($date, array $lines) |
||
96 | { |
||
97 | $data = "# " . $this->projectUrl . "\n# Updated " . $date . "\n\n" . |
||
98 | "<IfModule mod_rewrite.c>\n\nRewriteEngine On\n\n"; |
||
99 | View Code Duplication | foreach ($lines as $line) { |
|
1 ignored issue
–
show
|
|||
100 | if ($line === end($lines)) { |
||
101 | $data .= "RewriteCond %{HTTP_REFERER} ^http(s)?://(www.)?.*" . preg_quote($line) . ".*$ [NC]\n"; |
||
102 | break; |
||
103 | } |
||
104 | |||
105 | $data .= "RewriteCond %{HTTP_REFERER} ^http(s)?://(www.)?.*" . preg_quote($line) . ".*$ [NC,OR]\n"; |
||
106 | } |
||
107 | |||
108 | $data .= "RewriteRule ^(.*)$ – [F,L]\n\n</IfModule>\n\n<IfModule mod_setenvif.c>\n\n"; |
||
109 | foreach ($lines as $line) { |
||
110 | $data .= "SetEnvIfNoCase Referer " . preg_quote($line) . " spambot=yes\n"; |
||
111 | } |
||
112 | $data .= "\n</IfModule>\n\n# Apache 2.2\n<IfModule !mod_authz_core.c>\n\t<IfModule mod_authz_host.c>\n\t\t" . |
||
113 | "Order allow,deny\n\t\tAllow from all\n\t\tDeny from env=spambot\n\t</IfModule>\n</IfModule>\n# " . |
||
114 | "Apache 2.4\n<IfModule mod_authz_core.c>\n\t<RequireAll>" . |
||
115 | "\n\t\tRequire all granted\n\t\tRequire not env spambot\n\t</RequireAll>\n</IfModule>"; |
||
116 | |||
117 | $this->writeToFile('.htaccess', $data); |
||
118 | } |
||
119 | |||
120 | /** |
||
121 | * @param string $date |
||
122 | * @param array $lines |
||
123 | */ |
||
124 | View Code Duplication | public function createNginx($date, array $lines) |
|
1 ignored issue
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
125 | { |
||
126 | $data = "# " . $this->projectUrl . "\n# Updated " . $date . "\n#\n# /etc/nginx/referral-spam.conf\n#\n" . |
||
127 | "# With referral-spam.conf in /etc/nginx, include it globally from within /etc/nginx/nginx.conf:\n#\n" . |
||
128 | "# include referral-spam.conf;\n#\n" . |
||
129 | "# Add the following to each /etc/nginx/site-available/your-site.conf that needs protection:\n#\n" . |
||
130 | "# server {\n# if (\$bad_referer) {\n# return 444;\n# }\n# }\n" . |
||
131 | "#\nmap \$http_referer \$bad_referer {\n\tdefault 0;\n\n"; |
||
132 | foreach ($lines as $line) { |
||
133 | $data .= "\t\"~*" . preg_quote($line) . "\" 1;\n"; |
||
134 | } |
||
135 | $data .= "\n}"; |
||
136 | |||
137 | $this->writeToFile('referral-spam.conf', $data); |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * @param string $date |
||
142 | * @param array $lines |
||
143 | */ |
||
144 | public function createVarnish($date, array $lines) |
||
145 | { |
||
146 | $data = "# " . $this->projectUrl . "\n# Updated " . $date . "\nsub block_referral_spam {\n\tif (\n"; |
||
147 | View Code Duplication | foreach ($lines as $line) { |
|
1 ignored issue
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
148 | if ($line === end($lines)) { |
||
149 | $data .= "\t\treq.http.Referer ~ \"(?i)" . preg_quote($line) . "\"\n"; |
||
150 | break; |
||
151 | } |
||
152 | |||
153 | $data .= "\t\treq.http.Referer ~ \"(?i)" . preg_quote($line) . "\" ||\n"; |
||
154 | } |
||
155 | |||
156 | $data .= "\t) {\n\t\t\treturn (synth(444, \"No Response\"));\n\t}\n}"; |
||
157 | |||
158 | $this->writeToFile('referral-spam.vcl', $data); |
||
159 | } |
||
160 | |||
161 | /** |
||
162 | * @param string $date |
||
163 | * @param array $lines |
||
164 | */ |
||
165 | View Code Duplication | public function createIIS($date, array $lines) |
|
1 ignored issue
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
166 | { |
||
167 | $data = "<!-- " . $this->projectUrl . " -->\n<!-- Updated " . $date . " -->\n" . |
||
168 | "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" . |
||
169 | "<configuration>\n\t<system.webServer>\n\t\t<rewrite>\n\t\t\t<rules>\n"; |
||
170 | foreach ($lines as $line) { |
||
171 | |||
172 | $data .= "\t\t\t\t<rule name=\"Referrer Spam " . $line . "\" stopProcessing=\"true\">" . |
||
173 | "<match url=\".*\" /><conditions><add input=\"{HTTP_REFERER}\" pattern=\"(" . |
||
174 | preg_quote($line) . |
||
175 | ")\"/></conditions><action type=\"AbortRequest\" /></rule>\n"; |
||
176 | } |
||
177 | |||
178 | $data .= "\t\t\t</rules>\n\t\t</rewrite>\n\t</system.webServer>\n</configuration>"; |
||
179 | |||
180 | $this->writeToFile('web.config', $data); |
||
181 | } |
||
182 | |||
183 | |||
184 | /** |
||
185 | * @param string $date |
||
186 | * @param array $lines |
||
187 | */ |
||
188 | View Code Duplication | public function createuWSGI($date, array $lines) |
|
1 ignored issue
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
189 | { |
||
190 | $data = "# " . $this->projectUrl . "\n# Updated " . $date . "\n#\n" . |
||
191 | "# Put referral-spam.res in /path/to/vassals, then include it from within /path/to/vassals/vassal.ini:\n" . |
||
192 | "#\n# ini = referral_spam.res:blacklist_spam\n\n" . |
||
193 | "[blacklist_spam]\n"; |
||
194 | foreach ($lines as $line) { |
||
195 | $data .= "route-referer = (?i)" . preg_quote($line) . " break:403 Forbidden\n"; |
||
196 | } |
||
197 | $data .= "route-label = referral_spam"; |
||
198 | |||
199 | $this->writeToFile('referral_spam.res', $data); |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * @param array $lines |
||
204 | */ |
||
205 | public function createGoogleExclude(array $lines) |
||
206 | { |
||
207 | |||
208 | $regexLines = []; |
||
209 | |||
210 | foreach ($lines as $line) { |
||
211 | $regexLines[] = preg_quote($line); |
||
212 | } |
||
213 | $data = implode('|', $regexLines); |
||
214 | |||
215 | $googleLimit = 30000; |
||
216 | $dataLength = strlen($data); |
||
217 | |||
218 | // keep track of the last split |
||
219 | $lastPosition = 0; |
||
220 | for ($x = 1; $lastPosition < $dataLength; $x++) { |
||
221 | |||
222 | // already in the boundary limits? |
||
223 | if (($dataLength - $lastPosition) >= $googleLimit) { |
||
224 | // search for the last occurrence of | in the boundary limits |
||
225 | $pipePosition = strrpos(substr($data, $lastPosition, $googleLimit), '|'); |
||
226 | |||
227 | $dataSplit = substr($data, $lastPosition, $pipePosition); |
||
228 | |||
229 | // without trailing pipe at the beginning of next round |
||
230 | $lastPosition = $lastPosition + $pipePosition + 1; |
||
231 | } else { |
||
232 | // Rest of the regex (no pipe at the end) |
||
233 | $dataSplit = substr($data, $lastPosition); |
||
234 | $lastPosition = $dataLength; // Break |
||
235 | } |
||
236 | |||
237 | $this->writeToFile('google-exclude-' . $x . '.txt', $dataSplit); |
||
238 | } |
||
239 | |||
240 | } |
||
241 | } |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.