PluginProbe
HTTP Headers / 1.10.5
HTTP Headers v1.10.5
1.19.5 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.12.0 1.12.1 1.12.2 1.13.0 1.13.1 1.13.2 1.13.3 1.13.4 1.14.0 1.14.1 1.14.2 1.15.0 All 60 releases
http-headers / http-headers.php

http-headers.php in HTTP Headers 1.10.5, at http-headers.php

1,346 lines 48.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: HTTP Headers
4 Plugin URI: https://zinoui.com/blog/http-headers-for-wordpress
5 Description: A plugin for HTTP headers management including security, access-control (CORS), caching, compression, and authentication.
6 Version: 1.10.5
7 Author: Dimitar Ivanov
8 Author URI: https://zinoui.com
9 License: GPLv2 or later
10 Text Domain: http-headers
11 */
12
13 /*
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License
16 as published by the Free Software Foundation; either version 2
17 of the License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/copyleft/gpl.html>.
26
27 Copyright (c) 2017-2018 Zino UI
28 */
29
30 if (!defined('ABSPATH')) {
31 exit;
32 }
33
34 if (get_option('hh_strict_transport_security_max_age') === false) {
35 $value = get_option('hh_strict_transport_security_value');
36 $max_age = preg_match('/max-age=(\d+)/', $value, $match) ? $match[1] : 0;
37 $sub_domains = strpos($value, 'includeSubDomains') !== false ? 1 : 0;
38 add_option('hh_strict_transport_security_max_age', $max_age, null, 'yes');
39 add_option('hh_strict_transport_security_sub_domains', $sub_domains, null, 'yes');
40 add_option('hh_strict_transport_security_preload', 0, null, 'yes');
41 }
42
43 if (get_option('hh_referrer_policy') === false) {
44 add_option('hh_referrer_policy', 0, null, 'yes');
45 add_option('hh_referrer_policy_value', null, null, 'yes');
46 }
47
48 if (get_option('hh_content_security_policy') === false) {
49 add_option('hh_content_security_policy', 0, null, 'yes');
50 add_option('hh_content_security_policy_value', null, null, 'yes');
51 }
52
53 if (get_option('hh_content_security_policy_report_only') === false) {
54 add_option('hh_content_security_policy_report_only', 0, null, 'yes');
55 }
56
57 if (get_option('hh_public_key_pins_report_only') === false) {
58 add_option('hh_public_key_pins_report_only', 0, null, 'yes');
59 }
60
61 if (get_option('hh_x_xxs_protection_uri') === false) {
62 add_option('hh_x_xxs_protection_uri', null, null, 'yes');
63 }
64
65 if (get_option('hh_method') === false) {
66 add_option('hh_method', 'php', null, 'yes');
67 }
68
69 if (get_option('hh_connection') === false) {
70 add_option('hh_connection', 0, null, 'yes');
71 add_option('hh_connection_value', null, null, 'yes');
72 }
73
74 if (get_option('hh_cache_control') === false) {
75 add_option('hh_cache_control', 0, null, 'yes');
76 add_option('hh_cache_control_value', null, null, 'yes');
77 }
78
79 if (get_option('hh_age') === false) {
80 add_option('hh_age', 0, null, 'yes');
81 add_option('hh_age_value', null, null, 'yes');
82 }
83
84 if (get_option('hh_pragma') === false) {
85 add_option('hh_pragma', 0, null, 'yes');
86 add_option('hh_pragma_value', null, null, 'yes');
87 }
88
89 if (get_option('hh_expires') === false) {
90 add_option('hh_expires', 0, null, 'yes');
91 add_option('hh_expires_value', null, null, 'yes');
92 add_option('hh_expires_type', null, null, 'yes');
93 }
94
95 if (get_option('hh_content_encoding') === false) {
96 add_option('hh_content_encoding', 0, null, 'yes');
97 add_option('hh_content_encoding_value', null, null, 'yes');
98 add_option('hh_content_encoding_ext', null, null, 'yes');
99 }
100
101 if (get_option('hh_vary') === false) {
102 add_option('hh_vary', 0, null, 'yes');
103 add_option('hh_vary_value', null, null, 'yes');
104 }
105
106 if (get_option('hh_x_powered_by') === false) {
107 add_option('hh_x_powered_by', 0, null, 'yes');
108 add_option('hh_x_powered_by_option', null, null, 'yes');
109 add_option('hh_x_powered_by_value', null, null, 'yes');
110 }
111
112 if (get_option('hh_www_authenticate') === false) {
113 add_option('hh_www_authenticate', 0, null, 'yes');
114 add_option('hh_www_authenticate_type', null, null, 'yes');
115 add_option('hh_www_authenticate_realm', null, null, 'yes');
116 add_option('hh_www_authenticate_user', null, null, 'yes');
117 add_option('hh_www_authenticate_pswd', null, null, 'yes');
118 }
119
120 if (get_option('hh_cookie_security') === false) {
121 add_option('hh_cookie_security', 0, null, 'yes');
122 add_option('hh_cookie_security_value', null, null, 'yes');
123 }
124
125 if (get_option('hh_expect_ct') === false) {
126 add_option('hh_expect_ct', 0, null, 'yes');
127 add_option('hh_expect_ct_max_age', null, null, 'yes');
128 add_option('hh_expect_ct_report_uri', null, null, 'yes');
129 add_option('hh_expect_ct_enforce', null, null, 'yes');
130 }
131
132 if (get_option('hh_timing_allow_origin') === false) {
133 add_option('hh_timing_allow_origin', 0, null, 'yes');
134 add_option('hh_timing_allow_origin_value', null, null, 'yes');
135 add_option('hh_timing_allow_origin_url', null, null, 'yes');
136 }
137
138 if (get_option('hh_custom_headers') === false) {
139 add_option('hh_custom_headers', 0, null, 'yes');
140 add_option('hh_custom_headers_value', null, null, 'yes');
141 }
142
143 if (get_option('hh_x_permitted_cross_domain_policies') === false) {
144 add_option('hh_x_permitted_cross_domain_policies', 0, null, 'yes');
145 add_option('hh_x_permitted_cross_domain_policies_value', null, null, 'yes');
146 }
147
148 if (get_option('hh_x_download_options') === false) {
149 add_option('hh_x_download_options', 0, null, 'yes');
150 add_option('hh_x_download_options_value', null, null, 'yes');
151 }
152
153 if (get_option('hh_x_dns_prefetch_control') === false) {
154 add_option('hh_x_dns_prefetch_control', 0, null, 'yes');
155 add_option('hh_x_dns_prefetch_control_value', null, null, 'yes');
156 }
157
158 if (get_option('hh_report_to') === false) {
159 add_option('hh_report_to', 0, null, 'yes');
160 add_option('hh_report_to_value', null, null, 'yes');
161 }
162
163 if (get_option('hh_feature_policy') === false) {
164 add_option('hh_feature_policy', 0, null, 'yes');
165 add_option('hh_feature_policy_feature', null, null, 'yes');
166 add_option('hh_feature_policy_origin', null, null, 'yes');
167 add_option('hh_feature_policy_value', null, null, 'yes');
168 }
169
170 function get_http_headers() {
171 $statuses = array();
172 $unset = array();
173 $headers = array();
174 $append = array();
175 if (get_option('hh_x_frame_options') == 1) {
176 $x_frame_options_value = strtoupper(get_option('hh_x_frame_options_value'));
177 if ($x_frame_options_value == 'ALLOW-FROM') {
178 $x_frame_options_value .= ' ' . get_option('hh_x_frame_options_domain');
179 }
180 $headers['X-Frame-Options'] = $x_frame_options_value;
181 }
182 if (get_option('hh_x_powered_by') == 1) {
183 if (get_option('hh_x_powered_by_option') == 'set') {
184 $headers['X-Powered-By'] = get_option('hh_x_powered_by_value');
185 } else {
186 $unset[] = 'X-Powered-By';
187 }
188 }
189 if (get_option('hh_x_xxs_protection') == 1) {
190 $headers['X-XSS-Protection'] = get_option('hh_x_xxs_protection_value');
191 if ($headers['X-XSS-Protection'] == '1; report=') {
192 $headers['X-XSS-Protection'] .= get_option('hh_x_xxs_protection_uri');
193 }
194 }
195 if (get_option('hh_x_content_type_options') == 1) {
196 $headers['X-Content-Type-Options'] = get_option('hh_x_content_type_options_value');
197 }
198 if (get_option('hh_x_download_options') == 1) {
199 $headers['X-Download-Options'] = get_option('hh_x_download_options_value');
200 }
201 if (get_option('hh_x_permitted_cross_domain_policies') == 1) {
202 $headers['X-Permitted-Cross-Domain-Policies'] = get_option('hh_x_permitted_cross_domain_policies_value');
203 }
204 if (get_option('hh_x_dns_prefetch_control') == 1) {
205 $headers['X-DNS-Prefetch-Control'] = get_option('hh_x_dns_prefetch_control_value');
206 }
207 if (get_option('hh_connection') == 1) {
208 $headers['Connection'] = get_option('hh_connection_value');
209 }
210 if (get_option('hh_pragma') == 1) {
211 $headers['Pragma'] = get_option('hh_pragma_value');
212 }
213 if (get_option('hh_age') == 1) {
214 $headers['Age'] = sprintf("%u", get_option('hh_age_value'));
215 }
216 if (get_option('hh_cache_control') == 1) {
217 $hh_cache_control_value = get_option('hh_cache_control_value', array());
218 $tmp = array();
219 foreach ($hh_cache_control_value as $k => $v) {
220 if (in_array($k, array('max-age', 's-maxage'))) {
221 if (strlen($v) > 0) {
222 $tmp[] = sprintf("%s=%u", $k, $v);
223 }
224 } else {
225 $tmp[] = $k;
226 }
227 }
228 $hh_cache_control_value = join(', ', $tmp);
229 $headers['Cache-Control'] = $hh_cache_control_value;
230 }
231 if (get_option('hh_strict_transport_security') == 1) {
232 $hh_strict_transport_security = array();
233
234 $hh_strict_transport_security_max_age = get_option('hh_strict_transport_security_max_age');
235 if ($hh_strict_transport_security_max_age !== false)
236 {
237 $hh_strict_transport_security[] = sprintf('max-age=%u', get_option('hh_strict_transport_security_max_age'));
238 if (get_option('hh_strict_transport_security_sub_domains'))
239 {
240 $hh_strict_transport_security[] = 'includeSubDomains';
241 }
242 if (get_option('hh_strict_transport_security_preload'))
243 {
244 $hh_strict_transport_security[] = 'preload';
245 }
246 } else {
247 $hh_strict_transport_security = array(get_option('hh_strict_transport_security_value'));
248 }
249 $headers['Strict-Transport-Security'] = join('; ', $hh_strict_transport_security);
250 }
251 if (get_option('hh_x_ua_compatible') == 1) {
252 $headers['X-UA-Compatible'] = get_option('hh_x_ua_compatible_value');
253 }
254 if (get_option('hh_public_key_pins') == 1) {
255 $public_key_pins_sha256_1 = get_option('hh_public_key_pins_sha256_1');
256 $public_key_pins_sha256_2 = get_option('hh_public_key_pins_sha256_2');
257 $public_key_pins_max_age = get_option('hh_public_key_pins_max_age');
258 $public_key_pins_sub_domains = get_option('hh_public_key_pins_sub_domains');
259 $public_key_pins_report_uri = get_option('hh_public_key_pins_report_uri');
260 $public_key_pins_report_only = get_option('hh_public_key_pins_report_only');
261 if (!empty($public_key_pins_sha256_1) && !empty($public_key_pins_sha256_2) && !empty($public_key_pins_max_age)) {
262
263 $public_key_pins = array();
264 $public_key_pins[] = sprintf('pin-sha256="%s"', $public_key_pins_sha256_1);
265 $public_key_pins[] = sprintf('pin-sha256="%s"', $public_key_pins_sha256_2);
266 $public_key_pins[] = sprintf("max-age=%u", $public_key_pins_max_age);
267 if ($public_key_pins_sub_domains) {
268 $public_key_pins[] = "includeSubDomains";
269 }
270 if (!empty($public_key_pins_report_uri)) {
271 $public_key_pins[] = sprintf('report-uri="%s"', $public_key_pins_report_uri);
272 }
273 $headers['Public-Key-Pins'.($public_key_pins_report_only ? '-Report-Only' : NULL)] = join('; ', $public_key_pins);
274 }
275 }
276
277 if (get_option('hh_content_security_policy') == 1)
278 {
279 $csp = array();
280 $values = get_option('hh_content_security_policy_value');
281 $csp_report_only = get_option('hh_content_security_policy_report_only');
282 foreach ($values as $key => $val)
283 {
284 if (!empty($val))
285 {
286 $csp[] = sprintf("%s %s", $key, $val);
287 }
288 }
289 if (!empty($csp))
290 {
291 $headers['Content-Security-Policy'.($csp_report_only ? '-Report-Only' : NULL)] = join('; ', $csp);
292 }
293 }
294
295 if (get_option('hh_access_control_allow_origin') == 1)
296 {
297 $value = get_option('hh_access_control_allow_origin_value');
298 switch ($value)
299 {
300 case 'origin':
301 $value = get_option('hh_access_control_allow_origin_url', array());
302 if (is_scalar($value))
303 {
304 $value = array($value);
305 }
306 break;
307 }
308 if (!empty($value))
309 {
310 $headers['Access-Control-Allow-Origin'] = $value;
311 }
312 }
313 if (get_option('hh_access_control_allow_credentials') == 1)
314 {
315 $headers['Access-Control-Allow-Credentials'] = get_option('hh_access_control_allow_credentials_value');
316 }
317 if (get_option('hh_access_control_max_age') == 1)
318 {
319 $value = get_option('hh_access_control_max_age_value');
320 if (!empty($value))
321 {
322 $headers['Access-Control-Max-Age'] = intval($value);
323 }
324 }
325 if (get_option('hh_access_control_allow_methods') == 1)
326 {
327 $value = get_option('hh_access_control_allow_methods_value');
328 if (!empty($value))
329 {
330 $headers['Access-Control-Allow-Methods'] = join(', ', array_keys($value));
331 }
332 }
333 if (get_option('hh_access_control_allow_headers') == 1)
334 {
335 $value = get_option('hh_access_control_allow_headers_value');
336 if (!empty($value))
337 {
338 $headers['Access-Control-Allow-Headers'] = join(', ', array_keys($value));
339 }
340 }
341 if (get_option('hh_access_control_expose_headers') == 1)
342 {
343 $value = get_option('hh_access_control_expose_headers_value');
344 if (!empty($value))
345 {
346 $headers['Access-Control-Expose-Headers'] = join(', ', array_keys($value));
347 }
348 }
349 if (get_option('hh_p3p') == 1)
350 {
351 $value = get_option('hh_p3p_value');
352 if (!empty($value))
353 {
354 $headers['P3P'] = 'CP="' . join(' ', array_keys($value)) . '"';
355 }
356 }
357 if (get_option('hh_referrer_policy') == 1) {
358 $headers['Referrer-Policy'] = get_option('hh_referrer_policy_value');
359 }
360 if (get_option('hh_www_authenticate') == 1) {
361
362 switch (get_option('hh_www_authenticate_type')) {
363 case 'Basic':
364 if (!(isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])
365 && $_SERVER['PHP_AUTH_USER'] == get_option('hh_www_authenticate_user')
366 && $_SERVER['PHP_AUTH_PW'] == get_option('hh_www_authenticate_pswd'))) {
367 $headers['WWW-Authenticate'] = sprintf("Basic realm='%s'", get_option('hh_www_authenticate_realm'));
368 $statuses['HTTP/1.1'] = '401 Unauthorized';
369 }
370 break;
371 case 'Digest':
372 if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
373 $realm = get_option('hh_www_authenticate_realm');
374 $headers['WWW-Authenticate'] = sprintf("Digest realm='%s',qop='auth',nonce='%s',opaque='%s'",
375 $realm, uniqid(), md5($realm));
376 $statuses['HTTP/1.1'] = '401 Unauthorized';
377 }
378 break;
379 }
380 }
381 if (get_option('hh_vary') == 1)
382 {
383 $value = get_option('hh_vary_value');
384 if (!empty($value))
385 {
386 $append['Vary'] = join(', ', array_keys($value));
387 }
388 }
389
390 if (get_option('hh_expect_ct') == 1) {
391 $expect_ct_max_age = get_option('hh_expect_ct_max_age');
392 $expect_ct_report_uri = get_option('hh_expect_ct_report_uri');
393 if (!empty($expect_ct_report_uri) && !empty($expect_ct_max_age)) {
394
395 $expect_ct = array();
396 $expect_ct[] = sprintf("max-age=%u", $expect_ct_max_age);
397 if (get_option('hh_expect_ct_enforce') == 1) {
398 $expect_ct[] = "enforce";
399 }
400 $expect_ct[] = sprintf('report-uri="%s"', $expect_ct_report_uri);
401 $headers['Expect-CT'] = join(', ', $expect_ct);
402 }
403 }
404 if (get_option('hh_custom_headers') == 1) {
405 $custom_headers = get_option('hh_custom_headers_value');
406 if (isset($custom_headers['name'], $custom_headers['value']) && !empty($custom_headers['name'])) {
407 foreach ($custom_headers['name'] as $key => $name) {
408 $name = trim($name);
409 $value = trim($custom_headers['value'][$key]);
410 if (empty($name) || empty($value)) {
411 continue;
412 }
413 $headers[$name] = $value;
414 }
415 }
416 }
417 if (get_option('hh_report_to') == 1) {
418 $report_to = get_option('hh_report_to_value');
419 $tmp = array();
420 foreach ($report_to as $item)
421 {
422 $tmp[] = sprintf('{"url": "%s", "group": "%s", "max-age": %u%s}',
423 $item['url'], $item['group'], $item['max-age'], isset($item['includeSubDomains']) ? ', includeSubDomains' : NULL);
424 }
425 $headers['Report-To'] = join(', ', $tmp);
426 }
427 if (get_option('hh_feature_policy') == 1) {
428 $feature_policy_feature = get_option('hh_feature_policy_feature');
429 $feature_policy_value = get_option('hh_feature_policy_value');
430 $feature_policy_origin = get_option('hh_feature_policy_origin');
431 $tmp = array();
432 foreach ($feature_policy_feature as $feature => $whatever)
433 {
434 $value = NULL;
435 switch ($feature_policy_value[$feature])
436 {
437 case '*':
438 case "'none'":
439 $value = $feature_policy_value[$feature];
440 break;
441 case "'self'":
442 $value = $feature_policy_value[$feature];
443 if (!empty($feature_policy_origin[$feature]))
444 {
445 $value .= " " . $feature_policy_origin[$feature];
446 }
447 break;
448 case 'origin(s)':
449 $value = $feature_policy_origin[$feature];
450 break;
451 }
452
453 $tmp[] = sprintf("%s %s", $feature, $value);
454 }
455 $headers['Feature-Policy'] = join('; ', $tmp);
456 }
457
458 return array($headers, $statuses, $unset, $append);
459 }
460
461 function http_digest_parse($txt) {
462 $txt = stripslashes($txt);
463
464 $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
465 $data = array();
466 $keys = implode('|', array_keys($needed_parts));
467
468 preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
469
470 foreach ($matches as $m) {
471 $data[$m[1]] = $m[3] ? $m[3] : $m[4];
472 unset($needed_parts[$m[1]]);
473 }
474
475 return $needed_parts ? false : $data;
476 }
477
478 function php_auth_digest() {
479 if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || get_option('hh_www_authenticate_user') != $data['username']) {
480 die('Wrong Credentials!');
481 }
482
483 $A1 = md5($data['username'] . ':' . get_option('hh_www_authenticate_realm') . ':' . get_option('hh_www_authenticate_pswd'));
484 $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
485 $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
486 if ($data['response'] != $valid_response) {
487 die('Wrong Credentials!');
488 }
489 }
490
491 function php_content_encoding() {
492 if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
493 ob_start('ob_gzhandler');
494 } else {
495 ob_start();
496 }
497 }
498
499 function php_cookie_security_directives() {
500 $lines = array();
501 if (get_option('hh_cookie_security') == 1) {
502 $value = get_option('hh_cookie_security_value', array());
503 if (isset($value['HttpOnly'])) {
504 $lines[] = 'session.cookie_httponly = on';
505 }
506 if (isset($value['Secure'])) {
507 $lines[] = 'session.cookie_secure = on';
508 }
509 }
510
511 return $lines;
512 }
513
514 function http_headers() {
515 if (get_option('hh_method') !== 'php') {
516 return;
517 }
518 // PHP method below
519 list($headers, $statuses, $unset, $append) = get_http_headers();
520 $isCors = false;
521 foreach ($headers as $key => $value) {
522 if ($key == 'Access-Control-Allow-Origin') {
523 if (isset($_SERVER['HTTP_ORIGIN'])) {
524 if ($value == '*') {
525 $isCors = true;
526 header(sprintf("%s: *", $key));
527 }
528
529 if (is_array($value) && in_array($_SERVER['HTTP_ORIGIN'], $value)) {
530 $isCors = true;
531 header(sprintf("%s: %s", $key, $_SERVER['HTTP_ORIGIN']));
532 }
533 }
534 continue;
535 }
536 if (in_array($key, array('Access-Control-Allow-Headers', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Credentials', 'Access-Control-Max-Age', 'Access-Control-Expose-Headers'))) {
537 if ($isCors) {
538 header(sprintf("%s: %s", $key, $value));
539 }
540 continue;
541 }
542 header(sprintf("%s: %s", $key, $value));
543 }
544 foreach ($append as $key => $value) {
545 header(sprintf("%s: %s", $key, $value), false);
546 }
547 foreach ($unset as $header) {
548 if (function_exists('header_remove')) {
549 header_remove($header);
550 } else {
551 header("$header:");
552 }
553 }
554 foreach ($statuses as $key => $value) {
555 header(sprintf("%s %s", $key, $value));
556 exit;
557 }
558
559 if (get_option('hh_www_authenticate') == 1) {
560 php_auth_digest();
561 }
562
563 if (get_option('hh_content_encoding') == 1) {
564 php_content_encoding();
565 }
566 }
567
568 function http_headers_admin_add_page() {
569 add_options_page('HTTP Headers', 'HTTP Headers', 'manage_options', 'http-headers', 'http_headers_admin_page');
570 }
571
572 function http_headers_admin() {
573 register_setting('http-headers-mtd', 'hh_method');
574 register_setting('http-headers-xfo', 'hh_x_frame_options');
575 register_setting('http-headers-xfo', 'hh_x_frame_options_value');
576 register_setting('http-headers-xfo', 'hh_x_frame_options_domain');
577 register_setting('http-headers-xss', 'hh_x_xxs_protection');
578 register_setting('http-headers-xss', 'hh_x_xxs_protection_value');
579 register_setting('http-headers-xss', 'hh_x_xxs_protection_uri');
580 register_setting('http-headers-cto', 'hh_x_content_type_options');
581 register_setting('http-headers-cto', 'hh_x_content_type_options_value');
582 register_setting('http-headers-sts', 'hh_strict_transport_security');
583 register_setting('http-headers-sts', 'hh_strict_transport_security_value'); //obsolete
584 register_setting('http-headers-sts', 'hh_strict_transport_security_max_age');
585 register_setting('http-headers-sts', 'hh_strict_transport_security_sub_domains');
586 register_setting('http-headers-sts', 'hh_strict_transport_security_preload');
587 register_setting('http-headers-pkp', 'hh_public_key_pins');
588 register_setting('http-headers-pkp', 'hh_public_key_pins_sha256_1');
589 register_setting('http-headers-pkp', 'hh_public_key_pins_sha256_2');
590 register_setting('http-headers-pkp', 'hh_public_key_pins_max_age');
591 register_setting('http-headers-pkp', 'hh_public_key_pins_sub_domains');
592 register_setting('http-headers-pkp', 'hh_public_key_pins_report_uri');
593 register_setting('http-headers-pkp', 'hh_public_key_pins_report_only');
594 register_setting('http-headers-uac', 'hh_x_ua_compatible');
595 register_setting('http-headers-uac', 'hh_x_ua_compatible_value');
596 register_setting('http-headers-p3p', 'hh_p3p');
597 register_setting('http-headers-p3p', 'hh_p3p_value');
598 register_setting('http-headers-rp', 'hh_referrer_policy');
599 register_setting('http-headers-rp', 'hh_referrer_policy_value');
600 register_setting('http-headers-csp', 'hh_content_security_policy');
601 register_setting('http-headers-csp', 'hh_content_security_policy_value');
602 register_setting('http-headers-csp', 'hh_content_security_policy_report_only');
603 register_setting('http-headers-acao', 'hh_access_control_allow_origin');
604 register_setting('http-headers-acao', 'hh_access_control_allow_origin_value');
605 register_setting('http-headers-acao', 'hh_access_control_allow_origin_url');
606 register_setting('http-headers-acac', 'hh_access_control_allow_credentials');
607 register_setting('http-headers-acac', 'hh_access_control_allow_credentials_value');
608 register_setting('http-headers-acam', 'hh_access_control_allow_methods');
609 register_setting('http-headers-acam', 'hh_access_control_allow_methods_value');
610 register_setting('http-headers-acah', 'hh_access_control_allow_headers');
611 register_setting('http-headers-acah', 'hh_access_control_allow_headers_value');
612 register_setting('http-headers-aceh', 'hh_access_control_expose_headers');
613 register_setting('http-headers-aceh', 'hh_access_control_expose_headers_value');
614 register_setting('http-headers-acma', 'hh_access_control_max_age');
615 register_setting('http-headers-acma', 'hh_access_control_max_age_value');
616 register_setting('http-headers-ce', 'hh_content_encoding');
617 register_setting('http-headers-ce', 'hh_content_encoding_value');
618 register_setting('http-headers-ce', 'hh_content_encoding_ext');
619 register_setting('http-headers-vary', 'hh_vary');
620 register_setting('http-headers-vary', 'hh_vary_value');
621 register_setting('http-headers-xpb', 'hh_x_powered_by');
622 register_setting('http-headers-xpb', 'hh_x_powered_by_option');
623 register_setting('http-headers-xpb', 'hh_x_powered_by_value');
624 register_setting('http-headers-wwa', 'hh_www_authenticate');
625 register_setting('http-headers-wwa', 'hh_www_authenticate_type');
626 register_setting('http-headers-wwa', 'hh_www_authenticate_realm');
627 register_setting('http-headers-wwa', 'hh_www_authenticate_user');
628 register_setting('http-headers-wwa', 'hh_www_authenticate_pswd');
629 register_setting('http-headers-cc', 'hh_cache_control');
630 register_setting('http-headers-cc', 'hh_cache_control_value');
631 register_setting('http-headers-age', 'hh_age');
632 register_setting('http-headers-age', 'hh_age_value');
633 register_setting('http-headers-pra', 'hh_pragma');
634 register_setting('http-headers-pra', 'hh_pragma_value');
635 register_setting('http-headers-exp', 'hh_expires');
636 register_setting('http-headers-exp', 'hh_expires_value');
637 register_setting('http-headers-exp', 'hh_expires_type');
638 register_setting('http-headers-con', 'hh_connection');
639 register_setting('http-headers-con', 'hh_connection_value');
640 register_setting('http-headers-cose', 'hh_cookie_security');
641 register_setting('http-headers-cose', 'hh_cookie_security_value');
642 register_setting('http-headers-ect', 'hh_expect_ct');
643 register_setting('http-headers-ect', 'hh_expect_ct_max_age');
644 register_setting('http-headers-ect', 'hh_expect_ct_report_uri');
645 register_setting('http-headers-ect', 'hh_expect_ct_enforce');
646 register_setting('http-headers-tao', 'hh_timing_allow_origin');
647 register_setting('http-headers-tao', 'hh_timing_allow_origin_value');
648 register_setting('http-headers-tao', 'hh_timing_allow_origin_url');
649 register_setting('http-headers-che', 'hh_custom_headers');
650 register_setting('http-headers-che', 'hh_custom_headers_value');
651 register_setting('http-headers-xdo', 'hh_x_download_options');
652 register_setting('http-headers-xdo', 'hh_x_download_options_value');
653 register_setting('http-headers-xpcd', 'hh_x_permitted_cross_domain_policies');
654 register_setting('http-headers-xpcd', 'hh_x_permitted_cross_domain_policies_value');
655 register_setting('http-headers-xdpc', 'hh_x_dns_prefetch_control');
656 register_setting('http-headers-xdpc', 'hh_x_dns_prefetch_control_value');
657 register_setting('http-headers-rt', 'hh_report_to');
658 register_setting('http-headers-rt', 'hh_report_to_value');
659 register_setting('http-headers-fp', 'hh_feature_policy');
660 register_setting('http-headers-fp', 'hh_feature_policy_value');
661 register_setting('http-headers-fp', 'hh_feature_policy_feature');
662 register_setting('http-headers-fp', 'hh_feature_policy_origin');
663 }
664
665 function http_headers_option($option) {
666
667 include_once ABSPATH . 'wp-admin/includes/admin.php';
668
669 if (isset($_POST['hh_method']))
670 {
671 check_admin_referer('http-headers-mtd-options');
672 # When method is changed
673 update_headers_directives();
674 update_auth_credentials();
675 update_auth_directives();
676 update_content_encoding_directives();
677 update_expires_directives();
678 update_cookie_security_directives();
679 update_timing_directives();
680
681 } elseif (get_option('hh_method') == 'htaccess') {
682 # When particular header is changed
683 switch (true) {
684 case array_key_exists('hh_www_authenticate', $_POST):
685 check_admin_referer('http-headers-wwa-options');
686 update_auth_credentials();
687 update_auth_directives();
688 break;
689 case array_key_exists('hh_content_encoding', $_POST):
690 check_admin_referer('http-headers-ce-options');
691 update_content_encoding_directives();
692 break;
693 case array_key_exists('hh_vary', $_POST):
694 check_admin_referer('http-headers-vary-options');
695 update_content_encoding_directives();
696 break;
697 case array_key_exists('hh_expires', $_POST):
698 check_admin_referer('http-headers-exp-options');
699 update_expires_directives();
700 break;
701 case array_key_exists('hh_cookie_security', $_POST):
702 check_admin_referer('http-headers-cose-options');
703 update_cookie_security_directives();
704 break;
705 case array_key_exists('hh_timing_allow_origin', $_POST):
706 check_admin_referer('http-headers-tao-options');
707 update_timing_directives();
708 break;
709 case array_key_exists('option_page', $_POST) && strpos($_POST['option_page'], 'http-headers-') === 0:
710 check_admin_referer($_POST['option_page'].'-options');
711 update_headers_directives();
712 break;
713 }
714 }
715 }
716
717 function nginx_headers_directives() {
718 $lines = array();
719 list($headers, $statuses, $unset, $append) = get_http_headers();
720
721 foreach ($unset as $header) {
722 $lines[] = sprintf(' more_clear_headers "%s";', $header);
723 }
724 $cors = $cors_header = $cors_inner = $cors_footer = array();
725 $all = array();
726 foreach ($headers as $key => $value) {
727 if (in_array($key, array('WWW-Authenticate'))) {
728 continue;
729 }
730 if (in_array($key, array('X-Content-Type-Options'))) {
731 $all[] = sprintf('add_header %s %s always;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
732 continue;
733 }
734 if ($key == 'Access-Control-Allow-Origin' && is_array($value)) {
735 $cors_header[] = sprintf('if ($http_origin ~* ^(%s)$) {', str_replace('.', '\.', join('|', $value)));
736 $cors_footer[] = '}';
737 $cors_inner[] = ' add_header Access-Control-Allow-Origin "$http_origin";';
738 continue;
739 }
740 if (in_array($key, array('Access-Control-Allow-Headers', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Credentials', 'Access-Control-Max-Age', 'Access-Control-Expose-Headers'))) {
741 $cors_inner[] = sprintf(' add_header %s %s;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
742 continue;
743 }
744 $lines[] = sprintf(' add_header %s %s;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
745 }
746 foreach ($append as $key => $value) {
747 $lines[] = sprintf(' add_header %s %s;', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
748 }
749 if (!empty($cors_inner))
750 {
751 $cors = array_merge(
752 $cors_header,
753 $cors_inner,
754 $cors_footer
755 );
756 }
757 if (!empty($lines)) {
758 $lines = array_merge(
759 $all,
760 $cors,
761 array('location ~* \.(php|html)$ {'),
762 $lines,
763 array('}')
764 );
765 }
766 return $lines;
767 }
768
769 function nginx_content_encoding_directives() {
770 $lines = array();
771 if (get_option('hh_content_encoding') == 1) {
772
773 $lines[] = 'gzip on;';
774
775 $content_encoding_value = get_option('hh_content_encoding_value');
776 if (!$content_encoding_value) {
777 $content_encoding_value = array();
778 }
779
780 $content_encoding_ext = get_option('hh_content_encoding_ext');
781 if (!$content_encoding_ext) {
782 $content_encoding_ext = array();
783 }
784 if (!empty($content_encoding_ext)) {
785 //$lines[] = sprintf('<FilesMatch "\.(%s)$">', join('|', array_keys($content_encoding_ext)));
786 }
787 if (!empty($content_encoding_value)) {
788 $lines[] = sprintf('gzip_types %s;', join(' ', array_keys($content_encoding_value)));
789 }
790 }
791 return $lines;
792 }
793
794 function nginx_expires_directives() {
795 $lines = array();
796 if (get_option('hh_expires') == 1) {
797
798 $types = get_option('hh_expires_type', array());
799 $values = get_option('hh_expires_value', array());
800
801 $lines[] = 'map $sent_http_content_type $expires {';
802 foreach ($types as $type => $whatever) {
803 list($base, $period, $suffix) = explode('_', $values[$type]);
804 if (in_array($base, array('access', 'modification'))) {
805 $lines[] = $type != 'default'
806 ? sprintf(' %s %u%s;', $type, $period, $suffix[0])
807 : sprintf(' default %u%s;', $period, $suffix[0]);
808 } elseif ($base == 'invalid') {
809 $lines[] = $type != 'default'
810 ? sprintf(' %s 0;', $type)
811 : sprintf(' default 0;');
812 }
813 }
814 $lines[] = '}';
815
816 $lines[] = 'expires $expires;';
817 }
818 return $lines;
819 }
820
821 function nginx_timing_directives() {
822 $lines = array();
823 if (get_option('hh_timing_allow_origin') == 1) {
824 $value = get_option('hh_timing_allow_origin_value');
825 switch ($value)
826 {
827 case 'origin':
828 $value = get_option('hh_timing_allow_origin_url');
829 break;
830 }
831 if (!empty($value))
832 {
833 $lines[] = 'location ~* \.(js|css|jpe?g|png|gif|eot|otf|svg|ttf|woff2?)$ {';
834 $lines[] = sprintf(' add_header Timing-Allow-Origin "%s";', $value);
835 $lines[] = '}';
836 }
837 }
838 return $lines;
839 }
840
841 function nginx_auth_directives() {
842 $lines = array();
843 if (get_option('hh_www_authenticate') == 1) {
844
845 $type = get_option('hh_www_authenticate_type');
846
847 $file = $type == 'Basic' ? '.hh-htpasswd' : '.hh-htdigest';
848
849 $lines[] = 'location ~ ^\.hh-ht(digest|passwd)$ {';
850 $lines[] = ' deny all;';
851 $lines[] = '}';
852
853 $lines[] = sprintf('location %s {', get_home_path());
854 if ($type == 'Basic') {
855 $lines[] = sprintf(' auth_basic "%s";', get_option('hh_www_authenticate_realm'));
856 $lines[] = sprintf(' auth_basic_user_file %s%s;', get_home_path(), $file);
857 } else {
858 $lines[] = sprintf(' auth_digest "%s";', get_option('hh_www_authenticate_realm'));
859 $lines[] = sprintf(' auth_digest_user_file %s%s;', get_home_path(), $file);
860 }
861 $lines[] = '}';
862 }
863 return $lines;
864 }
865
866 function nginx_auth_credentials() {
867 return apache_auth_credentials();
868 }
869
870 function nginx_cookie_security_directives() {
871 $lines = array();
872
873 //TODO
874
875 return $lines;
876 }
877
878 function nginx_check_requirements() {
879 //TODO scheduled for v2.0.0
880 return true;
881 }
882
883 function iis_headers_directives() {
884 //TODO scheduled for v2.0.0
885 }
886
887 function iis_content_encoding_directives() {
888 //TODO scheduled for v2.0.0
889 }
890
891 function iis_expires_directives() {
892 //TODO scheduled for v2.0.0
893 }
894
895 function iis_timing_directives() {
896 //TODO scheduled for v2.0.0
897 }
898
899 function iis_auth_directives() {
900 //TODO scheduled for v2.0.0
901 }
902
903 function iis_auth_credentials() {
904 //TODO scheduled for v2.0.0
905 }
906
907 function iis_cookie_security_directives() {
908 //TODO scheduled for v2.0.0
909 }
910
911 function iis_check_requirements() {
912 //TODO scheduled for v2.0.0
913 return true;
914 }
915
916 function apache_headers_directives() {
917 $lines = array();
918 list($headers, $statuses, $unset, $append) = get_http_headers();
919
920 foreach ($unset as $header) {
921 $lines[] = sprintf(' Header unset %s', $header);
922 }
923 $all = array();
924 foreach ($headers as $key => $value) {
925 if (in_array($key, array('WWW-Authenticate'))) {
926 continue;
927 }
928 if (in_array($key, array('X-Content-Type-Options'))) {
929 $all[] = sprintf(' Header always set %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
930 continue;
931 }
932 if ($key == 'Strict-Transport-Security') {
933 $lines[] = sprintf(' Header set %s %s env=HTTPS', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
934 continue;
935 }
936 if ($key == 'Access-Control-Allow-Origin') {
937 $all[] = ' <IfModule mod_setenvif.c>';
938 if (is_array($value))
939 {
940 $all[] = sprintf(' SetEnvIf Origin "^(%s)$" CORS=$0', str_replace('.', '\.', join('|', $value)));
941 } else {
942 $all[] = ' SetEnvIf Origin "^(.+)$" CORS=$0';
943 }
944 $all[] = ' </IfModule>';
945 $all[] = ' Header set Access-Control-Allow-Origin %{CORS}e env=CORS';
946 continue;
947 }
948 if (in_array($key, array('Access-Control-Allow-Headers', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Credentials', 'Access-Control-Max-Age', 'Access-Control-Expose-Headers'))) {
949 $all[] = sprintf(' Header set %s %s env=CORS', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
950 continue;
951 }
952 $lines[] = sprintf(' Header set %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
953 }
954 foreach ($append as $key => $value) {
955 $lines[] = sprintf(' Header append %s %s', $key, sprintf('%1$s%2$s%1$s', strpos($value, '"') === false ? '"' : "'", $value));
956 }
957 if (!empty($lines)) {
958 $lines = array_merge(
959 array('<IfModule mod_headers.c>'),
960 $all,
961 array(' <FilesMatch "\.(php|html)$">'),
962 $lines,
963 array(' </FilesMatch>', '</IfModule>')
964 );
965 }
966 return $lines;
967 }
968
969 function apache_content_encoding_directives() {
970 $lines = array();
971 if (get_option('hh_content_encoding') == 1) {
972
973 $content_encoding_value = get_option('hh_content_encoding_value');
974 if (!$content_encoding_value) {
975 $content_encoding_value = array();
976 }
977
978 $content_encoding_ext = get_option('hh_content_encoding_ext');
979 if (!$content_encoding_ext) {
980 $content_encoding_ext = array();
981 }
982 if (!empty($content_encoding_ext)) {
983 $lines[] = sprintf('<FilesMatch "\.(%s)$">', join('|', array_keys($content_encoding_ext)));
984 $lines[] = ' <IfModule mod_deflate.c>';
985 $lines[] = ' SetOutputFilter DEFLATE';
986 $lines[] = ' </IfModule>';
987 $lines[] = '</FilesMatch>';
988 }
989 if (!empty($content_encoding_value)) {
990 if (!empty($lines)) {
991 $lines[] = '';
992 }
993 $lines[] = '<IfModule mod_deflate.c>';
994 foreach ($content_encoding_value as $item => $whatever) {
995 $lines[] = sprintf(' AddOutputFilterByType DEFLATE %s', $item);
996 }
997 $lines[] = '</IfModule>';
998 }
999 }
1000
1001 return $lines;
1002 }
1003
1004 function apache_expires_directives() {
1005 $lines = array();
1006 if (get_option('hh_expires') == 1) {
1007
1008 $types = get_option('hh_expires_type', array());
1009 $values = get_option('hh_expires_value', array());
1010
1011 $lines[] = '<IfModule mod_expires.c>';
1012 $lines[] = ' ExpiresActive On';
1013 foreach ($types as $type => $whatever) {
1014 list($base, $period, $suffix) = explode('_', $values[$type]);
1015 if (in_array($base, array('access', 'modification'))) {
1016 $lines[] = $type != 'default'
1017 ? sprintf(' ExpiresByType %s "%s plus %u %s"', $type, $base, $period, $suffix)
1018 : sprintf(' ExpiresDefault "%s plus %u %s"', $base, $period, $suffix);
1019 } elseif ($base == 'invalid') {
1020 $lines[] = $type != 'default'
1021 ? sprintf(' ExpiresByType %s A0', $type)
1022 : sprintf(' ExpiresDefault A0');
1023 }
1024 }
1025 $lines[] = '</IfModule>';
1026 }
1027
1028 return $lines;
1029 }
1030
1031 function apache_timing_directives() {
1032 $lines = array();
1033 if (get_option('hh_timing_allow_origin') == 1) {
1034 $value = get_option('hh_timing_allow_origin_value');
1035 switch ($value)
1036 {
1037 case 'origin':
1038 $value = get_option('hh_timing_allow_origin_url');
1039 break;
1040 }
1041 if (!empty($value))
1042 {
1043 $lines[] = '<IfModule mod_headers.c>';
1044 $lines[] = ' <FilesMatch "\\.(js|css|jpe?g|png|gif|eot|otf|svg|ttf|woff2?)$">';
1045 $lines[] = sprintf(' Header set Timing-Allow-Origin "%s"', $value);
1046 $lines[] = ' </FilesMatch>';
1047 $lines[] = '</IfModule>';
1048 }
1049 }
1050
1051 return $lines;
1052 }
1053
1054 function apache_auth_directives() {
1055 $lines = array();
1056 if (get_option('hh_www_authenticate') == 1) {
1057
1058 $type = get_option('hh_www_authenticate_type');
1059
1060 $file = $type == 'Basic' ? '.hh-htpasswd' : '.hh-htdigest';
1061
1062 $lines[] = '<FilesMatch "^\.hh-ht(digest|passwd)$">';
1063 $lines[] = ' Order deny,allow';
1064 $lines[] = ' Deny from all';
1065 $lines[] = '</FilesMatch>';
1066
1067 $lines[] = sprintf('<IfModule mod_auth_%s.c>', strtolower($type));
1068 $lines[] = sprintf(' AuthType %s', get_option('hh_www_authenticate_type'));
1069 $lines[] = sprintf(' AuthName "%s"', get_option('hh_www_authenticate_realm'));
1070 $lines[] = sprintf(' AuthUserFile "%s%s"', get_home_path(), $file);
1071 $lines[] = ' Require valid-user';
1072 $lines[] = '</IfModule>';
1073 }
1074
1075 return $lines;
1076 }
1077
1078 function apache_auth_credentials() {
1079 if (get_option('hh_www_authenticate') == 1) {
1080 $type = get_option('hh_www_authenticate_type');
1081 $usernames = get_option('hh_www_authenticate_user', array());
1082 $passwords = get_option('hh_www_authenticate_pswd', array());
1083 if (!is_array($usernames)) {
1084 $usernames = array($usernames);
1085 }
1086 if (!is_array($passwords)) {
1087 $passwords = array($passwords);
1088 }
1089 $realm = get_option('hh_www_authenticate_realm');
1090 $auth = array();
1091 switch ($type) {
1092 case 'Basic':
1093 $ht_file = get_home_path().'.hh-htpasswd';
1094 foreach ($usernames as $k => $user) {
1095 $auth[] = sprintf('%s:{SHA}%s', $user, base64_encode(sha1($passwords[$k], true)));
1096 }
1097 break;
1098 case 'Digest':
1099 $ht_file = get_home_path().'.hh-htdigest';
1100 foreach ($usernames as $k => $user) {
1101 $auth[] = sprintf('%s:%s:%s', $user, $realm, md5($user.':'.$realm.':'.$passwords[$k]));
1102 }
1103 break;
1104 }
1105 $auth = join("\n", $auth);
1106
1107 return compact('ht_file', 'auth');
1108 }
1109 return false;
1110 }
1111
1112 function apache_cookie_security_directives() {
1113 $lines = array();
1114 if (get_option('hh_cookie_security') == 1) {
1115 $value = get_option('hh_cookie_security_value', array());
1116 if (isset($value['HttpOnly'])) {
1117 $lines[] = 'php_flag session.cookie_httponly on';
1118 }
1119 if (isset($value['Secure'])) {
1120 $lines[] = 'php_flag session.cookie_secure on';
1121 }
1122 }
1123
1124 return $lines;
1125 }
1126
1127 function apache_check_requirements() {
1128 return check_filename(get_home_path().'.htaccess');
1129 }
1130
1131 function update_headers_directives() {
1132 $lines = array();
1133 if (get_option('hh_method') == 'htaccess') {
1134 $lines = apache_headers_directives();
1135 }
1136
1137 return insert_with_markers(get_home_path().'.htaccess', "HttpHeaders", $lines);
1138 }
1139
1140 function update_content_encoding_directives() {
1141 $lines = array();
1142 if (get_option('hh_method') == 'htaccess') {
1143 $lines = apache_content_encoding_directives();
1144 }
1145
1146 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersCompression", $lines);
1147 }
1148
1149 function update_expires_directives() {
1150 $lines = array();
1151 if (get_option('hh_method') == 'htaccess') {
1152 $lines = apache_expires_directives();
1153 }
1154
1155 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersExpires", $lines);
1156 }
1157
1158 function update_timing_directives() {
1159 $lines = array();
1160 if (get_option('hh_method') == 'htaccess') {
1161 $lines = apache_timing_directives();
1162 }
1163
1164 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersTiming", $lines);
1165 }
1166
1167 function update_auth_directives() {
1168 $lines = array();
1169 if (get_option('hh_method') == 'htaccess') {
1170 $lines = apache_auth_directives();
1171 }
1172
1173 return insert_with_markers(get_home_path().'.htaccess', "HttpHeadersAuth", $lines);
1174 }
1175
1176 function update_auth_credentials() {
1177 if (get_option('hh_method') == 'htaccess') {
1178 $credentials = apache_auth_credentials();
1179
1180 return @file_put_contents($credentials['ht_file'], $credentials['auth']);
1181 }
1182
1183 return false;
1184 }
1185
1186 function update_cookie_security_directives() {
1187 $lines = array();
1188 if (strpos(PHP_SAPI, 'cgi') !== false) {
1189 $filename = get_home_path().ini_get('user_ini.filename');
1190 $lines = php_cookie_security_directives();
1191 } elseif (get_option('hh_method') == 'htaccess') {
1192 $filename = get_home_path().'.htaccess';
1193 $lines = apache_cookie_security_directives();
1194 }
1195
1196 return insert_with_markers($filename, "HttpHeadersCookieSecurity", $lines);
1197 }
1198
1199 function http_headers_text_domain() {
1200 load_plugin_textdomain('http-headers', false, basename( dirname( __FILE__ ) ) . '/languages/');
1201 }
1202
1203 function http_headers_settings_link( $links ) {
1204 $url = get_admin_url() . 'options-general.php?page=http-headers';
1205 $settings_link = '<a href="' . $url . '">' . __('Settings', 'http-headers') . '</a>';
1206 array_unshift( $links, $settings_link );
1207 return $links;
1208 }
1209
1210 function http_headers_after_setup_theme() {
1211 add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'http_headers_settings_link');
1212 }
1213
1214 function http_headers_enqueue($hook) {
1215 if ( 'http-headers.php' != $hook ) {
1216 # FIXME
1217 //return;
1218 }
1219
1220 wp_enqueue_script('http_headers_admin_scripts', plugin_dir_url( __FILE__ ) . 'assets/scripts.js');
1221 wp_localize_script('http_headers_admin_scripts', 'hh', array(
1222 'lbl_delete' => __('Delete', 'http-headers'),
1223 'lbl_value' => __('Value', 'http-headers'),
1224 ));
1225 wp_enqueue_style('http_headers_admin_styles', plugin_dir_url( __FILE__ ) . 'assets/styles.css');
1226 }
1227
1228 function http_headers_ajax_inspect() {
1229 check_ajax_referer('inspect');
1230 if (current_user_can('manage_options')) {
1231 include 'views/ajax-inspect.php';
1232 }
1233 wp_die();
1234 }
1235
1236 function http_headers_post_import() {
1237 check_admin_referer('import');
1238 global $wpdb;
1239 if (!(isset($_FILES['file']['tmp_name'])
1240 && is_uploaded_file($_FILES['file']['tmp_name'])
1241 && $_FILES['file']['error'] == UPLOAD_ERR_OK
1242 )) {
1243 wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=ERR", get_admin_url()));
1244 exit;
1245 }
1246
1247 $string = @file_get_contents($_FILES['file']['tmp_name']);
1248 if ($string === false) {
1249 wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=ERR", get_admin_url()));
1250 exit;
1251 }
1252
1253 $arr = preg_split('/;(\s+)?\n/', $string);
1254 foreach ($arr as $statement) {
1255 $wpdb->query($statement);
1256 }
1257
1258 wp_redirect(sprintf("%soptions-general.php?page=http-headers&tab=advanced&status=OK", get_admin_url()));
1259 exit;
1260 }
1261
1262 function http_headers_post_export() {
1263 check_admin_referer('export');
1264 global $wpdb;
1265 include 'views/includes/config.inc.php';
1266 $statement = sprintf("SELECT * FROM %s WHERE option_name IN ('%s');", $wpdb->options, join("','", $options));
1267 $results = $wpdb->get_results($statement, ARRAY_A);
1268 $sql = array();
1269 foreach ($results as $item)
1270 {
1271 $value = str_replace("'", "''", $item['option_value']);
1272 $query = array();
1273 $query[] = sprintf("INSERT INTO %s (option_id, option_name, option_value, autoload)", $wpdb->options);
1274 $query[] = sprintf("VALUES (NULL, '%s', '%s', '%s')", $item['option_name'], $value, $item['autoload']);
1275 $query[] = sprintf("ON DUPLICATE KEY UPDATE option_value = '%s', autoload = '%s';", $value, $item['autoload']);
1276 $sql[] = join("\n", $query);
1277 }
1278
1279 $sql = join("\n\n", $sql);
1280 $length = function_exists('mb_strlen') ? mb_strlen($sql) : strlen($sql);
1281 $name = sprintf('WP-HTTP-Headers-%u.sql', time());
1282
1283 # Send headers
1284 header('Pragma: public');
1285 header('Expires: 0');
1286 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1287 header('Cache-Control: private', false);
1288 header('Content-Transfer-Encoding: binary');
1289 header('Content-Disposition: attachment; filename="'.$name.'";');
1290 header('Content-Type: application/sql');
1291 header('Content-Length: ' . $length);
1292
1293 echo $sql;
1294 exit;
1295 }
1296
1297 function check_filename($filename) {
1298 if (!is_file($filename)) {
1299 return -1;
1300 }
1301
1302 clearstatcache();
1303 if (!is_writable($filename)) {
1304 return -2;
1305 }
1306
1307 return true;
1308 }
1309
1310 function check_webserver_requirements() {
1311 $method = get_option('hh_method');
1312 if ($method == 'htaccess') {
1313 return apache_check_requirements();
1314 }
1315
1316 return true;
1317 }
1318
1319 function check_php_requirements() {
1320 if (strpos(PHP_SAPI, 'cgi') !== false) {
1321 // cgi, cgi-fcgi, fpm-fcgi
1322 return check_filename(get_home_path().ini_get('user_ini.filename'));
1323 }
1324
1325 return true;
1326 }
1327
1328 if ( is_admin() ){ // admin actions
1329 add_action('admin_menu', 'http_headers_admin_add_page');
1330 add_action('admin_init', 'http_headers_admin');
1331 add_action("added_option", 'http_headers_option');
1332 add_action("updated_option", 'http_headers_option');
1333 add_action('admin_enqueue_scripts', 'http_headers_enqueue');
1334 add_action('after_setup_theme', 'http_headers_after_setup_theme');
1335 add_action('plugins_loaded', 'http_headers_text_domain');
1336 add_action('wp_ajax_inspect', 'http_headers_ajax_inspect');
1337 add_action('admin_post_import', 'http_headers_post_import');
1338 add_action('admin_post_export', 'http_headers_post_export');
1339 } else {
1340 // non-admin enqueues, actions, and filters
1341 add_action('send_headers', 'http_headers');
1342 }
1343
1344 function http_headers_admin_page() {
1345 include 'views/index.php';
1346 }