diff --git a/modules/cdc/config-templates/module_cdc.php b/modules/cdc/config-templates/module_cdc.php deleted file mode 100644 index 411bbc47110b4581eab72f0174f4edd66da9ff3e..0000000000000000000000000000000000000000 --- a/modules/cdc/config-templates/module_cdc.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -$config = [ - 'example.org' => [ - /* - * The shared key for this CDC server. - */ - 'key' => 'ExampleSharedKey', - - /* - * The URL to the server script. - */ - 'server' => 'https://my-cdc.example.org/simplesaml/module.php/cdc/server.php', - - /* - * The lifetime of our cookie, in seconds. - * - * If this is 0, the cookie will expire when the browser is closed. - */ - 'cookie.lifetime' => 0, - ], -]; diff --git a/modules/cdc/default-disable b/modules/cdc/default-disable deleted file mode 100644 index fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f..0000000000000000000000000000000000000000 --- a/modules/cdc/default-disable +++ /dev/null @@ -1,3 +0,0 @@ -This file indicates that the default state of this module -is disabled. To enable, create a file named enable in the -same directory as this file. diff --git a/modules/cdc/lib/Auth/Process/CDC.php b/modules/cdc/lib/Auth/Process/CDC.php deleted file mode 100644 index bf2a669d67ca5b60275cb3c4f26ea71deab7fd29..0000000000000000000000000000000000000000 --- a/modules/cdc/lib/Auth/Process/CDC.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -namespace SimpleSAML\module\cdc\Auth\Process; - -/** - * Filter for setting the SAML 2 common domain cookie. - * - * @package SimpleSAMLphp - */ - -class CDC extends \SimpleSAML\Auth\ProcessingFilter -{ - /** - * Our CDC domain. - * - * @var string - */ - private $domain; - - - /** - * Our CDC client. - * - * @var \SimpleSAML\Module\cdc\Client - */ - private $client; - - - /** - * Initialize this filter. - * - * @param array $config Configuration information about this filter. - * @param mixed $reserved For future use. - */ - public function __construct($config, $reserved) - { - parent::__construct($config, $reserved); - assert(is_array($config)); - - if (!isset($config['domain'])) { - throw new \SimpleSAML\Error\Exception('Missing domain option in cdc:CDC filter.'); - } - $this->domain = (string) $config['domain']; - - $this->client = new \SimpleSAML\Module\cdc\Client($this->domain); - } - - - /** - * Redirect to page setting CDC. - * - * @param array &$state The request state. - */ - public function process(&$state) - { - assert(is_array($state)); - - if (!isset($state['Source']['entityid'])) { - \SimpleSAML\Logger::warning('saml:CDC: Could not find IdP entityID.'); - return; - } - - // Save state and build request - $id = \SimpleSAML\Auth\State::saveState($state, 'cdc:resume'); - - $returnTo = \SimpleSAML\Module::getModuleURL('cdc/resume.php', ['domain' => $this->domain]); - - $params = [ - 'id' => $id, - 'entityID' => $state['Source']['entityid'], - ]; - $this->client->sendRequest($returnTo, 'append', $params); - } -} diff --git a/modules/cdc/lib/Client.php b/modules/cdc/lib/Client.php deleted file mode 100644 index 609aef63f403f78256597fc3a2e4f6a4d075cfe9..0000000000000000000000000000000000000000 --- a/modules/cdc/lib/Client.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php - -namespace SimpleSAML\Module\cdc; - -/** - * CDC client class. - * - * @package SimpleSAMLphp - */ - -class Client -{ - /** - * Our CDC domain. - * - * @var string - */ - private $domain; - - - /** - * The CDC server we send requests to. - * - * @var Server|NULL - */ - private $server; - - - /** - * Initialize a CDC client. - * - * @param string $domain The domain we should query the server for. - */ - public function __construct($domain) - { - assert(is_string($domain)); - - $this->domain = $domain; - $this->server = new Server($domain); - } - - - /** - * Receive a CDC response. - * - * @return array|NULL The response, or NULL if no response is received. - */ - public function getResponse() - { - return $this->server->getResponse(); - } - - - /** - * Send a request. - * - * @param string $returnTo The URL we should return to afterwards. - * @param string $op The operation we are performing. - * @param array $params Additional parameters. - */ - public function sendRequest($returnTo, $op, array $params = []) - { - assert(is_string($returnTo)); - assert(is_string($op)); - - $params['op'] = $op; - $params['return'] = $returnTo; - $this->server->sendRequest($params); - } -} diff --git a/modules/cdc/lib/Server.php b/modules/cdc/lib/Server.php deleted file mode 100644 index affcf668ac241429c7eb933f87bfb48605dac0f1..0000000000000000000000000000000000000000 --- a/modules/cdc/lib/Server.php +++ /dev/null @@ -1,426 +0,0 @@ -<?php - -namespace SimpleSAML\Module\cdc; - -/** - * CDC server class. - * - * @package SimpleSAMLphp - */ - -class Server -{ - /** - * The domain. - * - * @var string - */ - private $domain; - - - /** - * The URL to the server. - * - * @var string - */ - private $server; - - - /** - * Our shared key. - * - * @var string - */ - private $key; - - - /** - * The lifetime of our cookie, in seconds. - * - * If this is 0, the cookie will expire when the browser is closed. - * - * @param int - */ - private $cookieLifetime; - - - /** - * Initialize a CDC server. - * - * @param string $domain The domain we are a server for. - */ - public function __construct($domain) - { - assert(is_string($domain)); - - $cdcConfig = \SimpleSAML\Configuration::getConfig('module_cdc.php'); - $config = $cdcConfig->getConfigItem($domain, null); - - if ($config === null) { - throw new \SimpleSAML\Error\Exception('Unknown CDC domain: '.var_export($domain, true)); - } - - $this->domain = $domain; - $this->server = $config->getString('server'); - $this->key = $config->getString('key'); - $this->cookieLifetime = $config->getInteger('cookie.lifetime', 0); - - if ($this->key === 'ExampleSharedKey') { - throw new \SimpleSAML\Error\Exception( - 'Key for CDC domain '.var_export($domain, true).' not changed from default.' - ); - } - } - - - /** - * Send a request to this CDC server. - * - * @param array $request The CDC request. - */ - public function sendRequest(array $request) - { - assert(isset($request['return'])); - assert(isset($request['op'])); - - $request['domain'] = $this->domain; - $this->send($this->server, 'CDCRequest', $request); - } - - - /** - * Parse and validate response received from a CDC server. - * - * @return array|NULL The response, or NULL if no response is received. - */ - public function getResponse() - { - $response = self::get('CDCResponse'); - if ($response === null) { - return null; - } - - if ($response['domain'] !== $this->domain) { - throw new \SimpleSAML\Error\Exception('Response received from wrong domain.'); - } - - $this->validate('CDCResponse'); - - return $response; - } - - - /** - * Parse and process a CDC request. - */ - public static function processRequest() - { - $request = self::get('CDCRequest'); - if ($request === null) { - throw new \SimpleSAML\Error\BadRequest('Missing "CDCRequest" parameter.'); - } - - $domain = $request['domain']; - $server = new Server($domain); - - $server->validate('CDCRequest'); - $server->handleRequest($request); - } - - - /** - * Handle a parsed CDC requst. - * - * @param array $request - */ - private function handleRequest(array $request) - { - if (!isset($request['op'])) { - throw new \SimpleSAML\Error\BadRequest('Missing "op" in CDC request.'); - } - $op = (string) $request['op']; - - \SimpleSAML\Logger::info('Received CDC request with "op": '.var_export($op, true)); - - if (!isset($request['return'])) { - throw new \SimpleSAML\Error\BadRequest('Missing "return" in CDC request.'); - } - $return = (string) $request['return']; - - switch ($op) { - case 'append': - $response = $this->handleAppend($request); - break; - case 'delete': - $response = $this->handleDelete($request); - break; - case 'read': - $response = $this->handleRead($request); - break; - default: - $response = 'unknown-op'; - } - - if (is_string($response)) { - $response = [ - 'status' => $response, - ]; - } - - $response['op'] = $op; - if (isset($request['id'])) { - $response['id'] = (string) $request['id']; - } - $response['domain'] = $this->domain; - - $this->send($return, 'CDCResponse', $response); - } - - - /** - * Handle an append request. - * - * @param array $request The request. - * @return string The response. - */ - private function handleAppend(array $request) - { - if (!isset($request['entityID'])) { - throw new \SimpleSAML\Error\BadRequest('Missing entityID in append request.'); - } - $entityID = (string) $request['entityID']; - - $list = $this->getCDC(); - - $prevIndex = array_search($entityID, $list, true); - if ($prevIndex !== false) { - unset($list[$prevIndex]); - } - $list[] = $entityID; - - $this->setCDC($list); - - return 'ok'; - } - - - /** - * Handle a delete request. - * - * @param array $request The request. - * @return string The response. - */ - private function handleDelete(array $request) - { - $params = [ - 'path' => '/', - 'domain' => '.'.$this->domain, - 'secure' => true, - 'httponly' => false, - ]; - - \SimpleSAML\Utils\HTTP::setCookie('_saml_idp', null, $params, false); - return 'ok'; - } - - - /** - * Handle a read request. - * - * @param array $request The request. - * @return array The response. - */ - private function handleRead(array $request) - { - $list = $this->getCDC(); - - return [ - 'status' => 'ok', - 'cdc' => $list, - ]; - } - - - /** - * Helper function for parsing and validating a CDC message. - * - * @param string $parameter The name of the query parameter. - * @return array|NULL The response, or NULL if no response is received. - */ - private static function get($parameter) - { - assert(is_string($parameter)); - - if (!isset($_REQUEST[$parameter])) { - return null; - } - $message = (string) $_REQUEST[$parameter]; - - $message = @base64_decode($message); - if ($message === false) { - throw new \SimpleSAML\Error\BadRequest('Error base64-decoding CDC message.'); - } - - $message = @json_decode($message, true); - if ($message === false) { - throw new \SimpleSAML\Error\BadRequest('Error json-decoding CDC message.'); - } - - if (!isset($message['timestamp'])) { - throw new \SimpleSAML\Error\BadRequest('Missing timestamp in CDC message.'); - } - $timestamp = (int) $message['timestamp']; - - if ($timestamp + 60 < time()) { - throw new \SimpleSAML\Error\BadRequest('CDC signature has expired.'); - } - if ($timestamp - 60 > time()) { - throw new \SimpleSAML\Error\BadRequest('CDC signature from the future.'); - } - - if (!isset($message['domain'])) { - throw new \SimpleSAML\Error\BadRequest('Missing domain in CDC message.'); - } - - return $message; - } - - - /** - * Helper function for validating the signature on a CDC message. - * - * Will throw an exception if the message is invalid. - * - * @param string $parameter The name of the query parameter. - */ - private function validate($parameter) - { - assert(is_string($parameter)); - assert(isset($_REQUEST[$parameter])); - - $message = (string) $_REQUEST[$parameter]; - - if (!isset($_REQUEST['Signature'])) { - throw new \SimpleSAML\Error\BadRequest('Missing Signature on CDC message.'); - } - $signature = (string) $_REQUEST['Signature']; - - $cSignature = $this->calcSignature($message); - if ($signature !== $cSignature) { - throw new \SimpleSAML\Error\BadRequest('Invalid signature on CDC message.'); - } - } - - - /** - * Helper function for sending CDC messages. - * - * @param string $to The URL the message should be delivered to. - * @param string $parameter The query parameter the message should be sent in. - * @param array $message The CDC message. - */ - private function send($to, $parameter, array $message) - { - assert(is_string($to)); - assert(is_string($parameter)); - - $message['timestamp'] = time(); - $message = json_encode($message); - $message = base64_encode($message); - - $signature = $this->calcSignature($message); - - $params = [ - $parameter => $message, - 'Signature' => $signature, - ]; - - $url = \SimpleSAML\Utils\HTTP::addURLParameters($to, $params); - if (strlen($url) < 2048) { - \SimpleSAML\Utils\HTTP::redirectTrustedURL($url); - } else { - \SimpleSAML\Utils\HTTP::submitPOSTData($to, $params); - } - } - - - /** - * Calculate the signature on the given message. - * - * @param string $rawMessage The base64-encoded message. - * @return string The signature. - */ - private function calcSignature($rawMessage) - { - assert(is_string($rawMessage)); - - return sha1($this->key.$rawMessage.$this->key); - } - - - /** - * Get the IdP entities saved in the common domain cookie. - * - * @return array List of IdP entities. - */ - private function getCDC() - { - if (!isset($_COOKIE['_saml_idp'])) { - return []; - } - - $ret = (string) $_COOKIE['_saml_idp']; - $ret = explode(' ', $ret); - foreach ($ret as &$idp) { - $idp = base64_decode($idp); - if ($idp === false) { - // Not properly base64 encoded - \SimpleSAML\Logger::warning('CDC - Invalid base64-encoding of CDC entry.'); - return []; - } - } - - return $ret; - } - - - /** - * Build a CDC cookie string. - * - * @param array $list The list of IdPs. - * @return string The CDC cookie value. - */ - private function setCDC(array $list) - { - foreach ($list as &$value) { - $value = base64_encode($value); - } - - $cookie = implode(' ', $list); - - while (strlen($cookie) > 4000) { - // The cookie is too long. Remove the oldest elements until it is short enough - $tmp = explode(' ', $cookie, 2); - if (count($tmp) === 1) { - /* - * We are left with a single entityID whose base64 - * representation is too long to fit in a cookie. - */ - break; - } - $cookie = $tmp[1]; - } - - $params = [ - 'lifetime' => $this->cookieLifetime, - 'path' => '/', - 'domain' => '.'.$this->domain, - 'secure' => true, - 'httponly' => false, - ]; - - \SimpleSAML\Utils\HTTP::setCookie('_saml_idp', $cookie, $params, false); - - return '_saml_idp'; - } -} diff --git a/modules/cdc/www/resume.php b/modules/cdc/www/resume.php deleted file mode 100644 index ebe6b1cc9f246b94dca7ab01d3b208f8f15bd281..0000000000000000000000000000000000000000 --- a/modules/cdc/www/resume.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php - -if (!array_key_exists('domain', $_REQUEST)) { - throw new \SimpleSAML\Error\BadRequest('Missing domain to CDC resume handler.'); -} - -$domain = (string) $_REQUEST['domain']; -$client = new \SimpleSAML\Module\cdc\Client($domain); - -$response = $client->getResponse(); -if ($response === null) { - throw new \SimpleSAML\Error\BadRequest('Missing CDC response to CDC resume handler.'); -} - -if (!isset($response['id'])) { - throw new \SimpleSAML\Error\BadRequest('CDCResponse without id.'); -} -$state = \SimpleSAML\Auth\State::loadState($response['id'], 'cdc:resume'); - -\SimpleSAML\Auth\ProcessingChain::resumeProcessing($state); diff --git a/modules/cdc/www/server.php b/modules/cdc/www/server.php deleted file mode 100644 index d5cfd16ece5aecda1184fdb626e824ca56e2d6a3..0000000000000000000000000000000000000000 --- a/modules/cdc/www/server.php +++ /dev/null @@ -1,3 +0,0 @@ -<?php - -\SimpleSAML\Module\cdc\Server::processRequest(); diff --git a/modules/oauth/config-template/module_oauth.php b/modules/oauth/config-template/module_oauth.php deleted file mode 100644 index 63327d6be9a83f009b69908ec944ac9f025feb31..0000000000000000000000000000000000000000 --- a/modules/oauth/config-template/module_oauth.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php -/* - * Configuration for the OAuth module. - * - */ - -$config = [ - /* Enable the getUserInfo endpoint. Do not enable unless you know what you do. - * It may give external parties access to userInfo unless properly secured. - */ - 'getUserInfo.enable' => true, - - 'requestTokenDuration' => 60 * 30, // 30 minutes - 'accessTokenDuration' => 60 * 60 * 24, // 24 hours - 'nonceCache' => 60 * 60 * 24 * 14, // 14 days - - // Tag to run storage cleanup script using the cron module... - 'cron_tag' => 'hourly', - - // auth is the idp to use for admin authentication, - // useridattr is the attribute-name that contains the userid as returned from idp - 'auth' => 'default-sp', - 'useridattr', 'user', -]; diff --git a/modules/oauth/default-disable b/modules/oauth/default-disable deleted file mode 100644 index fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f..0000000000000000000000000000000000000000 --- a/modules/oauth/default-disable +++ /dev/null @@ -1,3 +0,0 @@ -This file indicates that the default state of this module -is disabled. To enable, create a file named enable in the -same directory as this file. diff --git a/modules/oauth/hooks/hook_cron.php b/modules/oauth/hooks/hook_cron.php deleted file mode 100644 index 1a37cb41d6e4777583b75d23cad64f509ed2fc87..0000000000000000000000000000000000000000 --- a/modules/oauth/hooks/hook_cron.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -/** - * Hook to run a cron job. - * - * @param array &$croninfo Output - */ - -function oauth_hook_cron(&$croninfo) -{ - assert(is_array($croninfo)); - assert(array_key_exists('summary', $croninfo)); - assert(array_key_exists('tag', $croninfo)); - - $oauthconfig = \SimpleSAML\Configuration::getOptionalConfig('module_statistics.php'); - - if (is_null($oauthconfig->getValue('cron_tag', 'hourly'))) { - return; - } - if ($oauthconfig->getValue('cron_tag', null) !== $croninfo['tag']) { - return; - } - - try { - $store = new \SimpleSAML\Module\core\Storage\SQLPermanentStorage('oauth'); - $cleaned = $store->removeExpired(); - $croninfo['summary'][] = 'OAuth clean up. Removed '.$cleaned.' expired entries from OAuth storage.'; - } catch (\Exception $e) { - $message = 'OAuth clean up cron script failed: '.$e->getMessage(); - \SimpleSAML\Logger::warning($message); - $croninfo['summary'][] = $message; - } -} diff --git a/modules/oauth/hooks/hook_frontpage.php b/modules/oauth/hooks/hook_frontpage.php deleted file mode 100644 index 028e11c85d0750157741bb07f5b5cffe20ca6cbf..0000000000000000000000000000000000000000 --- a/modules/oauth/hooks/hook_frontpage.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -/** - * Hook to add link to the frontpage. - * - * @param array &$links The links on the frontpage, split into sections. - */ -function oauth_hook_frontpage(&$links) -{ - assert(is_array($links)); - assert(array_key_exists('links', $links)); - - $links['federation']['oauthregistry'] = [ - 'href' => SimpleSAML\Module::getModuleURL('oauth/registry.php'), - 'text' => '{core:frontpage:link_oauth}', - ]; -} diff --git a/modules/oauth/lib/Consumer.php b/modules/oauth/lib/Consumer.php deleted file mode 100644 index b3a4080ae6c384a48b3971fcc51c9354d1ac5f4d..0000000000000000000000000000000000000000 --- a/modules/oauth/lib/Consumer.php +++ /dev/null @@ -1,179 +0,0 @@ -<?php - -namespace SimpleSAML\Module\oauth; - -require_once(dirname(dirname(__FILE__)).'/libextinc/OAuth.php'); - -/** - * OAuth Consumer - * - * @author Andreas Ă…kre Solberg, <andreas.solberg@uninett.no>, UNINETT AS. - * @package SimpleSAMLphp - */ - -class Consumer -{ - private $consumer; - private $signer; - - public function __construct($key, $secret) - { - $this->consumer = new \OAuthConsumer($key, $secret, null); - $this->signer = new \OAuthSignatureMethod_HMAC_SHA1(); - } - - // Used only to load the libextinc library early - public static function dummy() - { - } - - public static function getOAuthError($hrh) - { - foreach ($hrh as $h) { - if (preg_match('|OAuth-Error:\s([^;]*)|i', $h, $matches)) { - return $matches[1]; - } - } - return null; - } - - public static function getContentType($hrh) - { - foreach ($hrh as $h) { - if (preg_match('|Content-Type:\s([^;]*)|i', $h, $matches)) { - return $matches[1]; - } - } - return null; - } - - /* - * This static helper function wraps \SimpleSAML\Utils\HTTP::fetch - * and throws an exception with diagnostics messages if it appear - * to be failing on an OAuth endpoint. - * - * If the status code is not 200, an exception is thrown. If the content-type - * of the response if text/plain, the content of the response is included in - * the text of the Exception thrown. - */ - public static function getHTTP($url, $context = '') - { - try { - $response = \SimpleSAML\Utils\HTTP::fetch($url); - } catch (\SimpleSAML\Error\Exception $e) { - $statuscode = 'unknown'; - if (preg_match('/^HTTP.*\s([0-9]{3})/', $http_response_header[0], $matches)) { - $statuscode = $matches[1]; - } - - $error = $context.' [statuscode: '.$statuscode.']: '; - $oautherror = self::getOAuthError($http_response_header); - - if (!empty($oautherror)) { - $error .= $oautherror; - } - - throw new \Exception($error.':'.$url); - } - // Fall back to return response, if could not reckognize HTTP header. Should not happen. - return $response; - } - - public function getRequestToken($url, $parameters = null) - { - $req_req = \OAuthRequest::from_consumer_and_token($this->consumer, null, "GET", $url, $parameters); - $req_req->sign_request($this->signer, $this->consumer, null); - - $response_req = self::getHTTP( - $req_req->to_url(), - 'Contacting request_token endpoint on the OAuth Provider' - ); - - parse_str($response_req, $responseParsed); - - if (array_key_exists('error', $responseParsed)) { - throw new \Exception('Error getting request token: '.$responseParsed['error']); - } - - $requestToken = $responseParsed['oauth_token']; - $requestTokenSecret = $responseParsed['oauth_token_secret']; - - return new \OAuthToken($requestToken, $requestTokenSecret); - } - - public function getAuthorizeRequest($url, $requestToken, $redirect = true, $callback = null) - { - $params = ['oauth_token' => $requestToken->key]; - if ($callback) { - $params['oauth_callback'] = $callback; - } - $authorizeURL = \SimpleSAML\Utils\HTTP::addURLParameters($url, $params); - if ($redirect) { - \SimpleSAML\Utils\HTTP::redirectTrustedURL($authorizeURL); - exit; - } - return $authorizeURL; - } - - public function getAccessToken($url, $requestToken, $parameters = null) - { - $acc_req = \OAuthRequest::from_consumer_and_token($this->consumer, $requestToken, "GET", $url, $parameters); - $acc_req->sign_request($this->signer, $this->consumer, $requestToken); - - try { - $response_acc = \SimpleSAML\Utils\HTTP::fetch($acc_req->to_url()); - } catch (\SimpleSAML\Error\Exception $e) { - throw new \Exception('Error contacting request_token endpoint on the OAuth Provider'); - } - - \SimpleSAML\Logger::debug('oauth: Reponse to get access token: '.$response_acc); - - parse_str($response_acc, $accessResponseParsed); - - if (array_key_exists('error', $accessResponseParsed)) { - throw new \Exception('Error getting request token: '.$accessResponseParsed['error']); - } - - $accessToken = $accessResponseParsed['oauth_token']; - $accessTokenSecret = $accessResponseParsed['oauth_token_secret']; - - return new \OAuthToken($accessToken, $accessTokenSecret); - } - - public function postRequest($url, $accessToken, $parameters) - { - $data_req = \OAuthRequest::from_consumer_and_token($this->consumer, $accessToken, "POST", $url, $parameters); - $data_req->sign_request($this->signer, $this->consumer, $accessToken); - $postdata = $data_req->to_postdata(); - - $opts = [ - 'ssl' => [ - 'verify_peer' => false, - 'capture_peer_cert' => true, - 'capture_peer_chain' => true - ], - 'http' => [ - 'method' => 'POST', - 'content' => $postdata, - 'header' => 'Content-Type: application/x-www-form-urlencoded', - ], - ]; - - try { - $response = \SimpleSAML\Utils\HTTP::fetch($url, $opts); - } catch (\SimpleSAML\Error\Exception $e) { - throw new \SimpleSAML\Error\Exception('Failed to push definition file to '.$url); - } - return $response; - } - - public function getUserInfo($url, $accessToken, $opts = null) - { - $data_req = \OAuthRequest::from_consumer_and_token($this->consumer, $accessToken, "GET", $url, null); - $data_req->sign_request($this->signer, $this->consumer, $accessToken); - - $data = \SimpleSAML\Utils\HTTP::fetch($data_req->to_url(), $opts); - - return json_decode($data, true); - } -} diff --git a/modules/oauth/lib/OAuthServer.php b/modules/oauth/lib/OAuthServer.php deleted file mode 100644 index 41e60383ad92a01ebecc95fb7695f5d6c14c59eb..0000000000000000000000000000000000000000 --- a/modules/oauth/lib/OAuthServer.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -namespace SimpleSAML\Module\oauth; - -require_once(dirname(dirname(__FILE__)).'/libextinc/OAuth.php'); - -/** - * OAuth Provider implementation.. - * - * @author Andreas Ă…kre Solberg, <andreas.solberg@uninett.no>, UNINETT AS. - * @package SimpleSAMLphp - */ - -class OAuthServer extends \OAuthServer -{ - public function __construct($store) - { - parent::__construct($store); - } - - public function get_signature_methods() - { - return $this->signature_methods; - } -} diff --git a/modules/oauth/lib/OAuthStore.php b/modules/oauth/lib/OAuthStore.php deleted file mode 100644 index b0c9d222dd5176dd343878a774309676bf03eb2c..0000000000000000000000000000000000000000 --- a/modules/oauth/lib/OAuthStore.php +++ /dev/null @@ -1,213 +0,0 @@ -<?php - -namespace SimpleSAML\Module\oauth; - -require_once(dirname(dirname(__FILE__)).'/libextinc/OAuth.php'); - -/** - * OAuth Store - * - * Updated version, works with consumer-callbacks, certificates and 1.0-RevA protocol - * behaviour (requestToken-callbacks and verifiers) - * - * @author Andreas Ă…kre Solberg, <andreas.solberg@uninett.no>, UNINETT AS. - * @author Mark Dobrinic, <mdobrinic@cozmanova.com>, Cozmanova bv - * @package SimpleSAMLphp - */ - -class OAuthStore extends \OAuthDataStore -{ - private $store; - private $config; - private $defaultversion = '1.0'; - - protected $_store_tables = [ - 'consumers' => 'consumer = array with consumer attributes', - 'nonce' => 'nonce+consumer_key = -boolean-', - 'requesttorequest' => 'requestToken.key = array(version,callback,consumerKey,)', - 'authorized' => 'requestToken.key, verifier = array(authenticated-user-attributes)', - 'access' => 'accessToken.key+consumerKey = accesstoken', - 'request' => 'requestToken.key+consumerKey = requesttoken', - ]; - - - public function __construct() - { - $this->store = new \SimpleSAML\Module\core\Storage\SQLPermanentStorage('oauth'); - $this->config = \SimpleSAML\Configuration::getOptionalConfig('module_oauth.php'); - } - - - /** - * Attach the data to the token, and establish the Callback URL and verifier - * @param string $requestTokenKey RequestToken that was authorized - * @param string $data Data that is authorized and to be attached to the requestToken - * @return array(string:url, string:verifier) ; empty verifier for 1.0-response - */ - public function authorize($requestTokenKey, $data) - { - $url = null; - - // See whether to remember values from the original requestToken request: - $request_attributes = $this->store->get('requesttorequest', $requestTokenKey, ''); - // must be there - if ($request_attributes['value']) { - // establish callback to use - if ($request_attributes['value']['callback']) { - $url = $request_attributes['value']['callback']; - } - } - - // Is there a callback registered? This is leading, even over a supplied oauth_callback-parameter - $oConsumer = $this->lookup_consumer($request_attributes['value']['consumerKey']); - - if ($oConsumer && ($oConsumer->callback_url)) { - $url = $oConsumer->callback_url; - } - - $verifier = \SimpleSAML\Utils\Random::generateID(); - $url = \SimpleSAML\Utils\HTTP::addURLParameters($url, ["oauth_verifier"=>$verifier]); - - $this->store->set('authorized', $requestTokenKey, $verifier, $data, $this->config->getValue('requestTokenDuration', 1800)); //60*30=1800 - - return [$url, $verifier]; - } - - /** - * Perform lookup whether a given token exists in the list of authorized tokens; if a verifier is - * passed as well, the verifier *must* match the verifier that was registered with the token<br/> - * Note that an accessToken should never be stored with a verifier - * @param string $requestToken - * @param string $verifier - * @return bool - */ - public function isAuthorized($requestToken, $verifier = '') - { - \SimpleSAML\Logger::info('OAuth isAuthorized('.$requestToken.')'); - return $this->store->exists('authorized', $requestToken, $verifier); - } - - public function getAuthorizedData($token, $verifier = '') - { - \SimpleSAML\Logger::info('OAuth getAuthorizedData('.$token.')'); - $data = $this->store->get('authorized', $token, $verifier); - return $data['value']; - } - - public function moveAuthorizedData($requestToken, $verifier, $accessTokenKey) - { - \SimpleSAML\Logger::info('OAuth moveAuthorizedData('.$requestToken.', '.$accessTokenKey.')'); - - // Retrieve authorizedData from authorized.requestToken (with provider verifier) - $authorizedData = $this->getAuthorizedData($requestToken, $verifier); - - // Remove the requesttoken+verifier from authorized store - $this->store->remove('authorized', $requestToken, $verifier); - - // Add accesstoken with authorizedData to authorized store (with empty verifier) - // accessTokenKey+consumer => accessToken is already registered in 'access'-table - $this->store->set('authorized', $accessTokenKey, '', $authorizedData, $this->config->getValue('accessTokenDuration', 86400)); //60*60*24=86400 - } - - public function lookup_consumer($consumer_key) - { - \SimpleSAML\Logger::info('OAuth lookup_consumer('.$consumer_key.')'); - if (!$this->store->exists('consumers', $consumer_key, '')) { - return null; - } - $consumer = $this->store->get('consumers', $consumer_key, ''); - - $callback = null; - if ($consumer['value']['callback_url']) { - $callback = $consumer['value']['callback_url']; - } - - if ($consumer['value']['RSAcertificate']) { - return new \OAuthConsumer($consumer['value']['key'], $consumer['value']['RSAcertificate'], $callback); - } else { - return new \OAuthConsumer($consumer['value']['key'], $consumer['value']['secret'], $callback); - } - } - - public function lookup_token($consumer, $tokenType = 'default', $token) - { - \SimpleSAML\Logger::info('OAuth lookup_token('.$consumer->key.', '.$tokenType.','.$token.')'); - $data = $this->store->get($tokenType, $token, $consumer->key); - if ($data == null) { - throw new \Exception('Could not find token'); - } - return $data['value']; - } - - public function lookup_nonce($consumer, $token, $nonce, $timestamp) - { - \SimpleSAML\Logger::info('OAuth lookup_nonce('.$consumer.', '.$token.','.$nonce.')'); - if ($this->store->exists('nonce', $nonce, $consumer->key)) { - return true; - } - $this->store->set('nonce', $nonce, $consumer->key, true, $this->config->getValue('nonceCache', 1209600)); //60*60*24*14=1209600 - return false; - } - - public function new_request_token($consumer, $callback = null, $version = null) - { - \SimpleSAML\Logger::info('OAuth new_request_token('.$consumer.')'); - - $lifetime = $this->config->getValue('requestTokenDuration', 1800); //60*30 - - $token = new \OAuthToken(\SimpleSAML\Utils\Random::generateID(), \SimpleSAML\Utils\Random::generateID()); - $token->callback = $callback; // OAuth1.0-RevA - $this->store->set('request', $token->key, $consumer->key, $token, $lifetime); - - // also store in requestToken->key => array('callback'=>CallbackURL, 'version'=>oauth_version - $request_attributes = [ - 'callback' => $callback, - 'version' => ($version ? $version : $this->defaultversion), - 'consumerKey' => $consumer->key, - ]; - $this->store->set('requesttorequest', $token->key, '', $request_attributes, $lifetime); - - /* also store in requestToken->key => - * Consumer->key (enables consumer-lookup during reqToken-authorization stage) - */ - $this->store->set('requesttoconsumer', $token->key, '', $consumer->key, $lifetime); - - return $token; - } - - public function new_access_token($requestToken, $consumer, $verifier = null) - { - \SimpleSAML\Logger::info('OAuth new_access_token('.$requestToken.','.$consumer.')'); - $accesstoken = new \OAuthToken(\SimpleSAML\Utils\Random::generateID(), \SimpleSAML\Utils\Random::generateID()); - $this->store->set( - 'access', - $accesstoken->key, - $consumer->key, - $accesstoken, - $this->config->getValue('accessTokenDuration', 86400) //60*60*24=86400 - ); - return $accesstoken; - } - - /** - * Return OAuthConsumer-instance that a given requestToken was issued to - * @param string $requestTokenKey - * @return mixed - */ - public function lookup_consumer_by_requestToken($requestTokenKey) - { - \SimpleSAML\Logger::info('OAuth lookup_consumer_by_requestToken('.$requestTokenKey.')'); - if (!$this->store->exists('requesttorequest', $requestTokenKey, '')) { - return null; - } - - $request = $this->store->get('requesttorequest', $requestTokenKey, ''); - $consumerKey = $request['value']['consumerKey']; - if (!$consumerKey) { - return null; - } - - $consumer = $this->store->get('consumers', $consumerKey['value'], ''); - return $consumer['value']; - } -} diff --git a/modules/oauth/lib/Registry.php b/modules/oauth/lib/Registry.php deleted file mode 100644 index 0939be6f410ce90c587c388c7ffa15e7cbc89c12..0000000000000000000000000000000000000000 --- a/modules/oauth/lib/Registry.php +++ /dev/null @@ -1,151 +0,0 @@ -<?php - -namespace SimpleSAML\Module\oauth; - -/** - * Editor for OAuth Client Registry - * - * @author Andreas Ă…kre Solberg <andreas@uninett.no>, UNINETT AS. - * @package SimpleSAMLphp - */ - -class Registry -{ - public static function requireOwnership($entry, $userid) - { - if (!isset($entry['owner'])) { - throw new \Exception('OAuth Consumer has no owner. Which means no one is granted access, not even you.'); - } elseif ($entry['owner'] !== $userid) { - throw new \Exception( - 'OAuth Consumer has an owner that is not equal to your userid, hence you are not granted access.' - ); - } - } - - protected function getStandardField($request, &$entry, $key) - { - if (array_key_exists('field_'.$key, $request)) { - $entry[$key] = $request['field_'.$key]; - } elseif (isset($entry[$key])) { - unset($entry[$key]); - } - } - - public function formToMeta($request, $entry = [], $override = null) - { - $this->getStandardField($request, $entry, 'name'); - $this->getStandardField($request, $entry, 'description'); - $this->getStandardField($request, $entry, 'key'); - $this->getStandardField($request, $entry, 'secret'); - $this->getStandardField($request, $entry, 'RSAcertificate'); - $this->getStandardField($request, $entry, 'callback_url'); - - if ($override) { - foreach ($override as $key => $value) { - $entry[$key] = $value; - } - } - return $entry; - } - - protected function requireStandardField($request, $key) - { - if (!array_key_exists('field_'.$key, $request)) { - throw new \Exception('Required field ['.$key.'] was missing.'); - } - if (empty($request['field_'.$key])) { - throw new \Exception('Required field ['.$key.'] was empty.'); - } - } - - public function checkForm($request) - { - $this->requireStandardField($request, 'name'); - $this->requireStandardField($request, 'description'); - $this->requireStandardField($request, 'key'); - } - - protected function header($name) - { - return '<tr><td> </td><td class="header">'.$name.'</td></tr>'; - } - - protected function readonlyDateField($metadata, $key, $name) - { - $value = '<span style="color: #aaa">Not set</a>'; - if (array_key_exists($key, $metadata)) { - $value = date('j. F Y, G:i', $metadata[$key]); - } - return '<tr><td class="name">'.$name.'</td><td class="data">'.$value.'</td></tr>'; - } - - protected function readonlyField($metadata, $key, $name) - { - $value = ''; - if (array_key_exists($key, $metadata)) { - $value = $metadata[$key]; - } - return '<tr><td class="name">'.$name.'</td><td class="data">'.htmlspecialchars($value).'</td></tr>'; - } - - protected function hiddenField($key, $value) - { - return '<input type="hidden" name="'.$key.'" value="'.htmlspecialchars($value).'" />'; - } - - protected function flattenLanguageField(&$metadata, $key) - { - if (array_key_exists($key, $metadata)) { - if (is_array($metadata[$key])) { - if (isset($metadata[$key]['en'])) { - $metadata[$key] = $metadata[$key]['en']; - } else { - unset($metadata[$key]); - } - } - } - } - - protected function standardField($metadata, $key, $name, $textarea = false) - { - $value = ''; - if (array_key_exists($key, $metadata)) { - $value = htmlspecialchars($metadata[$key]); - } - - if ($textarea) { - return '<tr><td class="name">'.$name.'</td><td class="data"> - <textarea name="field_'.$key.'" rows="5" cols="50">'.$value.'</textarea></td></tr>'; - } else { - return '<tr><td class="name">'.$name.'</td><td class="data"> - <input type="text" size="60" name="field_'.$key.'" value="'.$value.'" /></td></tr>'; - } - } - - public function metaToForm($metadata) - { - return '<form action="registry.edit.php" method="post">'. - '<div id="tabdiv">'. - '<ul class="tabset_tabs">'. - '<li class="tab-link current" data-tab="basic"><a href="#basic">Name and description</a></li>'. - '</ul>'. - '<div id="basic" class="tabset_content current"><table class="formtable">'. - $this->standardField($metadata, 'name', 'Name of client'). - $this->standardField($metadata, 'description', 'Description of client', true). - $this->readonlyField($metadata, 'owner', 'Owner'). - $this->standardField($metadata, 'key', 'Consumer Key'). - $this->readonlyField($metadata, 'secret', 'Consumer Secret<br />(Used for HMAC_SHA1 signatures)'). - $this->standardField( - $metadata, - 'RSAcertificate', - 'RSA certificate (PEM)<br />(Used for RSA_SHA1 signatures)', - true - ). - $this->standardField($metadata, 'callback_url', 'Static/enforcing callback-url'). - '</table></div>'. - '</div>'. - $this->hiddenField('field_secret', $metadata['secret']). - '<input type="submit" name="submit" value="Save" style="margin-top: 5px" />'. - '</form>'; - } -} diff --git a/modules/oauth/libextinc/LICENSE.txt b/modules/oauth/libextinc/LICENSE.txt deleted file mode 100644 index 89f0591697f2a550b2003c9e05c778f367aac189..0000000000000000000000000000000000000000 --- a/modules/oauth/libextinc/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License - -Copyright (c) 2007 Andy Smith - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/modules/oauth/libextinc/OAuth.php b/modules/oauth/libextinc/OAuth.php deleted file mode 100644 index c8811d6ce1263032e6fe32c9227546a5014ad945..0000000000000000000000000000000000000000 --- a/modules/oauth/libextinc/OAuth.php +++ /dev/null @@ -1,991 +0,0 @@ -<?php -/** - * @file - * OAuth 1.0 server and client library. - */ - -/** - * OAuth PECL extension includes an OAuth Exception class, so we need to wrap - * the definition of this class in order to avoid a PHP error. - */ -if (!class_exists('OAuthException')) { - /* - * Generic exception class - */ - class OAuthException extends Exception - { - // pass - } -} - -if (!class_exists('OAuthConsumer')) { - class OAuthConsumer - { - public $key; - public $secret; - public $callback_url; - - public function __construct($key, $secret, $callback_url = null) - { - $this->key = $key; - $this->secret = $secret; - $this->callback_url = $callback_url; - } - - public function __toString() - { - return "OAuthConsumer[key=$this->key,secret=$this->secret]"; - } - } -} - -class OAuthToken -{ - // access tokens and request tokens - public $key; - public $secret; - - /** - * key = the token - * secret = the token secret - */ - public function __construct($key, $secret) - { - $this->key = $key; - $this->secret = $secret; - } - - /** - * generates the basic string serialization of a token that a server - * would respond to request_token and access_token calls with - */ - public function to_string() - { - return "oauth_token=". - OAuthUtil::urlencode_rfc3986($this->key). - "&oauth_token_secret=". - OAuthUtil::urlencode_rfc3986($this->secret). - "&oauth_callback_confirmed=true"; - } - - public function __toString() - { - return $this->to_string(); - } -} - -/** - * A class for implementing a Signature Method - * See section 9 ("Signing Requests") in the spec - */ -abstract class OAuthSignatureMethod -{ - /** - * Needs to return the name of the Signature Method (ie HMAC-SHA1) - * @return string - */ - abstract public function get_name(); - - /** - * Build up the signature - * NOTE: The output of this function MUST NOT be urlencoded. - * the encoding is handled in OAuthRequest when the final - * request is serialized - * @param OAuthRequest $request - * @param OAuthConsumer $consumer - * @param OAuthToken $token - * @return string - */ - abstract public function build_signature($request, $consumer, $token); - - /** - * Verifies that a given signature is correct - * @param OAuthRequest $request - * @param OAuthConsumer $consumer - * @param OAuthToken $token - * @param string $signature - * @return bool - */ - public function check_signature($request, $consumer, $token, $signature) - { - $built = $this->build_signature($request, $consumer, $token); - - // Check for zero length, although unlikely here - if (strlen($built) == 0 || strlen($signature) == 0) { - return false; - } - - if (strlen($built) != strlen($signature)) { - return false; - } - - // Avoid a timing leak with a (hopefully) time insensitive compare - $result = 0; - for ($i = 0; $i < strlen($signature); $i++) { - $result |= ord($built{$i}) ^ ord($signature{$i}); - } - - return $result == 0; - } -} - -/** - * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104] - * where the Signature Base String is the text and the key is the concatenated values (each first - * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&' - * character (ASCII code 38) even if empty. - * - Chapter 9.2 ("HMAC-SHA1") - */ -class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod -{ - public function get_name() - { - return "HMAC-SHA1"; - } - - public function build_signature($request, $consumer, $token) - { - $base_string = $request->get_signature_base_string(); - $request->base_string = $base_string; - - $key_parts = [ - $consumer->secret, - ($token) ? $token->secret : "" - ]; - - $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); - $key = implode('&', $key_parts); - - return base64_encode(hash_hmac('sha1', $base_string, $key, true)); - } -} - -/** - * The PLAINTEXT method does not provide any security protection and SHOULD only be used - * over a secure channel such as HTTPS. It does not use the Signature Base String. - * - Chapter 9.4 ("PLAINTEXT") - */ -class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod -{ - public function get_name() - { - return "PLAINTEXT"; - } - - /** - * oauth_signature is set to the concatenated encoded values of the Consumer Secret and - * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is - * empty. The result MUST be encoded again. - * - Chapter 9.4.1 ("Generating Signatures") - * - * Please note that the second encoding MUST NOT happen in the SignatureMethod, as - * OAuthRequest handles this! - */ - public function build_signature($request, $consumer, $token) - { - $key_parts = [ - $consumer->secret, - ($token) ? $token->secret : "" - ]; - - $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); - $key = implode('&', $key_parts); - $request->base_string = $key; - - return $key; - } -} - -/** - * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in - * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for - * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a - * verified way to the Service Provider, in a manner which is beyond the scope of this - * specification. - * - Chapter 9.3 ("RSA-SHA1") - */ -abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod -{ - public function get_name() - { - return "RSA-SHA1"; - } - - // Up to the SP to implement this lookup of keys. Possible ideas are: - // (1) do a lookup in a table of trusted certs keyed off of consumer - // (2) fetch via http using a url provided by the requester - // (3) some sort of specific discovery code based on request - // - // Either way should return a string representation of the certificate - abstract protected function fetch_public_cert(&$request); - - // Up to the SP to implement this lookup of keys. Possible ideas are: - // (1) do a lookup in a table of trusted certs keyed off of consumer - // - // Either way should return a string representation of the certificate - abstract protected function fetch_private_cert(&$request); - - public function build_signature($request, $consumer, $token) - { - $base_string = $request->get_signature_base_string(); - $request->base_string = $base_string; - - // Fetch the private key cert based on the request - $cert = $this->fetch_private_cert($request); - - // Pull the private key ID from the certificate - $privatekeyid = openssl_get_privatekey($cert); - - // Sign using the key - openssl_sign($base_string, $signature, $privatekeyid); - - // Release the key resource - openssl_free_key($privatekeyid); - - return base64_encode($signature); - } - - public function check_signature($request, $consumer, $token, $signature) - { - $decoded_sig = base64_decode($signature); - - $base_string = $request->get_signature_base_string(); - - // Fetch the public key cert based on the request - $cert = $this->fetch_public_cert($request); - - // Pull the public key ID from the certificate - $publickeyid = openssl_get_publickey($cert); - - // Check the computed signature against the one passed in the query - $ok = openssl_verify($base_string, $decoded_sig, $publickeyid); - - // Release the key resource - openssl_free_key($publickeyid); - - return $ok == 1; - } -} - -class OAuthRequest -{ - protected $parameters; - protected $http_method; - protected $http_url; - // for debug purposes - public $base_string; - public static $version = '1.0'; - public static $POST_INPUT = 'php://input'; - - public function __construct($http_method, $http_url, $parameters = null) - { - $parameters = ($parameters) ? $parameters : []; - $parameters = array_merge(OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters); - $this->parameters = $parameters; - $this->http_method = $http_method; - $this->http_url = $http_url; - } - - - /** - * attempt to build up a request from what was passed to the server - */ - public static function from_request($http_method = null, $http_url = null, $parameters = null) - { - $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") - ? 'http' - : 'https'; - $http_url = ($http_url) ? $http_url : $scheme. - '://'.$_SERVER['SERVER_NAME']. - ':'. - $_SERVER['SERVER_PORT']. - $_SERVER['REQUEST_URI']; - $http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD']; - - // We weren't handed any parameters, so let's find the ones relevant to - // this request. - // If you run XML-RPC or similar you should use this to provide your own - // parsed parameter-list - if (!$parameters) { - // Find request headers - $request_headers = OAuthUtil::get_headers(); - - // Parse the query-string to find GET parameters - $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); - - // It's a POST request of the proper content-type, so parse POST - // parameters and add those overriding any duplicates from GET - if ($http_method == "POST" - && isset($request_headers['Content-Type']) - && strstr($request_headers['Content-Type'], 'application/x-www-form-urlencoded') - ) { - $post_data = OAuthUtil::parse_parameters( - file_get_contents(self::$POST_INPUT) - ); - $parameters = array_merge($parameters, $post_data); - } - - // We have a Authorization-header with OAuth data. Parse the header - // and add those overriding any duplicates from GET or POST - if (isset($request_headers['Authorization']) - && substr($request_headers['Authorization'], 0, 6) == 'OAuth ' - ) { - $header_parameters = OAuthUtil::split_header( - $request_headers['Authorization'] - ); - $parameters = array_merge($parameters, $header_parameters); - } - } - - return new OAuthRequest($http_method, $http_url, $parameters); - } - - /** - * pretty much a helper function to set up the request - */ - public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters = null) - { - $parameters = ($parameters) ? $parameters : []; - $defaults = ["oauth_version" => OAuthRequest::$version, - "oauth_nonce" => OAuthRequest::generate_nonce(), - "oauth_timestamp" => OAuthRequest::generate_timestamp(), - "oauth_consumer_key" => $consumer->key]; - if ($token) { - $defaults['oauth_token'] = $token->key; - } - - $parameters = array_merge($defaults, $parameters); - - return new OAuthRequest($http_method, $http_url, $parameters); - } - - public function set_parameter($name, $value, $allow_duplicates = true) - { - if ($allow_duplicates && isset($this->parameters[$name])) { - // We have already added parameter(s) with this name, so add to the list - if (is_scalar($this->parameters[$name])) { - // This is the first duplicate, so transform scalar (string) - // into an array so we can add the duplicates - $this->parameters[$name] = [$this->parameters[$name]]; - } - - $this->parameters[$name][] = $value; - } else { - $this->parameters[$name] = $value; - } - } - - public function get_parameter($name) - { - return isset($this->parameters[$name]) ? $this->parameters[$name] : null; - } - - public function get_parameters() - { - return $this->parameters; - } - - public function unset_parameter($name) - { - unset($this->parameters[$name]); - } - - /** - * The request parameters, sorted and concatenated into a normalized string. - * @return string - */ - public function get_signable_parameters() - { - // Grab all parameters - $params = $this->parameters; - - // Remove oauth_signature if present - // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") - if (isset($params['oauth_signature'])) { - unset($params['oauth_signature']); - } - - return OAuthUtil::build_http_query($params); - } - - /** - * Returns the base string of this request - * - * The base string defined as the method, the url - * and the parameters (normalized), each urlencoded - * and the concated with &. - */ - public function get_signature_base_string() - { - $parts = [ - $this->get_normalized_http_method(), - $this->get_normalized_http_url(), - $this->get_signable_parameters() - ]; - - $parts = OAuthUtil::urlencode_rfc3986($parts); - - return implode('&', $parts); - } - - /** - * just uppercases the http method - */ - public function get_normalized_http_method() - { - return strtoupper($this->http_method); - } - - /** - * parses the url and rebuilds it to be - * scheme://host/path - */ - public function get_normalized_http_url() - { - $parts = parse_url($this->http_url); - - $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http'; - $port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80'); - $host = (isset($parts['host'])) ? strtolower($parts['host']) : ''; - $path = (isset($parts['path'])) ? $parts['path'] : ''; - - if (($scheme == 'https' && $port != '443') - || ($scheme == 'http' && $port != '80')) { - $host = "$host:$port"; - } - return "$scheme://$host$path"; - } - - /** - * builds a url usable for a GET request - */ - public function to_url() - { - $post_data = $this->to_postdata(); - $out = $this->get_normalized_http_url(); - if ($post_data) { - $out .= '?'.$post_data; - } - return $out; - } - - /** - * builds the data one would send in a POST request - */ - public function to_postdata() - { - return OAuthUtil::build_http_query($this->parameters); - } - - /** - * builds the Authorization: header - */ - public function to_header($realm = null) - { - $first = true; - if ($realm) { - $out = 'Authorization: OAuth realm="'.OAuthUtil::urlencode_rfc3986($realm).'"'; - $first = false; - } else { - $out = 'Authorization: OAuth'; - } - - foreach ($this->parameters as $k => $v) { - if (substr($k, 0, 5) != "oauth") { - continue; - } - if (is_array($v)) { - throw new OAuthException('Arrays not supported in headers'); - } - $out .= ($first) ? ' ' : ','; - $out .= OAuthUtil::urlencode_rfc3986($k). - '="'. - OAuthUtil::urlencode_rfc3986($v). - '"'; - $first = false; - } - return $out; - } - - public function __toString() - { - return $this->to_url(); - } - - - public function sign_request($signature_method, $consumer, $token) - { - $this->set_parameter( - "oauth_signature_method", - $signature_method->get_name(), - false - ); - $signature = $this->build_signature($signature_method, $consumer, $token); - $this->set_parameter("oauth_signature", $signature, false); - } - - public function build_signature($signature_method, $consumer, $token) - { - $signature = $signature_method->build_signature($this, $consumer, $token); - return $signature; - } - - /** - * util function: current timestamp - */ - private static function generate_timestamp() - { - return time(); - } - - /** - * util function: current nonce - */ - private static function generate_nonce() - { - $mt = microtime(); - $rand = mt_rand(); - - return md5($mt.$rand); // md5s look nicer than numbers - } -} - -class OAuthServer -{ - protected $timestamp_threshold = 300; // in seconds, five minutes - protected $version = '1.0'; // hi blaine - protected $signature_methods = []; - - protected $data_store; - - public function __construct($data_store) - { - $this->data_store = $data_store; - } - - public function add_signature_method($signature_method) - { - $this->signature_methods[$signature_method->get_name()] = - $signature_method; - } - - // high level functions - - /** - * process a request_token request - * returns the request token on success - */ - public function fetch_request_token(&$request) - { - $this->getVersion($request); - - $consumer = $this->getConsumer($request); - - // no token required for the initial token request - $token = null; - - $this->checkSignature($request, $consumer, $token); - - // Rev A change - $callback = $request->get_parameter('oauth_callback'); - $new_token = $this->data_store->new_request_token($consumer, $callback); - - return $new_token; - } - - /** - * process an access_token request - * returns the access token on success - */ - public function fetch_access_token(&$request) - { - $this->getVersion($request); - - $consumer = $this->getConsumer($request); - - // requires authorized request token - $token = $this->getToken($request, $consumer, "request"); - - $this->checkSignature($request, $consumer, $token); - - // Rev A change - $verifier = $request->get_parameter('oauth_verifier'); - $new_token = $this->data_store->new_access_token($token, $consumer, $verifier); - - return $new_token; - } - - /** - * verify an api call, checks all the parameters - */ - public function verify_request(&$request) - { - $this->getVersion($request); - $consumer = $this->getConsumer($request); - $token = $this->getToken($request, $consumer, "access"); - $this->checkSignature($request, $consumer, $token); - return [$consumer, $token]; - } - - // Internals from here - /** - * version 1 - */ - private function getVersion(&$request) - { - $version = $request->get_parameter("oauth_version"); - if (!$version) { - // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. - // Chapter 7.0 ("Accessing Protected Ressources") - $version = '1.0'; - } - if ($version !== $this->version) { - throw new OAuthException("OAuth version '$version' not supported"); - } - return $version; - } - - /** - * figure out the signature with some defaults - */ - private function getSignatureMethod($request) - { - $signature_method = $request instanceof OAuthRequest - ? $request->get_parameter("oauth_signature_method") - : null; - - if (!$signature_method) { - // According to chapter 7 ("Accessing Protected Ressources") the signature-method - // parameter is required, and we can't just fallback to PLAINTEXT - throw new OAuthException('No signature method parameter. This parameter is required'); - } - - if (!in_array($signature_method, array_keys($this->signature_methods))) { - throw new OAuthException( - "Signature method '$signature_method' not supported ". - "try one of the following: ". - implode(", ", array_keys($this->signature_methods)) - ); - } - return $this->signature_methods[$signature_method]; - } - - /** - * try to find the consumer for the provided request's consumer key - */ - private function getConsumer($request) - { - $consumer_key = $request instanceof OAuthRequest - ? $request->get_parameter("oauth_consumer_key") - : null; - - if (!$consumer_key) { - throw new OAuthException("Invalid consumer key"); - } - - $consumer = $this->data_store->lookup_consumer($consumer_key); - if (!$consumer) { - throw new OAuthException("Invalid consumer"); - } - - return $consumer; - } - - /** - * try to find the token for the provided request's token key - */ - private function getToken($request, $consumer, $token_type = "access") - { - $token_field = $request instanceof OAuthRequest - ? $request->get_parameter('oauth_token') - : null; - - if (!empty($token_field)) { - $token = $this->data_store->lookup_token($consumer, $token_type, $token_field); - if (!$token) { - throw new OAuthException('Invalid '.$token_type.' token: '.$token_field); - } - } else { - $token = new OAuthToken('', ''); - } - return $token; - } - - /** - * all-in-one function to check the signature on a request - * should guess the signature method appropriately - */ - private function checkSignature($request, $consumer, $token) - { - // this should probably be in a different method - $timestamp = $request instanceof OAuthRequest - ? $request->get_parameter('oauth_timestamp') - : null; - $nonce = $request instanceof OAuthRequest - ? $request->get_parameter('oauth_nonce') - : null; - - $this->checkTimestamp($timestamp); - $this->checkNonce($consumer, $token, $nonce, $timestamp); - - $signature_method = $this->getSignatureMethod($request); - - $signature = $request->get_parameter('oauth_signature'); - $valid_sig = $signature_method->checkSignature( - $request, - $consumer, - $token, - $signature - ); - - if (!$valid_sig) { - throw new OAuthException("Invalid signature"); - } - } - - /** - * check that the timestamp is new enough - */ - private function checkTimestamp($timestamp) - { - if (!$timestamp) { - throw new OAuthException( - 'Missing timestamp parameter. The parameter is required' - ); - } - - // verify that timestamp is recentish - $now = time(); - if (abs($now - $timestamp) > $this->timestamp_threshold) { - throw new OAuthException( - "Expired timestamp, yours $timestamp, ours $now" - ); - } - } - - /** - * check that the nonce is not repeated - */ - private function checkNonce($consumer, $token, $nonce, $timestamp) - { - if (!$nonce) { - throw new OAuthException( - 'Missing nonce parameter. The parameter is required' - ); - } - - // verify that the nonce is uniqueish - $found = $this->data_store->lookup_nonce( - $consumer, - $token, - $nonce, - $timestamp - ); - if ($found) { - throw new OAuthException("Nonce already used: $nonce"); - } - } -} - -class OAuthDataStore -{ - public function lookup_consumer($consumer_key) - { - // implement me - } - - public function lookup_token($consumer, $token_type, $token) - { - // implement me - } - - public function lookup_nonce($consumer, $token, $nonce, $timestamp) - { - // implement me - } - - public function new_request_token($consumer, $callback = null) - { - // return a new token attached to this consumer - } - - public function new_access_token($token, $consumer, $verifier = null) - { - // return a new access token attached to this consumer - // for the user associated with this token if the request token - // is authorized - // should also invalidate the request token - } -} - -class OAuthUtil -{ - public static function urlencode_rfc3986($input) - { - if (is_array($input)) { - return array_map(['OAuthUtil', 'urlencode_rfc3986'], $input); - } elseif (is_scalar($input)) { - return str_replace( - '+', - ' ', - str_replace('%7E', '~', rawurlencode($input)) - ); - } else { - return ''; - } - } - - - // This decode function isn't taking into consideration the above - // modifications to the encoding process. However, this method doesn't - // seem to be used anywhere so leaving it as is. - public static function urldecode_rfc3986($string) - { - return urldecode($string); - } - - // Utility function for turning the Authorization: header into - // parameters, has to do some unescaping - // Can filter out any non-oauth parameters if needed (default behaviour) - // May 28th, 2010 - method updated to tjerk.meesters for a speed improvement. - // see http://code.google.com/p/oauth/issues/detail?id=163 - public static function split_header($header, $only_allow_oauth_parameters = true) - { - $params = []; - if (preg_match_all( - '/('.($only_allow_oauth_parameters ? 'oauth_' : '').'[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', - $header, - $matches - )) { - foreach ($matches[1] as $i => $h) { - $params[$h] = OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]); - } - if (isset($params['realm'])) { - unset($params['realm']); - } - } - return $params; - } - - // helper to try to sort out headers for people who aren't running apache - public static function get_headers() - { - if (function_exists('apache_request_headers')) { - // we need this to get the actual Authorization: header - // because apache tends to tell us it doesn't exist - $headers = apache_request_headers(); - - // sanitize the output of apache_request_headers because - // we always want the keys to be Cased-Like-This and arh() - // returns the headers in the same case as they are in the - // request - $out = []; - foreach ($headers as $key => $value) { - $key = str_replace( - " ", - "-", - ucwords(strtolower(str_replace("-", " ", $key))) - ); - $out[$key] = $value; - } - } else { - // otherwise we don't have apache and are just going to have to hope - // that $_SERVER actually contains what we need - $out = []; - if (isset($_SERVER['CONTENT_TYPE'])) { - $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; - } - if (isset($_ENV['CONTENT_TYPE'])) { - $out['Content-Type'] = $_ENV['CONTENT_TYPE']; - } - - foreach ($_SERVER as $key => $value) { - if (substr($key, 0, 5) == "HTTP_") { - // this is chaos, basically it is just there to capitalize the first - // letter of every word that is not an initial HTTP and strip HTTP - // code from przemek - $key = str_replace( - " ", - "-", - ucwords(strtolower(str_replace("_", " ", substr($key, 5)))) - ); - $out[$key] = $value; - } - } - // The "Authorization" header may get turned into "Auth". - if (isset($out['Auth'])) { - $out['Authorization'] = $out['Auth']; - } - } - return $out; - } - - // This function takes a input like a=b&a=c&d=e and returns the parsed - // parameters like this - // array('a' => array('b','c'), 'd' => 'e') - public static function parse_parameters($input) - { - if (!isset($input) || !$input) { - return []; - } - - $pairs = explode('&', $input); - - $parsed_parameters = []; - foreach ($pairs as $pair) { - $split = explode('=', $pair, 2); - $parameter = OAuthUtil::urldecode_rfc3986($split[0]); - $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : ''; - - if (isset($parsed_parameters[$parameter])) { - // We have already recieved parameter(s) with this name, so add to the list - // of parameters with this name - - if (is_scalar($parsed_parameters[$parameter])) { - // This is the first duplicate, so transform scalar (string) into an array - // so we can add the duplicates - $parsed_parameters[$parameter] = [$parsed_parameters[$parameter]]; - } - - $parsed_parameters[$parameter][] = $value; - } else { - $parsed_parameters[$parameter] = $value; - } - } - return $parsed_parameters; - } - - public static function build_http_query($params) - { - if (!$params) { - return ''; - } - - // Urlencode both keys and values - $keys = OAuthUtil::urlencode_rfc3986(array_keys($params)); - $values = OAuthUtil::urlencode_rfc3986(array_values($params)); - $params = array_combine($keys, $values); - - // Parameters are sorted by name, using lexicographical byte value ordering. - // Ref: Spec: 9.1.1 (1) - uksort($params, 'strcmp'); - - $pairs = []; - foreach ($params as $parameter => $value) { - if (is_array($value)) { - // If two or more parameters share the same name, they are sorted by their value - // Ref: Spec: 9.1.1 (1) - // June 12th, 2010 - changed to sort because of issue 164 by hidetaka - sort($value, SORT_STRING); - foreach ($value as $duplicate_value) { - $pairs[] = $parameter.'='.$duplicate_value; - } - } else { - $pairs[] = $parameter.'='.$value; - } - } - // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) - // Each name-value pair is separated by an '&' character (ASCII code 38) - return implode('&', $pairs); - } -} diff --git a/modules/oauth/templates/registry.edit.tpl.php b/modules/oauth/templates/registry.edit.tpl.php deleted file mode 100644 index b43c40d39c3239424a148bff6084f0aa056b2406..0000000000000000000000000000000000000000 --- a/modules/oauth/templates/registry.edit.tpl.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php - -$this->data['jquery'] = ['core' => true, 'ui' => true, 'css' => true]; -$this->data['head'] = '<link rel="stylesheet" type="text/css" href="/'. - $this->data['baseurlpath'].'module.php/oauth/assets/css/oauth.css" />'."\n"; -$this->data['head'] .= '<script type="text/javascript" src="/'. - $this->data['baseurlpath'].'module.php/oauth/assets/js/oauth.js"></script>'; - -$this->includeAtTemplateBase('includes/header.php'); - -echo '<h1>OAuth Client</h1>'; - -echo $this->data['form']; - -echo '<p style="float: right"><a href="registry.php">'. - 'Return to entity listing <strong>without saving...</strong></a></p>'; - -$this->includeAtTemplateBase('includes/footer.php'); diff --git a/modules/oauth/templates/registry.edit.twig b/modules/oauth/templates/registry.edit.twig deleted file mode 100644 index ad9345d731a93a397528e1c6e2c0a05d7dd940f6..0000000000000000000000000000000000000000 --- a/modules/oauth/templates/registry.edit.twig +++ /dev/null @@ -1,18 +0,0 @@ -{% set pagetitle = 'SimpleSAMLphp'|trans %} -{% extends "base.twig" %} - -{% block preload %} - <link href="{{ baseurlpath }}assets/css/oauth.css" rel="stylesheet"> -{% endblock %} - -{% block postload %} - <script src="{{ baseurlpath}}assets/js/oauth.js"></script> -{% endblock %} - -{% block content %} - <h1>OAuth Client</h1> - {{ form|raw }} - <p style="float: right"> - <a href="registry.php">Return to entity listing <strong>without saving...</strong></a> - </p> -{% endblock %} diff --git a/modules/oauth/templates/registry.list.php b/modules/oauth/templates/registry.list.php deleted file mode 100644 index 1c3b287fb696b8ced33285dbe34599ebd85426ef..0000000000000000000000000000000000000000 --- a/modules/oauth/templates/registry.list.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -$this->data['jquery'] = ['core' => true, 'ui' => true, 'css' => true]; -$this->data['head'] = '<link rel="stylesheet" type="text/css" href="/'. - $this->data['baseurlpath'].'module.php/oauth/assets/oauth.css" />'."\n"; -$this->includeAtTemplateBase('includes/header.php'); - -echo '<h1>OAuth Client Registry</h1>'; -echo '<p>Here you can register new OAuth Clients. You are successfully logged in as '. - htmlspecialchars($this->data['userid']).'</p>'; - -echo '<h2>Your clients</h2>'; -echo '<table class="metalist" style="width: 100%">'; -$i = 0; -$rows = ['odd', 'even']; -foreach ($this->data['entries']['mine'] as $entryc) { - $entry = $entryc['value']; - $i++; - echo '<tr class="'.$rows[$i % 2].'"><td>'. - htmlspecialchars($entry['name']).'</td> <td><code>'.htmlspecialchars($entry['key']). - '</code></td><td><a href="registry.edit.php?editkey='.urlencode($entry['key']). - '">edit</a><a href="registry.php?delete='.urlencode($entry['key']).'">delete</a></td></tr>'; -} -if ($i == 0) { - echo'<tr><td colspan="3">No entries registered</td></tr>'; -} -echo '</table>'; - -echo '<p><a href="registry.edit.php">Add new client</a></p>'; - -echo '<h2>Other clients</h2>'; -echo '<table class="metalist" style="width: 100%">'; -$i = 0; -$rows = ['odd', 'even']; -foreach ($this->data['entries']['others'] as $entryc) { - $entry = $entryc['value']; - $i++; - echo '<tr class="'.$rows[$i % 2].'"><td>'. - htmlspecialchars($entry['name']).'</td><td><code>'.htmlspecialchars($entry['key']). - '</code></td><td>'.(isset($entry['owner']) ? htmlspecialchars($entry['owner']) : 'No owner'). - '</td></tr>'; -} -if ($i == 0) { - echo '<tr><td colspan="3">No entries registered</td></tr>'; -} -echo '</table>'; - -$this->includeAtTemplateBase('includes/footer.php'); diff --git a/modules/oauth/templates/registry.list.twig b/modules/oauth/templates/registry.list.twig deleted file mode 100644 index 86bc5a6792a26489a6d52ec13b65538ab764ca82..0000000000000000000000000000000000000000 --- a/modules/oauth/templates/registry.list.twig +++ /dev/null @@ -1,58 +0,0 @@ -{% set pagetitle = 'SimpleSAMLphp'|trans %} -{% extends "base.twig" %} - -{% block preload %} - <link href="{{ baseurlpath }}assets/css/oauth.css" rel="stylesheet" /> -{% endblock %} - -{% block content %} - <h1>OAuth Client Registry</h1> - <p>Here you can register new OAuth Clients. You are successfully logged in as {{ userid|escape('html') }}</p> - <h2>Your clients</h2> - - <table class="metalist" style="width: 100%;"> - {% for key, entryc in entries.mine %} - {% if loop.index0 is even %} - {% set class = 'even' %} - {% else %} - {% set class = 'odd' %} - {% endif %} - {% set entry = entryc.value %} - <tr class="{{ class }}"> - <td>{{ entry.name|escape('html') }}</td> - <td><kbd>{{ entry.key|escape('html') }}</kbd></td> - <td> - <a href="registry.edit.php?editkey={{ entry.key|escape('url') }}">edit</a> - <a href="registry.php?delete={{ entry.key|escape('url') }}">delete</a> - </td> - </tr> - {% else %} - <tr><td colspan="3">No entries registered</td></tr> - {% endfor %} - </table> - - <p><a href="registry.edit.php">Add new client</a></p> - <h2>Other clients</h2> - - <table class="metalist" style="width: 100%"> - {% for key, entryc in entries.others %} - {% if loop.index0 is even %} - {% set class = 'even' %} - {% else %} - {% set class = 'odd' %} - {% endif %} - {% set entry = entryc.value %} - <tr class="{{ class }}"> - <td>{{ entry.name|escape('html') }}</td> - <td><kbd>{{ entry.key|escape('html') }}</kbd></td> - {% if eentry.owner is defined %}} - <td>{{ entry.owner|escape('html') }}</td> - {% else %} - <td>No owner</td> - {% endif %} - </tr> - {% else %} - <tr><td colspan="3">No entries registered</td></tr> - {% endfor %} - </table> -{% endblock%} diff --git a/modules/oauth/templates/registry.saved.php b/modules/oauth/templates/registry.saved.php deleted file mode 100644 index 2e4bd27a92a916384f614e8b55fd058803e9c199..0000000000000000000000000000000000000000 --- a/modules/oauth/templates/registry.saved.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php - -$this->includeAtTemplateBase('includes/header.php'); - -echo '<h1>OAuth Client saved</h1>'; -echo '<p><a href="registry.php">Go back to OAuth client listing</a></p>'; - -$this->includeAtTemplateBase('includes/footer.php'); diff --git a/modules/oauth/templates/registry.saved.twig b/modules/oauth/templates/registry.saved.twig deleted file mode 100644 index 6c36465f7162b6b759ba0f41fdb4497b0364a8da..0000000000000000000000000000000000000000 --- a/modules/oauth/templates/registry.saved.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% set pagetitle = 'SimpleSAMLphp'|trans %} -{% extends "base.twig" %} - -{% block content %} - <h1>OAith Client saved</h1> - <p> - <a href="registry.php">Go back to OAuth client listing</a> - </p> -{% endblock %} diff --git a/modules/oauth/www/assets/css/oauth.css b/modules/oauth/www/assets/css/oauth.css deleted file mode 100644 index 7b8ad7e92cb2d9fcf4f6f57ecaf714898bd15fa3..0000000000000000000000000000000000000000 --- a/modules/oauth/www/assets/css/oauth.css +++ /dev/null @@ -1,84 +0,0 @@ -table.formtable { - width: 100%; -} -table.formtable tr td.name { - text-align: right; - vertical-align: top; - padding-right: .6em; -} -table.formtable tr td.value { - text-align: left; - padding: 0px; -} -table.formtable tr td.header { - padding-left: 5px; - padding-top: 8px; - font-weight: bold; - font-size: 110%; -} - -table.formtable tr td input,table.formtable tr td textarea { - width: 90%; - border: 1px solid #bbb; - margin: 2px 5px; - padding: 2px 4px; -} - -table.metalist { - border: 1px solid #aaa; - border-collapse: collapse; -} -table.metalist tr td { - padding: 2px 5px; -} -table.metalist tr.even td { - background: #e5e5e5; -} - -@media all { - div#content { - margin: .4em ! important; - } - - form { - display: inline; - } - - ul.tabset_tabs { - margin: 0px; - padding: 0px; - list-style: none; - } - - ul.tabset_tabs li { - background: none; - color: #222; - display: inline-block; - padding: 10px 15px; - cursor: pointer; - } - - ul.tabset_tabs li.current { - background: #ededed; - color: #222; - } - - .tabset_content { - display: none; - background: #ededed; - padding: 15px; - } - - .tabset_content.current { - display: inherit; - } - - #graph img { - max-width: 77%; - height: auto; - } - #table img { - max-width: 77%; - height: auto; - } -} diff --git a/modules/oauth/www/assets/js/oauth.js b/modules/oauth/www/assets/js/oauth.js deleted file mode 100644 index 442c63effcc4101a5f3ca02b50fb522cb83fd229..0000000000000000000000000000000000000000 --- a/modules/oauth/www/assets/js/oauth.js +++ /dev/null @@ -1,3 +0,0 @@ -document.addEventListener('DOMContentLoaded', function () { - $("#tabdiv").tabs(); -}); diff --git a/modules/oauth/www/getUserInfo.php b/modules/oauth/www/getUserInfo.php deleted file mode 100644 index ad9f878c8b511be1eaa9c87a1ff7ac15120f7b22..0000000000000000000000000000000000000000 --- a/modules/oauth/www/getUserInfo.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -require_once(dirname(dirname(__FILE__)).'/libextinc/OAuth.php'); - -$oauthconfig = \SimpleSAML\Configuration::getConfig('module_oauth.php'); - -if (!$oauthconfig->getBoolean('getUserInfo.enable', false)) { - throw new \Exception( - 'Get user info endpoint is disabled. This endpoint can be enabled in the module_oauth.php configuration file.' - ); -} - -$store = new \SimpleSAML\Module\oauth\OAuthStore(); -$server = new \SimpleSAML\Module\oauth\OAuthServer($store); - -$hmac_method = new OAuthSignatureMethod_HMAC_SHA1(); -$plaintext_method = new OAuthSignatureMethod_PLAINTEXT(); - -$server->add_signature_method($hmac_method); -$server->add_signature_method($plaintext_method); - -$req = OAuthRequest::from_request(); -list($consumer, $token) = $server->verify_request($req); - -$data = $store->getAuthorizedData($token->key); - -echo json_encode($data); diff --git a/modules/oauth/www/registry.edit.php b/modules/oauth/www/registry.edit.php deleted file mode 100644 index a367c482050addb0af428e566bcdc40a6b1564bc..0000000000000000000000000000000000000000 --- a/modules/oauth/www/registry.edit.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -// Load SimpleSAMLphp, configuration and metadata -$config = \SimpleSAML\Configuration::getInstance(); -$session = \SimpleSAML\Session::getSessionFromRequest(); -$oauthconfig = \SimpleSAML\Configuration::getOptionalConfig('module_oauth.php'); - -$store = new \SimpleSAML\Module\core\Storage\SQLPermanentStorage('oauth'); - -$authsource = "admin"; // force admin to authenticate as registry maintainer -$useridattr = $oauthconfig->getValue('useridattr', 'user'); - -if ($session->isValid($authsource)) { - $attributes = $session->getAuthData($authsource, 'Attributes'); - // Check if userid exists - if (!isset($attributes[$useridattr])) { - throw new \Exception('User ID is missing'); - } - $userid = $attributes[$useridattr][0]; -} else { - $as = \SimpleSAML\Auth\Source::getById($authsource); - $as->initLogin(\SimpleSAML\Utils\HTTP::getSelfURL()); -} - -if (array_key_exists('editkey', $_REQUEST)) { - $entryc = $store->get('consumers', $_REQUEST['editkey'], ''); - $entry = $entryc['value']; - \SimpleSAML\Module\oauth\Registry::requireOwnership($entry, $userid); -} else { - $entry = [ - 'owner' => $userid, - 'key' => \SimpleSAML\Utils\Random::generateID(), - 'secret' => \SimpleSAML\Utils\Random::generateID(), - ]; -} - -$editor = new \SimpleSAML\Module\oauth\Registry(); - -if (isset($_POST['submit'])) { - $editor->checkForm($_POST); - - $entry = $editor->formToMeta($_POST, [], ['owner' => $userid]); - - \SimpleSAML\Module\oauth\Registry::requireOwnership($entry, $userid); - - $store->set('consumers', $entry['key'], '', $entry); - - $template = new \SimpleSAML\XHTML\Template($config, 'oauth:registry.saved.php'); - $template->data['entry'] = $entry; - $template->show(); - exit; -} - -$form = $editor->metaToForm($entry); - -$template = new \SimpleSAML\XHTML\Template($config, 'oauth:registry.edit.tpl.php'); -$template->data['form'] = $form; -$template->data['jquery'] = ['core' => false, 'ui' => true, 'css' => true]; -$template->show(); diff --git a/modules/oauth/www/registry.php b/modules/oauth/www/registry.php deleted file mode 100644 index 4431835a63786095977605465fdb10254b097940..0000000000000000000000000000000000000000 --- a/modules/oauth/www/registry.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -// Load SimpleSAMLphp, configuration and metadata -$config = \SimpleSAML\Configuration::getInstance(); -$session = \SimpleSAML\Session::getSessionFromRequest(); -$oauthconfig = \SimpleSAML\Configuration::getOptionalConfig('module_oauth.php'); - -$store = new \SimpleSAML\Module\core\Storage\SQLPermanentStorage('oauth'); - -$authsource = "admin"; // force admin to authenticate as registry maintainer -$useridattr = $oauthconfig->getValue('useridattr', 'user'); - -if ($session->isValid($authsource)) { - $attributes = $session->getAuthData($authsource, 'Attributes'); - // Check if userid exists - if (!isset($attributes[$useridattr])) { - throw new \Exception('User ID is missing'); - } - $userid = $attributes[$useridattr][0]; -} else { - $as = \SimpleSAML\Auth\Source::getById($authsource); - $as->initLogin(\SimpleSAML\Utils\HTTP::getSelfURL()); -} - -if (isset($_REQUEST['delete'])) { - $entryc = $store->get('consumers', $_REQUEST['delete'], ''); - $entry = $entryc['value']; - - \SimpleSAML\Module\oauth\Registry::requireOwnership($entry, $userid); - $store->remove('consumers', $entry['key'], ''); -} - -$list = $store->getList('consumers'); - -$slist = ['mine' => [], 'others' => []]; -if (is_array($list)) { - foreach ($list as $listitem) { - if (array_key_exists('owner', $listitem['value'])) { - if ($listitem['value']['owner'] === $userid) { - $slist['mine'][] = $listitem; - continue; - } - } - } - $slist['others'][] = $listitem; -} - -$template = new \SimpleSAML\XHTML\Template($config, 'oauth:registry.list.php'); -$template->data['entries'] = $slist; -$template->data['userid'] = $userid; -$template->show(); diff --git a/modules/portal/lib/Portal.php b/modules/portal/lib/Portal.php index e4edd87cdf1dfcee8aadf44e2d2f45f5e84917e9..3df6495b583b9db2d96925bc28e4355b485716d1 100644 --- a/modules/portal/lib/Portal.php +++ b/modules/portal/lib/Portal.php @@ -56,9 +56,9 @@ class Portal /** - * @param \SimpleSAML\Locate\Translate $translator + * @param \SimpleSAML\Locale\Translate $translator * @param string $thispage - * @return array + * @return string */ public function getLoginInfo($translator, $thispage) { diff --git a/modules/riak/config-templates/module_riak.php b/modules/riak/config-templates/module_riak.php deleted file mode 100644 index 99f535fee579d461b295c9bfcc90234f3d4cf099..0000000000000000000000000000000000000000 --- a/modules/riak/config-templates/module_riak.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -/* - * The configuration of the riak Store module - * - */ - -$config = [ - /* - * This module has the following config options and defaults. - * - * 'path' => 'riak-php-client/riak.php', - * 'host' => 'localhost', - * 'port' => 8098, - * 'bucket' => 'SimpleSAMLphp', - */ -]; diff --git a/modules/riak/default-disable b/modules/riak/default-disable deleted file mode 100644 index fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f..0000000000000000000000000000000000000000 --- a/modules/riak/default-disable +++ /dev/null @@ -1,3 +0,0 @@ -This file indicates that the default state of this module -is disabled. To enable, create a file named enable in the -same directory as this file. diff --git a/modules/riak/docs/simplesamlphp-riak.md b/modules/riak/docs/simplesamlphp-riak.md deleted file mode 100644 index c5e13a721098f14ba275690acd0ffbe6c4722129..0000000000000000000000000000000000000000 --- a/modules/riak/docs/simplesamlphp-riak.md +++ /dev/null @@ -1,117 +0,0 @@ -Riak Store module -================= - -<!-- - This file is written in Markdown syntax. - For more information about how to use the Markdown syntax, read here: - http://daringfireball.net/projects/markdown/syntax ---> - - -<!-- {{TOC}} --> - -Introduction ------------- - -The riak module implements a Store that can be used as a backend -for SimpleSAMLphp session data like the phpsession, sql, or memcache -backends. - -Preparations ------------- - -The obvious first step for using Riak as a backend is to install -and configure a Riak cluster for SimpleSAMLphp to use. Please refer -to the Riak documentation for this. - -This module requires the use of a Riak backend that supports secondary -indexes. Refer to the Riak documentation on how to enable an -appropriate backend for use by this module. Currently the only -storage backend that supports secondary indexes is leveldb. - -Next, you will need to install the Riak PHP Client library, available -from https://github.com/basho/riak-php-client. - -Finally, you need to config SimpleSAMLphp to for the riak Store by -enabling the following modules: - - 1. cron - 2. riak - -The cron module allows you to do tasks regularly by setting up a -cronjob that calls hooks in SimpleSAMLphp. This is required by the -riak module to remove expired entries in the store. - -Enabling the riak module allows it to be loaded and used as a storage -backend. - -You also need to copy the `config-templates` files from the cron -module above into the global `config/` directory. - - $ cd /var/simplesamlphp - $ touch modules/cron/enable - $ cp modules/cron/config-templates/*.php config/ - $ touch modules/riak/enable - $ cp modules/riak/config-templates/*.php config/ - - -Configuring the cron module ---------------------------- - -At `/var/simplesamlphp/config` - - $ vi module_cron.php - -edit: - - $config = array ( - 'key' => 'secret', - 'allowed_tags' => array('daily', 'hourly', 'frequent'), - 'debug_message' => TRUE, - 'sendemail' => TRUE, - ); - -Then: With your browser go to => https://simplesamlphp_machine/simplesaml/module.php/cron/croninfo.php - -And copy the cron's sugestion: - - ------------------------------------------------------------------------------------------------------------------- - Cron is a way to run things regularly on unix systems. - - Here is a suggestion for a crontab file: - - # Run cron [daily] - 02 0 * * * curl --silent "https://simplesamlphp_machine/simplesaml/module.php/cron/cron.php?key=secret&tag=daily" > /dev/null 2>&1 - # Run cron [hourly] - 01 * * * * curl --silent "https://simplesamlphp_machine/simplesaml/module.php/cron/cron.php?key=secret&tag=hourly" > /dev/null 2>&1 - # Run cron [frequent] - XXXXXXXXXX curl --silent "https://simplesamlphp_machine/simplesaml/module.php/cron/cron.php?key=secret&tag=frequent" > /dev/null 2>&1 - Click here to run the cron jobs: - - Run cron [daily] - Run cron [hourly] - Run cron [frequent] - ------------------------------------------------------------------------------------------------------------------- - -Add to CRON with - - # crontab -e - -Configuring the riak module ---------------------------- - -The riak module uses the following configuration options specified -in `config/module_riak.php`. The defaults are listed: - - $config = array( - 'path' => 'riak-php-client/riak.php', - 'host' => 'localhost', - 'port' => 8098, - 'bucket' => 'SimpleSAMLphp', - ); - -Finally, the module can be specified as the Store in `config/config.php` -with the following setting: - - 'store.type' => 'riak:Store', - diff --git a/modules/riak/hooks/hook_cron.php b/modules/riak/hooks/hook_cron.php deleted file mode 100644 index c42d2c313e75b66cb6855a2b353e7033e1ebdff9..0000000000000000000000000000000000000000 --- a/modules/riak/hooks/hook_cron.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php - -namespace SimpleSAML\Module\riak; - -/* - * Copyright (c) 2012 The University of Queensland - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Written by David Gwynne <dlg@uq.edu.au> as part of the IT - * Infrastructure Group in the Faculty of Engineering, Architecture - * and Information Technology. - */ - -/** - * Hook to run a cron job. - * - * @param array &$croninfo Output - */ -function riak_hook_cron(&$croninfo) -{ - assert(is_array($croninfo)); - assert(array_key_exists('summary', $croninfo)); - assert(array_key_exists('tag', $croninfo)); - - if ($croninfo['tag'] !== 'hourly') { - return; - } - - try { - $store = new \SimpleSAML\Module\riak\Store\Store(); - $result = $store->bucket->indexSearch('expires', 'int', 1, time() - 30); - foreach ($result as $link) { - $link->getBinary()->delete(); - } - - \SimpleSAML\Logger::info( - sprintf("deleted %s riak key%s", sizeof($result), sizeof($result) == 1 ? '' : 's') - ); - } catch (\Exception $e) { - $message = 'riak threw exception: '.$e->getMessage(); - \SimpleSAML\Logger::warning($message); - $croninfo['summary'][] = $message; - } -} diff --git a/modules/riak/lib/Store/Store.php b/modules/riak/lib/Store/Store.php deleted file mode 100644 index c44f599502e9bea7073e5ce84d164ebd4f782ee8..0000000000000000000000000000000000000000 --- a/modules/riak/lib/Store/Store.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php - -namespace SimpleSAML\Module\riak\Store; - -/* - * Copyright (c) 2012 The University of Queensland - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Written by David Gwynne <dlg@uq.edu.au> as part of the IT - * Infrastructure Group in the Faculty of Engineering, Architecture - * and Information Technology. - */ - -class Store extends \SimpleSAML\Store -{ - public $client; - public $bucket; - - protected function __construct() - { - $config = \SimpleSAML\Configuration::getConfig('module_riak.php'); - - $path = $config->getString('path', 'riak-php-client/riak.php'); - $host = $config->getString('host', 'localhost'); - $port = $config->getString('port', 8098); - $bucket = $config->getString('bucket', 'simpleSAMLphp'); - - require_once($path); - $this->client = new \RiakClient($host, $port); - $this->bucket = $this->client->bucket($bucket); - } - - /** - * Retrieve a value from the datastore. - * - * @param string $type The datatype. - * @param string $key The key. - * @return mixed|NULL The value. - */ - public function get($type, $key) - { - assert(is_string($type)); - assert(is_string($key)); - - $v = $this->bucket->getBinary("$type.$key"); - if (!$v->exists()) { - return null; - } - - $expires = $v->getIndex('Expires', 'int'); - if (sizeof($expires) && (int) array_shift($expires) <= time()) { - $v->delete(); - return null; - } - - return (unserialize($v->getData())); - } - - /** - * Save a value to the datastore. - * - * @param string $type The datatype. - * @param string $key The key. - * @param mixed $value The value. - * @param int|NULL $expire The expiration time (unix timestamp), or NULL if it never expires. - */ - public function set($type, $key, $value, $expire = null) - { - assert(is_string($type)); - assert(is_string($key)); - assert($expire === null || (is_int($expire) && $expire > 2592000)); - - $v = $this->bucket->newBinary("$type.$key", serialize($value), 'application/php'); - if (!is_null($expire)) { - $v->addIndex("Expires", "int", $expire); - } - - $v->store(); - } - - /** - * Delete a value from the datastore. - * - * @param string $type The datatype. - * @param string $key The key. - */ - public function delete($type, $key) - { - assert(is_string($type)); - assert(is_string($key)); - - $v = $this->bucket->getBinary("$type.$key"); - if (!$v->exists()) { - return; - } - $v->delete(); - } -}