PluginProbe ʕ •ᴥ•ʔ
Really Simple Security – Simple and Performant Security (formerly Really Simple SSL) / 9.5.11
Really Simple Security – Simple and Performant Security (formerly Really Simple SSL) v9.5.11
9.5.11 9.5.10.1 9.5.10 trunk 9.4.0 9.4.1 9.4.2 9.4.3 9.5.0 9.5.0.1 9.5.0.2 9.5.1 9.5.2 9.5.2.2 9.5.2.3 9.5.3 9.5.3.1 9.5.3.2 9.5.4 9.5.5 9.5.6 9.5.7 9.5.8 9.5.9
really-simple-ssl / lets-encrypt / functions.php
really-simple-ssl / lets-encrypt Last commit date
config 4 weeks ago integrations 4 weeks ago vendor 4 weeks ago class-le-restapi.php 4 weeks ago class-letsencrypt-handler.php 4 weeks ago composer.json 4 weeks ago cron.php 4 weeks ago download.php 4 weeks ago functions.php 4 weeks ago index.php 4 weeks ago letsencrypt.php 4 weeks ago
functions.php
591 lines
1 <?php defined( 'ABSPATH' ) or die();
2
3 /**
4 * Create a generic read more text with link for help texts.
5 *
6 * @param string $url
7 * @param bool $add_space
8 *
9 * @return string
10 */
11 function rsssl_le_read_more( $url, $add_character = ' ' ) {
12 $html = sprintf( __( "For more information, please read this %sarticle%s",
13 'really-simple-ssl' ), '<a target="_blank" rel="noopener noreferrer" href="' . $url . '">',
14 '</a>' );
15 if ( is_string($add_character) ) {
16 $html = $add_character . $html;
17 }
18
19 return $html;
20 }
21
22
23
24 /**
25 * Check if we need to use DNS verification
26 * @return bool
27 */
28 function rsssl_dns_verification_required(){
29
30 if ( get_option('rsssl_manually_changed_verification_type') ) {
31 return rsssl_get_option( 'verification_type' ) === 'dns';
32 }
33 /**
34 * If our current hosting provider does not allow or require local SSL certificate generation,
35 * We do not need to DNS verification either.
36 */
37
38 if ( !rsssl_do_local_lets_encrypt_generation() ) {
39 return false;
40 }
41
42 if ( rsssl_get_option('verification_type')==='dns' ) {
43 return true;
44 }
45
46 if ( rsssl_wildcard_certificate_required() ) {
47 //if the user hasn't manually forced the verification type to anything else, we set it to dns now.
48 //otherwise we get a difference between this requirement, and the actual verification type that could be 'dir'
49 if ( !get_option('rsssl_manually_changed_verification_type') && rsssl_get_option('verification_type')!=='dns' ) {
50 rsssl_update_option('verification_type', 'dns');
51 }
52 return true;
53 }
54 return false;
55 }
56
57 if ( !function_exists('rsssl_is_cpanel')) {
58 /**
59 * Check if we're on CPanel
60 *
61 * @return bool
62 */
63 function rsssl_is_cpanel() {
64 $open_basedir = ini_get("open_basedir");
65 if ( empty($open_basedir) && file_exists( "/usr/local/cpanel" ) ) {
66 return true;
67 } else if (rsssl_check_port(2082)) {
68 return true;
69 } else {
70 return false;
71 }
72 }
73 }
74
75 if (!function_exists('rsssl_cpanel_api_supported')) {
76 /**
77 * Check if CPanel supports the api
78 *
79 * @return bool
80 */
81 function rsssl_cpanel_api_supported() {
82 if ( rsssl_is_cpanel() ) {
83 return true;
84 }
85
86 return !rsssl_openbasedir_restriction("/usr/local/cpanel/php/cpanel.php") && file_exists( "/usr/local/cpanel/php/cpanel.php" );
87 }
88 }
89
90 if (!function_exists('rsssl_activated_by_default')) {
91 /**
92 * Check if the host has ssl, activated by default
93 *
94 * @return bool
95 */
96 function rsssl_activated_by_default() {
97 $activated_by_default = false;
98 $activated_by_default_hosts = RSSSL_LE()->hosts->activated_by_default;
99 $current_host = rsssl_get_other_host();
100 if ( in_array( $current_host, $activated_by_default_hosts ) ) {
101 $activated_by_default = true;
102 }
103 return $activated_by_default;
104 }
105 }
106
107 if ( !function_exists('rsssl_openbasedir_restriction')) {
108 function rsssl_openbasedir_restriction( string $path): bool {
109
110 // Default error handler is required
111 set_error_handler(null);
112
113 // Clean last error info.
114 error_clear_last();
115
116 // Testing...
117 @file_exists($path);
118
119 // Restore previous error handler
120 restore_error_handler();
121
122 // Return `true` if error has occurred
123 return ($error = error_get_last()) && $error['message'] !== '__clean_error_info';
124 }
125 }
126
127 if (!function_exists('rsssl_activation_required')) {
128 /**
129 * Check if the host has ssl, activation required
130 *
131 * @return bool
132 */
133 function rsssl_activation_required() {
134 $dashboard_activation_required = false;
135 $dashboard_activation_required_hosts = RSSSL_LE()->hosts->dashboard_activation_required;
136 $current_host = rsssl_get_other_host();
137 if ( in_array( $current_host, $dashboard_activation_required_hosts ) ) {
138 $dashboard_activation_required = true;
139 }
140 return $dashboard_activation_required;
141 }
142 }
143
144 if (!function_exists('rsssl_paid_only')) {
145 /**
146 * Check if the host has ssl, paid only
147 *
148 * @return bool
149 */
150 function rsssl_paid_only() {
151 $paid_only = false;
152 $paid_only_hosts = RSSSL_LE()->hosts->paid_only;
153 $current_host = rsssl_get_other_host();
154 if ( in_array( $current_host, $paid_only_hosts ) ) {
155 $paid_only = true;
156 }
157 return $paid_only;
158 }
159 }
160
161 if ( !function_exists('rsssl_is_plesk')) {
162 /**
163 * https://stackoverflow.com/questions/26927248/how-to-detect-servers-control-panel-type-with-php
164 * @return false
165 */
166 function rsssl_is_plesk() {
167
168 if ( get_option('rsssl_hosting_dashboard')==='plesk' ){
169 return true;
170 }
171
172 //cpanel takes precedence, as it's more precise
173 if ( rsssl_is_cpanel() ) {
174 return false;
175 }
176
177 $open_basedir = ini_get("open_basedir");
178 if ( empty($open_basedir) && is_dir( '/usr/local/psa' ) ) {
179 return true;
180 } else if (rsssl_check_port(8443)) {
181 return true;
182 } else {
183 return false;
184 }
185 }
186 }
187
188 if ( !function_exists('rsssl_is_directadmin')) {
189 /**
190 * https://stackoverflow.com/questions/26927248/how-to-detect-servers-control-panel-type-with-php
191 * @return bool
192 */
193 function rsssl_is_directadmin() {
194 if ( get_option('rsssl_hosting_dashboard')==='directadmin' ){
195 return true;
196 }
197
198 //cpanel takes precedence, as it's more precise
199 if ( rsssl_is_cpanel() ) {
200 return false;
201 }
202
203 if ( rsssl_is_plesk() ) {
204 return false;
205 }
206
207 if (rsssl_check_port(2222)) {
208 return true;
209 } else {
210 return false;
211 }
212 }
213 }
214
215 /**
216 * @param int $port
217 *
218 * @return bool
219 */
220
221 function rsssl_check_port( $port)
222 {
223 $port_check_status = get_option("rsssl_port_check_$port");
224 if ( !function_exists('fsockopen') || $port_check_status === 'fail' ) {
225 return false;
226 }
227
228 $ipAddress = gethostbyname('localhost');
229 $link = @fsockopen( $ipAddress, $port, $errno, $error, 5 );
230
231 if ( $link ) {
232 update_option("rsssl_port_check_$port", 'success', false);
233 return true;
234 }
235
236 update_option("rsssl_port_check_$port", 'fail', false);
237 return false;
238 }
239
240 if ( !function_exists('rsssl_get_other_host') ) {
241 /**
242 * Get the selected hosting provider, if any.
243 * @return bool|string
244 */
245 function rsssl_get_other_host() {
246 return rsssl_get_option( 'other_host_type', false );
247 }
248 }
249
250 /**
251 * Add some information to the javascript
252 * @param array $args
253 *
254 * @return array
255 */
256 function rsssl_le_localize_script($args){
257 $hosting_dashboard = 'other';
258 if ( rsssl_is_cpanel() ) $hosting_dashboard = 'cpanel';
259 if ( rsssl_is_directadmin() ) $hosting_dashboard = 'directadmin';
260 if ( rsssl_is_plesk() ) $hosting_dashboard = 'plesk';
261 $args['hosting_dashboard'] = $hosting_dashboard;
262 return $args;
263 }
264 add_filter("rsssl_localize_script", 'rsssl_le_localize_script', 10, 3);
265
266
267 if ( !function_exists('rsssl_progress_add')) {
268 /**
269 * @param string $item
270 */
271 function rsssl_progress_add( $item ) {
272 $progress = get_option( "rsssl_le_installation_progress", array() );
273 if ( ! in_array( $item, $progress ) ) {
274 $progress[] = $item;
275 update_option( "rsssl_le_installation_progress", $progress, false );
276 }
277 }
278 }
279
280 if ( !function_exists('rsssl_uses_known_dashboard')) {
281 /**
282 * Check if website uses any of the known dashboards.
283 */
284 function rsssl_uses_known_dashboard( ) {
285 if ( rsssl_is_cpanel() || rsssl_is_plesk() || rsssl_is_directadmin() ) {
286 return true;
287 } else {
288 return false;
289 }
290 }
291 }
292
293 if ( !function_exists('rsssl_is_ready_for')) {
294 /**
295 * @param string $item
296 */
297 function rsssl_is_ready_for( $item ) {
298 if ( !rsssl_do_local_lets_encrypt_generation() ) {
299 rsssl_progress_add('directories');
300 rsssl_progress_add('generation');
301 rsssl_progress_add('dns-verification');
302 }
303
304 if ( !rsssl_dns_verification_required() ) {
305 rsssl_progress_add('dns-verification');
306 }
307
308 if (empty(rsssl_get_not_completed_steps($item))){
309 return true;
310 } else{
311 return false;
312 }
313 }
314 }
315
316 function rsssl_get_not_completed_steps($item){
317 $sequence = array_column( rsssl_le_steps(), 'id');
318 //drop first
319 array_shift($sequence);
320 //drop all statuses after $item. We only need to know if all previous ones have been completed
321 $index = array_search($item, $sequence);
322 $sequence = array_slice($sequence, 0, $index, true);
323 $not_completed = array();
324 $finished = get_option("rsssl_le_installation_progress", array());
325 foreach ($sequence as $status ) {
326 if (!in_array($status, $finished)) {
327 $not_completed[] = $status;
328 }
329 }
330
331 return $not_completed;
332 }
333
334 if ( !function_exists('rsssl_progress_remove')) {
335 /**
336 * @param string $item
337 */
338 function rsssl_progress_remove( $item ) {
339 $progress = get_option( "rsssl_le_installation_progress", array() );
340 if ( in_array( $item, $progress ) ) {
341 $index = array_search( $item, $progress );
342 unset( $progress[ $index ] );
343 update_option( "rsssl_le_installation_progress", $progress, false );
344 }
345 }
346 }
347
348 if ( !function_exists('rsssl_do_local_lets_encrypt_generation')) {
349 /**
350 * Check if the setup requires local certificate generation
351 * @return bool
352 */
353 function rsssl_do_local_lets_encrypt_generation() {
354 $not_local_cert_hosts = RSSSL_LE()->hosts->not_local_certificate_hosts;
355 $current_host = rsssl_get_other_host();
356 if ( in_array( $current_host, $not_local_cert_hosts ) ) {
357 return false;
358 }
359 return true;
360 }
361 }
362
363 if ( !function_exists('rsssl_get_manual_instructions_text')) {
364 /**
365 * Manual installation instructions
366 *
367 * @param string $url
368 *
369 * @return string
370 */
371 function rsssl_get_manual_instructions_text( $url ) {
372 $default_url = rsssl_link('install-ssl-certificate');
373 $dashboard_activation_required = rsssl_activation_required();
374 $activated_by_default = rsssl_activated_by_default();
375 $paid_only = rsssl_paid_only();
376 $button_activate = '<br><a href="' . $default_url . '" target="_blank" rel="noopener noreferrer" class="button button-primary">' . __( "Instructions", "really-simple-ssl" ) . '</a>&nbsp;&nbsp;';
377 $button_complete = '<br><a href="' . $default_url . '" target="_blank" rel="noopener noreferrer" class="button button-primary">' . __( "Instructions", "really-simple-ssl" ) . '</a>&nbsp;&nbsp;';
378
379 if ( $url === $default_url ) {
380 $complete_manually = sprintf( __( "Please complete manually in your hosting dashboard.", "really-simple-ssl" ), '<a target="_blank" href="' . $url . '">', '</a>' );
381 $activate_manually = sprintf( __( "Please activate it manually on your hosting dashboard.", "really-simple-ssl" ), '<a target="_blank" href="' . $url . '">', '</a>' );
382 } else {
383 $complete_manually = sprintf( __( "Please complete %smanually%s", "really-simple-ssl" ), '<a target="_blank" rel="noopener noreferrer" href="' . $url . '">', '</a>' );
384 $activate_manually = sprintf( __( "Please activate it on your dashboard %smanually%s", "really-simple-ssl" ), '<a target="_blank" rel="noopener noreferrer" href="' . $url . '">', '</a>' );
385 $button_activate .= '<a href="' . $url . '" target="_blank" rel="noopener noreferrer" class="button button-primary">' . __( "Go to activation", "really-simple-ssl" ) . '</a>';
386 $button_complete .= '<a href="' . $url . '" target="_blank" rel="noopener noreferrer" class="button button-primary">' . __( "Go to installation", "really-simple-ssl" ) . '</a>';
387 }
388
389 if ( $activated_by_default ) {
390 $msg
391 = sprintf( __( "According to our information, your hosting provider supplies your account with an SSL certificate by default. Please contact your %shosting support%s if this is not the case.",
392 "really-simple-ssl" ), '<a target="_blank "rel="noopener noreferrer" href="' . $url . '">', '</a>' ) . '&nbsp' .
393 __( "After completing the installation, you can continue to the next step to complete your configuration.", "really-simple-ssl" );
394 } else if ( $dashboard_activation_required ) {
395 $msg = __( "You already have free SSL on your hosting environment.", "really-simple-ssl" ) . '&nbsp' .
396 $activate_manually . ' ' .
397 __( "After completing the installation, you can continue to the next step to complete your configuration.", "really-simple-ssl" )
398 . $button_activate;
399 } else if ( $paid_only ) {
400 $msg
401 = sprintf( __( "According to our information, your hosting provider does not allow any kind of SSL installation, other than their own paid certificate. For an alternative hosting provider with SSL, see this %sarticle%s.",
402 "really-simple-ssl" ), '<a target="_blank" rel="noopener noreferrer" href='.rsssl_link("hosting-providers-with-free-ssl").'>', '</a>' );
403 } else {
404 $msg = __( "Your hosting environment does not allow automatic SSL installation.", "really-simple-ssl" ) . ' ' .
405 $complete_manually . ' ' .
406 sprintf( __( "You can follow these %sinstructions%s.", "really-simple-ssl" ), '<a target="_blank" rel="noopener noreferrer" href="' . $default_url . '">', '</a>' ) . '&nbsp' .
407 __( "After completing the installation, you can continue to the next step to complete your configuration.", "really-simple-ssl" )
408 . $button_complete;
409 }
410
411 return $msg;
412 }
413 }
414
415 register_activation_hook( __FILE__, 'rsssl_set_activation_time_stamp' );
416 if ( ! function_exists( 'rsssl_set_activation_time_stamp' ) ) {
417 function rsssl_set_activation_time_stamp( $networkwide ) {
418 update_option( 'rsssl_activation_time', time(), false );
419 }
420 }
421
422 if ( ! function_exists( 'rsssl_array_filter_multidimensional' ) ) {
423 function rsssl_array_filter_multidimensional(
424 $array, $filter_key, $filter_value
425 ) {
426 $new = array_filter( $array,
427 function ( $var ) use ( $filter_value, $filter_key ) {
428 return isset( $var[ $filter_key ] ) ? ( $var[ $filter_key ]
429 == $filter_value )
430 : false;
431 } );
432
433 return $new;
434 }
435 }
436
437 if ( !function_exists('rsssl_is_subdomain') ) {
438 /**
439 * Check if we're on a subdomain.
440 * If this is a www domain, we return false
441 */
442 function rsssl_is_subdomain(){
443 $domain = rsssl_get_domain();
444 if ( strpos($domain, 'www.') !== false ) return false;
445 $root = rsssl_get_root_domain($domain);
446 if ($root === $domain ) {
447 return false;
448 } else {
449 return true;
450 }
451 }
452 }
453
454 if ( !function_exists('rsssl_get_root_domain') ) {
455 /**
456 * Get root domain of a domain
457 */
458 function rsssl_get_root_domain($domain){
459 $sub = strtolower(trim($domain));
460 $count = substr_count($sub, '.');
461 if($count === 2){
462 if(strlen(explode('.', $sub)[1]) > 3) $sub = explode('.', $sub, 2)[1];
463 } else if($count > 2){
464 $sub = rsssl_get_root_domain(explode('.', $sub, 2)[1]);
465 }
466 return $sub;
467 }
468 }
469
470 if ( ! function_exists( 'rsssl_get_domain' ) ) {
471 /**
472 * Get current domain
473 *
474 * @return string
475 */
476 function rsssl_get_domain() {
477 //Get current domain
478 $domain = site_url();
479 //Parse to strip off any /subfolder/
480 $parse = parse_url($domain);
481 $domain = $parse['host'];
482 $domain = str_replace(array('http://', 'https://' ), '', $domain);
483 return $domain;
484 }
485 }
486
487 function rsssl_insert_after_key($array, $key, $items){
488 $keys = array_keys($array);
489 $key = array_search($key, $keys);
490 $array = array_slice($array, 0, $key, true) +
491 $items +
492 array_slice($array, 3, count($array)-3, true);
493
494 return $array;
495 }
496
497 if ( !function_exists('rsssl_wildcard_certificate_required') ) {
498 /**
499 * Check if the site requires a wildcard
500 *
501 * @return bool
502 */
503 function rsssl_wildcard_certificate_required() {
504 //if DNS verification, create wildcard.
505 if ( rsssl_get_option('verification_type') === 'dns' ) {
506 return true;
507 }
508
509 if ( ! is_multisite() ) {
510 return false;
511 } else {
512 if ( defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ) {
513 return true;
514 } else {
515 return false;
516 }
517 }
518 }
519 }
520
521 if ( !function_exists('rsssl_can_install_shell_addon') ) {
522
523 /**
524 * check if this environment has shell capability
525 *
526 * @return bool
527 */
528
529 function rsssl_can_install_shell_addon(){
530 //if not cpanel
531 if ( !rsssl_is_cpanel() ) {
532 return false;
533 }
534
535 //if already installed
536 if (defined('rsssl_shell_path')){
537 return false;
538 }
539
540 if ( function_exists('shell_exec') || function_exists('system') || function_exists('passthru') || function_exists('exec') ) {
541 return true;
542 } else {
543 return false;
544 }
545 }
546 }
547
548 if ( !function_exists('rsssl_generated_by_rsssl')) {
549 /**
550 * If a bundle generation is completed, this value is set to true.
551 *
552 * @return bool
553 */
554 function rsssl_generated_by_rsssl() {
555 return get_option( 'rsssl_le_certificate_generated_by_rsssl' );
556 }
557 }
558
559 /**
560 * Checks if a CAA DNS record is preventing the use of Let's Encrypt for the current site.
561 *
562 * @return bool Returns true if a CAA DNS record exists and does not allow Let's Encrypt, false otherwise.
563 */
564 if ( ! function_exists( 'rsssl_caa_record_prevents_le' ) ) {
565 function rsssl_caa_record_prevents_le(): bool {
566 // Get DNS CAA records for site_url()
567 $caa_records = dns_get_record( parse_url( site_url(), PHP_URL_HOST ), DNS_CAA );
568
569 // If no CAA records found, return false
570 if ( empty( $caa_records ) ) {
571 return false;
572 }
573
574 // Check if the CAA record contains letsencrypt.org
575 $caa_contains_le = false;
576 foreach ( $caa_records as $caa_record ) {
577 if ( strpos( $caa_record['value'], 'letsencrypt.org' ) !== false ) {
578 $caa_contains_le = true;
579 break;
580 }
581 }
582
583 // If the CAA record is set, but does not contain letsencrypt.org, return true;
584 if ( ! $caa_contains_le ) {
585 return true;
586 }
587
588 // CAA record contains Let's Encrypt, generation allowed
589 return false;
590 }
591 }