sign_request() public method

body_hash v. body-hash is annoying. Refactor to accept an array?
public sign_request ( $token = '', $timestamp, $nonce = '', $body_hash = '', $method = '', $url = '', $body = null, $verify_body_hash = true )
 /**
  * Makes an authorized remote request using Jetpack_Signature
  *
  * @return array|WP_Error WP HTTP response on success
  */
 public static function remote_request($args, $body = null)
 {
     $defaults = array('url' => '', 'user_id' => 0, 'blog_id' => 0, 'auth_location' => JETPACK_CLIENT__AUTH_LOCATION, 'method' => 'POST', 'timeout' => 10, 'redirection' => 0);
     $args = wp_parse_args($args, $defaults);
     $args['blog_id'] = (int) $args['blog_id'];
     if ('header' != $args['auth_location']) {
         $args['auth_location'] = 'query_string';
     }
     $token = Jetpack_Data::get_access_token($args['user_id']);
     if (!$token) {
         return new Jetpack_Error('missing_token');
     }
     $method = strtoupper($args['method']);
     $timeout = intval($args['timeout']);
     $redirection = $args['redirection'];
     $request = compact('method', 'body', 'timeout', 'redirection');
     @(list($token_key, $secret) = explode('.', $token->secret));
     if (empty($token) || empty($secret)) {
         return new Jetpack_Error('malformed_token');
     }
     $token_key = sprintf('%s:%d:%d', $token_key, JETPACK__API_VERSION, $token->external_user_id);
     require_once dirname(__FILE__) . '/class.jetpack-signature.php';
     $time_diff = (int) Jetpack_Options::get_option('time_diff');
     $jetpack_signature = new Jetpack_Signature($token->secret, $time_diff);
     $timestamp = time() + $time_diff;
     $nonce = wp_generate_password(10, false);
     // Kind of annoying.  Maybe refactor Jetpack_Signature to handle body-hashing
     if (is_null($body)) {
         $body_hash = '';
     } else {
         if (!is_string($body)) {
             return new Jetpack_Error('invalid_body', 'Body is malformed.');
         }
         $body_hash = jetpack_sha1_base64($body);
     }
     $auth = array('token' => $token_key, 'timestamp' => $timestamp, 'nonce' => $nonce, 'body-hash' => $body_hash);
     if (false !== strpos($args['url'], 'xmlrpc.php')) {
         $url_args = array('for' => 'jetpack', 'wpcom_blog_id' => Jetpack_Options::get_option('id'));
     } else {
         $url_args = array();
     }
     if ('header' != $args['auth_location']) {
         $url_args += $auth;
     }
     $url = add_query_arg(urlencode_deep($url_args), $args['url']);
     $url = Jetpack::fix_url_for_bad_hosts($url);
     $signature = $jetpack_signature->sign_request($token_key, $timestamp, $nonce, $body_hash, $method, $url, $body, false);
     if (!$signature || is_wp_error($signature)) {
         return $signature;
     }
     // Send an Authorization header so various caches/proxies do the right thing
     $auth['signature'] = $signature;
     $auth['version'] = JETPACK__VERSION;
     $header_pieces = array();
     foreach ($auth as $key => $value) {
         $header_pieces[] = sprintf('%s="%s"', $key, $value);
     }
     $request['headers'] = array('Authorization' => "X_JETPACK " . join(' ', $header_pieces));
     if ('header' != $args['auth_location']) {
         $url = add_query_arg('signature', urlencode($signature), $url);
     }
     return Jetpack_Client::_wp_remote_request($url, $request);
 }
Esempio n. 2
0
 function verify_json_api_authorization_request()
 {
     require_once JETPACK__PLUGIN_DIR . 'class.jetpack-signature.php';
     $token = Jetpack_Data::get_access_token(JETPACK_MASTER_USER);
     if (!$token || empty($token->secret)) {
         wp_die(__('You must connect your Jetpack plugin to WordPress.com to use this feature.', 'jetpack'));
     }
     $die_error = __('Someone may be trying to trick you into giving them access to your site.  Or it could be you just encountered a bug :).  Either way, please close this window.', 'jetpack');
     $jetpack_signature = new Jetpack_Signature($token->secret, (int) Jetpack_Options::get_option('time_diff'));
     if (isset($_POST['jetpack_json_api_original_query'])) {
         $signature = $jetpack_signature->sign_request($_GET['token'], $_GET['timestamp'], $_GET['nonce'], '', 'GET', $_POST['jetpack_json_api_original_query'], null, true);
     } else {
         $signature = $jetpack_signature->sign_current_request(array('body' => null, 'method' => 'GET'));
     }
     if (!$signature) {
         wp_die($die_error);
     } else {
         if (is_wp_error($signature)) {
             wp_die($die_error);
         } else {
             if ($signature !== $_GET['signature']) {
                 if (is_ssl()) {
                     // If we signed an HTTP request on the Jetpack Servers, but got redirected to HTTPS by the local blog, check the HTTP signature as well
                     $signature = $jetpack_signature->sign_current_request(array('scheme' => 'http', 'body' => null, 'method' => 'GET'));
                     if (!$signature || is_wp_error($signature) || $signature !== $_GET['signature']) {
                         wp_die($die_error);
                     }
                 } else {
                     wp_die($die_error);
                 }
             }
         }
     }
     $timestamp = (int) $_GET['timestamp'];
     $nonce = stripslashes((string) $_GET['nonce']);
     if (!$this->add_nonce($timestamp, $nonce)) {
         // De-nonce the nonce, at least for 5 minutes.
         // We have to reuse this nonce at least once (used the first time when the initial request is made, used a second time when the login form is POSTed)
         $old_nonce_time = get_option("jetpack_nonce_{$timestamp}_{$nonce}");
         if ($old_nonce_time < time() - 300) {
             wp_die(__('The authorization process expired.  Please go back and try again.', 'jetpack'));
         }
     }
     $data = json_decode(base64_decode(stripslashes($_GET['data'])));
     $data_filters = array('state' => 'opaque', 'client_id' => 'int', 'client_title' => 'string', 'client_image' => 'url');
     foreach ($data_filters as $key => $sanitation) {
         if (!isset($data->{$key})) {
             wp_die($die_error);
         }
         switch ($sanitation) {
             case 'int':
                 $this->json_api_authorization_request[$key] = (int) $data->{$key};
                 break;
             case 'opaque':
                 $this->json_api_authorization_request[$key] = (string) $data->{$key};
                 break;
             case 'string':
                 $this->json_api_authorization_request[$key] = wp_kses((string) $data->{$key}, array());
                 break;
             case 'url':
                 $this->json_api_authorization_request[$key] = esc_url_raw((string) $data->{$key});
                 break;
         }
     }
     if (empty($this->json_api_authorization_request['client_id'])) {
         wp_die($die_error);
     }
 }
 /**
  * Makes an authorized remote request using Jetpack_Signature
  *
  * @return array|WP_Error WP HTTP response on success
  */
 public static function remote_request($args, $body = null)
 {
     $defaults = array('url' => '', 'user_id' => 0, 'blog_id' => 0, 'auth_location' => JETPACK_CLIENT__AUTH_LOCATION, 'method' => 'POST', 'timeout' => 10, 'redirection' => 0, 'headers' => array(), 'stream' => false, 'filename' => null);
     $args = wp_parse_args($args, $defaults);
     $args['blog_id'] = (int) $args['blog_id'];
     if ('header' != $args['auth_location']) {
         $args['auth_location'] = 'query_string';
     }
     $token = Jetpack_Data::get_access_token($args['user_id']);
     if (!$token) {
         return new Jetpack_Error('missing_token');
     }
     $method = strtoupper($args['method']);
     $timeout = intval($args['timeout']);
     $redirection = $args['redirection'];
     $stream = $args['stream'];
     $filename = $args['filename'];
     $request = compact('method', 'body', 'timeout', 'redirection', 'stream', 'filename');
     @(list($token_key, $secret) = explode('.', $token->secret));
     if (empty($token) || empty($secret)) {
         return new Jetpack_Error('malformed_token');
     }
     $token_key = sprintf('%s:%d:%d', $token_key, JETPACK__API_VERSION, $token->external_user_id);
     require_once JETPACK__PLUGIN_DIR . 'class.jetpack-signature.php';
     $time_diff = (int) Jetpack_Options::get_option('time_diff');
     $jetpack_signature = new Jetpack_Signature($token->secret, $time_diff);
     $timestamp = time() + $time_diff;
     if (function_exists('wp_generate_password')) {
         $nonce = wp_generate_password(10, false);
     } else {
         $nonce = substr(sha1(rand(0, 1000000)), 0, 10);
     }
     // Kind of annoying.  Maybe refactor Jetpack_Signature to handle body-hashing
     if (is_null($body)) {
         $body_hash = '';
     } else {
         // Allow arrays to be used in passing data.
         $body_to_hash = $body;
         if (is_array($body)) {
             // We cast this to a new variable, because the array form of $body needs to be
             // maintained so it can be passed into the request later on in the code.
             if (count($body) > 0) {
                 $body_to_hash = json_encode(self::_stringify_data($body));
             } else {
                 $body_to_hash = '';
             }
         }
         if (!is_string($body_to_hash)) {
             return new Jetpack_Error('invalid_body', 'Body is malformed.');
         }
         $body_hash = jetpack_sha1_base64($body_to_hash);
     }
     $auth = array('token' => $token_key, 'timestamp' => $timestamp, 'nonce' => $nonce, 'body-hash' => $body_hash);
     if (false !== strpos($args['url'], 'xmlrpc.php')) {
         $url_args = array('for' => 'jetpack', 'wpcom_blog_id' => Jetpack_Options::get_option('id'));
     } else {
         $url_args = array();
     }
     if ('header' != $args['auth_location']) {
         $url_args += $auth;
     }
     $url = add_query_arg(urlencode_deep($url_args), $args['url']);
     $url = Jetpack::fix_url_for_bad_hosts($url);
     $signature = $jetpack_signature->sign_request($token_key, $timestamp, $nonce, $body_hash, $method, $url, $body, false);
     if (!$signature || is_wp_error($signature)) {
         return $signature;
     }
     // Send an Authorization header so various caches/proxies do the right thing
     $auth['signature'] = $signature;
     $auth['version'] = JETPACK__VERSION;
     $header_pieces = array();
     foreach ($auth as $key => $value) {
         $header_pieces[] = sprintf('%s="%s"', $key, $value);
     }
     $request['headers'] = array_merge($args['headers'], array('Authorization' => "X_JETPACK " . join(' ', $header_pieces)));
     // Make sure we keep the host when we do JETPACK__WPCOM_JSON_API_HOST requests.
     $host = parse_url($url, PHP_URL_HOST);
     if ($host === JETPACK__WPCOM_JSON_API_HOST) {
         $request['headers']['Host'] = 'public-api.wordpress.com';
     }
     if ('header' != $args['auth_location']) {
         $url = add_query_arg('signature', urlencode($signature), $url);
     }
     return Jetpack_Client::_wp_remote_request($url, $request);
 }