summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-server-sandbox.php')
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-server-sandbox.php140
1 files changed, 126 insertions, 14 deletions
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-server-sandbox.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-server-sandbox.php
index 619194ad..2d45a0b6 100644
--- a/plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-server-sandbox.php
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-server-sandbox.php
@@ -26,14 +26,14 @@ class Server_Sandbox {
return;
}
- add_action( 'requests-requests.before_request', array( $this, 'server_sandbox' ), 10, 2 );
+ add_action( 'requests-requests.before_request', array( $this, 'server_sandbox' ), 10, 4 );
add_action( 'admin_bar_menu', array( $this, 'admin_bar_add_sandbox_item' ), 999 );
/**
* Fires when the server sandbox is initialized. This action is used to ensure that
* the server sandbox action hooks are set up only once.
*
- * @since $$next_version$$
+ * @since 1.30.7
*/
do_action( 'jetpack_server_sandbox_init' );
}
@@ -44,16 +44,20 @@ class Server_Sandbox {
* @param string $sandbox Sandbox domain.
* @param string $url URL of request about to be made.
* @param array $headers Headers of request about to be made.
+ * @param string $data The body of request about to be made.
+ * @param string $method The method of request about to be made.
*
- * @return array [ 'url' => new URL, 'host' => new Host ]
+ * @return array [ 'url' => new URL, 'host' => new Host, 'new_signature => New signature if url was changed ]
*/
- public function server_sandbox_request_parameters( $sandbox, $url, $headers ) {
- $host = '';
+ public function server_sandbox_request_parameters( $sandbox, $url, $headers, $data = null, $method = 'GET' ) {
+ $host = '';
+ $new_signature = '';
if ( ! is_string( $sandbox ) || ! is_string( $url ) ) {
return array(
- 'url' => $url,
- 'host' => $host,
+ 'url' => $url,
+ 'host' => $host,
+ 'new_signature' => $new_signature,
);
}
@@ -64,16 +68,118 @@ class Server_Sandbox {
case 'jetpack.wordpress.com':
case 'jetpack.com':
case 'dashboard.wordpress.com':
- $host = isset( $headers['Host'] ) ? $headers['Host'] : $url_host;
- $url = preg_replace(
+ $host = isset( $headers['Host'] ) ? $headers['Host'] : $url_host;
+ $original_url = $url;
+ $url = preg_replace(
'@^(https?://)' . preg_quote( $url_host, '@' ) . '(?=[/?#].*|$)@',
'${1}' . $sandbox,
$url,
1
);
+
+ /**
+ * Whether to add the X Debug query parameter to the request made to the Sandbox
+ *
+ * @since 1.36.0
+ *
+ * @param bool $add_parameter Whether to add the parameter to the request or not. Default is to false.
+ * @param string $url The URL of the request being made.
+ * @param string $host The host of the request being made.
+ */
+ if ( apply_filters( 'jetpack_sandbox_add_profile_parameter', false, $url, $host ) ) {
+ $url = add_query_arg( 'XDEBUG_PROFILE', 1, $url );
+
+ // URL has been modified since the signature was created. We'll need a new one.
+ $original_url = add_query_arg( 'XDEBUG_PROFILE', 1, $original_url );
+ $new_signature = $this->get_new_signature( $original_url, $headers, $data, $method );
+
+ }
+ }
+
+ return compact( 'url', 'host', 'new_signature' );
+ }
+
+ /**
+ * Gets a new signature for the request
+ *
+ * @param string $url The new URL to be signed.
+ * @param array $headers The headers of the request about to be made.
+ * @param string $data The body of request about to be made.
+ * @param string $method The method of the request about to be made.
+ * @return string|null
+ */
+ private function get_new_signature( $url, $headers, $data, $method ) {
+
+ if ( ! empty( $headers['Authorization'] ) ) {
+ $a_headers = $this->extract_authorization_headers( $headers );
+ if ( ! empty( $a_headers ) ) {
+ $token_details = explode( ':', $a_headers['token'] );
+
+ if ( count( $token_details ) === 3 ) {
+ $user_id = $token_details[2];
+ $token = ( new Tokens() )->get_access_token( $user_id );
+ $time_diff = (int) \Jetpack_Options::get_option( 'time_diff' );
+ $jetpack_signature = new \Jetpack_Signature( $token->secret, $time_diff );
+
+ $signature = $jetpack_signature->sign_request(
+ $a_headers['token'],
+ $a_headers['timestamp'],
+ $a_headers['nonce'],
+ $a_headers['body-hash'],
+ $method,
+ $url,
+ $data,
+ false
+ );
+
+ if ( $signature && ! is_wp_error( $signature ) ) {
+ return $signature;
+ } elseif ( is_wp_error( $signature ) ) {
+ $this->log_new_signature_error( $signature->get_error_message() );
+ }
+ } else {
+ $this->log_new_signature_error( 'Malformed token on Authorization Header' );
+ }
+ } else {
+ $this->log_new_signature_error( 'Error extracting Authorization Header' );
+ }
+ } else {
+ $this->log_new_signature_error( 'Empty Authorization Header' );
}
- return compact( 'url', 'host' );
+ }
+
+ /**
+ * Logs error if the attempt to create a new signature fails
+ *
+ * @param string $message The error message.
+ * @return void
+ */
+ private function log_new_signature_error( $message ) {
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
+ error_log( sprintf( "SANDBOXING: Error re-signing the request. '%s'", $message ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
+ }
+ }
+
+ /**
+ * Extract the values in the Authorization header into an array
+ *
+ * @param array $headers The headers of the request about to be made.
+ * @return array|null
+ */
+ public function extract_authorization_headers( $headers ) {
+ if ( ! empty( $headers['Authorization'] ) && is_string( $headers['Authorization'] ) ) {
+ $header = str_replace( 'X_JETPACK ', '', $headers['Authorization'] );
+ $vars = explode( ' ', $header );
+ $result = array();
+ foreach ( $vars as $var ) {
+ $elements = explode( '"', $var );
+ if ( count( $elements ) === 3 ) {
+ $result[ substr( $elements[0], 0, -1 ) ] = $elements[1];
+ }
+ }
+ return $result;
+ }
}
/**
@@ -82,24 +188,30 @@ class Server_Sandbox {
*
* Attached to the `requests-requests.before_request` filter.
*
- * @param string $url URL of request about to be made.
- * @param array $headers Headers of request about to be made.
+ * @param string $url URL of request about to be made.
+ * @param array $headers Headers of request about to be made.
+ * @param array|string $data Data of request about to be made.
+ * @param string $type Type of request about to be made.
* @return void
*/
- public function server_sandbox( &$url, &$headers ) {
+ public function server_sandbox( &$url, &$headers, &$data = null, &$type = null ) {
if ( ! Constants::get_constant( 'JETPACK__SANDBOX_DOMAIN' ) ) {
return;
}
$original_url = $url;
- $request_parameters = $this->server_sandbox_request_parameters( Constants::get_constant( 'JETPACK__SANDBOX_DOMAIN' ), $url, $headers );
+ $request_parameters = $this->server_sandbox_request_parameters( Constants::get_constant( 'JETPACK__SANDBOX_DOMAIN' ), $url, $headers, $data, $type );
$url = $request_parameters['url'];
if ( $request_parameters['host'] ) {
$headers['Host'] = $request_parameters['host'];
+ if ( $request_parameters['new_signature'] ) {
+ $headers['Authorization'] = preg_replace( '/signature=\"[^\"]+\"/', 'signature="' . $request_parameters['new_signature'] . '"', $headers['Authorization'] );
+ }
+
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( sprintf( "SANDBOXING via '%s': '%s'", Constants::get_constant( 'JETPACK__SANDBOX_DOMAIN' ), $original_url ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
}