Example #1
0
/**
 * PAM: Confirm the HMAC signature
 *
 * @return true if success - otherwise throws exception
 *
 * @throws SecurityException
 * @since 1.7.0
 * @access private
 */
function api_auth_hmac()
{
    global $CONFIG;
    // 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);
    if (!$api_user) {
        throw new SecurityException(elgg_echo('SecurityException:InvalidAPIKey'), ErrorResult::$RESULT_FAIL_APIKEY_INVALID);
    }
    // Get the secret key
    $secret_key = $api_user->secret;
    // get the query string
    $query = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], '?') + 1);
    // calculate expected HMAC
    $hmac = calculate_hmac($api_header->hmac_algo, $api_header->time, $api_header->nonce, $api_header->api_key, $secret_key, $query, $api_header->method == 'POST' ? $api_header->posthash : "");
    if ($api_header->hmac !== $hmac) {
        throw new SecurityException("HMAC is invalid.  {$api_header->hmac} != [calc]{$hmac}");
    }
    // Now make sure this is not a replay
    if (cache_hmac_check_replay($hmac)) {
        throw new SecurityException(elgg_echo('SecurityException:DupePacket'));
    }
    // Validate post data
    if ($api_header->method == "POST") {
        $postdata = get_post_data();
        $calculated_posthash = calculate_posthash($postdata, $api_header->posthash_algo);
        if (strcmp($api_header->posthash, $calculated_posthash) != 0) {
            $msg = elgg_echo('SecurityException:InvalidPostHash', array($calculated_posthash, $api_header->posthash));
            throw new SecurityException($msg);
        }
    }
    return true;
}
Example #2
0
File: api.php Project: eokyere/elgg
/**
 * Secure authentication through headers and HMAC.
 */
function pam_auth_hmac($credentials = NULL)
{
    global $CONFIG;
    $api_header = get_and_validate_api_headers();
    // Get api header
    $api_user = get_api_user($CONFIG->site_id, $api_header->api_key);
    // Pull API user details
    if ($api_user) {
        // Get the secret key
        $secret_key = $api_user->secret;
        // Serialise parameters
        $encoded_params = array();
        foreach ($api_header->get_variables as $k => $v) {
            $encoded_params[] = urlencode($k) . '=' . urlencode($v);
        }
        $params = implode('&', $encoded_params);
        // Validate HMAC
        $hmac = calculate_hmac($api_header->hmac_algo, $api_header->time, $api_header->api_key, $secret_key, $params, $api_header->method == 'POST' ? $api_header->posthash : "");
        if (strcmp($api_header->hmac, $hmac) == 0 && $api_header->hmac && $hmac) {
            // Now make sure this is not a replay
            if (!cache_hmac_check_replay($hmac)) {
                // Validate post data
                if ($api_header->method == "POST") {
                    $postdata = get_post_data();
                    $calculated_posthash = calculate_posthash($postdata, $api_header->posthash_algo);
                    if (strcmp($api_header->posthash, $calculated_posthash) != 0) {
                        throw new SecurityException(sprintf(elgg_echo('SecurityException:InvalidPostHash'), $calculated_posthash, $api_header->posthash));
                    }
                }
                // If we've passed all the checks so far then we can be reasonably certain that the request is authentic, so return this fact to the PAM engine.
                return true;
            } else {
                throw new SecurityException(elgg_echo('SecurityException:DupePacket'));
            }
        } else {
            throw new SecurityException("HMAC is invalid.  {$api_header->hmac} != [calc]{$hmac} = {$api_header->hmac_algo}(**SECRET KEY**, time:{$api_header->time}, apikey:{$api_header->api_key}, get_vars:{$params}" . ($api_header->method == "POST" ? "posthash:{$api_header->posthash}}" : ")"));
        }
    } else {
        throw new SecurityException(elgg_echo('SecurityException:InvalidAPIKey'), ErrorResult::$RESULT_FAIL_APIKEY_INVALID);
    }
    return false;
}