WordPress HTTPS (SSL) - Version 2.0.3

Version Description

  • Force SSL Admin will always be enabled when FORCE_SSL_ADMIN is true in wp-config.php.
  • Bug Fix - Users using Shared SSL should no longer have issues with the SSL Host path duplicating in URL's.
  • Bug Fix - The plugin should now function properly when using a subdomain as the SSL Host.
  • Bug Fix - Page and post links will only be forced to HTTPS when using a different SSL Host that is not a subdomain of your Home URL.
  • Bug Fix - WordPress HTTPS should no longer generate erroneous notices and warnings in apache error logs. (If I missed any, let me know)
Download this release

Release Info

Developer Mvied
Plugin Icon wp plugin WordPress HTTPS (SSL)
Version 2.0.3
Comparing to
See all releases

Code changes from version 2.0.2 to 2.0.3

Files changed (3) hide show
  1. readme.txt +13 -15
  2. uninstall.php +1 -0
  3. wordpress-https.php +88 -45
readme.txt CHANGED
@@ -17,30 +17,25 @@ WordPress HTTPS is intended to be an all-in-one solution to using SSL on WordPre
17
 
18
  If you're having partially encrypted/mixed content errors or other problems, please read the <a href="http://wordpress.org/extend/plugins/wordpress-https/faq/">FAQ</a>. If you're still having trouble, please <a href="http://wordpress.org/tags/wordpress-https#postform">start a support topic</a> and I will do my best to assist you.
19
 
20
- = Known Issues =
21
- When using a subdomain as the SSL Host, logged in cookies are not properly deleted upon logging out.
22
-
23
  == Installation ==
24
-
25
  1. Upload the `wordpress-https` folder to the `/wp-content/plugins/` directory.
26
  1. Activate the plugin through the 'Plugins' menu in WordPress.
27
 
28
  == Frequently Asked Questions ==
29
-
30
  = How do I make my whole website secure? =
31
-
32
  To make your entire website secure, you simply need to change your home url and site url to use HTTPS instead of HTTP. Please read <a href="http://codex.wordpress.org/Changing_The_Site_URL" target="_blank">how to change the site url</a>.
33
 
34
  = How do I make only certain pages secure? =
35
-
36
  In the Publish box on the add/edit post screen, a checkbox for 'Force SSL' has been added to make this process easy. See Screenshots if you're having a hard time finding it.
37
 
38
- = I'm getting 404 errors on all of my pages. Why? =
 
 
39
 
 
40
  If you're using a public/shared SSL, try disabling your custom permalink structure. Some public/shared SSL's have issues with WordPress' permalinks because of the way they are configured.
41
 
42
  = How do I fix partially encrypted/mixed content errors? =
43
-
44
  To identify what is causing your page(s) to be insecure, please follow the instructions below.
45
  <ol>
46
  <li>Download <a href="http://www.google.com/chrome" target="_blank">Google Chrome</a>.</li>
@@ -61,25 +56,28 @@ Most insecure content warnings can generally be resolved by changing absolute re
61
  = Is there a hook or filter to force pages to be secure? =
62
 
63
  Yes! Here is an example of how to use the 'force_ssl' hook to force a page to be secure.
64
- <code>
65
- function custom_force_ssl( $force_ssl, $post_id ) {
66
  if ( $post_id == 5 ) {
67
  return true
68
  }
69
  return $force_ssl;
70
  }
71
 
72
- add_filter('force_ssl' , 'custom_force_ssl', 10, 2);
73
- </code>
74
 
75
  == Screenshots ==
76
  1. WordPress HTTPS Settings screen
77
  2. Force SSL checkbox added to add/edit posts screen
78
 
79
  == Changelog ==
80
-
 
 
 
 
 
81
  = 2.0.2 =
82
- * Bug Fix - SSL Host option was not being saved correctly upon subsiquent saves. This was causing redirect loops for most users.
83
  = 2.0.1 =
84
  * Ensured that deprected options are removed from a WordPress installation when activating the plugin.
85
  * Added a button to the WordPress HTTPS settings page to reset all plugin settings and cache.
17
 
18
  If you're having partially encrypted/mixed content errors or other problems, please read the <a href="http://wordpress.org/extend/plugins/wordpress-https/faq/">FAQ</a>. If you're still having trouble, please <a href="http://wordpress.org/tags/wordpress-https#postform">start a support topic</a> and I will do my best to assist you.
19
 
 
 
 
20
  == Installation ==
 
21
  1. Upload the `wordpress-https` folder to the `/wp-content/plugins/` directory.
22
  1. Activate the plugin through the 'Plugins' menu in WordPress.
23
 
24
  == Frequently Asked Questions ==
 
25
  = How do I make my whole website secure? =
 
26
  To make your entire website secure, you simply need to change your home url and site url to use HTTPS instead of HTTP. Please read <a href="http://codex.wordpress.org/Changing_The_Site_URL" target="_blank">how to change the site url</a>.
27
 
28
  = How do I make only certain pages secure? =
 
29
  In the Publish box on the add/edit post screen, a checkbox for 'Force SSL' has been added to make this process easy. See Screenshots if you're having a hard time finding it.
30
 
31
+ = I changed my SSL Host and now I can't get into my admin panel! =
32
+ Go to your wp-config.php file and add this line. Hit any page on your site, and then remove it.
33
+ `define('WPHTTPS_RESET', true);`
34
 
35
+ = I'm getting 404 errors on all of my pages. Why? =
36
  If you're using a public/shared SSL, try disabling your custom permalink structure. Some public/shared SSL's have issues with WordPress' permalinks because of the way they are configured.
37
 
38
  = How do I fix partially encrypted/mixed content errors? =
 
39
  To identify what is causing your page(s) to be insecure, please follow the instructions below.
40
  <ol>
41
  <li>Download <a href="http://www.google.com/chrome" target="_blank">Google Chrome</a>.</li>
56
  = Is there a hook or filter to force pages to be secure? =
57
 
58
  Yes! Here is an example of how to use the 'force_ssl' hook to force a page to be secure.
59
+ `function custom_force_ssl( $force_ssl, $post_id ) {
 
60
  if ( $post_id == 5 ) {
61
  return true
62
  }
63
  return $force_ssl;
64
  }
65
 
66
+ add_filter('force_ssl' , 'custom_force_ssl', 10, 2);`
 
67
 
68
  == Screenshots ==
69
  1. WordPress HTTPS Settings screen
70
  2. Force SSL checkbox added to add/edit posts screen
71
 
72
  == Changelog ==
73
+ = 2.0.3 =
74
+ * Force SSL Admin will always be enabled when FORCE_SSL_ADMIN is true in wp-config.php.
75
+ * Bug Fix - Users using Shared SSL should no longer have issues with the SSL Host path duplicating in URL's.
76
+ * Bug Fix - The plugin should now function properly when using a subdomain as the SSL Host.
77
+ * Bug Fix - Page and post links will only be forced to HTTPS when using a different SSL Host that is not a subdomain of your Home URL.
78
+ * Bug Fix - WordPress HTTPS should no longer generate erroneous notices and warnings in apache error logs. (If I missed any, let me know)
79
  = 2.0.2 =
80
+ * Bug Fix - SSL Host option was not being saved correctly upon subsequent saves. This was causing redirect loops for most users.
81
  = 2.0.1 =
82
  * Ensured that deprected options are removed from a WordPress installation when activating the plugin.
83
  * Added a button to the WordPress HTTPS settings page to reset all plugin settings and cache.
uninstall.php CHANGED
@@ -14,6 +14,7 @@ delete_option('wordpress-https_ssl_port');
14
  delete_option('wordpress-https_exclusive_https');
15
  delete_option('wordpress-https_frontpage');
16
  delete_option('wordpress-https_ssl_admin');
 
17
 
18
  // Delete force_ssl custom_field from posts and pages
19
  delete_metadata('post', null, 'force_ssl', null, true);
14
  delete_option('wordpress-https_exclusive_https');
15
  delete_option('wordpress-https_frontpage');
16
  delete_option('wordpress-https_ssl_admin');
17
+ delete_option('wordpress-https_ssl_host_subdomain');
18
 
19
  // Delete force_ssl custom_field from posts and pages
20
  delete_metadata('post', null, 'force_ssl', null, true);
wordpress-https.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin URI: http://mvied.com/projects/wordpress-https/
5
  Description: WordPress HTTPS is intended to be an all-in-one solution to using SSL on WordPress sites.
6
  Author: Mike Ems
7
- Version: 2.0.2
8
  Author URI: http://mvied.com/
9
  */
10
 
@@ -24,7 +24,7 @@ if ( !class_exists('WordPressHTTPS') ) {
24
  *
25
  * @var int
26
  */
27
- public $version = '2.0.2';
28
 
29
  /**
30
  * Debug Mode
@@ -98,9 +98,10 @@ if ( !class_exists('WordPressHTTPS') ) {
98
  'wordpress-https_unsecure_external_urls' => array(), // External URL's that are okay to rewrite to HTTPS
99
  'wordpress-https_ssl_host' => '', // Hostname for SSL Host
100
  'wordpress-https_ssl_port' => '', // Port number for SSL Host
 
101
  'wordpress-https_exclusive_https' => 0, // Exclusively force SSL on posts and pages with the `Force SSL` option checked.
102
  'wordpress-https_frontpage' => 0, // Force SSL on front page
103
- 'wordpress-https_ssl_admin' => 0 // Force SSL Over Administration Panel (The same as FORCE_SSL_ADMIN)
104
  );
105
 
106
  /**
@@ -127,6 +128,11 @@ if ( !class_exists('WordPressHTTPS') ) {
127
  } else {
128
  $this->plugin_url = WP_PLUGIN_URL . '/' . plugin_basename(dirname(__FILE__));
129
  }
 
 
 
 
 
130
 
131
  // HTTP URL
132
  $this->http_url = 'http://' . parse_url(get_option('home'), PHP_URL_HOST);
@@ -135,7 +141,7 @@ if ( !class_exists('WordPressHTTPS') ) {
135
  // SSL Port
136
  $this->ssl_port = ((get_option('wordpress-https_ssl_port') > 0) ? get_option('wordpress-https_ssl_port') : null);
137
  // Force SSL Admin
138
- $this->ssl_admin = ((get_option('wordpress-https_ssl_admin') > 0) ? true : false);
139
 
140
  // If using a different host for SSL
141
  if ( get_option('wordpress-https_ssl_host') && get_option('wordpress-https_ssl_host') != $this->https_url ) {
@@ -248,7 +254,7 @@ if ( !class_exists('WordPressHTTPS') ) {
248
  }
249
 
250
  // Change all page and post links to HTTPS in the admin panel when using different SSL Host
251
- if ( $this->diff_host && is_admin() ) {
252
  add_filter('page_link', array(&$this, 'replace_http_url'));
253
  add_filter('post_link', array(&$this, 'replace_http_url'));
254
  }
@@ -261,12 +267,21 @@ if ( !class_exists('WordPressHTTPS') ) {
261
  * @return void
262
  */
263
  public function install() {
264
- // Set default options
265
  foreach ( $this->options_default as $option => $value ) {
266
  if ( get_option($option) === false ) {
267
  add_option($option, $value);
268
  }
269
  }
 
 
 
 
 
 
 
 
 
270
  // Run plugin updates
271
  $this->update();
272
  }
@@ -317,6 +332,21 @@ if ( !class_exists('WordPressHTTPS') ) {
317
  delete_option($option);
318
  }
319
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  }
321
 
322
  /**
@@ -340,7 +370,7 @@ if ( !class_exists('WordPressHTTPS') ) {
340
  $i = 0;
341
 
342
  // Warnings about unsecure external URL's
343
- $unsecure_external_urls = (array)get_option('wordpress-https_unsecure_external_urls');
344
  foreach( $unsecure_external_urls as $admin => $urls ) {
345
  if ( $urls && sizeof($urls) > 0 ) {
346
  $warnings[$i]['label'] = 'Unsecure External Content';
@@ -373,10 +403,10 @@ if ( !class_exists('WordPressHTTPS') ) {
373
  function get_url_domain($url) {
374
  $url = $this->get_url($url);
375
  $url_parts = parse_url($url);
376
- $url_host_parts = explode('.', $url_parts['host']);
377
 
378
  // Find base hostname
379
- $url_host = $url_parts['host'];
380
  for ($i = 0; $i < sizeof($url_host_parts)-1; $i++) {
381
  $test_host = str_replace($url_host_parts[$i] . '.', '', $url_host);
382
  if ( $this->get_file_contents($url_parts['scheme'] . '://' . $test_host) ) {
@@ -415,8 +445,7 @@ if ( !class_exists('WordPressHTTPS') ) {
415
  * @return boolean
416
  */
417
  function is_local($url) {
418
- $url_parts = parse_url($url);
419
- if ( strpos($this->http_url, $url_parts['host']) !== false || strpos($this->https_url, $url_parts['host']) !== false ) {
420
  return true;
421
  } else {
422
  return false;
@@ -432,7 +461,7 @@ if ( !class_exists('WordPressHTTPS') ) {
432
  function add_port($string) {
433
  $url = $this->get_url($string);
434
  $url_parts = parse_url($url);
435
- if ( $url_parts['port'] ) {
436
  $url = $this->remove_port($url);
437
  }
438
 
@@ -473,7 +502,11 @@ if ( !class_exists('WordPressHTTPS') ) {
473
  if ( $this->diff_host ) {
474
  $https_url_path = parse_url($this->https_url, PHP_URL_PATH);
475
  if ( strpos($url_parts['path'], $https_url_path) === false ) {
476
- $url = str_replace($url_parts['path'], $https_url_path . $url_parts['path'], $url);
 
 
 
 
477
  }
478
  }
479
 
@@ -501,7 +534,7 @@ if ( !class_exists('WordPressHTTPS') ) {
501
  $url = str_replace($url_parts['host'], parse_url($this->http_url, PHP_URL_HOST), $url_original);
502
  if ( $this->diff_host ) {
503
  $https_url_path = parse_url($this->https_url, PHP_URL_PATH);
504
- if ( strpos($url_parts['path'], $https_url_path) !== false ) {
505
  $url = str_replace($https_url_path, '', $url);
506
  }
507
  }
@@ -530,7 +563,7 @@ if ( !class_exists('WordPressHTTPS') ) {
530
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
531
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
532
  curl_setopt($ch, CURLOPT_FAILONERROR, true);
533
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
534
  curl_setopt($ch, CURLOPT_HEADER, false);
535
  curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
536
 
@@ -626,7 +659,7 @@ if ( !class_exists('WordPressHTTPS') ) {
626
  $buffer = str_replace($html, str_replace($url, $processed_urls[$url], $html), $buffer);
627
  // If external and not HTTPS
628
  } else if ( strpos($url, 'https://') === false ) {
629
- if ( !in_array($url, $external_urls) && !in_array($url, $unsecure_external_urls[$location]) ) {
630
  if ( $this->get_file_contents($this->replace_http($url)) !== false ) {
631
  // Cache this URL as available over HTTPS for future reference
632
  $external_urls[] = $url;
@@ -720,14 +753,15 @@ if ( !class_exists('WordPressHTTPS') ) {
720
  } else {
721
  $post = get_option('page_on_front');
722
  }
 
723
  } else if ( ( strpos($url_parts['path'], 'wp-admin') !== false || strpos($url_parts['path'], 'wp-login') !== false ) && ( $this->is_ssl() || $this->ssl_admin )) {
724
  $post = true;
725
  $force_ssl = true;
726
  }
727
 
728
- if ( $post ) {
729
  // Always change links to HTTPS when logged in via different SSL Host
730
- if ( $type == 'a' && $this->diff_host && $this->ssl_admin && is_user_logged_in() ) {
731
  $force_ssl = true;
732
  } else if ( is_int($post) ) {
733
  $force_ssl = (( !isset($force_ssl) ) ? get_post_meta($post, 'force_ssl', true) : $force_ssl);
@@ -751,7 +785,7 @@ if ( !class_exists('WordPressHTTPS') ) {
751
  }
752
 
753
  // If an unsecure element has been removed from the site, remove it from $unsecure_external_urls to clear warnings
754
- if ( is_array($unsecure_external_urls[$location]) ) {
755
  $unsecure_external_urls[$location] = array_values($unsecure_external_urls[$location]);
756
  for( $i = 0; $i < sizeof($unsecure_external_urls[$location]); $i++ ) {
757
  $removed = true;
@@ -814,13 +848,13 @@ if ( !class_exists('WordPressHTTPS') ) {
814
  public function is_ssl() {
815
  $https_url = parse_url($this->https_url);
816
  // Some extra checks for proxies and Shared SSL
817
- if ( is_ssl() && $_SERVER['HTTP_HOST'] != $https_url['host'] ) {
818
  return false;
819
  } else if ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' ) {
820
  return true;
821
  } else if ( $this->diff_host && !is_ssl() && isset($_SERVER['HTTP_X_FORWARDED_SERVER']) && strpos($this->https_url, 'https://' . $_SERVER['HTTP_X_FORWARDED_SERVER']) !== false ) {
822
  return true;
823
- } else if ( $this->diff_host && !is_ssl() && strpos($_SERVER['HTTP_HOST'], $https_url['host']) !== false && (!$this->ssl_port || $_SERVER['SERVER_PORT'] == $this->ssl_port) && (!$https_url['path'] || strpos($_SERVER['REQUEST_URI'], $https_url['path']) !== false) ) {
824
  return true;
825
  }
826
  return is_ssl();
@@ -850,7 +884,7 @@ if ( !class_exists('WordPressHTTPS') ) {
850
  }
851
  }
852
 
853
- if ( $scheme ) {
854
  $this->redirect($scheme);
855
  }
856
  }
@@ -888,7 +922,7 @@ if ( !class_exists('WordPressHTTPS') ) {
888
  $url = false;
889
  }
890
  if ( $url ) {
891
- $destination = $url['scheme'] . '://' . $url['host'] . (( $url['port'] ) ? ':' . $url['port'] : '') . (( $this->diff_host ) ? $url['path'] : '') . $_SERVER['REQUEST_URI'];
892
  if ( function_exists('wp_redirect') ) {
893
  wp_redirect($destination, 301);
894
 
@@ -945,14 +979,12 @@ if ( !class_exists('WordPressHTTPS') ) {
945
  $cookie_path_admin = ADMIN_COOKIE_PATH;
946
 
947
  if ( $this->diff_host && $this->is_ssl() ) {
948
- $http_domain = $this->get_url_domain($this->http_url);
949
- $https_domain = $this->get_url_domain($this->https_url);
950
  // If SSL Host is a subdomain and we're setting an authentication cookie, the cookie does not need to be set
951
- if ( $http_domain == $https_domain && $scheme == 'auth' ) {
952
  return;
953
  // If SSL Host is a subdomain, make cookie domain a wildcard
954
- } else if ( $http_domain == $https_domain ) {
955
- $cookie_domain = '.' . $https_domain;
956
  // Otherwise, cookie domain set for different SSL Host
957
  } else {
958
  $cookie_domain = parse_url($this->https_url, PHP_URL_HOST);
@@ -1001,20 +1033,17 @@ if ( !class_exists('WordPressHTTPS') ) {
1001
  * @return void
1002
  */
1003
  public function clear_cookies() {
1004
- $http_domain = $this->get_url_domain($this->http_url);
1005
- $https_domain = $this->get_url_domain($this->https_url);
1006
- if ( $http_domain == $https_domain ) {
1007
- $cookie_domain = '.' . $https_domain;
1008
- setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, $cookie_path, $cookie_domain);
1009
- setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, $cookie_path_site, $cookie_domain);
1010
- }
1011
-
1012
- $cookie_domain = parse_url($this->https_url, PHP_URL_HOST);
1013
  $cookie_path = rtrim(parse_url($this->https_url, PHP_URL_PATH), '/') . COOKIEPATH;
1014
  $cookie_path_site = rtrim(parse_url($this->https_url, PHP_URL_PATH), '/') . SITECOOKIEPATH;
1015
  $cookie_path_plugins = rtrim(parse_url($this->https_url, PHP_URL_PATH), '/') . PLUGINS_COOKIE_PATH;
1016
  $cookie_path_admin = $cookie_path_site . 'wp-admin';
1017
 
 
 
 
 
 
1018
  setcookie(AUTH_COOKIE, ' ', time() - 31536000, $cookie_path_admin);
1019
  setcookie(AUTH_COOKIE, ' ', time() - 31536000, $cookie_path_plugins);
1020
  setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, $cookie_path_admin);
@@ -1038,7 +1067,7 @@ if ( !class_exists('WordPressHTTPS') ) {
1038
  if ( $post->ID ) {
1039
  $checked = get_post_meta($post->ID, 'force_ssl', true);
1040
  }
1041
- echo '<div class="misc-pub-section misc-pub-section-wphttps"><label>Force SSL: <input type="checkbox" value="1" name="force_ssl" id="force_ssl"'.(($checked) ? ' checked="checked"' : '').' /></label></div>';
1042
  }
1043
 
1044
  /**
@@ -1049,7 +1078,7 @@ if ( !class_exists('WordPressHTTPS') ) {
1049
  */
1050
  public function post_save( $post_id ) {
1051
  if ( array_key_exists('wordpress-https', $_POST) ) {
1052
- if ( !wp_verify_nonce($_POST['wordpress-https'], plugin_basename(__FILE__))) {
1053
  return $post_id;
1054
  }
1055
 
@@ -1121,10 +1150,10 @@ if ( !class_exists('WordPressHTTPS') ) {
1121
 
1122
  if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
1123
  $errors = array();
 
 
1124
  if ( @$_POST['Reset'] ) {
1125
- foreach ( $this->options_default as $option => $value ) {
1126
- update_option($option, $value);
1127
- }
1128
  $reload = true;
1129
  } else {
1130
  foreach ($this->options_default as $key => $default) {
@@ -1133,7 +1162,7 @@ if ( !class_exists('WordPressHTTPS') ) {
1133
  update_option($key, $_POST[$key]);
1134
  } else {
1135
  if ( $key == 'wordpress-https_ssl_host' ) {
1136
- if ( $_POST[$key] != '' ) {
1137
  $url = strtolower($_POST[$key]);
1138
  // Add scheme if it doesn't exist so that parse_url does not fail
1139
  if ( strpos($url, 'http://') === false && strpos($url, 'https://') === false ) {
@@ -1167,8 +1196,10 @@ if ( !class_exists('WordPressHTTPS') ) {
1167
  $_POST[$key] = get_option($key);
1168
  }
1169
  } else {
1170
- $_POST[$key] = $this->https_url;
1171
  }
 
 
1172
  }
1173
  } else if ( $key == 'wordpress-https_ssl_admin' ) {
1174
  if ( force_ssl_admin() || force_ssl_login() ) {
@@ -1178,6 +1209,16 @@ if ( !class_exists('WordPressHTTPS') ) {
1178
  } else if ( !$this->is_ssl() ) {
1179
  $logout = true;
1180
  }
 
 
 
 
 
 
 
 
 
 
1181
  }
1182
 
1183
  update_option($key, $_POST[$key]);
@@ -1285,6 +1326,8 @@ if ( !class_exists('WordPressHTTPS') ) {
1285
  <form name="form" id="wordpress-https" action="options-general.php?page=wordpress-https" method="post">
1286
  <?php settings_fields('wordpress-https'); ?>
1287
 
 
 
1288
  <h3 class="title">General Settings</h3>
1289
  <table class="form-table">
1290
  <tr valign="top">
@@ -1316,7 +1359,7 @@ if ( !class_exists('WordPressHTTPS') ) {
1316
  <td>
1317
  <fieldset>
1318
  <label for="wordpress-https_ssl_admin">
1319
- <input name="wordpress-https_ssl_admin" type="checkbox" id="wordpress-https_ssl_admin" value="1"<?php echo ((get_option('wordpress-https_ssl_admin')) ? ' checked="checked"' : ''); ?> />
1320
  </label>
1321
  </fieldset>
1322
  </td>
4
  Plugin URI: http://mvied.com/projects/wordpress-https/
5
  Description: WordPress HTTPS is intended to be an all-in-one solution to using SSL on WordPress sites.
6
  Author: Mike Ems
7
+ Version: 2.0.3
8
  Author URI: http://mvied.com/
9
  */
10
 
24
  *
25
  * @var int
26
  */
27
+ public $version = '2.0.3';
28
 
29
  /**
30
  * Debug Mode
98
  'wordpress-https_unsecure_external_urls' => array(), // External URL's that are okay to rewrite to HTTPS
99
  'wordpress-https_ssl_host' => '', // Hostname for SSL Host
100
  'wordpress-https_ssl_port' => '', // Port number for SSL Host
101
+ 'wordpress-https_ssl_host_subdomain' => 0, // Is SSL Host a subdomain
102
  'wordpress-https_exclusive_https' => 0, // Exclusively force SSL on posts and pages with the `Force SSL` option checked.
103
  'wordpress-https_frontpage' => 0, // Force SSL on front page
104
+ 'wordpress-https_ssl_admin' => 0, // Force SSL Over Administration Panel (The same as FORCE_SSL_ADMIN)
105
  );
106
 
107
  /**
128
  } else {
129
  $this->plugin_url = WP_PLUGIN_URL . '/' . plugin_basename(dirname(__FILE__));
130
  }
131
+
132
+ // If WPHTTPS_RESET global is defined, run reset method
133
+ if ( defined('WPHTTPS_RESET') && constant('WPHTTPS_RESET') == true ) {
134
+ $this->reset();
135
+ }
136
 
137
  // HTTP URL
138
  $this->http_url = 'http://' . parse_url(get_option('home'), PHP_URL_HOST);
141
  // SSL Port
142
  $this->ssl_port = ((get_option('wordpress-https_ssl_port') > 0) ? get_option('wordpress-https_ssl_port') : null);
143
  // Force SSL Admin
144
+ $this->ssl_admin = ((force_ssl_admin() || get_option('wordpress-https_ssl_admin') > 0) ? true : false);
145
 
146
  // If using a different host for SSL
147
  if ( get_option('wordpress-https_ssl_host') && get_option('wordpress-https_ssl_host') != $this->https_url ) {
254
  }
255
 
256
  // Change all page and post links to HTTPS in the admin panel when using different SSL Host
257
+ if ( get_option('wordpress-https_ssl_host_subdomain') == 0 && $this->diff_host && is_admin() && $this->is_ssl() ) {
258
  add_filter('page_link', array(&$this, 'replace_http_url'));
259
  add_filter('post_link', array(&$this, 'replace_http_url'));
260
  }
267
  * @return void
268
  */
269
  public function install() {
270
+ // Add plugin options
271
  foreach ( $this->options_default as $option => $value ) {
272
  if ( get_option($option) === false ) {
273
  add_option($option, $value);
274
  }
275
  }
276
+
277
+ // Checks to see if the SSL Host is a subdomain
278
+ $http_domain = $this->get_url_domain($this->http_url);
279
+ $https_domain = $this->get_url_domain($this->https_url);
280
+
281
+ if ( $this->replace_https($url) != $this->http_url && $http_domain == $https_domain ) {
282
+ update_option('wordpress-https_ssl_host_subdomain', 1);
283
+ }
284
+
285
  // Run plugin updates
286
  $this->update();
287
  }
332
  delete_option($option);
333
  }
334
  }
335
+
336
+ // Update current version
337
+ update_option('wordpress-https_version', $this->version);
338
+ }
339
+
340
+ /**
341
+ * Rests all plugin options to the defaults
342
+ *
343
+ * @param none
344
+ * @return void
345
+ */
346
+ public function reset() {
347
+ foreach ( $this->options_default as $option => $value ) {
348
+ update_option($option, $value);
349
+ }
350
  }
351
 
352
  /**
370
  $i = 0;
371
 
372
  // Warnings about unsecure external URL's
373
+ $unsecure_external_urls = (array) get_option('wordpress-https_unsecure_external_urls');
374
  foreach( $unsecure_external_urls as $admin => $urls ) {
375
  if ( $urls && sizeof($urls) > 0 ) {
376
  $warnings[$i]['label'] = 'Unsecure External Content';
403
  function get_url_domain($url) {
404
  $url = $this->get_url($url);
405
  $url_parts = parse_url($url);
406
+ $url_host_parts = explode('.', @$url_parts['host']);
407
 
408
  // Find base hostname
409
+ $url_host = @$url_parts['host'];
410
  for ($i = 0; $i < sizeof($url_host_parts)-1; $i++) {
411
  $test_host = str_replace($url_host_parts[$i] . '.', '', $url_host);
412
  if ( $this->get_file_contents($url_parts['scheme'] . '://' . $test_host) ) {
445
  * @return boolean
446
  */
447
  function is_local($url) {
448
+ if ( ($url_parts = parse_url($url)) && strpos($this->http_url, $url_parts['host']) !== false || strpos($this->https_url, $url_parts['host']) !== false ) {
 
449
  return true;
450
  } else {
451
  return false;
461
  function add_port($string) {
462
  $url = $this->get_url($string);
463
  $url_parts = parse_url($url);
464
+ if ( isset($url_parts['port']) ) {
465
  $url = $this->remove_port($url);
466
  }
467
 
502
  if ( $this->diff_host ) {
503
  $https_url_path = parse_url($this->https_url, PHP_URL_PATH);
504
  if ( strpos($url_parts['path'], $https_url_path) === false ) {
505
+ if ( $url_parts['path'] == '/' ) {
506
+ $url = rtrim('/', $url) . $https_url_path;
507
+ } else {
508
+ $url = str_replace($url_parts['path'], $https_url_path . $url_parts['path'], $url);
509
+ }
510
  }
511
  }
512
 
534
  $url = str_replace($url_parts['host'], parse_url($this->http_url, PHP_URL_HOST), $url_original);
535
  if ( $this->diff_host ) {
536
  $https_url_path = parse_url($this->https_url, PHP_URL_PATH);
537
+ if ( $https_url_path != '/' && strpos(@$url_parts['path'], $https_url_path) !== false ) {
538
  $url = str_replace($https_url_path, '', $url);
539
  }
540
  }
563
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
564
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
565
  curl_setopt($ch, CURLOPT_FAILONERROR, true);
566
+ @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
567
  curl_setopt($ch, CURLOPT_HEADER, false);
568
  curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
569
 
659
  $buffer = str_replace($html, str_replace($url, $processed_urls[$url], $html), $buffer);
660
  // If external and not HTTPS
661
  } else if ( strpos($url, 'https://') === false ) {
662
+ if ( @in_array($url, $external_urls) == false && @in_array($url, $unsecure_external_urls[$location]) == false ) {
663
  if ( $this->get_file_contents($this->replace_http($url)) !== false ) {
664
  // Cache this URL as available over HTTPS for future reference
665
  $external_urls[] = $url;
753
  } else {
754
  $post = get_option('page_on_front');
755
  }
756
+ //TODO When logged in to HTTP and visiting an HTTPS page, admin links will always be forced to HTTPS, even if the user is not logged in via HTTPS. I need to find a way to detect this.
757
  } else if ( ( strpos($url_parts['path'], 'wp-admin') !== false || strpos($url_parts['path'], 'wp-login') !== false ) && ( $this->is_ssl() || $this->ssl_admin )) {
758
  $post = true;
759
  $force_ssl = true;
760
  }
761
 
762
+ if ( isset($post) ) {
763
  // Always change links to HTTPS when logged in via different SSL Host
764
+ if ( $type == 'a' && get_option('wordpress-https_ssl_host_subdomain') == 0 && $this->diff_host && $this->ssl_admin && is_user_logged_in() ) {
765
  $force_ssl = true;
766
  } else if ( is_int($post) ) {
767
  $force_ssl = (( !isset($force_ssl) ) ? get_post_meta($post, 'force_ssl', true) : $force_ssl);
785
  }
786
 
787
  // If an unsecure element has been removed from the site, remove it from $unsecure_external_urls to clear warnings
788
+ if ( isset($unsecure_external_urls[$location]) && is_array($unsecure_external_urls[$location]) ) {
789
  $unsecure_external_urls[$location] = array_values($unsecure_external_urls[$location]);
790
  for( $i = 0; $i < sizeof($unsecure_external_urls[$location]); $i++ ) {
791
  $removed = true;
848
  public function is_ssl() {
849
  $https_url = parse_url($this->https_url);
850
  // Some extra checks for proxies and Shared SSL
851
+ if ( is_ssl() && strpos($_SERVER['HTTP_HOST'], $https_url['host']) === false ) {
852
  return false;
853
  } else if ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' ) {
854
  return true;
855
  } else if ( $this->diff_host && !is_ssl() && isset($_SERVER['HTTP_X_FORWARDED_SERVER']) && strpos($this->https_url, 'https://' . $_SERVER['HTTP_X_FORWARDED_SERVER']) !== false ) {
856
  return true;
857
+ } else if ( $this->diff_host && !is_ssl() && strpos($_SERVER['HTTP_HOST'], $https_url['host']) !== false && (!$this->ssl_port || $_SERVER['SERVER_PORT'] == $this->ssl_port) && (isset($https_url['path']) && !$https_url['path'] || strpos($_SERVER['REQUEST_URI'], $https_url['path']) !== false) ) {
858
  return true;
859
  }
860
  return is_ssl();
884
  }
885
  }
886
 
887
+ if ( isset($scheme) ) {
888
  $this->redirect($scheme);
889
  }
890
  }
922
  $url = false;
923
  }
924
  if ( $url ) {
925
+ $destination = $url['scheme'] . '://' . $url['host'] . (( isset($url['port']) ) ? ':' . $url['port'] : '') . (( $this->diff_host && isset($url['path']) ) ? $url['path'] : '') . $_SERVER['REQUEST_URI'];
926
  if ( function_exists('wp_redirect') ) {
927
  wp_redirect($destination, 301);
928
 
979
  $cookie_path_admin = ADMIN_COOKIE_PATH;
980
 
981
  if ( $this->diff_host && $this->is_ssl() ) {
 
 
982
  // If SSL Host is a subdomain and we're setting an authentication cookie, the cookie does not need to be set
983
+ if ( get_option('wordpress-https_ssl_host_subdomain') == 1 && ( $scheme == 'auth' || $scheme == 'secure_auth' ) ) {
984
  return;
985
  // If SSL Host is a subdomain, make cookie domain a wildcard
986
+ } else if ( get_option('wordpress-https_ssl_host_subdomain') == 1 ) {
987
+ $cookie_domain = '.' . $this->get_url_domain($this->https_url);
988
  // Otherwise, cookie domain set for different SSL Host
989
  } else {
990
  $cookie_domain = parse_url($this->https_url, PHP_URL_HOST);
1033
  * @return void
1034
  */
1035
  public function clear_cookies() {
1036
+ $cookie_domain = '.' . $this->get_url_domain($this->https_url);
 
 
 
 
 
 
 
 
1037
  $cookie_path = rtrim(parse_url($this->https_url, PHP_URL_PATH), '/') . COOKIEPATH;
1038
  $cookie_path_site = rtrim(parse_url($this->https_url, PHP_URL_PATH), '/') . SITECOOKIEPATH;
1039
  $cookie_path_plugins = rtrim(parse_url($this->https_url, PHP_URL_PATH), '/') . PLUGINS_COOKIE_PATH;
1040
  $cookie_path_admin = $cookie_path_site . 'wp-admin';
1041
 
1042
+ if ( get_option('wordpress-https_ssl_host_subdomain') == 1 ) {
1043
+ setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, $cookie_path, $cookie_domain);
1044
+ setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, $cookie_path_site, $cookie_domain);
1045
+ }
1046
+
1047
  setcookie(AUTH_COOKIE, ' ', time() - 31536000, $cookie_path_admin);
1048
  setcookie(AUTH_COOKIE, ' ', time() - 31536000, $cookie_path_plugins);
1049
  setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, $cookie_path_admin);
1067
  if ( $post->ID ) {
1068
  $checked = get_post_meta($post->ID, 'force_ssl', true);
1069
  }
1070
+ echo '<div class="misc-pub-section misc-pub-section-wphttps"><label>Force SSL: <input type="checkbox" value="1" name="force_ssl" id="force_ssl"' . (( $checked ) ? ' checked="checked"' : '') . ' /></label></div>';
1071
  }
1072
 
1073
  /**
1078
  */
1079
  public function post_save( $post_id ) {
1080
  if ( array_key_exists('wordpress-https', $_POST) ) {
1081
+ if ( !wp_verify_nonce($_POST['wordpress-https'], plugin_basename(__FILE__)) ) {
1082
  return $post_id;
1083
  }
1084
 
1150
 
1151
  if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
1152
  $errors = array();
1153
+ $reload = false;
1154
+ $logout = false;
1155
  if ( @$_POST['Reset'] ) {
1156
+ $this->reset();
 
 
1157
  $reload = true;
1158
  } else {
1159
  foreach ($this->options_default as $key => $default) {
1162
  update_option($key, $_POST[$key]);
1163
  } else {
1164
  if ( $key == 'wordpress-https_ssl_host' ) {
1165
+ if ( $_POST[$key] != '' ) {
1166
  $url = strtolower($_POST[$key]);
1167
  // Add scheme if it doesn't exist so that parse_url does not fail
1168
  if ( strpos($url, 'http://') === false && strpos($url, 'https://') === false ) {
1196
  $_POST[$key] = get_option($key);
1197
  }
1198
  } else {
1199
+ $_POST[$key] = $this->https_url;
1200
  }
1201
+ } else {
1202
+ $_POST[$key] = get_option($key);
1203
  }
1204
  } else if ( $key == 'wordpress-https_ssl_admin' ) {
1205
  if ( force_ssl_admin() || force_ssl_login() ) {
1209
  } else if ( !$this->is_ssl() ) {
1210
  $logout = true;
1211
  }
1212
+ } else if ( $key == 'wordpress-https_ssl_host_subdomain' ) {
1213
+ // Checks to see if the SSL Host is a subdomain
1214
+ $http_domain = $this->get_url_domain($this->http_url);
1215
+ $https_domain = $this->get_url_domain($this->https_url);
1216
+
1217
+ if ( $this->replace_https($url) != $this->http_url && $http_domain == $https_domain ) {
1218
+ $_POST[$key] = 1;
1219
+ } else {
1220
+ $_POST[$key] = 0;
1221
+ }
1222
  }
1223
 
1224
  update_option($key, $_POST[$key]);
1326
  <form name="form" id="wordpress-https" action="options-general.php?page=wordpress-https" method="post">
1327
  <?php settings_fields('wordpress-https'); ?>
1328
 
1329
+ <input type="hidden" name="wordpress-https_ssl_host_subdomain" value="<?php echo ((get_option('wordpress-https_ssl_host_subdomain') != 1) ? 0 : 1); ?>" />
1330
+
1331
  <h3 class="title">General Settings</h3>
1332
  <table class="form-table">
1333
  <tr valign="top">
1359
  <td>
1360
  <fieldset>
1361
  <label for="wordpress-https_ssl_admin">
1362
+ <input name="wordpress-https_ssl_admin" type="checkbox" id="wordpress-https_ssl_admin" value="1"<?php echo (($this->ssl_admin) ? ' checked="checked"' : ''); ?><?php echo ((force_ssl_admin()) ? ' disabled="disabled" title="FORCE_SSL_ADMIN is true in wp-config.php"' : ''); ?> />
1363
  </label>
1364
  </fieldset>
1365
  </td>