PluginProbe
WPTerm / trunk
WPTerm vtrunk
1.3 trunk 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2
wpterm / class-ajax.php

class-ajax.php in WPTerm trunk, at class-ajax.php

119 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 +=====================================================================+
4 | __ ______ _____ |
5 | \ \ / / _ \_ _|__ _ __ _ __ ___ |
6 | \ \ /\ / /| |_) || |/ _ \ '__| '_ ` _ \ |
7 | \ V V / | __/ | | __/ | | | | | | | |
8 | \_/\_/ |_| |_|\___|_| |_| |_| |_| |
9 | |
10 | (c) Jerome Bruandet ~ https://nintechnet.com/ |
11 +=====================================================================+
12 */
13 if (! defined('ABSPATH') ) {
14 die('Forbidden');
15 }
16
17
18 class WPTerm_ajax {
19
20
21 /**
22 * Terminal AJAX action.
23 */
24 public static function init() {
25
26 add_action('wp_ajax_wptermajax', [ __CLASS__, 'wptermajax_callback' ] );
27
28 }
29
30
31 public static function wptermajax_callback() {
32
33 // The terminal AJAX callback function:
34
35 if (! current_user_can('install_plugins' ) || ! is_main_site() ) {
36 wp_die(0);
37 }
38
39 // Check AJAX security nonce:
40 if ( check_ajax_referer( 'wpterm_menu_terminal', 'wpterm_ajax_nonce', false ) ) {
41
42 // Path to return in case of fatal error:
43 $if_error = htmlspecialchars( rtrim( ABSPATH, '/' ) ) . '::';
44
45 // If the password protection is enabled, check the password:
46 if (! wpterm_is_allowed( 'ajax' ) ) {
47 echo $if_error . __( 'WPTerm: error, your password has expired. Reload this page to renew it.', 'wpterm');
48 wp_die();
49 }
50
51 if ( empty( $_POST['cmd'] ) || empty( $_POST['cwd'] ) ||
52 empty( $_POST['exec'] ) || empty( $_POST['abs'] ) ) {
53
54 echo $if_error . __( 'WPTerm error: missing command, path, function or abspath', 'wpterm' );
55 wp_die();
56 }
57 // Make sure the max number of lines to returned to WPTerm
58 // is a digit, otherwise set it to 512, its default value:
59 if ( empty( $_POST['scrollback'] ) || ! ctype_digit( $_POST['scrollback'] ) ) {
60 $scrollback = 512;
61 } else {
62 $scrollback = (int)$_POST['scrollback'];
63 if ( $scrollback > 3000 ) {
64 $scrollback = 3000;
65 }
66 }
67
68 // We don't want WordPress to escape strings with slashes.
69 $cmd = wp_unslash( base64_decode( trim( $_POST['cmd'] ) ) );
70 $cwd = wp_unslash( trim( $_POST['cwd'] ) );
71 $abs = wp_unslash( trim( $_POST['abs'] ) );
72 $cwd_real = realpath( $cwd );
73 $abs_real = realpath( $abs );
74 if ( false === $cwd_real || false === $abs_real ) {
75 wp_die( $if_error . __('Invalid path.', 'wpterm') );
76 }
77
78 // Set the ABSPATH variable, go to the current working directory,
79 // run the command, redirect STDERR to STDOUT and return the current
80 // working directory (it may have been changed e.g., `cd /foo/bar`):
81 $command = sprintf(
82 'ABSPATH=%s; cd %s; %s 2>&1; echo [-{-`pwd`-}-]',
83 escapeshellarg( $abs_real ),
84 escapeshellarg( $cwd_real ),
85 $cmd // arbitrary by design, we're a terminal.
86 );
87
88 // Run the command:
89 list( $res, $ret_var ) = @run_command( $command, trim( $_POST['exec'] ) );
90
91 // Split the PWD and the data returned by the command:
92 if ( preg_match('`^(.+)?\[-{-(/.*?)-}-\]`s', $res, $match ) ) {
93 // Turn the string into an array...
94 $res_array = explode( "\n", $match[1] );
95 // ...keep only the last $scrollback lines and re-create the string...
96 $res_str = implode( "\n", array_slice( $res_array, -$scrollback ) );
97 // ...and return it to WPTerm terminal:
98 echo rtrim( $match[2] . '::' . $res_str );
99 } else {
100 if (! empty( $ret_var ) ) {
101 echo $if_error . sprintf( esc_html__('WPTerm: error %s', 'wpterm'), (int) $ret_var );
102 } else {
103 echo $if_error . esc_html__('WPTerm: unknown error. Are you allowed to run PHP program execution functions?', 'wpterm');
104 }
105 }
106 } else {
107 echo '/::' . esc_html__('WPTerm: error, security nonces do not match. Try to reload this page to renew them.', 'wpterm');
108 }
109 wp_die();
110
111 }
112
113 }
114
115 WPTerm_ajax::init();
116
117 /* ================================================================== */
118 // EOF
119