From ad7cc3522a86bec8c37f205eec768995d7113dff Mon Sep 17 00:00:00 2001 From: Thomas Vervest Date: Mon, 24 Jun 2013 01:22:55 +0200 Subject: [PATCH] Added OAuth-like signature support for API calls. To use the signature supply the following parameters: nonce: http://en.wikipedia.org/wiki/Cryptographic_nonce (to be stored in the database to prevent replay attacks) timestamp: the unix timestamp when the message was created access_token: the public access token matching the private token used to create the signature signature: a sha1 hash of the request parameters (excluding the signature) ordered as per http://oauth.net/core/1.0/#rfc.section.9.1.1, concatenated with the private key (pseudo code: sha1(order_params(params) + private_key)) --- core/Tracker.php | 56 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/core/Tracker.php b/core/Tracker.php index 6f6e26738d3..6e9b0eadbac 100644 --- a/core/Tracker.php +++ b/core/Tracker.php @@ -635,13 +635,67 @@ protected function handleDisabledTracker() $this->setState(self::STATE_LOGGING_DISABLE); } } + + private function generateRequestSignature($token_auth) + { + $requestArrayToUse = $_GET + $_POST; + + $keys = array_keys($requestArrayToUse); + usort($keys, function($a, $b) { + return ord($a[0]) - ord($b[0]); + }); + + $ordered = array(); + foreach ($keys as $key) + { + $ordered[$key] = $requestArrayToUse[$key]; + } + + $variables = array(); + foreach ($ordered as $key => $value) + { + if ($key !== 'signature') + $variables[] = $key . '=' . rawurlencode($value); + } + + //die(implode('&', $variables) . $token_auth); + return sha1(implode('&', $variables) . $token_auth); + } protected function authenticateSuperUserOrAdmin($request) { $tokenAuth = $this->getTokenAuth(); if (!$tokenAuth) { - return false; + $signature = Piwik_Common::getRequestVar('signature', '', 'string', $request); + $nonce = Piwik_Common::getRequestVar('nonce', '', 'string', $request); + $timestamp = Piwik_Common::getRequestVar('timestamp', '', 'string', $request); + $access_token = Piwik_Common::getRequestVar('access_token', '', 'string', $request); + + if ($signature && $nonce && $timestamp && $access_token) { + if ($access_token !== Piwik_Config::getInstance()->superuser['access_token']) { + return false; + } + + $superUserLogin = Piwik_Config::getInstance()->superuser['login']; + $superUserPassword = Piwik_Config::getInstance()->superuser['password']; + + $token_auth = md5($superUserLogin . $superUserPassword); + + if ($signature === $this->generateRequestSignature($token_auth)) + { + $this->authenticated = true; + return true; + } + + /* + die(json_encode(array( + 'signature' => $signature, + 'generated' => $this->generateRequestSignature($token_auth) + ))); + */ + } + return false; } $superUserLogin = Piwik_Config::getInstance()->superuser['login']; $superUserPassword = Piwik_Config::getInstance()->superuser['password'];