PageRenderTime 60ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-content/plugins/really-simple-ssl/class-admin.php

https://bitbucket.org/carloskikea/helpet
PHP | 2582 lines | 1602 code | 427 blank | 553 comment | 387 complexity | 6e7a5d1bfff3eb272f501b92aecef16c MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. <?php
  2. defined('ABSPATH') or die("you do not have access to this page!");
  3. class rsssl_admin extends rsssl_front_end {
  4. private static $_this;
  5. public $wpconfig_siteurl_not_fixed = FALSE;
  6. public $no_server_variable = FALSE;
  7. public $errors = Array();
  8. public $do_wpconfig_loadbalancer_fix = FALSE;
  9. public $site_has_ssl = FALSE;
  10. public $ssl_enabled = FALSE;
  11. //multisite variables
  12. public $sites = Array(); //for multisite, list of all activated sites.
  13. //general settings
  14. public $capability = 'activate_plugins';
  15. public $ssl_test_page_error;
  16. public $htaccess_test_success = FALSE;
  17. public $plugin_version = rsssl_version; //deprecated, but used in pro plugin until 1.0.25
  18. public $plugin_dir = "really-simple-ssl";
  19. public $plugin_filename = "rlrsssl-really-simple-ssl.php";
  20. public $ABSpath;
  21. public $do_not_edit_htaccess = FALSE;
  22. public $htaccess_redirect = FALSE;
  23. public $htaccess_warning_shown = FALSE;
  24. public $ssl_success_message_shown = FALSE;
  25. public $hsts = FALSE;
  26. public $debug = TRUE;
  27. public $debug_log;
  28. public $plugin_conflict = ARRAY();
  29. public $plugin_db_version;
  30. public $plugin_upgraded;
  31. public $mixed_content_fixer_status = "OK";
  32. public $ssl_type = "NA";
  33. private $pro_url = "https://www.really-simple-ssl.com/pro";
  34. function __construct() {
  35. if ( isset( self::$_this ) )
  36. wp_die( sprintf( __( '%s is a singleton class and you cannot create a second instance.','really-simple-ssl' ), get_class( $this ) ) );
  37. self::$_this = $this;
  38. $this->ABSpath = $this->getABSPATH();
  39. $this->get_options();
  40. $this->get_admin_options();
  41. $this->get_plugin_upgraded(); //call always, otherwise db version will not match anymore.
  42. register_deactivation_hook(dirname( __FILE__ )."/".$this->plugin_filename, array($this,'deactivate') );
  43. }
  44. static function this() {
  45. return self::$_this;
  46. }
  47. /**
  48. * Initializes the admin class
  49. *
  50. * @since 2.2
  51. *
  52. * @access public
  53. *
  54. */
  55. public function init() {
  56. if (!current_user_can($this->capability)) return;
  57. $is_on_settings_page = $this->is_settings_page();
  58. /*
  59. Detect configuration when:
  60. - SSL activation just confirmed.
  61. - on settings page
  62. - No SSL detected
  63. */
  64. //when configuration should run again
  65. if ($this->clicked_activate_ssl() || !$this->ssl_enabled || !$this->site_has_ssl || $is_on_settings_page || is_network_admin()) {
  66. if (is_multisite()) $this->build_domain_list();//has to come after clicked_activate_ssl, otherwise this domain won't get counted.
  67. $this->detect_configuration();
  68. //flush caches when just activated ssl
  69. //flush the permalinks
  70. if ($this->clicked_activate_ssl()) {
  71. if (isset($_POST["rsssl_flush_rewrite_rules"])) {
  72. add_action( 'shutdown', 'flush_rewrite_rules');
  73. }
  74. add_action('admin_init', array(RSSSL()->rsssl_cache,'flush'),40);
  75. }
  76. if (!$this->wpconfig_ok()) {
  77. //if we were to activate ssl, this could result in a redirect loop. So warn first.
  78. add_action("admin_notices", array($this, 'show_notice_wpconfig_needs_fixes'));
  79. if (is_multisite()) add_action('network_admin_notices', array($this, 'show_notice_wpconfig_needs_fixes'), 10);
  80. $this->ssl_enabled = false;
  81. $this->save_options();
  82. } elseif ($this->ssl_enabled) {
  83. add_action('init',array($this,'configure_ssl'),20);
  84. }
  85. }
  86. //when SSL is enabled, and not enabled by user, ask for activation.
  87. add_action("admin_notices", array($this, 'show_notice_activate_ssl'),10);
  88. add_action('plugins_loaded', array($this,'check_plugin_conflicts'),30);
  89. //add the settings page for the plugin
  90. add_action('admin_enqueue_scripts', array($this, 'enqueue_assets'));
  91. add_action('admin_init', array($this, 'load_translation'),20);
  92. add_action('rsssl_configuration_page', array($this, 'configuration_page_more'),10);
  93. //settings page, form and settings link in the plugins page
  94. add_action('admin_menu', array($this, 'add_settings_page'),40);
  95. add_action('admin_init', array($this, 'create_form'),40);
  96. $plugin = rsssl_plugin;
  97. add_filter("plugin_action_links_$plugin", array($this,'plugin_settings_link'));
  98. //check if the uninstallfile is safely renamed to php.
  99. $this->check_for_uninstall_file();
  100. //callbacks for the ajax dismiss buttons
  101. add_action('wp_ajax_dismiss_htaccess_warning', array($this,'dismiss_htaccess_warning_callback') );
  102. add_action('wp_ajax_dismiss_success_message', array($this,'dismiss_success_message_callback') );
  103. //handle notices
  104. add_action('admin_notices', array($this,'show_notices'));
  105. }
  106. //change deprecated function depending on version.
  107. public function get_sites_bw_compatible(){
  108. global $wp_version;
  109. $sites = ($wp_version >= 4.6 ) ? get_sites() : wp_get_sites();
  110. return $sites;
  111. }
  112. /*
  113. The new get_sites function returns an object.
  114. */
  115. public function switch_to_blog_bw_compatible($site){
  116. global $wp_version;
  117. if ($wp_version >= 4.6 ) {
  118. switch_to_blog( $site->blog_id );
  119. } else {
  120. switch_to_blog( $site[ 'blog_id' ] );
  121. }
  122. }
  123. /*
  124. checks if the user just clicked the "activate SSL" button.
  125. */
  126. private function clicked_activate_ssl() {
  127. if (!current_user_can($this->capability)) return;
  128. //if (!isset( $_POST['rsssl_nonce'] ) || !wp_verify_nonce( $_POST['rsssl_nonce'], 'rsssl_nonce' )) return false;
  129. if (isset($_POST['rsssl_do_activate_ssl'])) {
  130. $this->activate_ssl();
  131. return true;
  132. }
  133. return false;
  134. }
  135. /*
  136. Activate the SSL for this site
  137. */
  138. public function activate_ssl(){
  139. $this->ssl_enabled = true;
  140. $this->wp_redirect = true;
  141. $this->set_siteurl_to_ssl();
  142. $this->save_options();
  143. }
  144. public function deactivate_ssl(){
  145. $this->ssl_enabled = false;
  146. $this->wp_redirect = false;
  147. $this->htaccess_redirect = false;
  148. $this->remove_ssl_from_siteurl();
  149. $this->save_options();
  150. }
  151. public function wpconfig_ok(){
  152. if (($this->do_wpconfig_loadbalancer_fix || $this->no_server_variable || $this->wpconfig_siteurl_not_fixed) && !$this->wpconfig_is_writable() ) {
  153. $result = false;
  154. } else {
  155. $result = true;
  156. }
  157. return apply_filters('rsssl_wpconfig_ok_check', $result);
  158. }
  159. /*
  160. This message is shown when no SSL is not enabled by the user yet
  161. */
  162. public function show_notice_activate_ssl(){
  163. if ($this->ssl_enabled) return;
  164. if (defined("RSSSL_DISMISS_ACTIVATE_SSL_NOTICE") && RSSSL_DISMISS_ACTIVATE_SSL_NOTICE) return;
  165. //for multisite, show only activate when a choice has been made to activate networkwide or per site.
  166. if (is_multisite() && !RSSSL()->rsssl_multisite->selected_networkwide_or_per_site) return;
  167. //on multistie, only show this message on the network admin. Per site activated sites have to go to the settings page.
  168. //otherwise sites that do not need SSL possibly get to see this message.
  169. if (is_multisite() && !is_network_admin()) return;
  170. if (!$this->wpconfig_ok()) return;
  171. if (!current_user_can($this->capability)) return;
  172. if (!$this->site_has_ssl) {
  173. global $wp;
  174. $current_url = "https://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
  175. ?>
  176. <div id="message" class="error fade notice activate-ssl">
  177. <p><?php _e("No SSL was detected. If you do have an SSL certificate, try to reload this page over https by clicking this link:","really-simple-ssl");?>&nbsp;<a href="<?php echo $current_url?>"><?php _e("reload over https.","really-simple-ssl");?></a>
  178. <?php _e("You can check your certificate on","really-simple-ssl");?>&nbsp;<a target="_blank" href="https://www.ssllabs.com/ssltest/">Qualys SSL Labs</a>
  179. </p>
  180. </div>
  181. <?php } ?>
  182. <div id="message" class="updated fade notice activate-ssl">
  183. <?php if ($this->site_has_ssl) { ?>
  184. <h1><?php _e("Almost ready to migrate to SSL!","really-simple-ssl");?></h1>
  185. <?php } ?>
  186. <?php _e("Some things can't be done automatically. Before you migrate, please check for: ",'really-simple-ssl');?>
  187. <p>
  188. <ul>
  189. <li><?php _e('Http references in your .css and .js files: change any http:// into //','really-simple-ssl');?></li>
  190. <li><?php _e('Images, stylesheets or scripts from a domain without an SSL certificate: remove them or move to your own server.','really-simple-ssl');?></li><?php
  191. $backup_link = "https://really-simple-ssl.com/knowledge-base/backing-up-your-site/";
  192. $link_open = '<a target="_blank" href="'.$backup_link.'">';
  193. $link_close = '</a>';
  194. ?> <li> <?php printf(__("It is recommended to take a %sbackup%s of your site before activating SSL", 'really-simple-ssl'), $link_open, $link_close); ?> </li>
  195. </ul>
  196. </p>
  197. <?php $this->show_pro(); ?>
  198. <?php RSSSL()->really_simple_ssl->show_enable_ssl_button();?>
  199. </div>
  200. <?php }
  201. /**
  202. * @since 2.3
  203. * Returns button to enable SSL.
  204. */
  205. public function show_enable_ssl_button(){
  206. if ($this->site_has_ssl || (defined('rsssl_force_activate') && rsssl_force_activate)) {
  207. ?>
  208. <p>
  209. <form action="" method="post">
  210. <?php wp_nonce_field( 'rsssl_nonce', 'rsssl_nonce' );?>
  211. <div>
  212. <input type="checkbox" name="rsssl_flush_rewrite_rules" checked><label><?php _e("Flush rewrite rules on activation (deselect when you encounter errors)","really-simple-ssl")?></label>
  213. </div>
  214. <input type="submit" class='button button-primary' value="<?php _e("Go ahead, activate SSL!","really-simple-ssl");?>" id="rsssl_do_activate_ssl" name="rsssl_do_activate_ssl">
  215. <br><?php _e("You may need to login in again.", "really-simple-ssl")?>
  216. </form>
  217. </p>
  218. <?php
  219. }
  220. }
  221. /**
  222. * @since 2.3
  223. * Shows option to buy pro
  224. */
  225. public function show_pro(){
  226. if ( !defined("rsssl_pro_version") ) {
  227. ?>
  228. <p><?php _e('You can also let the automatic scan of the pro version handle this for you, and get premium support, increased security with HSTS and more!','really-simple-ssl');?>&nbsp;<a target="_blank" href="<?php echo $this->pro_url;?>"><?php _e("Check out Really Simple SSL Premium","really-simple-ssl");?></a></p>
  229. <?php
  230. }
  231. }
  232. public function wpconfig_is_writable() {
  233. $wpconfig_path = $this->find_wp_config_path();
  234. if (is_writable($wpconfig_path))
  235. return true;
  236. else
  237. return false;
  238. }
  239. /*
  240. * Check if the uninstall file is renamed to .php
  241. */
  242. protected function check_for_uninstall_file() {
  243. if (file_exists(dirname( __FILE__ ) . '/force-deactivate.php')) {
  244. $this->errors["DEACTIVATE_FILE_NOT_RENAMED"] = true;
  245. }
  246. }
  247. /**
  248. * Get the options for this plugin
  249. *
  250. * @since 2.0
  251. *
  252. * @access public
  253. *
  254. */
  255. public function get_admin_options(){
  256. $options = get_option('rlrsssl_options');
  257. if (isset($options)) {
  258. $this->site_has_ssl = isset($options['site_has_ssl']) ? $options['site_has_ssl'] : FALSE;
  259. $this->hsts = isset($options['hsts']) ? $options['hsts'] : FALSE;
  260. $this->htaccess_warning_shown = isset($options['htaccess_warning_shown']) ? $options['htaccess_warning_shown'] : FALSE;
  261. $this->ssl_success_message_shown = isset($options['ssl_success_message_shown']) ? $options['ssl_success_message_shown'] : FALSE;
  262. $this->plugin_db_version = isset($options['plugin_db_version']) ? $options['plugin_db_version'] : "1.0";
  263. $this->debug = isset($options['debug']) ? $options['debug'] : FALSE;
  264. $this->do_not_edit_htaccess = isset($options['do_not_edit_htaccess']) ? $options['do_not_edit_htaccess'] : FALSE;
  265. $this->htaccess_redirect = isset($options['htaccess_redirect']) ? $options['htaccess_redirect'] : FALSE;
  266. $this->switch_mixed_content_fixer_hook = isset($options['switch_mixed_content_fixer_hook']) ? $options['switch_mixed_content_fixer_hook'] : FALSE;
  267. $this->debug_log = isset($options['debug_log']) ? $options['debug_log'] : $this->debug_log;
  268. }
  269. if (is_multisite()) {
  270. $network_options = get_site_option('rlrsssl_network_options');
  271. $network_htaccess_redirect = isset($network_options["htaccess_redirect"]) ? $network_options["htaccess_redirect"] : false;
  272. $network_do_not_edit_htaccess = isset($network_options["do_not_edit_htaccess"]) ? $network_options["do_not_edit_htaccess"] : false;
  273. /*
  274. If multiste, and networkwide, only the networkwide setting counts.
  275. if multisite, and per site, only the networkwide setting counts if it is true.
  276. */
  277. $ssl_enabled_networkwide = isset($network_options["ssl_enabled_networkwide"]) ? $network_options["ssl_enabled_networkwide"] : false;
  278. if ($ssl_enabled_networkwide) {
  279. $this->htaccess_redirect = $network_htaccess_redirect;
  280. $this->do_not_edit_htaccess = $network_do_not_edit_htaccess;
  281. } else {
  282. if ($network_do_not_edit_htaccess) $this->do_not_edit_htaccess = $network_do_not_edit_htaccess;
  283. if ($network_htaccess_redirect) $this->htaccess_redirect = $network_htaccess_redirect;
  284. }
  285. }
  286. //if the define is true, it overrides the db setting.
  287. if (defined( 'RLRSSSL_DO_NOT_EDIT_HTACCESS')) {
  288. $this->do_not_edit_htaccess = RLRSSSL_DO_NOT_EDIT_HTACCESS;
  289. }
  290. }
  291. /**
  292. * Creates an array of all domains where the plugin is active AND SSL is active, only used for multisite.
  293. *
  294. * @since 2.1
  295. *
  296. * @access public
  297. *
  298. */
  299. public function build_domain_list() {
  300. if (!is_multisite()) return;
  301. //create list of all activated sites with SSL
  302. $this->sites = array();
  303. $sites = $this->get_sites_bw_compatible();
  304. if ($this->debug) $this->trace_log("building domain list for multisite...");
  305. foreach ( $sites as $site ) {
  306. $this->switch_to_blog_bw_compatible($site);
  307. $options = get_option('rlrsssl_options');
  308. $ssl_enabled = FALSE;
  309. if (isset($options)) {
  310. $site_has_ssl = isset($options['site_has_ssl']) ? $options['site_has_ssl'] : FALSE;
  311. $ssl_enabled = isset($options['ssl_enabled']) ? $options['ssl_enabled'] : $site_has_ssl;
  312. }
  313. if (is_plugin_active(rsssl_plugin) && $ssl_enabled) {
  314. if ($this->debug) $this->trace_log("adding: ".home_url());
  315. $this->sites[] = home_url();
  316. }
  317. restore_current_blog(); //switches back to previous blog, not current, so we have to do it each loop
  318. }
  319. $this->save_options();
  320. }
  321. /**
  322. * check if the plugin was upgraded to a new version
  323. *
  324. * @since 2.1
  325. *
  326. * @access public
  327. *
  328. */
  329. public function get_plugin_upgraded() {
  330. if ($this->plugin_db_version!= rsssl_version) {
  331. $this->plugin_db_version = rsssl_version;
  332. $this->plugin_upgraded = true;
  333. $this->save_options();
  334. }
  335. $this->plugin_upgraded = false;
  336. }
  337. /**
  338. * Log events during plugin execution
  339. *
  340. * @since 2.1
  341. *
  342. * @access public
  343. *
  344. */
  345. public function trace_log($msg) {
  346. if (!$this->debug) return;
  347. $this->debug_log = $this->debug_log."<br>".$msg;
  348. $this->debug_log = strstr($this->debug_log,'** Detecting configuration **');
  349. error_log($msg);
  350. }
  351. /**
  352. * Configures the site for SSL
  353. *
  354. * @since 2.2
  355. *
  356. * @access public
  357. *
  358. */
  359. public function configure_ssl() {
  360. if (!current_user_can($this->capability)) return;
  361. $safe_mode = FALSE;
  362. if (defined('RSSSL_SAFE_MODE') && RSSSL_SAFE_MODE) $safe_mode = RSSSL_SAFE_MODE;
  363. if (!current_user_can($this->capability)) return;
  364. $this->trace_log("** Configuring SSL **");
  365. if ($this->site_has_ssl) {
  366. //when one of the used server variables was found, test if the redirect works
  367. if (RSSSL()->rsssl_server->uses_htaccess() && $this->ssl_type != "NA")
  368. $this->test_htaccess_redirect();
  369. //in a configuration reverse proxy without a set server variable https, add code to wpconfig
  370. if ($this->do_wpconfig_loadbalancer_fix){
  371. $this->wpconfig_loadbalancer_fix();
  372. }
  373. if ($this->no_server_variable)
  374. $this->wpconfig_server_variable_fix();
  375. if (!$safe_mode) {
  376. $this->editHtaccess();
  377. }
  378. if (!$safe_mode && $this->clicked_activate_ssl()) {
  379. $this->wp_redirect = TRUE;
  380. $this->save_options();
  381. }
  382. if (!$safe_mode && $this->wpconfig_siteurl_not_fixed)
  383. $this->fix_siteurl_defines_in_wpconfig();
  384. if (!$safe_mode) {
  385. $this->set_siteurl_to_ssl();
  386. }
  387. }
  388. }
  389. /**
  390. * Check to see if we are on the settings page, action hook independent
  391. *
  392. * @since 2.1
  393. *
  394. * @access public
  395. *
  396. */
  397. public function is_settings_page() {
  398. if (!isset($_SERVER['QUERY_STRING'])) return false;
  399. parse_str($_SERVER['QUERY_STRING'], $params);
  400. if (array_key_exists("page", $params) && ($params["page"]=="rlrsssl_really_simple_ssl")) {
  401. return true;
  402. }
  403. return false;
  404. }
  405. /**
  406. * Find the path to wp-config
  407. *
  408. * @since 2.1
  409. *
  410. * @access public
  411. *
  412. */
  413. public function find_wp_config_path() {
  414. //limit nr of iterations to 20
  415. $i=0;
  416. $maxiterations = 20;
  417. $dir = dirname(__FILE__);
  418. do {
  419. $i++;
  420. if( file_exists($dir."/wp-config.php") ) {
  421. return $dir."/wp-config.php";
  422. }
  423. } while( ($dir = realpath("$dir/..")) && ($i<$maxiterations) );
  424. return null;
  425. }
  426. /**
  427. * remove https from defined siteurl and homeurl in the wpconfig, if present
  428. *
  429. * @since 2.1
  430. *
  431. * @access public
  432. *
  433. */
  434. public function remove_ssl_from_siteurl_in_wpconfig() {
  435. if (!current_user_can($this->capability)) return;
  436. $wpconfig_path = $this->find_wp_config_path();
  437. if (!empty($wpconfig_path)) {
  438. $wpconfig = file_get_contents($wpconfig_path);
  439. $homeurl_pos = strpos($wpconfig, "define('WP_HOME','https://");
  440. $siteurl_pos = strpos($wpconfig, "define('WP_SITEURL','https://");
  441. if (($homeurl_pos !== false) || ($siteurl_pos !== false)) {
  442. if (is_writable($wpconfig_path)) {
  443. $search_array = array("define('WP_HOME','https://","define('WP_SITEURL','https://");
  444. $ssl_array = array("define('WP_HOME','http://","define('WP_SITEURL','http://");
  445. //now replace these urls
  446. $wpconfig = str_replace ($search_array , $ssl_array , $wpconfig);
  447. file_put_contents($wpconfig_path, $wpconfig);
  448. } else {
  449. $this->errors['wpconfig not writable'] = TRUE;
  450. }
  451. }
  452. }
  453. }
  454. /**
  455. *
  456. * Checks if the wp config contains any defined siteurl and homeurl
  457. *
  458. *
  459. */
  460. private function check_for_siteurl_in_wpconfig(){
  461. $wpconfig_path = $this->find_wp_config_path();
  462. if (empty($wpconfig_path)) return;
  463. $wpconfig = file_get_contents($wpconfig_path);
  464. $homeurl_pattern = '/(define\(\s*\'WP_HOME\'\s*,\s*\'http\:\/\/)/';
  465. $siteurl_pattern = '/(define\(\s*\'WP_SITEURL\'\s*,\s*\'http\:\/\/)/';
  466. $this->wpconfig_siteurl_not_fixed = FALSE;
  467. if (preg_match($homeurl_pattern, $wpconfig) || preg_match($siteurl_pattern, $wpconfig) ) {
  468. $this->wpconfig_siteurl_not_fixed = TRUE;
  469. $this->trace_log("siteurl or home url defines found in wpconfig");
  470. }
  471. }
  472. /**
  473. * Runs only when siteurl or homeurl define was found in the wpconfig, with the check_for_siteurl_in_wpconfig function
  474. * and only when wpconfig is writable.
  475. *
  476. * @since 2.1
  477. *
  478. * @access public
  479. *
  480. */
  481. private function fix_siteurl_defines_in_wpconfig() {
  482. $wpconfig_path = $this->find_wp_config_path();
  483. if (empty($wpconfig_path)) return;
  484. $wpconfig = file_get_contents($wpconfig_path);
  485. $homeurl_pattern = '/(define\(\s*\'WP_HOME\'\s*,\s*\'http\:\/\/)/';
  486. $siteurl_pattern = '/(define\(\s*\'WP_SITEURL\'\s*,\s*\'http\:\/\/)/';
  487. if (preg_match($homeurl_pattern, $wpconfig) || preg_match($siteurl_pattern, $wpconfig) ) {
  488. if (is_writable($wpconfig_path)) {
  489. $this->trace_log("wp config siteurl/homeurl edited.");
  490. $wpconfig = preg_replace($homeurl_pattern, "define('WP_HOME','https://", $wpconfig);
  491. $wpconfig = preg_replace($siteurl_pattern, "define('WP_SITEURL','https://", $wpconfig);
  492. file_put_contents($wpconfig_path, $wpconfig);
  493. }
  494. else {
  495. if ($this->debug) {$this->trace_log("not able to fix wpconfig siteurl/homeurl.");}
  496. //only when siteurl or homeurl is defined in wpconfig, and wpconfig is not writable is there a possible issue because we cannot edit the defined urls.
  497. $this->wpconfig_siteurl_not_fixed = TRUE;
  498. }
  499. } else {
  500. if ($this->debug) {$this->trace_log("no siteurl/homeurl defines in wpconfig");}
  501. }
  502. }
  503. /**
  504. * Check if the wpconfig is already fixed
  505. *
  506. * @since 2.2
  507. *
  508. * @access public
  509. *
  510. */
  511. public function wpconfig_has_fixes() {
  512. $wpconfig_path = $this->find_wp_config_path();
  513. if (empty($wpconfig_path)) return false;
  514. $wpconfig = file_get_contents($wpconfig_path);
  515. //only one of two fixes possible.
  516. if (strpos($wpconfig, "//Begin Really Simple SSL Load balancing fix")!==FALSE ) {
  517. return true;
  518. }
  519. if (strpos($wpconfig, "//Begin Really Simple SSL Server variable fix")!==FALSE ) {
  520. return true;
  521. }
  522. return false;
  523. }
  524. /**
  525. * In case of load balancer without server https on, add fix in wp-config
  526. *
  527. * @since 2.1
  528. *
  529. * @access public
  530. *
  531. */
  532. public function wpconfig_loadbalancer_fix() {
  533. if (!current_user_can($this->capability)) return;
  534. $wpconfig_path = $this->find_wp_config_path();
  535. if (empty($wpconfig_path)) return;
  536. $wpconfig = file_get_contents($wpconfig_path);
  537. $this->wpconfig_loadbalancer_fix_failed = FALSE;
  538. //only if loadbalancer AND NOT SERVER-HTTPS-ON should the following be added. (is_ssl = false)
  539. if (strpos($wpconfig, "//Begin Really Simple SSL Load balancing fix")===FALSE ) {
  540. if (is_writable($wpconfig_path)) {
  541. $rule = "\n"."//Begin Really Simple SSL Load balancing fix"."\n";
  542. $rule .= '$server_opts = array("HTTP_CLOUDFRONT_FORWARDED_PROTO" => "https", "HTTP_CF_VISITOR"=>"https", "HTTP_X_FORWARDED_PROTO"=>"https", "HTTP_X_FORWARDED_SSL"=>"on", "HTTP_X_FORWARDED_SSL"=>"1");'."\n";
  543. $rule .= 'foreach( $server_opts as $option => $value ) {'."\n";
  544. $rule .= 'if ( (isset($_ENV["HTTPS"]) && ( "on" == $_ENV["HTTPS"] )) || (isset( $_SERVER[ $option ] ) && ( strpos( $_SERVER[ $option ], $value ) !== false )) ) {'."\n";
  545. $rule .= '$_SERVER[ "HTTPS" ] = "on";'."\n";
  546. $rule .= 'break;'."\n";
  547. $rule .= '}'."\n";
  548. $rule .= '}'."\n";
  549. $rule .= "//END Really Simple SSL"."\n";
  550. $insert_after = "<?php";
  551. $pos = strpos($wpconfig, $insert_after);
  552. if ($pos !== false) {
  553. $wpconfig = substr_replace($wpconfig,$rule,$pos+1+strlen($insert_after),0);
  554. }
  555. file_put_contents($wpconfig_path, $wpconfig);
  556. if ($this->debug) {$this->trace_log("wp config loadbalancer fix inserted");}
  557. } else {
  558. if ($this->debug) {$this->trace_log("wp config loadbalancer fix FAILED");}
  559. $this->wpconfig_loadbalancer_fix_failed = TRUE;
  560. }
  561. } else {
  562. if ($this->debug) {$this->trace_log("wp config loadbalancer fix already in place, great!");}
  563. }
  564. $this->save_options();
  565. }
  566. /**
  567. * Getting WordPress to recognize setup as being SSL when no https server variable is available
  568. *
  569. * @since 2.1
  570. *
  571. * @access public
  572. *
  573. */
  574. public function wpconfig_server_variable_fix() {
  575. if (!current_user_can($this->capability)) return;
  576. $wpconfig_path = $this->find_wp_config_path();
  577. if (empty($wpconfig_path)) return;
  578. $wpconfig = file_get_contents($wpconfig_path);
  579. //check permissions
  580. if (!is_writable($wpconfig_path)) {
  581. if ($this->debug) $this->trace_log("wp-config.php not writable");
  582. return;
  583. }
  584. //when more than one blog, first remove what we have
  585. if (is_multisite() && !RSSSL()->rsssl_multisite->is_multisite_subfolder_install() && !RSSSL()->rsssl_multisite->ssl_enabled_networkwide && count($this->sites)>1) {
  586. $wpconfig = preg_replace("/\/\/Begin\s?Really\s?Simple\s?SSL.*?\/\/END\s?Really\s?Simple\s?SSL/s", "", $wpconfig);
  587. $wpconfig = preg_replace("/\n+/","\n", $wpconfig);
  588. file_put_contents($wpconfig_path, $wpconfig);
  589. }
  590. //now create new
  591. //check if the fix is already there
  592. if (strpos($wpconfig, "//Begin Really Simple SSL Server variable fix")!==FALSE ) {
  593. if ($this->debug) {$this->trace_log("wp config server variable fix already in place, great!");}
  594. return;
  595. }
  596. if ($this->debug) {$this->trace_log("Adding server variable to wpconfig");}
  597. $rule = $this->get_server_variable_fix_code();
  598. $insert_after = "<?php";
  599. $pos = strpos($wpconfig, $insert_after);
  600. if ($pos !== false) {
  601. $wpconfig = substr_replace($wpconfig,$rule,$pos+1+strlen($insert_after),0);
  602. }
  603. file_put_contents($wpconfig_path, $wpconfig);
  604. if ($this->debug) $this->trace_log("wp config server variable fix inserted");
  605. $this->save_options();
  606. }
  607. protected function get_server_variable_fix_code(){
  608. if (is_multisite() && !RSSSL()->rsssl_multisite->ssl_enabled_networkwide && RSSSL()->rsssl_multisite->is_multisite_subfolder_install()) {
  609. if ($this->debug) $this->trace_log("per site activation on subfolder install, wp config server variable fix skipped");
  610. return "";
  611. }
  612. if (is_multisite() && !RSSSL()->rsssl_multisite->ssl_enabled_networkwide && count($this->sites)==0) {
  613. if ($this->debug) $this->trace_log("no sites left with SSL, wp config server variable fix skipped");
  614. return "";
  615. }
  616. if (is_multisite() && !RSSSL()->rsssl_multisite->ssl_enabled_networkwide) {
  617. $rule = "\n"."//Begin Really Simple SSL Server variable fix"."\n";
  618. foreach ($this->sites as $domain ) {
  619. //remove http or https.
  620. if ($this->debug) {$this->trace_log("getting server variable rule for:".$domain);}
  621. $domain = preg_replace("/(http:\/\/|https:\/\/)/","",$domain);
  622. //we excluded subfolders, so treat as domain
  623. //check only for domain without www, as the www variant is found as well with the no www search.
  624. $domain_no_www = str_replace ( "www." , "" , $domain);
  625. $rule .= 'if ( strpos($_SERVER["HTTP_HOST"], "'.$domain_no_www.'")!==FALSE ) {'."\n";
  626. $rule .= ' $_SERVER["HTTPS"] = "on";'."\n";
  627. $rule .= '}'."\n";
  628. }
  629. $rule .= "//END Really Simple SSL"."\n";
  630. } else {
  631. $rule = "\n"."//Begin Really Simple SSL Server variable fix"."\n";
  632. $rule .= '$_SERVER["HTTPS"] = "on";'."\n";
  633. $rule .= "//END Really Simple SSL"."\n";
  634. }
  635. return $rule;
  636. }
  637. /**
  638. * Removing changes made to the wpconfig
  639. *
  640. * @since 2.1
  641. *
  642. * @access public
  643. *
  644. */
  645. public function remove_wpconfig_edit() {
  646. $wpconfig_path = $this->find_wp_config_path();
  647. if (empty($wpconfig_path)) return;
  648. $wpconfig = file_get_contents($wpconfig_path);
  649. //check for permissions
  650. if (!is_writable($wpconfig_path)) {
  651. if ($this->debug) $this->trace_log("could not remove wpconfig edits, wp-config.php not writable");
  652. $this->errors['wpconfig not writable'] = TRUE;
  653. return;
  654. }
  655. //remove edits
  656. $wpconfig = preg_replace("/\/\/Begin\s?Really\s?Simple\s?SSL.*?\/\/END\s?Really\s?Simple\s?SSL/s", "", $wpconfig);
  657. $wpconfig = preg_replace("/\n+/","\n", $wpconfig);
  658. file_put_contents($wpconfig_path, $wpconfig);
  659. //in multisite environment, with per site activation, re-add
  660. if (is_multisite() && ! RSSSL()->rsssl_multisite->ssl_enabled_networkwide) {
  661. if ($this->do_wpconfig_loadbalancer_fix)
  662. $this->wpconfig_loadbalancer_fix();
  663. if ($this->no_server_variable)
  664. $this->wpconfig_server_variable_fix();
  665. }
  666. }
  667. /**
  668. * Changes the siteurl and homeurl to https
  669. *
  670. * @since 2.0
  671. *
  672. * @access public
  673. *
  674. */
  675. public function set_siteurl_to_ssl() {
  676. if (!current_user_can($this->capability)) return;
  677. $this->trace_log("converting siteurl and homeurl to https");
  678. $siteurl_ssl = str_replace ( "http://" , "https://" , get_option('siteurl'));
  679. $homeurl_ssl = str_replace ( "http://" , "https://" , get_option('home'));
  680. update_option('siteurl',$siteurl_ssl);
  681. update_option('home',$homeurl_ssl);
  682. }
  683. /**
  684. * On de-activation, siteurl and homeurl are reset to http
  685. *
  686. * @since 2.0
  687. *
  688. * @access public
  689. *
  690. */
  691. public function remove_ssl_from_siteurl() {
  692. $siteurl_no_ssl = str_replace ( "https://" , "http://" , get_option('siteurl'));
  693. $homeurl_no_ssl = str_replace ( "https://" , "http://" , get_option('home'));
  694. update_option('siteurl',$siteurl_no_ssl);
  695. update_option('home',$homeurl_no_ssl);
  696. }
  697. /**
  698. * Save the plugin options
  699. *
  700. * @since 2.0
  701. *
  702. * @access public
  703. *
  704. */
  705. public function save_options() {
  706. if (!current_user_can($this->capability)) return;
  707. //any options added here should also be added to function options_validate()
  708. $options = array(
  709. 'site_has_ssl' => $this->site_has_ssl,
  710. 'hsts' => $this->hsts,
  711. 'htaccess_warning_shown' => $this->htaccess_warning_shown,
  712. 'ssl_success_message_shown' => $this->ssl_success_message_shown,
  713. 'autoreplace_insecure_links' => $this->autoreplace_insecure_links,
  714. 'plugin_db_version' => $this->plugin_db_version,
  715. 'debug' => $this->debug,
  716. 'do_not_edit_htaccess' => $this->do_not_edit_htaccess,
  717. 'htaccess_redirect' => $this->htaccess_redirect,
  718. 'ssl_enabled' => $this->ssl_enabled,
  719. 'javascript_redirect' => $this->javascript_redirect,
  720. 'wp_redirect' => $this->wp_redirect,
  721. 'switch_mixed_content_fixer_hook' => $this->switch_mixed_content_fixer_hook,
  722. );
  723. update_option('rlrsssl_options',$options);
  724. }
  725. /**
  726. * Load the translation files
  727. *
  728. * @since 1.0
  729. *
  730. * @access public
  731. *
  732. */
  733. public function load_translation()
  734. {
  735. load_plugin_textdomain('really-simple-ssl', FALSE, dirname(plugin_basename(__FILE__)).'/languages/');
  736. }
  737. /**
  738. * Handles deactivation of this plugin
  739. *
  740. * @since 2.0
  741. *
  742. * @access public
  743. *
  744. */
  745. public function deactivate($networkwide) {
  746. $this->remove_ssl_from_siteurl();
  747. $this->remove_ssl_from_siteurl_in_wpconfig();
  748. $this->site_has_ssl = FALSE;
  749. $this->hsts = FALSE;
  750. $this->htaccess_warning_shown = FALSE;
  751. $this->ssl_success_message_shown = FALSE;
  752. $this->autoreplace_insecure_links = TRUE;
  753. $this->do_not_edit_htaccess = FALSE;
  754. $this->htaccess_redirect = FALSE;
  755. $this->javascript_redirect = FALSE;
  756. $this->wp_redirect = FALSE;
  757. $this->ssl_enabled = FALSE;
  758. $this->switch_mixed_content_fixer_hook = FALSE;
  759. $this->save_options();
  760. //when on multisite, per site activation, recreate domain list for htaccess and wpconfig rewrite actions
  761. if (is_multisite()) {
  762. RSSSL()->rsssl_multisite->deactivate();
  763. if (!RSSSL()->rsssl_multisite->ssl_enabled_networkwide) $this->build_domain_list();
  764. }
  765. $this->remove_wpconfig_edit();
  766. $this->removeHtaccessEdit();
  767. }
  768. /**
  769. * Checks if we are currently on SSL protocol, but extends standard wp with loadbalancer check.
  770. *
  771. * @since 2.0
  772. *
  773. * @access public
  774. *
  775. */
  776. public function is_ssl_extended(){
  777. $server_var = FALSE;
  778. $server_opts = array(
  779. 'HTTP_X_FORWARDED_PROTO'=>'https',
  780. 'HTTP_CLOUDFRONT_FORWARDED_PROTO' => 'https',
  781. 'HTTP_CF_VISITOR'=>'https',
  782. 'HTTP_X_FORWARDED_SSL'=>'on',
  783. 'HTTP_X_FORWARDED_SSL'=>'1'
  784. );
  785. foreach( $server_opts as $option => $value ) {
  786. if ( (isset($_ENV['HTTPS']) && ( 'on' == $_ENV['HTTPS'] ))
  787. || (isset( $_SERVER[ $option ] ) && ( strpos( $_SERVER[ $option ], $value ) !== false ) )) {
  788. $server_var = TRUE;
  789. break;
  790. }
  791. }
  792. if (is_ssl() || $server_var){
  793. return true;
  794. } else {
  795. return false;
  796. }
  797. }
  798. /**
  799. * Checks for SSL by opening a test page in the plugin directory
  800. *
  801. * @since 2.0
  802. *
  803. * @access public
  804. *
  805. */
  806. public function detect_configuration() {
  807. $this->trace_log("** Detecting configuration **");
  808. $this->trace_log("plugin version: ".rsssl_version);
  809. $old_ssl_setting = $this->site_has_ssl;
  810. $filecontents = "";
  811. //if current page is on SSL, we can assume SSL is available, even when an errormsg was returned
  812. if($this->is_ssl_extended()){
  813. $this->trace_log("Already on SSL, start detecting configuration");
  814. $this->site_has_ssl = TRUE;
  815. } else {
  816. //we're not on SSL, or no server vars were returned, so test with the test-page.
  817. //plugin url: domain.com/wp-content/etc
  818. $testpage_url = trailingslashit($this->test_url())."ssl-test-page.php";
  819. $this->trace_log("Opening testpage to check for SSL: ".$testpage_url);
  820. $response = wp_remote_get( $testpage_url );
  821. if( is_array($response) ) {
  822. $status = wp_remote_retrieve_response_code( $response );
  823. $filecontents = wp_remote_retrieve_body($response);
  824. }
  825. $this->trace_log("test page url, enter in browser to check manually: ".$testpage_url);
  826. if(!is_wp_error( $response ) && (strpos($filecontents, "#SSL TEST PAGE#") !== false)) {
  827. $this->site_has_ssl = TRUE;
  828. $this->trace_log("SSL test page loaded successfully");
  829. } else {
  830. $this->site_has_ssl = FALSE;
  831. $error = "";
  832. if (is_wp_error( $response ) ) $error = $response->get_error_message();
  833. $this->trace_log("No SSL detected. No certificate, or the testpage is blocked by security settings. The SSL testpage returned the error: ".$error);
  834. }
  835. }
  836. if ($this->site_has_ssl) {
  837. //check the type of SSL, either by parsing the returned string, or by reading the server vars.
  838. if ((strpos($filecontents, "#CLOUDFRONT#") !== false) || (isset($_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO']) && ($_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'] == 'https'))) {
  839. $this->ssl_type = "CLOUDFRONT";
  840. } elseif ((strpos($filecontents, "#CLOUDFLARE#") !== false) || (isset($_SERVER['HTTP_CF_VISITOR']) && ($_SERVER['HTTP_CF_VISITOR'] == 'https'))) {
  841. $this->ssl_type = "CLOUDFLARE";
  842. } elseif ((strpos($filecontents, "#LOADBALANCER#") !== false) || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))) {
  843. $this->ssl_type = "LOADBALANCER";
  844. } elseif ((strpos($filecontents, "#CDN#") !== false) || (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && ($_SERVER['HTTP_X_FORWARDED_SSL'] == 'on' || $_SERVER['HTTP_X_FORWARDED_SSL'] == '1'))) {
  845. $this->ssl_type = "CDN";
  846. } elseif ((strpos($filecontents, "#SERVER-HTTPS-ON#") !== false) || (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on')) {
  847. $this->ssl_type = "SERVER-HTTPS-ON";
  848. } elseif ((strpos($filecontents, "#SERVER-HTTPS-1#") !== false) || (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == '1')) {
  849. $this->ssl_type = "SERVER-HTTPS-1";
  850. } elseif ((strpos($filecontents, "#SERVERPORT443#") !== false) || (isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ))) {
  851. $this->ssl_type = "SERVERPORT443";
  852. } elseif ((strpos($filecontents, "#ENVHTTPS#") !== false) || (isset($_ENV['HTTPS']) && ( 'on' == $_ENV['HTTPS'] ))) {
  853. $this->ssl_type = "ENVHTTPS";
  854. } elseif ((strpos($filecontents, "#NO KNOWN SSL CONFIGURATION DETECTED#") !== false)) {
  855. //if we are here, SSL was detected, but without any known server variables set.
  856. //So we can use this info to set a server variable ourselfes.
  857. if (!$this->wpconfig_has_fixes()) {
  858. $this->no_server_variable = TRUE;
  859. }
  860. $this->trace_log("No server variable detected ");
  861. $this->ssl_type = "NA";
  862. } else {
  863. //no valid response, so set to NA
  864. $this->ssl_type = "NA";
  865. }
  866. //check for is_ssl()
  867. if ( (!$this->is_ssl_extended() &&
  868. (strpos($filecontents, "#SERVER-HTTPS-ON#") === false) &&
  869. (strpos($filecontents, "#SERVER-HTTPS-1#") === false) &&
  870. (strpos($filecontents, "#SERVERPORT443#") === false)) || (!is_ssl() && $this->is_ssl_extended())) {
  871. //when is_ssl would return false, we should add some code to wp-config.php
  872. if (!$this->wpconfig_has_fixes()) {
  873. $this->trace_log("is_ssl() will return false: wp-config fix needed");
  874. $this->do_wpconfig_loadbalancer_fix = TRUE;
  875. }
  876. }
  877. $this->trace_log("SSL type: ".$this->ssl_type);
  878. }
  879. $this->check_for_siteurl_in_wpconfig();
  880. $this->save_options();
  881. }
  882. /**
  883. * Test if the htaccess redirect will work
  884. * This way, no redirect loops should occur.
  885. *
  886. * @since 2.1
  887. *
  888. * @access public
  889. *
  890. */
  891. public function test_htaccess_redirect() {
  892. if (!current_user_can($this->capability)) return;
  893. if ($this->debug) {$this->trace_log("testing htaccess rules...");}
  894. $filecontents = "";
  895. $testpage_url = trailingslashit($this->test_url())."testssl/";
  896. switch ($this->ssl_type) {
  897. case "CLOUDFRONT":
  898. $testpage_url .= "cloudfront";
  899. break;
  900. case "CLOUDFLARE":
  901. $testpage_url .= "cloudflare";
  902. break;
  903. case "LOADBALANCER":
  904. $testpage_url .= "loadbalancer";
  905. break;
  906. case "CDN":
  907. $testpage_url .= "cdn";
  908. break;
  909. case "SERVER-HTTPS-ON":
  910. $testpage_url .= "serverhttpson";
  911. break;
  912. case "SERVER-HTTPS-1":
  913. $testpage_url .= "serverhttps1";
  914. break;
  915. case "SERVERPORT443":
  916. $testpage_url .= "serverport443";
  917. break;
  918. case "ENVHTTPS":
  919. $testpage_url .= "envhttps";
  920. break;
  921. }
  922. $testpage_url .= ("/ssl-test-page.html");
  923. $response = wp_remote_get( $testpage_url );
  924. if( is_array($response) ) {
  925. $status = wp_remote_retrieve_response_code( $response );
  926. $filecontents = wp_remote_retrieve_body($response);
  927. }
  928. $this->trace_log("test page url, enter in browser to check manually: ".$testpage_url);
  929. if (!is_wp_error( $response ) && (strpos($filecontents, "#SSL TEST PAGE#") !== false)) {
  930. $this->htaccess_test_success = TRUE;
  931. $this->trace_log("htaccess rules tested successfully.");
  932. } else {
  933. //.htaccess rewrite rule seems to be giving problems.
  934. $this->htaccess_test_success = FALSE;
  935. if (is_wp_error( $response )) {
  936. $this->trace_log("htaccess rules test failed with error: ".$response->get_error_message());
  937. } else {
  938. $this->trace_log("htaccess test rules failed. Set WordPress redirect in settings/SSL");
  939. }
  940. }
  941. }
  942. /**
  943. * Get an url with which we can test the SSL connection and htaccess redirect rules.
  944. *
  945. * @since 2.0
  946. *
  947. * @access public
  948. *
  949. */
  950. public function test_url(){
  951. $plugin_url = str_replace("http://", "https://", trailingslashit(rsssl_url) );;
  952. $https_home_url = str_replace("http://", "https://", home_url());
  953. //in some case we get a relative url here, so we check that.
  954. //we compare to urls replaced to https, in case one of them is still on http.
  955. if ( (strpos($plugin_url, "https://")===FALSE ) &&
  956. (strpos($plugin_url, $https_home_url)===FALSE)
  957. ) {
  958. //make sure we do not have a slash at the start
  959. $plugin_url = ltrim($plugin_url,"/");
  960. $plugin_url = trailingslashit(home_url()).$plugin_url;
  961. }
  962. //for subdomains or domain mapping situations, we have to convert the plugin_url from main site to the subdomain url.
  963. if (is_multisite() && ( !is_main_site(get_current_blog_id()) ) && (! RSSSL()->rsssl_multisite->is_multisite_subfolder_install()) ) {
  964. $mainsiteurl = trailingslashit(str_replace("http://","https://",network_site_url()));
  965. $home = trailingslashit($https_home_url);
  966. $plugin_url = str_replace($mainsiteurl, $home, $plugin_url);
  967. //return http link if original url is http.
  968. //if (strpos(home_url(), "https://")===FALSE) $plugin_url = str_replace("https://","http://",$plugin_url);
  969. }
  970. return $plugin_url;
  971. }
  972. /**
  973. * removes the added redirect to https rules to the .htaccess file.
  974. *
  975. * @since 2.0
  976. *
  977. * @access public
  978. *
  979. */
  980. public function removeHtaccessEdit() {
  981. if(file_exists($this->ABSpath.".htaccess") && is_writable($this->ABSpath.".htaccess")){
  982. $htaccess = file_get_contents($this->ABSpath.".htaccess");
  983. //if multisite, per site activation and more than one blog remaining on ssl, remove condition for this site only
  984. //the domain list has been rebuilt already, so current site is already removed.
  985. if (is_multisite() && ! RSSSL()->rsssl_multisite->ssl_enabled_networkwide && count($this->sites)>0) {
  986. //remove http or https.
  987. $domain = preg_replace("/(http:\/\/|https:\/\/)/","",home_url());
  988. $pattern = "/#wpmu\srewritecond\s?".preg_quote($domain, "/")."\n.*?#end\swpmu\srewritecond\s?".preg_quote($domain, "/")."\n/s";
  989. //only remove if the pattern is there at all
  990. if (preg_match($pattern, $htaccess)) $htaccess = preg_replace($pattern, "", $htaccess);
  991. //now replace any remaining "or" on the last condition.
  992. $pattern = "/(\[OR\])(?!.*(\[OR\]|#start).*?RewriteRule)/s";
  993. $htaccess = preg_replace($pattern, "", $htaccess,1);
  994. } else {
  995. // remove everything
  996. $pattern = "/#\s?BEGIN\s?rlrssslReallySimpleSSL.*?#\s?END\s?rlrssslReallySimpleSSL/s";
  997. //only remove if the pattern is there at all
  998. if (preg_match($pattern, $htaccess)) $htaccess = preg_replace($pattern, "", $htaccess);
  999. }
  1000. $htaccess = preg_replace("/\n+/","\n", $htaccess);
  1001. file_put_contents($this->ABSpath.".htaccess", $htaccess);
  1002. $this->save_options();
  1003. } else {
  1004. $this->errors['HTACCESS_NOT_WRITABLE'] = TRUE;
  1005. if ($this->debug) $this->trace_log("could not remove rules from htaccess, file not writable");
  1006. }
  1007. }
  1008. public function get_htaccess_version() {
  1009. if (!file_exists($this->ABSpath.".htaccess")) return false;
  1010. $htaccess = file_get_contents($this->ABSpath.".htaccess");
  1011. $versionpos = strpos($htaccess, "rsssl_version");
  1012. if ($versionpos===false) {
  1013. //no version found, so not .htaccess rules.
  1014. return false;
  1015. } else {
  1016. //find closing marker of version
  1017. $close = strpos($htaccess, "]", $versionpos);
  1018. $version = substr($htaccess, $versionpos+14, $close-($versionpos+14));
  1019. return $version;
  1020. }
  1021. }
  1022. /* deprecated */
  1023. function htaccess_redirect_allowed(){
  1024. if (is_multisite() && RSSSL()->rsssl_multisite->is_per_site_activated_multisite_subfolder_install()) {
  1025. return false;
  1026. } else {
  1027. return true;
  1028. }
  1029. }
  1030. /*
  1031. Checks if the htaccess contains redirect rules, either actual redirect or a rsssl marker.
  1032. */
  1033. public function htaccess_contains_redirect_rules() {
  1034. if (!file_exists($this->ABSpath.".htaccess")) {
  1035. return false;
  1036. }
  1037. $htaccess = file_get_contents($this->ABSpath.".htaccess");
  1038. $needle = "RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]";
  1039. if(strpos($htaccess, $needle) !== FALSE || $this->contains_rsssl_rules()){
  1040. return true;
  1041. } else {
  1042. $this->trace_log(".htaccess does not contain default Really Simple SSL redirect");
  1043. return false;
  1044. }
  1045. }
  1046. /*
  1047. * Checks if the htaccess contains the Really Simple SSL comment.
  1048. *
  1049. */
  1050. public function contains_rsssl_rules() {
  1051. if (!file_exists($this->ABSpath.".htaccess")) {
  1052. return false;
  1053. }
  1054. $htaccess = file_get_contents($this->ABSpath.".htaccess");
  1055. $check=null;
  1056. preg_match("/BEGIN rlrssslReallySimpleSSL/", $htaccess, $check);
  1057. if(count($check) === 0){
  1058. return false;
  1059. } else {
  1060. return true;
  1061. }
  1062. }
  1063. /*
  1064. * Checks if a 301 redirect is set
  1065. * this is the case if either the wp_redirect is set, or the htaccess redirect is set.
  1066. *
  1067. */
  1068. public function has_301_redirect() {
  1069. if ($this->wp_redirect) return true;
  1070. if (RSSSL()->rsssl_server->uses_htaccess() && $this->htaccess_contains_redirect_rules() ) {
  1071. return true;
  1072. }
  1073. return false;
  1074. }
  1075. /**
  1076. * Checks if the HSTS rule is already in the htaccess file
  1077. * Set the hsts variable in the db accordingly. applies to preload version as well.
  1078. *
  1079. * @since 2.1
  1080. *
  1081. * @access public
  1082. *
  1083. */
  1084. public function contains_hsts() {
  1085. if (!file_exists($this->ABSpath.".htaccess")) {
  1086. $this->trace_log(".htaccess not found in ".$this->ABSpath);
  1087. $result = $this->hsts; //just return the setting.
  1088. } else {
  1089. $htaccess = file_get_contents($this->ABSpath.".htaccess");
  1090. preg_match("/Strict-Transport-Security/", $htaccess, $check);
  1091. if(count($check) === 0){
  1092. $result = false;
  1093. } else {
  1094. $result = true;
  1095. }
  1096. }
  1097. return $result;
  1098. }
  1099. /**
  1100. * Adds redirect to https rules to the .htaccess file.
  1101. *
  1102. * @since 2.0
  1103. *
  1104. * @access public
  1105. *
  1106. */
  1107. public function editHtaccess(){
  1108. if (!current_user_can($this->capability)) return;
  1109. //check if htacces exists and if htaccess is writable
  1110. //update htaccess to redirect to ssl
  1111. $this->trace_log("checking if .htaccess can or should be edited...");
  1112. //does it exist?
  1113. if (!file_exists($this->ABSpath.".htaccess")) {
  1114. $this->trace_log(".htaccess not found.");
  1115. return;
  1116. }
  1117. //check if editing is blocked.
  1118. if ($this->do_not_edit_htaccess) {
  1119. $this->trace_log("Edit of .htaccess blocked by setting or define 'do not edit htaccess' in Really Simple SSL.");
  1120. return;
  1121. }
  1122. $htaccess = file_get_contents($this->ABSpath.".htaccess");
  1123. if(!$this->htaccess_contains_redirect_rules()){
  1124. if (!is_writable($this->ABSpath.".htaccess")) {
  1125. //set the wp redirect as fallback, because .htaccess couldn't be edited.
  1126. if ($this->clicked_activate_ssl()) $this->wp_redirect = true;
  1127. if (is_multisite()) {
  1128. RSSSL()->rsssl_multisite->wp_redirect = true;
  1129. RSSSL()->rsssl_multisite->save_options();
  1130. }
  1131. $this->save_options();
  1132. $this->trace_log(".htaccess not writable.");
  1133. return;
  1134. }
  1135. $rules = $this->get_redirect_rules();
  1136. //insert rules before wordpress part.
  1137. if (strlen($rules)>0) {
  1138. $wptag = "# BEGIN WordPress";
  1139. if (strpos($htaccess, $wptag)!==false) {
  1140. $htaccess = str_replace($wptag, $rules.$wptag, $htaccess);
  1141. } else {
  1142. $htaccess = $htaccess.$rules;
  1143. }
  1144. file_put_contents($this->ABSpath.".htaccess", $htaccess);
  1145. }
  1146. } elseif ($this->is_settings_page() || is_network_admin()) {
  1147. if ($this->debug) {$this->trace_log("settings page, or network admin, updating htaccess...");}
  1148. if (!is_writable($this->ABSpath.".htaccess")) {
  1149. if($this->debug) $this->trace_log(".htaccess not writable.");
  1150. return;
  1151. }
  1152. $htaccess = preg_replace("/#\s?BEGIN\s?rlrssslReallySimpleSSL.*?#\s?END\s?rlrssslReallySimpleSSL/s", "", $htaccess);
  1153. $htaccess = preg_replace("/\n+/","\n", $htaccess);
  1154. $rules = $this->get_redirect_rules();
  1155. //insert rules before WordPress part.
  1156. $wptag = "# BEGIN WordPress";
  1157. if (strpos($htaccess, $wptag)!==false) {
  1158. $htaccess = str_replace($wptag, $rules.$wptag, $htaccess);
  1159. } else {
  1160. $htaccess = $htaccess.$rules;
  1161. }
  1162. file_put_contents($this->ABSpath.".htaccess", $htaccess);
  1163. }
  1164. }
  1165. /**
  1166. *
  1167. * @since 2.2
  1168. * Check if the mixed content fixer is functioning on the front end, by scanning the source of the homepage for the fixer comment.
  1169. *
  1170. */
  1171. public function mixed_content_fixer_detected(){
  1172. $status = 0;
  1173. $web_source = "";
  1174. //check if the mixed content fixer is active
  1175. $response = wp_remote_get( home_url() );
  1176. if( is_array($response) ) {
  1177. $status = wp_remote_retrieve_response_code( $response );
  1178. $web_source = wp_remote_retrieve_body($response);
  1179. }
  1180. if ($status!=200 || (strpos($web_source, "data-rsssl=") === false)) {
  1181. $this->trace_log("Check for Mixed Content detection failed, http statuscode ".$status);
  1182. return false;
  1183. } else {
  1184. $this->trace_log("Mixed content fixer was successfully detected on the front end.");
  1185. return true;
  1186. }
  1187. }
  1188. /**
  1189. * Create redirect rules for the .htaccess.
  1190. *
  1191. * @since 2.1
  1192. *
  1193. * @access public
  1194. *
  1195. */
  1196. public function get_redirect_rules($manual=false) {
  1197. if (!current_user_can($this->capability)) return;
  1198. $this->trace_log("retrieving redirect rules");
  1199. //only add the redirect rules when a known type of SSL was detected. Otherwise, we use https.
  1200. $rule = "";
  1201. //if the htaccess test was successfull, and we know the redirectype, edit
  1202. if ($this->htaccess_redirect && ($manual || $this->htaccess_test_success) && $this->ssl_type!="NA") {
  1203. $this->trace_log("starting insertion of .htaccess redirects.");
  1204. $rule .= "<IfModule mod_rewrite.c>"."\n";
  1205. $rule .= "RewriteEngine on"."\n";
  1206. // Fetch last array key
  1207. //$types = array_keys($this->ssl_type);
  1208. //$last_type = array_pop($types);
  1209. // reset($this->ssl_type);
  1210. // $type = key($this->ssl_type);
  1211. //select rewrite condition based on detected type of SSL
  1212. //foreach($this->ssl_type as $type => $value) {
  1213. $or = "";
  1214. //if ($last_type != $type) $or = " [OR] ";
  1215. if ($this->ssl_type == "SERVER-HTTPS-ON") {
  1216. $rule .= "RewriteCond %{HTTPS} !=on [NC]"."\n";
  1217. } elseif ($this->ssl_type == "SERVER-HTTPS-1") {
  1218. $rule .= "RewriteCond %{HTTPS} !=1"."\n";
  1219. } elseif ($this->ssl_type == "LOADBALANCER") {
  1220. $rule .="RewriteCond %{HTTP:X-Forwarded-Proto} !https"."\n";
  1221. } elseif ($this->ssl_type == "CLOUDFLARE") {
  1222. $rule .= "RewriteCond %{HTTP:CF-Visitor} '".'"scheme":"http"'."'"."\n";//some concatenation to get the quotes right.
  1223. } elseif ($this->ssl_type == "SERVERPORT443") {
  1224. $rule .= "RewriteCond %{SERVER_PORT} !443"."\n";
  1225. } elseif ($this->ssl_type == "CLOUDFRONT") {
  1226. $rule .="RewriteCond %{HTTP:CloudFront-Forwarded-Proto} !https"."\n";
  1227. } elseif ($this->ssl_type == "CDN") {
  1228. $rule .= "RewriteCond %{HTTP:X-Forwarded-SSL} !on"."\n";
  1229. } elseif ($type == "ENVHTTPS") {
  1230. $rule .= "RewriteCond %{ENV:HTTPS} !=on"."\n";
  1231. }
  1232. //}
  1233. //if multisite, and NOT subfolder install (checked for in the detec_config function)
  1234. //, add a condition so it only applies to sites where plugin is activated
  1235. if (is_multisite() && !RSSSL()->rsssl_multisite->ssl_enabled_networkwide) {
  1236. $this->trace_log("multisite, per site activation");
  1237. foreach ($this->sites as $domain ) {
  1238. $this->trace_log("adding condition for:".$domain);
  1239. //remove http or https.
  1240. $domain = preg_replace("/(http:\/\/|https:\/\/)/","",$domain);
  1241. //We excluded subfolders, so treat as domain
  1242. $domain_no_www = str_replace ( "www." , "" , $domain);
  1243. $domain_yes_www = "www.".$domain_no_www;
  1244. $rule .= "#wpmu rewritecond ".$domain."\n";
  1245. $rule .= "RewriteCond %{HTTP_HOST} ^".preg_quote($domain_no_www, "/")." [OR]"."\n";
  1246. $rule .= "RewriteCond %{HTTP_HOST} ^".preg_quote($domain_yes_www, "/")." [OR]"."\n";
  1247. $rule .= "#end wpmu rewritecond ".$domain."\n";
  1248. }
  1249. //now remove last [OR] if at least on one site the plugin was activated, so we have at lease one condition
  1250. if (count($this->sites)>0) {
  1251. $rule = strrev(implode("", explode(strrev("[OR]"), strrev($rule), 2)));
  1252. }
  1253. } else {
  1254. if ($this->debug) {$this->trace_log("single site or networkwide activation");}
  1255. }
  1256. //fastest cache compatibility
  1257. if(class_exists('WpFastestCache') ) {
  1258. $rule .= "RewriteCond %{REQUEST_URI} !wp-content\/cache\/(all|wpfc-mobile-cache)"."\n";
  1259. }
  1260. $rule .= "RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]"."\n";
  1261. $rule .= "</IfModule>"."\n";
  1262. }
  1263. if (strlen($rule)>0) {
  1264. $rule = "\n"."# BEGIN rlrssslReallySimpleSSL rsssl_version[".rsssl_version."]\n".$rule."# END rlrssslReallySimpleSSL"."\n";
  1265. }
  1266. $rule = apply_filters("rsssl_htaccess_output", $rule);
  1267. $rule = preg_replace("/\n+/","\n", $rule);
  1268. return $rule;
  1269. }
  1270. /**
  1271. * Show warning when wpconfig could not be fixed
  1272. *
  1273. * @since 2.2
  1274. *
  1275. */
  1276. public function show_notice_wpconfig_needs_fixes(){ ?>
  1277. <div id="message" class="error fade notice">
  1278. <h1><?php echo __("System detection encountered issues","really-simple-ssl");?></h1>
  1279. <?php if ($this->wpconfig_siteurl_not_fixed) { ?>
  1280. <p>
  1281. <?php echo __("A definition of a siteurl or homeurl was detected in your wp-config.php, but the file is not writable.","really-simple-ssl");?>
  1282. </p>
  1283. <p><?php echo __("Set your wp-config.php to writable and reload this page.", "really-simple-ssl");?></p>
  1284. <?php }
  1285. if ($this->do_wpconfig_loadbalancer_fix) { ?>
  1286. <p><?php echo __("Your wp-config.php has to be edited, but is not writable.","really-simple-ssl");?></p>
  1287. <p><?php echo __("Because your site is behind a loadbalancer and is_ssl() returns false, you should add the following line of code to your wp-config.php.","really-simple-ssl");?>
  1288. <br><br><code>
  1289. //Begin Really Simple SSL Load balancing fix<br>
  1290. $server_opts = array("HTTP_CLOUDFRONT_FORWARDED_PROTO" => "https", "HTTP_CF_VISITOR"=>"https", "HTTP_X_FORWARDED_PROTO"=>"https", "HTTP_X_FORWARDED_SSL"=>"on", "HTTP_X_FORWARDED_SSL"=>"1");<br>
  1291. foreach( $server_opts as $option => $value ) {<br>
  1292. &nbsp;if ((isset($_ENV["HTTPS"]) && ( "on" == $_ENV["HTTPS"] )) || (isset( $_SERVER[ $option ] ) && ( strpos( $_SERVER[ $option ], $value ) !== false )) ) {<br>
  1293. &nbsp;&nbsp;$_SERVER[ "HTTPS" ] = "on";<br>
  1294. &nbsp;&nbsp;break;<br>
  1295. &nbsp;}<br>
  1296. }<br>
  1297. //END Really Simple SSL
  1298. </code><br>
  1299. </p>
  1300. <p><?php echo __("Or set your wp-config.php to writable and reload this page.", "really-simple-ssl");?></p>
  1301. <?php
  1302. }
  1303. if ( $this->no_server_variable ) {
  1304. ?>
  1305. <p><?php echo __('Because your server does not pass a variable with which WordPress can detect SSL, WordPress may create redirect loops on SSL.','really-simple-ssl');?></p>
  1306. <p><?php echo __("Set your wp-config.php to writable and reload this page.", "really-simple-ssl");?></p>
  1307. <?php
  1308. }
  1309. ?>
  1310. </div>
  1311. <?php
  1312. }
  1313. /**
  1314. * Show notices
  1315. *
  1316. * @since 2.0
  1317. *
  1318. * @access public
  1319. *
  1320. */
  1321. public function show_notices()
  1322. {
  1323. /*
  1324. show a notice when the .htaccess file does not contain redirect rules
  1325. */
  1326. if (!$this->wp_redirect && $this->ssl_enabled && !$this->htaccess_warning_shown && !$this->htaccess_contains_redirect_rules()) {
  1327. add_action('admin_print_footer_scripts', array($this, 'insert_dismiss_htaccess'));
  1328. ?>
  1329. <div id="message" class="error fade notice is-dismissible rlrsssl-htaccess">
  1330. <p>
  1331. <?php echo __("You do not have a 301 redirect to https active in the settings. For SEO purposes it is advised to use 301 redirects. You can enable a 301 redirect in the settings.","really-simple-ssl");?>
  1332. <a href="options-general.php?page=rlrsssl_really_simple_ssl"><?php echo __("View settings page","really-simple-ssl");?></a>
  1333. </p>
  1334. </div>
  1335. <?php
  1336. }
  1337. if (isset($this->errors["DEACTIVATE_FILE_NOT_RENAMED"])) {
  1338. ?>
  1339. <div id="message" class="error fade notice is-dismissible rlrsssl-fail">
  1340. <h1>
  1341. <?php _e("Major security issue!","really-simple-ssl");?>
  1342. </h1>
  1343. <p>
  1344. <?php _e("The 'force-deactivate.php' file has to be renamed to .txt. Otherwise your ssl can be deactived by anyone on the internet.","really-simple-ssl");?>
  1345. </p>
  1346. <a href="options-general.php?page=rlrsssl_really_simple_ssl"><?php echo __("Check again","really-simple-ssl");?></a>
  1347. </div>
  1348. <?php
  1349. }
  1350. if (is_multisite() && !is_main_site(get_current_blog_id())) return;
  1351. /*
  1352. SSL success message
  1353. */
  1354. if ($this->ssl_enabled && $this->site_has_ssl && !$this->ssl_success_message_shown) {
  1355. if (!current_user_can("activate_plugins")) return;
  1356. add_action('admin_print_footer_scripts', array($this, 'insert_dismiss_success'));
  1357. ?>
  1358. <div id="message" class="updated fade notice is-dismissible rlrsssl-success">
  1359. <p>
  1360. <?php _e("SSL activated!","really-simple-ssl");?>&nbsp;
  1361. <?php _e("Don't forget to change your settings in Google Analytics and Webmaster tools.","really-simple-ssl");?>&nbsp;
  1362. <a target="_blank" href="https://really-simple-ssl.com/knowledge-base/how-to-setup-google-analytics-and-google-search-consolewebmaster-tools/"><?php _e("More info.","really-simple-ssl");?></a>
  1363. </p>
  1364. </div>
  1365. <?php
  1366. }
  1367. //some notices for SSL situations
  1368. if ($this->site_has_ssl) {
  1369. if (sizeof($this->plugin_conflict)>0) {
  1370. //pre WooCommerce 2.5
  1371. if (isset($this->plugin_conflict["WOOCOMMERCE_FORCEHTTP"]) && $this->plugin_conflict["WOOCOMMERCE_FORCEHTTP"] && isset($this->plugin_conflict["WOOCOMMERCE_FORCESSL"]) && $this->plugin_conflict["WOOCOMMERCE_FORCESSL"]) {
  1372. ?>
  1373. <div id="message" class="error fade notice"><p>
  1374. <?php _e("Really Simple SSL has a conflict with another plugin.","really-simple-ssl");?><br>
  1375. <?php _e("The force http after leaving checkout in WooCommerce will create a redirect loop.","really-simple-ssl");?><br>
  1376. <a href="admin.php?page=wc-settings&tab=checkout"><?php _e("Show me this setting","really-simple-ssl");?></a>
  1377. </p></div>
  1378. <?php
  1379. }
  1380. }
  1381. }
  1382. }
  1383. /**
  1384. * Insert some ajax script to dismiss the SSL success message, and stop nagging about it
  1385. *
  1386. * @since 2.0
  1387. *
  1388. * @access public
  1389. *
  1390. */
  1391. public function insert_dismiss_success() {
  1392. $ajax_nonce = wp_create_nonce( "really-simple-ssl-dismiss" );
  1393. ?>
  1394. <script type='text/javascript'>
  1395. jQuery(document).ready(function($) {
  1396. $(".rlrsssl-success.notice.is-dismissible").on("click", ".notice-dismiss", function(event){
  1397. var data = {
  1398. 'action': 'dismiss_success_message',
  1399. 'security': '<?php echo $ajax_nonce; ?>'
  1400. };
  1401. $.post(ajaxurl, data, function(response) {
  1402. });
  1403. });
  1404. });
  1405. </script>
  1406. <?php
  1407. }
  1408. /**
  1409. * Insert some ajax script to dismis the htaccess failed fail message, and stop nagging about it
  1410. *
  1411. * @since 2.0
  1412. *
  1413. * @access public
  1414. *
  1415. */
  1416. public function insert_dismiss_htaccess() {
  1417. $ajax_nonce = wp_create_nonce( "really-simple-ssl" );
  1418. ?>
  1419. <script type='text/javascript'>
  1420. jQuery(document).ready(function($) {
  1421. $(".rlrsssl-htaccess.notice.is-dismissible").on("click", ".notice-dismiss", function(event){
  1422. var data = {
  1423. 'action': 'dismiss_htaccess_warning',
  1424. 'security': '<?php echo $ajax_nonce; ?>'
  1425. };
  1426. $.post(ajaxurl, data, function(response) {
  1427. });
  1428. });
  1429. });
  1430. </script>
  1431. <?php
  1432. }
  1433. /**
  1434. * Process the ajax dismissal of the success message.
  1435. *
  1436. * @since 2.0
  1437. *
  1438. * @access public
  1439. *
  1440. */
  1441. public function dismiss_success_message_callback() {
  1442. //nonce check fails if url is changed to SSL.
  1443. //check_ajax_referer( 'really-simple-ssl-dismiss', 'security' );
  1444. $this->ssl_success_message_shown = TRUE;
  1445. $this->save_options();
  1446. wp_die();
  1447. }
  1448. /**
  1449. * Process the ajax dismissal of the htaccess message.
  1450. *
  1451. * @since 2.1
  1452. *
  1453. * @access public
  1454. *
  1455. */
  1456. public function dismiss_htaccess_warning_callback() {
  1457. check_ajax_referer( 'really-simple-ssl', 'security' );
  1458. $this->htaccess_warning_shown = TRUE;
  1459. $this->save_options();
  1460. wp_die(); // this is required to terminate immediately and return a proper response
  1461. }
  1462. /**
  1463. * Adds the admin options page
  1464. *
  1465. * @since 2.0
  1466. *
  1467. * @access public
  1468. *
  1469. */
  1470. public function add_settings_page() {
  1471. if (!current_user_can($this->capability)) return;
  1472. //hides the settings page if the hide menu for subsites setting is enabled
  1473. if(is_multisite() && rsssl_multisite::this()->hide_menu_for_subsites) return;
  1474. global $rsssl_admin_page;
  1475. $rsssl_admin_page = add_options_page(
  1476. __("SSL settings","really-simple-ssl"), //link title
  1477. __("SSL","really-simple-ssl"), //page title
  1478. $this->capability, //capability
  1479. 'rlrsssl_really_simple_ssl', //url
  1480. array($this,'settings_page')); //function
  1481. // Adds my_help_tab when my_admin_page loads
  1482. add_action('load-'.$rsssl_admin_page, array($this,'admin_add_help_tab'));
  1483. }
  1484. /**
  1485. * Admin help tab
  1486. *
  1487. * @since 2.0
  1488. *
  1489. * @access public
  1490. *
  1491. */
  1492. public function admin_add_help_tab() {
  1493. $screen = get_current_screen();
  1494. // Add my_help_tab if current screen is My Admin Page
  1495. $screen->add_help_tab( array(
  1496. 'id' => "really-simple-ssl-documentation",
  1497. 'title' => __("Documentation","really-simple-ssl"),
  1498. 'content' => '<p>' . __("On <a href='https://really-simple-ssl.com'>really-simple-ssl.com</a> you can find a lot of articles and documentation about installing this plugin, and installing SSL in general.","really-simple-ssl") . '</p>',
  1499. ) );
  1500. }
  1501. /**
  1502. * Create tabs on the settings page
  1503. *
  1504. * @since 2.1
  1505. *
  1506. * @access public
  1507. *
  1508. */
  1509. public function admin_tabs( $current = 'homepage' ) {
  1510. $tabs = array(
  1511. 'configuration' => __("Configuration","really-simple-ssl"),
  1512. 'settings'=>__("Settings","really-simple-ssl"),
  1513. 'debug' => __("Debug","really-simple-ssl")
  1514. );
  1515. $tabs = apply_filters("rsssl_tabs", $tabs);
  1516. echo '<h2 class="nav-tab-wrapper">';
  1517. foreach( $tabs as $tab => $name ){
  1518. $class = ( $tab == $current ) ? ' nav-tab-active' : '';
  1519. echo "<a class='nav-tab$class' href='?page=rlrsssl_really_simple_ssl&tab=$tab'>$name</a>";
  1520. }
  1521. echo '</h2>';
  1522. }
  1523. /**
  1524. * Build the settings page
  1525. *
  1526. * @since 2.0
  1527. *
  1528. * @access public
  1529. *
  1530. */
  1531. public function settings_page() {
  1532. if (!current_user_can($this->capability)) return;
  1533. if ( isset ( $_GET['tab'] ) ) $this->admin_tabs($_GET['tab']); else $this->admin_tabs('configuration');
  1534. if ( isset ( $_GET['tab'] ) ) $tab = $_GET['tab']; else $tab = 'configuration';
  1535. ?><div class="rsssl-container"><div class="rsssl-main"><?php
  1536. switch ( $tab ){
  1537. case 'configuration' :
  1538. /*
  1539. First tab, configuration
  1540. */
  1541. ?>
  1542. <h2><?php echo __("Detected setup","really-simple-ssl");?></h2>
  1543. <table class="really-simple-ssl-table">
  1544. <?php if ($this->site_has_ssl) { ?>
  1545. <tr>
  1546. <td><?php echo $this->ssl_enabled ? $this->img("success") : $this->img("error");?></td>
  1547. <td><?php
  1548. if ($this->ssl_enabled) {
  1549. _e("SSL is enabled on your site.","really-simple-ssl")."&nbsp;";
  1550. } else {
  1551. _e("SSL is not enabled yet","really-simple-ssl")."&nbsp;";
  1552. $this->show_enable_ssl_button();
  1553. }
  1554. ?>
  1555. </td><td></td>
  1556. </tr>
  1557. <?php }
  1558. /* check if the mixed content fixer is working */
  1559. if ($this->ssl_enabled && $this->autoreplace_insecure_links && $this->site_has_ssl) {
  1560. $mixed_content_fixer_detected = $this->mixed_content_fixer_detected();
  1561. ?>
  1562. <tr>
  1563. <td><?php echo $mixed_content_fixer_detected ? $this->img("success") : $this->img("error");?></td>
  1564. <td><?php
  1565. if ($mixed_content_fixer_detected) {
  1566. _e("Mixed content fixer was successfully detected on the front-end","really-simple-ssl")."&nbsp;";
  1567. } else {
  1568. _e('The mixed content fixer is active, but was not detected on the frontpage. Please follow these steps to check if the mixed content fixer is working.',"really-simple-ssl").":&nbsp;";
  1569. echo '&nbsp;<a target="_blank" href="https://www.really-simple-ssl.com/knowledge-base/how-to-check-if-the-mixed-content-fixer-is-active/">';
  1570. _e('Instructions', 'really-simple-ssl');
  1571. echo '</a>';
  1572. }
  1573. ?>
  1574. </td><td></td>
  1575. </tr>
  1576. <?php } ?>
  1577. <tr>
  1578. <td><?php echo ($this->site_has_ssl && $this->wpconfig_ok()) ? $this->img("success") : $this->img("error");?></td>
  1579. <td><?php
  1580. if ( !$this->wpconfig_ok()) {
  1581. _e("Failed activating SSL","really-simple-ssl")."&nbsp;";
  1582. } elseif (!$this->site_has_ssl) {
  1583. _e("No SSL detected.","really-simple-ssl")."&nbsp;";
  1584. } else {
  1585. _e("An SSL certificate was detected on your site. ","really-simple-ssl");
  1586. }
  1587. ?>
  1588. </td><td></td>
  1589. </tr>
  1590. <?php if($this->ssl_enabled) { ?>
  1591. <tr>
  1592. <td>
  1593. <?php echo ($this->has_301_redirect()) ? $this->img("success") :$this->img("warning");?>
  1594. </td>
  1595. <td>
  1596. <?php
  1597. if($this->has_301_redirect()) {
  1598. _e("301 redirect to https set: ","really-simple-ssl");
  1599. if (RSSSL()->rsssl_server->uses_htaccess() && $this->htaccess_contains_redirect_rules())
  1600. _e(".htaccess redirect","really-simple-ssl");
  1601. if (RSSSL()->rsssl_server->uses_htaccess() && $this->htaccess_contains_redirect_rules() && $this->wp_redirect)
  1602. echo "&nbsp;" . __("and", "really-simple-ssl") . "&nbsp;";
  1603. if ($this->wp_redirect)
  1604. _e("WordPress redirect","really-simple-ssl");
  1605. } elseif (RSSSL()->rsssl_server->uses_htaccess() && (!is_multisite() || !RSSSL()->rsssl_multisite->is_per_site_activated_multisite_subfolder_install())) {
  1606. if (is_writable($this->ABSpath.".htaccess")) {
  1607. _e("Enable a .htaccess redirect or WordPress redirect in the settings to create a 301 redirect.","really-simple-ssl");
  1608. } elseif (!is_writable($this->ABSpath.".htaccess")) {
  1609. _e(".htaccess is not writable. Set 301 WordPress redirect, or set the .htaccess manually if you want to redirect in .htaccess.","really-simple-ssl");
  1610. } else {
  1611. _e("Https redirect cannot be set in the .htaccess. Set the .htaccess redirect manually or enable WordPress redirect in the settings.","really-simple-ssl");
  1612. }
  1613. } else {
  1614. _e("No 301 redirect is set. Enable the WordPress 301 redirect in the settings to get a 301 permanent redirect.","really-simple-ssl");
  1615. }
  1616. ?>
  1617. </td><td></td>
  1618. </tr>
  1619. <?php
  1620. }
  1621. ?>
  1622. </table>
  1623. <?php do_action("rsssl_configuration_page");?>
  1624. <?php
  1625. break;
  1626. case 'settings' :
  1627. /*
  1628. Second tab, Settings
  1629. */
  1630. ?>
  1631. <form action="options.php" method="post">
  1632. <?php
  1633. settings_fields('rlrsssl_options');
  1634. do_settings_sections('rlrsssl');
  1635. ?>
  1636. <input class="button button-primary" name="Submit" type="submit" value="<?php echo __("Save","really-simple-ssl"); ?>" />
  1637. </form>
  1638. <?php
  1639. break;
  1640. case 'debug' :
  1641. /*
  1642. third tab: debug
  1643. */
  1644. ?>
  1645. <div>
  1646. <?php
  1647. if ($this->debug) {
  1648. echo "<h2>".__("Log for debugging purposes","really-simple-ssl")."</h2>";
  1649. echo "<p>".__("Send me a copy of these lines if you have any issues. The log will be erased when debug is set to false","really-simple-ssl")."</p>";
  1650. echo "<div class='debug-log'>";
  1651. if (defined('RSSSL_SAFE_MODE') && RSSSL_SAFE_MODE) echo "SAFE MODE<br>";
  1652. echo "Options:<br>";
  1653. if ($this->htaccess_redirect) echo "* htaccess redirect<br>";
  1654. if ($this->wp_redirect) echo "* WordPress redirect<br>";
  1655. if ($this->autoreplace_insecure_links) echo "* Mixed content fixer<br>";
  1656. echo "SERVER: ".RSSSL()->rsssl_server->get_server() . "<br>";
  1657. if (is_multisite()) {
  1658. echo "MULTISITE<br>";
  1659. echo (!RSSSL()->rsssl_multisite->ssl_enabled_networkwide) ? "SSL is being activated per site<br>" : "SSL is activated network wide<br>";
  1660. }
  1661. echo ($this->ssl_enabled) ? "SSL is enabled for this site<br>" : "SSL is not yet enabled for this site<br>";
  1662. echo $this->debug_log;
  1663. echo "</div>";
  1664. //$this->debug_log.="<br><b>-----------------------</b>";
  1665. $this->debug_log="";
  1666. $this->save_options();
  1667. }
  1668. else {
  1669. echo "<br>";
  1670. _e("To view results here, enable the debug option in the settings tab.","really-simple-ssl");
  1671. }
  1672. ?>
  1673. </div>
  1674. <?php
  1675. break;
  1676. }
  1677. //possibility to hook into the tabs.
  1678. do_action("show_tab_{$tab}");
  1679. ?>
  1680. </div><!-- end main-->
  1681. <div class="rsssl-sidebar">
  1682. <div class="rsssl-wrapper">
  1683. </div>
  1684. </div>
  1685. </div><!-- end container -->
  1686. <?php
  1687. }
  1688. /**
  1689. * Returns a success, error or warning image for the settings page
  1690. *
  1691. * @since 2.0
  1692. *
  1693. * @access public
  1694. *
  1695. * @param string $type the type of image
  1696. *
  1697. * @return html string
  1698. */
  1699. public function img($type) {
  1700. if ($type=='success') {
  1701. return "<img class='rsssl-icons' src='" . trailingslashit(rsssl_url) . "img/check-icon.png' alt='success'>";
  1702. } elseif ($type=="error") {
  1703. return "<img class='rsssl-icons' src='". trailingslashit(rsssl_url) . "img/cross-icon.png' alt='error'>";
  1704. } else {
  1705. return "<img class='rsssl-icons' src='". trailingslashit(rsssl_url) ."img/warning-icon.png' alt='warning'>";
  1706. }
  1707. }
  1708. /**
  1709. * Add some css for the settings page
  1710. *
  1711. * @since 2.0
  1712. *
  1713. * @access public
  1714. *
  1715. */
  1716. public function enqueue_assets($hook){
  1717. global $rsssl_admin_page;
  1718. //prevent from loading on other pages than settings page.
  1719. if( (!is_network_admin() && ($hook != $rsssl_admin_page)) && $this->ssl_enabled )
  1720. return;
  1721. wp_register_style( 'rlrsssl-css', trailingslashit(rsssl_url) . 'css/main.css', "", rsssl_version);
  1722. wp_enqueue_style( 'rlrsssl-css');
  1723. }
  1724. /*
  1725. feedback for the free users. Pro users see something different.
  1726. */
  1727. public function configuration_page_more(){
  1728. ?>
  1729. <table>
  1730. <tr>
  1731. <td>
  1732. <?php echo $this->contains_hsts() ? $this->img("success") :$this->img("warning");?>
  1733. </td>
  1734. <td>
  1735. <?php
  1736. if($this->contains_hsts()) {
  1737. _e("HTTP Strict Transport Security was enabled","really-simple-ssl");
  1738. } else {
  1739. $wiki_open = '<a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security" target="_blank">';
  1740. $link_open = '<a target="_blank" href="'.$this->pro_url.'">';
  1741. $link_close = '</a>';
  1742. printf( __('%sHTTP Strict Transport Security%s is not enabled.',"really-simple-ssl"), $wiki_open, $link_close);
  1743. echo "&nbsp;";
  1744. printf(__("To enable, %sget Premium%s ","really-simple-ssl"), $link_open, $link_close);
  1745. }
  1746. ?>
  1747. </td><td></td>
  1748. </tr>
  1749. <tr>
  1750. <td><?php echo ($this->contains_secure_cookie_settings()) ? $this->img("success") : $this->img("warning");?></td>
  1751. <td><?php
  1752. if ($this->contains_secure_cookie_settings()) {
  1753. _e("Secure cookies set","really-simple-ssl")."&nbsp;";
  1754. } else {
  1755. $link_open = '<a target="_blank" href="'.$this->pro_url.'">';
  1756. $link_close = '</a>';
  1757. _e('Secure cookie settings not enabled.',"really-simple-ssl");
  1758. echo "&nbsp;";
  1759. printf(__("To enable, %sget Premium%s ","really-simple-ssl"), $link_open, $link_close);
  1760. }
  1761. ?>
  1762. </td><td></td>
  1763. </tr>
  1764. </table>
  1765. <?php
  1766. if (!$this->site_has_ssl) {
  1767. $this->show_pro();
  1768. } else {
  1769. if (!$this->ssl_enabled) { ?>
  1770. <p><?php _e("If you want to be sure you're ready to migrate to SSL, get Premium, which includes an extensive scan and premium support.", "really-simple-ssl")?>
  1771. &nbsp;<a target="_blank" href="<?php echo $this->pro_url?>"><?php _e("Learn more", "really-simple-ssl")?></a></p>
  1772. <?php } else { ?>
  1773. <p><?php _e('Still having issues with mixed content? Check out Premium, which includes an extensive scan and premium support. ', "really-simple-ssl")?>
  1774. &nbsp;<a target="_blank" href="<?php echo $this->pro_url?>"><?php _e("Learn more", "really-simple-ssl")?></a></p>
  1775. <?php
  1776. }
  1777. }
  1778. }
  1779. /**
  1780. * Create the settings page form
  1781. *
  1782. * @since 2.0
  1783. *
  1784. * @access public
  1785. *
  1786. */
  1787. public function create_form(){
  1788. register_setting( 'rlrsssl_options', 'rlrsssl_options', array($this,'options_validate') );
  1789. add_settings_section('rlrsssl_settings', __("Settings","really-simple-ssl"), array($this,'section_text'), 'rlrsssl');
  1790. add_settings_field('id_autoreplace_insecure_links', __("Auto replace mixed content","really-simple-ssl"), array($this,'get_option_autoreplace_insecure_links'), 'rlrsssl', 'rlrsssl_settings');
  1791. //only show option to enable or disable mixed content and redirect when SSL is detected
  1792. if($this->ssl_enabled) {
  1793. add_settings_field('id_wp_redirect', __("Enable WordPress 301 redirection to SSL","really-simple-ssl"), array($this,'get_option_wp_redirect'), 'rlrsssl', 'rlrsssl_settings');
  1794. //when enabled networkwide, it's handled on the network settings page
  1795. if (RSSSL()->rsssl_server->uses_htaccess() && (!is_multisite() || !RSSSL()->rsssl_multisite->ssl_enabled_networkwide)) {
  1796. add_settings_field('id_htaccess_redirect', __("Enable 301 .htaccess redirect","really-simple-ssl"), array($this,'get_option_htaccess_redirect'), 'rlrsssl', 'rlrsssl_settings');
  1797. }
  1798. add_settings_field('id_javascript_redirect', __("Enable Javascript redirection to SSL","really-simple-ssl"), array($this,'get_option_javascript_redirect'), 'rlrsssl', 'rlrsssl_settings');
  1799. }
  1800. add_settings_field('id_debug', __("Debug","really-simple-ssl"), array($this,'get_option_debug'), 'rlrsssl', 'rlrsssl_settings');
  1801. //on multisite this setting can only be set networkwide
  1802. if (RSSSL()->rsssl_server->uses_htaccess() && !is_multisite()) {
  1803. add_settings_field('id_do_not_edit_htaccess', __("Stop editing the .htaccess file","really-simple-ssl"), array($this,'get_option_do_not_edit_htaccess'), 'rlrsssl', 'rlrsssl_settings');
  1804. }
  1805. add_settings_field('id_switch_mixed_content_fixer_hook', __("Switch mixed content fixer hook","really-simple-ssl"), array($this,'get_option_switch_mixed_content_fixer_hook'), 'rlrsssl', 'rlrsssl_settings');
  1806. }
  1807. /**
  1808. * Insert some explanation above the form
  1809. *
  1810. * @since 2.0
  1811. *
  1812. * @access public
  1813. *
  1814. */
  1815. public function section_text() {
  1816. ?>
  1817. <p><?php _e('Settings to optimize your SSL configuration','really-simple-ssl');?></p>
  1818. <?php
  1819. }
  1820. /**
  1821. * Check the posted values in the settings page for validity
  1822. *
  1823. * @since 2.0
  1824. *
  1825. * @access public
  1826. *
  1827. */
  1828. public function options_validate($input) {
  1829. //fill array with current values, so we don't lose any
  1830. $newinput = array();
  1831. $newinput['site_has_ssl'] = $this->site_has_ssl;
  1832. $newinput['ssl_success_message_shown'] = $this->ssl_success_message_shown;
  1833. $newinput['htaccess_warning_shown'] = $this->htaccess_warning_shown;
  1834. $newinput['plugin_db_version'] = $this->plugin_db_version;
  1835. $newinput['ssl_enabled'] = $this->ssl_enabled;
  1836. $newinput['debug_log'] = $this->debug_log;
  1837. if (!empty($input['hsts']) && $input['hsts']=='1') {
  1838. $newinput['hsts'] = TRUE;
  1839. } else {
  1840. $newinput['hsts'] = FALSE;
  1841. }
  1842. if (!empty($input['javascript_redirect']) && $input['javascript_redirect']=='1') {
  1843. $newinput['javascript_redirect'] = TRUE;
  1844. } else {
  1845. $newinput['javascript_redirect'] = FALSE;
  1846. }
  1847. if (!empty($input['wp_redirect']) && $input['wp_redirect']=='1') {
  1848. $newinput['wp_redirect'] = TRUE;
  1849. } else {
  1850. $newinput['wp_redirect'] = FALSE;
  1851. }
  1852. if (!empty($input['autoreplace_insecure_links']) && $input['autoreplace_insecure_links']=='1') {
  1853. $newinput['autoreplace_insecure_links'] = TRUE;
  1854. } else {
  1855. $newinput['autoreplace_insecure_links'] = FALSE;
  1856. }
  1857. if (!empty($input['debug']) && $input['debug']=='1') {
  1858. $newinput['debug'] = TRUE;
  1859. } else {
  1860. $newinput['debug'] = FALSE;
  1861. $this->debug_log = "";
  1862. }
  1863. if (!empty($input['do_not_edit_htaccess']) && $input['do_not_edit_htaccess']=='1') {
  1864. $newinput['do_not_edit_htaccess'] = TRUE;
  1865. } else {
  1866. $newinput['do_not_edit_htaccess'] = FALSE;
  1867. }
  1868. if (!empty($input['switch_mixed_content_fixer_hook']) && $input['switch_mixed_content_fixer_hook']=='1') {
  1869. $newinput['switch_mixed_content_fixer_hook'] = TRUE;
  1870. } else {
  1871. $newinput['switch_mixed_content_fixer_hook'] = FALSE;
  1872. }
  1873. if (!empty($input['htaccess_redirect']) && $input['htaccess_redirect']=='1') {
  1874. $newinput['htaccess_redirect'] = TRUE;
  1875. } else {
  1876. $newinput['htaccess_redirect'] = FALSE;
  1877. }
  1878. return $newinput;
  1879. }
  1880. /**
  1881. * Insert option into settings form
  1882. * deprecated
  1883. * @since 2.0
  1884. *
  1885. * @access public
  1886. *
  1887. */
  1888. public function get_option_debug() {
  1889. $options = get_option('rlrsssl_options');
  1890. echo '<input id="rlrsssl_options" name="rlrsssl_options[debug]" size="40" type="checkbox" value="1"' . checked( 1, $this->debug, false ) ." />";
  1891. RSSSL()->rsssl_help->get_help_tip(__("Enable this option to get debug info in the debug tab.", "really-simple-ssl"));
  1892. }
  1893. /**
  1894. * Insert option into settings form
  1895. * @since 2.2
  1896. *
  1897. * @access public
  1898. *
  1899. */
  1900. public function get_option_javascript_redirect() {
  1901. $javascript_redirect = $this->javascript_redirect;
  1902. $disabled = "";
  1903. $comment = "";
  1904. if (is_multisite() && rsssl_multisite::this()->javascript_redirect) {
  1905. $disabled = "disabled";
  1906. $javascript_redirect = TRUE;
  1907. $comment = __( "This option is enabled on the network menu.", "really-simple-ssl" );
  1908. }
  1909. echo '<input '.$disabled.' id="rlrsssl_options" name="rlrsssl_options[javascript_redirect]" size="40" type="checkbox" value="1"' . checked( 1, $javascript_redirect, false ) ." />";
  1910. RSSSL()->rsssl_help->get_help_tip(__("This is a fallback you should only use if other redirection methods do not work.", "really-simple-ssl"));
  1911. echo $comment;
  1912. }
  1913. /**
  1914. * Insert option into settings form
  1915. * @since 2.5.0
  1916. *
  1917. * @access public
  1918. *
  1919. */
  1920. public function get_option_wp_redirect() {
  1921. $wp_redirect = $this->wp_redirect;
  1922. $disabled = "";
  1923. $comment = "";
  1924. if (is_multisite() && rsssl_multisite::this()->wp_redirect) {
  1925. $disabled = "disabled";
  1926. $wp_redirect = TRUE;
  1927. $comment = __( "This option is enabled on the network menu.", "really-simple-ssl" );
  1928. }
  1929. echo '<input '.$disabled.' id="rlrsssl_options" name="rlrsssl_options[wp_redirect]" size="40" type="checkbox" value="1"' . checked( 1, $wp_redirect, false ) ." />";
  1930. RSSSL()->rsssl_help->get_help_tip(__("Enable this if you want to use the internal WordPress 301 redirect. Needed on NGINX servers, or if the .htaccess redirect cannot be used.", "really-simple-ssl"));
  1931. echo $comment;
  1932. }
  1933. /**
  1934. * Insert option into settings form
  1935. * The .htaccess redirect is not shown for multisite sites that are enabled network wide.
  1936. *
  1937. * @since 2.5.8
  1938. *
  1939. * @access public
  1940. *
  1941. */
  1942. public function get_option_htaccess_redirect() {
  1943. $options = get_option('rlrsssl_options');
  1944. $htaccess_redirect = $this->htaccess_redirect;
  1945. $disabled = "";
  1946. $comment = "";
  1947. //networkwide is not shown, so this only applies to per site activated sites.
  1948. if (is_multisite() && RSSSL()->rsssl_multisite->htaccess_redirect) {
  1949. $disabled = "disabled";
  1950. $htaccess_redirect = TRUE;
  1951. $comment = __( "This option is enabled on the network menu.", "really-simple-ssl" );
  1952. } else {
  1953. $disabled = ($this->do_not_edit_htaccess) ? "disabled" : "";
  1954. }
  1955. echo '<input '.$disabled.' id="rlrsssl_options" name="rlrsssl_options[htaccess_redirect]" size="40" type="checkbox" value="1"' . checked( 1, $this->htaccess_redirect, false ) ." />";
  1956. RSSSL()->rsssl_help->get_help_tip(__("A .htaccess redirect is faster. Really Simple SSL detects the redirect code that is most likely to work (99% of websites), but this is not 100%. Make sure you know how to regain access to your site if anything goes wrong!", "really-simple-ssl"));
  1957. echo $comment;
  1958. if ($this->htaccess_redirect && (!is_writable($this->ABSpath.".htaccess") || !$this->htaccess_test_success)) {
  1959. echo "<br><br>";
  1960. if (!is_writable($this->ABSpath.".htaccess")) _e("The .htaccess file is not writable. Add these lines to your .htaccess manually, or set 644 writing permissions", "really-simple-ssl");
  1961. if (!$this->htaccess_test_success) _e("The .htaccess redirect rules that were selected by this plugin failed in the test. The following redirect rules were tested:", "really-simple-ssl");
  1962. echo "<br><br>";
  1963. if ($this->ssl_type!="NA") {
  1964. $manual = true;
  1965. $rules = $this->get_redirect_rules($manual);
  1966. $arr_search = array("<",">","\n");
  1967. $arr_replace = array("&lt","&gt","<br>");
  1968. $rules = str_replace($arr_search, $arr_replace, $rules);
  1969. ?>
  1970. <code>
  1971. <?php echo $rules; ?>
  1972. </code>
  1973. <?php
  1974. } else {
  1975. _e("The plugin could not detect any possible redirect rule.", "really-simple-ssl");
  1976. }
  1977. }
  1978. //on multisite, the .htaccess do not edit option is not available
  1979. if (!is_multisite()) {
  1980. if ($this->do_not_edit_htaccess) {
  1981. _e("If the setting 'do not edit htaccess' is enabled, you can't change this setting.","really-simple-ssl");
  1982. } elseif (!$this->htaccess_redirect) {
  1983. $link_start = '<a target="_blank" href="https://really-simple-ssl.com/knowledge-base/remove-htaccess-redirect-site-lockout/">';
  1984. $link_end = '</a>';
  1985. printf(
  1986. __( 'Before you enable this, make sure you know how to %1$sregain access%2$s to your site in case of a redirect loop.', 'really-simple-ssl' ),
  1987. $link_start,
  1988. $link_end
  1989. );
  1990. }
  1991. }
  1992. }
  1993. /**
  1994. * Insert option into settings form
  1995. *
  1996. * @since 2.0
  1997. *
  1998. * @access public
  1999. *
  2000. */
  2001. public function get_option_do_not_edit_htaccess() {
  2002. $options = get_option('rlrsssl_options');
  2003. echo '<input id="rlrsssl_options" name="rlrsssl_options[do_not_edit_htaccess]" size="40" type="checkbox" value="1"' . checked( 1, $this->do_not_edit_htaccess, false ) ." />";
  2004. RSSSL()->rsssl_help->get_help_tip(__("If you want to customize the Really Simple SSL .htaccess, you need to prevent Really Simple SSL from rewriting it. Enabling this option will do that.", "really-simple-ssl"));
  2005. if (!$this->do_not_edit_htaccess && !is_writable($this->ABSpath.".htaccess")) _e(".htaccess is currently not writable.","really-simple-ssl");
  2006. }
  2007. /**
  2008. * Insert option into settings form
  2009. *
  2010. * @since 2.1
  2011. *
  2012. * @access public
  2013. *
  2014. */
  2015. public function get_option_switch_mixed_content_fixer_hook() {
  2016. $options = get_option('rslrsssl_options');
  2017. echo '<input id="rlrsssl_options" name="rlrsssl_options[switch_mixed_content_fixer_hook]" size="40" type="checkbox" value="1"' . checked( 1, $this->switch_mixed_content_fixer_hook, false ) ." />";
  2018. RSSSL()->rsssl_help->get_help_tip(__("If this option is set to true, the mixed content fixer will fire on the init hook instead of the template_redirect hook. Only use this option when you experience problems with the mixed content fixer.", "really-simple-ssl"));
  2019. }
  2020. public function get_option_autoreplace_insecure_links() {
  2021. //$options = get_option('rlrsssl_options');
  2022. $autoreplace_mixed_content = $this->autoreplace_insecure_links;
  2023. $disabled = "";
  2024. $comment = "";
  2025. if (is_multisite() && rsssl_multisite::this()->autoreplace_mixed_content) {
  2026. $disabled = "disabled";
  2027. $autoreplace_mixed_content = TRUE;
  2028. $comment = __( "This option is enabled on the network menu.", "really-simple-ssl" );
  2029. }
  2030. echo '<input '.$disabled.' id="rlrsssl_options" name="rlrsssl_options[autoreplace_insecure_links]" size="40" type="checkbox" value="1"' . checked( 1, $autoreplace_mixed_content, false ) .' />';
  2031. RSSSL()->rsssl_help->get_help_tip(__("In most cases you need to leave this enabled, to prevent mixed content issues on your site.", "really-simple-ssl"));
  2032. echo $comment;
  2033. }
  2034. /**
  2035. * Add settings link on plugins overview page
  2036. *
  2037. * @since 2.0
  2038. *
  2039. * @access public
  2040. *
  2041. */
  2042. public function plugin_settings_link($links) {
  2043. $settings_link = '<a href="options-general.php?page=rlrsssl_really_simple_ssl">'.__("Settings","really-simple-ssl").'</a>';
  2044. array_unshift($links, $settings_link);
  2045. $faq_link = '<a target="_blank" href="https://really-simple-ssl.com/knowledge-base/">' . __( 'Docs', 'really-simple-ssl' ) . '</a>';
  2046. array_unshift( $links, $faq_link );
  2047. if ( defined("rsssl_pro_version") ) {
  2048. if (class_exists('RSSSL_PRO')) {
  2049. if(RSSSL_PRO()->rsssl_licensing->license_is_valid()) return $links;
  2050. }
  2051. }
  2052. if ( !defined("rsssl_pro_version") ) {
  2053. if (!class_exists('RSSSL_PRO')) {
  2054. $premium_link = '<a target="_blank" href="https://really-simple-ssl.com/premium-support">' . __( 'Premium Support', 'really-simple-ssl' ) . '</a>';
  2055. array_unshift( $links, $premium_link );
  2056. }
  2057. }
  2058. return $links;
  2059. }
  2060. /**
  2061. * Check for possible plugin conflicts
  2062. *
  2063. * @since 2.0
  2064. *
  2065. * @access public
  2066. * @return none
  2067. *
  2068. */
  2069. public function check_plugin_conflicts() {
  2070. // $this->plugin_conflict["WOOCOMMERCE_FORCESSL"] = TRUE;
  2071. }
  2072. /**
  2073. * Check if wpconfig contains httponly cooky settings
  2074. *
  2075. * @since 2.5
  2076. *
  2077. * @access public
  2078. * @return boolean
  2079. *
  2080. */
  2081. public function contains_secure_cookie_settings() {
  2082. $wpconfig_path = $this->find_wp_config_path();
  2083. if (!$wpconfig_path) return false;
  2084. $wpconfig = file_get_contents($wpconfig_path);
  2085. if ( (strpos($wpconfig, "//Begin Really Simple SSL session cookie settings")===FALSE) && (strpos($wpconfig, "cookie_httponly")===FALSE) ) {
  2086. return false;
  2087. }
  2088. return true;
  2089. }
  2090. /**
  2091. * Get the absolute path the the www directory of this site, where .htaccess lives.
  2092. *
  2093. * @since 2.0
  2094. *
  2095. * @access public
  2096. *
  2097. */
  2098. public function getABSPATH(){
  2099. $path = ABSPATH;
  2100. if($this->is_subdirectory_install()){
  2101. $siteUrl = site_url();
  2102. $homeUrl = home_url();
  2103. $diff = str_replace($homeUrl, "", $siteUrl);
  2104. $diff = trim($diff,"/");
  2105. $pos = strrpos($path, $diff);
  2106. if($pos !== false){
  2107. $path = substr_replace($path, "", $pos, strlen($diff));
  2108. $path = trim($path,"/");
  2109. $path = "/".$path."/";
  2110. }
  2111. }
  2112. return $path;
  2113. }
  2114. /**
  2115. * Find if this WordPress installation is installed in a subdirectory
  2116. *
  2117. * @since 2.0
  2118. *
  2119. * @access protected
  2120. *
  2121. */
  2122. protected function is_subdirectory_install(){
  2123. if(strlen(site_url()) > strlen(home_url())){
  2124. return true;
  2125. }
  2126. return false;
  2127. }
  2128. } //class closure