aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine/lib/api.php88
-rw-r--r--engine/lib/pam.php44
-rw-r--r--engine/tests/services/api.php2
-rw-r--r--services/api/rest.php6
4 files changed, 46 insertions, 94 deletions
diff --git a/engine/lib/api.php b/engine/lib/api.php
index 38b93cd3a..5372c0214 100644
--- a/engine/lib/api.php
+++ b/engine/lib/api.php
@@ -411,7 +411,7 @@ function authenticate_method($method) {
// check API authentication if required
if ($API_METHODS[$method]["require_api_auth"] == true) {
- if (api_authenticate() == false) {
+ if (pam_authenticate(null, "api") == false) {
throw new APIException(elgg_echo('APIException:APIAuthenticationFailed'));
}
}
@@ -426,65 +426,6 @@ function authenticate_method($method) {
return true;
}
-$API_AUTH_HANDLERS = array();
-
-/**
- * Register an API authorization handler
- *
- * @param $handler
- * @param $importance
- * @return bool
- */
-function register_api_auth_handler($handler, $importance = "sufficient") {
- global $API_AUTH_HANDLERS;
-
- if (is_callable($handler)) {
- $API_AUTH_HANDLERS[$handler] = new stdClass;
-
- $API_AUTH_HANDLERS[$handler]->handler = $handler;
- $API_AUTH_HANDLERS[$handler]->importance = strtolower($importance);
-
- return true;
- }
-
- return false;
-}
-
-/**
- * Authenticate an API method call
- *
- * @return bool
- */
-function api_authenticate() {
- global $API_AUTH_HANDLERS;
-
- $authenticated = false;
-
- foreach ($API_AUTH_HANDLERS as $k => $v) {
- $handler = $v->handler;
- $importance = $v->importance;
-
- try {
- // Execute the handler
- if ($handler()) {
- $authenticated = true;
- } else {
- // If this is required then abort.
- if ($importance == 'required') {
- return false;
- }
- }
- } catch (Exception $e) {
- // If this is required then abort.
- if ($importance == 'required') {
- return false;
- }
- }
- }
-
- return $authenticated;
-}
-
/**
* Executes a method.
* A method is a function which you have previously exposed using expose_function.
@@ -758,7 +699,7 @@ function api_auth_hmac() {
// Get api header
$api_header = get_and_validate_api_headers();
-
+
// Pull API user details
$api_user = get_api_user($CONFIG->site_id, $api_header->api_key);
@@ -777,7 +718,7 @@ function api_auth_hmac() {
$api_header->time,
$api_header->api_key,
$secret_key,
- $params,
+ $query,
$api_header->method == 'POST' ? $api_header->posthash : "");
@@ -842,7 +783,7 @@ function get_and_validate_api_headers() {
}
// Basic timecheck, think about making this smaller if we get loads of users and the cache gets really big.
- if (($result->time<(microtime(true)-86400.00)) || ($result->time>(microtime(true)+86400.00))) {
+ if (($result->time<(time()-86400)) || ($result->time>(time()+86400))) {
throw new APIException(elgg_echo('APIException:TemporalDrift'));
}
@@ -899,7 +840,7 @@ function map_api_hash($algo) {
* @param $time string String representation of unix time as stored in X-Searunner-time.
* @param $api_key string Your api key.
* @param $secret string Your secret key.
- * @param $get_variables string URLEncoded string representation of the get variable parameters, eg "format=php&method=searunner.test".
+ * @param $get_variables string URLEncoded string representation of the get variable parameters, eg "method=user&guid=2"
* @param $post_hash string Optional sha1 hash of the post data.
* @return string The HMAC string.
*/
@@ -1036,8 +977,11 @@ function pam_auth_usertoken($credentials = NULL) {
global $CONFIG;
$token = get_input('auth_token');
-
- $validated_userid = validate_user_token($token);
+ if (!$token) {
+ return false;
+ }
+
+ $validated_userid = validate_user_token($token, $CONFIG->site_id);
if ($validated_userid) {
$u = get_entity($validated_userid);
@@ -1218,17 +1162,11 @@ function send_api_call(array $keys, $url, array $call, $method = 'GET', $post_da
}
// Time
- $time = microtime(true);
+ $time = time();
- // URL encode all the parameters, ensuring auth_token (if present) is at the end!
+ // URL encode all the parameters
foreach ($call as $k => $v){
- if ($k!='auth_token') {
- $encoded_params[] = urlencode($k).'='.urlencode($v);
- }
- }
-
- if ($call['auth_token']) {
- $encoded_params[] = urlencode('auth_token').'='.urlencode($call['auth_token']);
+ $encoded_params[] = urlencode($k).'='.urlencode($v);
}
$params = implode('&', $encoded_params);
diff --git a/engine/lib/pam.php b/engine/lib/pam.php
index 17b10b5cc..590ef9fde 100644
--- a/engine/lib/pam.php
+++ b/engine/lib/pam.php
@@ -3,12 +3,13 @@
* Elgg Simple PAM library
* Contains functions for managing authentication.
* This is not a full implementation of PAM. It supports a single facility
- * (authentication) and only allows one policy at a time. There are two control
- * flags possible for each module: sufficient or required. The entire chain for
- * a policy is processed (or until a required module fails). A module fails by
- * returning false or throwing an exception. The order that modules are
- * processed is determined by the order they are registered. For an example of
- * a PAM, see pam_auth_userpass() in sessions.php.
+ * (authentication) and allows multiple policies (user authentication is the
+ * default). There are two control flags possible for each module: sufficient
+ * or required. The entire chain for a policy is processed (or until a
+ * required module fails). A module fails by returning false or throwing an
+ * exception. The order that modules are processed is determined by the order
+ * they are registered. For an example of a PAM, see pam_auth_userpass() in
+ * sessions.php.
*
* For more information on PAMs see:
* http://www.freebsd.org/doc/en/articles/pam/index.html
@@ -27,16 +28,23 @@ $_PAM_HANDLERS_MSG = array();
*
* @param string $handler The handler function in the format
* pam_handler($credentials = NULL);
- * @param string $importance The importance - "sufficient" or "required"
+ * @param string $importance The importance - "sufficient" (default) or "required"
+ * @param string $policy - the policy type, default is "user"
+ * @return boolean
*/
-function register_pam_handler($handler, $importance = "sufficient") {
+function register_pam_handler($handler, $importance = "sufficient", $policy = "user") {
global $_PAM_HANDLERS;
+ // setup array for this type of pam if not already set
+ if (!isset($_PAM_HANDLERS[$policy])) {
+ $_PAM_HANDLERS[$policy] = array();
+ }
+
if (is_callable($handler)) {
- $_PAM_HANDLERS[$handler] = new stdClass;
+ $_PAM_HANDLERS[$policy][$handler] = new stdClass;
- $_PAM_HANDLERS[$handler]->handler = $handler;
- $_PAM_HANDLERS[$handler]->importance = strtolower($importance);
+ $_PAM_HANDLERS[$policy][$handler]->handler = $handler;
+ $_PAM_HANDLERS[$policy][$handler]->importance = strtolower($importance);
return true;
}
@@ -48,18 +56,19 @@ function register_pam_handler($handler, $importance = "sufficient") {
* Unregisters a PAM handler.
*
* @param string $handler The PAM handler function name
+ * @param string $policy - the policy type, default is "user"
*/
-function unregister_pam_handler($handler) {
+function unregister_pam_handler($handler, $policy = "user") {
global $_PAM_HANDLERS;
- unset($_PAM_HANDLERS[$handler]);
+ unset($_PAM_HANDLERS[$policy][$handler]);
}
/**
* Attempt to authenticate.
* This function will process all registered PAM handlers or stop when the first
* handler fails. A handler fails by either returning false or throwing an
- * exception. The advatange of throwing an exception is that it returns a message
+ * exception. The advantage of throwing an exception is that it returns a message
* through the global $_PAM_HANDLERS_MSG which can be used in communication with
* a user. The order that handlers are processed is determined by the order that
* they were registered.
@@ -69,14 +78,17 @@ function unregister_pam_handler($handler) {
* otherwise retrieved (eg from the HTTP header or $_SESSION).
*
* @param mixed $credentials Mixed PAM handler specific credentials (e.g. username, password)
+ * @param string $policy - the policy type, default is "user"
* @return bool true if authenticated, false if not.
*/
-function pam_authenticate($credentials = NULL) {
+function pam_authenticate($credentials = NULL, $policy = "user") {
global $_PAM_HANDLERS, $_PAM_HANDLERS_MSG;
+ $_PAM_HANDLERS_MSG = array();
+
$authenticated = false;
- foreach ($_PAM_HANDLERS as $k => $v) {
+ foreach ($_PAM_HANDLERS[$policy] as $k => $v) {
$handler = $v->handler;
$importance = $v->importance;
diff --git a/engine/tests/services/api.php b/engine/tests/services/api.php
index 66fff268d..28a7a64bc 100644
--- a/engine/tests/services/api.php
+++ b/engine/tests/services/api.php
@@ -257,7 +257,7 @@ class ElggCoreServicesApiTest extends ElggCoreUnitTest {
// api key methods
public function testApiAuthenticate() {
- $this->assertFalse(api_authenticate());
+ $this->assertFalse(pam_authenticate(null, "api"));
}
public function testApiAuthKeyNoKey() {
diff --git a/services/api/rest.php b/services/api/rest.php
index 8ac63022d..4d3e39aaa 100644
--- a/services/api/rest.php
+++ b/services/api/rest.php
@@ -34,8 +34,10 @@ if (trigger_plugin_hook('rest', 'init', null, false) == false) {
// user token can also be used for user authentication
register_pam_handler('pam_auth_usertoken');
- // for api authentication, we default to a simple API key check
- register_api_auth_handler('api_auth_key');
+ // simple API key check
+ register_pam_handler('api_auth_key', "sufficient", "api");
+ // hmac
+ register_pam_handler('api_auth_hmac', "sufficient", "api");
}
// Get parameter variables