use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\HTML;
use Friendica\Core\Addon;
+use Friendica\Core\Authentication;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Core\NotificationsManager;
require_once 'include/conversation.php';
require_once 'mod/share.php';
require_once 'mod/item.php';
-require_once 'include/security.php';
require_once 'mod/wall_upload.php';
define('API_METHOD_ANY', '*');
throw new UnauthorizedException("This API requires login");
}
- authenticate_success($record);
+ Authentication::authenticate_success($record);
$_SESSION["allow_api"] = true;
+++ /dev/null
-<?php
-/**
- * @file include/security.php
- */
-
-use Friendica\Core\Addon;
-use Friendica\Core\Config;
-use Friendica\Core\L10n;
-use Friendica\Core\PConfig;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\Model\Contact;
-use Friendica\Model\Group;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Model\PermissionSet;
-
-/**
- * @brief Calculate the hash that is needed for the "Friendica" cookie
- *
- * @param array $user Record from "user" table
- *
- * @return string Hashed data
- */
-function cookie_hash($user)
-{
- return(hash("sha256", Config::get("system", "site_prvkey") .
- $user["prvkey"] .
- $user["password"]));
-}
-
-/**
- * @brief Set the "Friendica" cookie
- *
- * @param int $time
- * @param array $user Record from "user" table
- */
-function new_cookie($time, $user = [])
-{
- if ($time != 0) {
- $time = $time + time();
- }
-
- if ($user) {
- $value = json_encode(["uid" => $user["uid"],
- "hash" => cookie_hash($user),
- "ip" => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0')]);
- } else {
- $value = "";
- }
-
- setcookie("Friendica", $value, $time, "/", "", (Config::get('system', 'ssl_policy') == SSL_POLICY_FULL), true);
-}
-
-/**
- * @brief Sets the provided user's authenticated session
- *
- * @todo Should be moved to Friendica\Core\Session once it's created
- *
- * @param type $user_record
- * @param type $login_initial
- * @param type $interactive
- * @param type $login_refresh
- */
-function authenticate_success($user_record, $login_initial = false, $interactive = false, $login_refresh = false)
-{
- $a = get_app();
-
- $_SESSION['uid'] = $user_record['uid'];
- $_SESSION['theme'] = $user_record['theme'];
- $_SESSION['mobile-theme'] = PConfig::get($user_record['uid'], 'system', 'mobile_theme');
- $_SESSION['authenticated'] = 1;
- $_SESSION['page_flags'] = $user_record['page-flags'];
- $_SESSION['my_url'] = System::baseUrl() . '/profile/' . $user_record['nickname'];
- $_SESSION['my_address'] = $user_record['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3);
- $_SESSION['addr'] = defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0');
-
- $a->user = $user_record;
-
- if ($interactive) {
- if ($a->user['login_date'] <= NULL_DATE) {
- $_SESSION['return_url'] = 'profile_photo/new';
- $a->module = 'profile_photo';
- info(L10n::t("Welcome ") . $a->user['username'] . EOL);
- info(L10n::t('Please upload a profile photo.') . EOL);
- } else {
- info(L10n::t("Welcome back ") . $a->user['username'] . EOL);
- }
- }
-
- $member_since = strtotime($a->user['register_date']);
- if (time() < ($member_since + ( 60 * 60 * 24 * 14))) {
- $_SESSION['new_member'] = true;
- } else {
- $_SESSION['new_member'] = false;
- }
- if (strlen($a->user['timezone'])) {
- date_default_timezone_set($a->user['timezone']);
- $a->timezone = $a->user['timezone'];
- }
-
- $master_record = $a->user;
-
- if ((x($_SESSION, 'submanage')) && intval($_SESSION['submanage'])) {
- $user = DBA::selectFirst('user', [], ['uid' => $_SESSION['submanage']]);
- if (DBA::isResult($user)) {
- $master_record = $user;
- }
- }
-
- if ($master_record['parent-uid'] == 0) {
- // First add our own entry
- $a->identities = [['uid' => $master_record['uid'],
- 'username' => $master_record['username'],
- 'nickname' => $master_record['nickname']]];
-
- // Then add all the children
- $r = DBA::select('user', ['uid', 'username', 'nickname'],
- ['parent-uid' => $master_record['uid'], 'account_removed' => false]);
- if (DBA::isResult($r)) {
- $a->identities = array_merge($a->identities, DBA::toArray($r));
- }
- } else {
- // Just ensure that the array is always defined
- $a->identities = [];
-
- // First entry is our parent
- $r = DBA::select('user', ['uid', 'username', 'nickname'],
- ['uid' => $master_record['parent-uid'], 'account_removed' => false]);
- if (DBA::isResult($r)) {
- $a->identities = DBA::toArray($r);
- }
-
- // Then add all siblings
- $r = DBA::select('user', ['uid', 'username', 'nickname'],
- ['parent-uid' => $master_record['parent-uid'], 'account_removed' => false]);
- if (DBA::isResult($r)) {
- $a->identities = array_merge($a->identities, DBA::toArray($r));
- }
- }
-
- $r = DBA::p("SELECT `user`.`uid`, `user`.`username`, `user`.`nickname`
- FROM `manage`
- INNER JOIN `user` ON `manage`.`mid` = `user`.`uid`
- WHERE `user`.`account_removed` = 0 AND `manage`.`uid` = ?",
- $master_record['uid']
- );
- if (DBA::isResult($r)) {
- $a->identities = array_merge($a->identities, DBA::toArray($r));
- }
-
- if ($login_initial) {
- logger('auth_identities: ' . print_r($a->identities, true), LOGGER_DEBUG);
- }
- if ($login_refresh) {
- logger('auth_identities refresh: ' . print_r($a->identities, true), LOGGER_DEBUG);
- }
-
- $contact = DBA::selectFirst('contact', [], ['uid' => $_SESSION['uid'], 'self' => true]);
- if (DBA::isResult($contact)) {
- $a->contact = $contact;
- $a->cid = $contact['id'];
- $_SESSION['cid'] = $a->cid;
- }
-
- header('X-Account-Management-Status: active; name="' . $a->user['username'] . '"; id="' . $a->user['nickname'] . '"');
-
- if ($login_initial || $login_refresh) {
- DBA::update('user', ['login_date' => DateTimeFormat::utcNow()], ['uid' => $_SESSION['uid']]);
-
- // Set the login date for all identities of the user
- DBA::update('user', ['login_date' => DateTimeFormat::utcNow()],
- ['parent-uid' => $master_record['uid'], 'account_removed' => false]);
- }
-
- if ($login_initial) {
- /*
- * If the user specified to remember the authentication, then set a cookie
- * that expires after one week (the default is when the browser is closed).
- * The cookie will be renewed automatically.
- * The week ensures that sessions will expire after some inactivity.
- */
- if (!empty($_SESSION['remember'])) {
- logger('Injecting cookie for remembered user ' . $a->user['nickname']);
- new_cookie(604800, $user_record);
- unset($_SESSION['remember']);
- }
- }
-
- if ($login_initial) {
- Addon::callHooks('logged_in', $a->user);
-
- if (($a->module !== 'home') && isset($_SESSION['return_url'])) {
- goaway(System::baseUrl() . '/' . $_SESSION['return_url']);
- }
- }
-}
-
-function can_write_wall($owner)
-{
- static $verified = 0;
-
- if (!local_user() && !remote_user()) {
- return false;
- }
-
- $uid = local_user();
- if ($uid == $owner) {
- return true;
- }
-
- if (local_user() && ($owner == 0)) {
- return true;
- }
-
- if (remote_user()) {
- // use remembered decision and avoid a DB lookup for each and every display item
- // DO NOT use this function if there are going to be multiple owners
- // We have a contact-id for an authenticated remote user, this block determines if the contact
- // belongs to this page owner, and has the necessary permissions to post content
-
- if ($verified === 2) {
- return true;
- } elseif ($verified === 1) {
- return false;
- } else {
- $cid = 0;
-
- if (!empty($_SESSION['remote'])) {
- foreach ($_SESSION['remote'] as $visitor) {
- if ($visitor['uid'] == $owner) {
- $cid = $visitor['cid'];
- break;
- }
- }
- }
-
- if (!$cid) {
- return false;
- }
-
- $r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` INNER JOIN `user` on `user`.`uid` = `contact`.`uid`
- WHERE `contact`.`uid` = %d AND `contact`.`id` = %d AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
- AND `user`.`blockwall` = 0 AND `readonly` = 0 AND ( `contact`.`rel` IN ( %d , %d ) OR `user`.`page-flags` = %d ) LIMIT 1",
- intval($owner),
- intval($cid),
- intval(Contact::SHARING),
- intval(Contact::FRIEND),
- intval(Contact::PAGE_COMMUNITY)
- );
-
- if (DBA::isResult($r)) {
- $verified = 2;
- return true;
- } else {
- $verified = 1;
- }
- }
- }
-
- return false;
-}
-
-/// @TODO $groups should be array
-function permissions_sql($owner_id, $remote_verified = false, $groups = null)
-{
- $local_user = local_user();
- $remote_user = remote_user();
-
- /**
- * Construct permissions
- *
- * default permissions - anonymous user
- */
- $sql = " AND allow_cid = ''
- AND allow_gid = ''
- AND deny_cid = ''
- AND deny_gid = ''
- ";
-
- /**
- * Profile owner - everything is visible
- */
- if ($local_user && $local_user == $owner_id) {
- $sql = '';
- /**
- * Authenticated visitor. Unless pre-verified,
- * check that the contact belongs to this $owner_id
- * and load the groups the visitor belongs to.
- * If pre-verified, the caller is expected to have already
- * done this and passed the groups into this function.
- */
- } elseif ($remote_user) {
- /*
- * Authenticated visitor. Unless pre-verified,
- * check that the contact belongs to this $owner_id
- * and load the groups the visitor belongs to.
- * If pre-verified, the caller is expected to have already
- * done this and passed the groups into this function.
- */
-
- if (!$remote_verified) {
- if (DBA::exists('contact', ['id' => $remote_user, 'uid' => $owner_id, 'blocked' => false])) {
- $remote_verified = true;
- $groups = Group::getIdsByContactId($remote_user);
- }
- }
-
- if ($remote_verified) {
- $gs = '<<>>'; // should be impossible to match
-
- if (is_array($groups)) {
- foreach ($groups as $g) {
- $gs .= '|<' . intval($g) . '>';
- }
- }
-
- $sql = sprintf(
- " AND ( NOT (deny_cid REGEXP '<%d>' OR deny_gid REGEXP '%s')
- AND ( allow_cid REGEXP '<%d>' OR allow_gid REGEXP '%s' OR ( allow_cid = '' AND allow_gid = '') )
- )
- ",
- intval($remote_user),
- DBA::escape($gs),
- intval($remote_user),
- DBA::escape($gs)
- );
- }
- }
- return $sql;
-}
-
-function item_permissions_sql($owner_id, $remote_verified = false, $groups = null)
-{
- $local_user = local_user();
- $remote_user = remote_user();
-
- /*
- * Construct permissions
- *
- * default permissions - anonymous user
- */
- $sql = " AND NOT `item`.`private`";
-
- // Profile owner - everything is visible
- if ($local_user && ($local_user == $owner_id)) {
- $sql = '';
- } elseif ($remote_user) {
- /*
- * Authenticated visitor. Unless pre-verified,
- * check that the contact belongs to this $owner_id
- * and load the groups the visitor belongs to.
- * If pre-verified, the caller is expected to have already
- * done this and passed the groups into this function.
- */
- $set = PermissionSet::get($owner_id, $remote_user, $groups);
-
- if (!empty($set)) {
- $sql_set = " OR (`item`.`private` IN (1,2) AND `item`.`wall` AND `item`.`psid` IN (" . implode(',', $set) . "))";
- } else {
- $sql_set = '';
- }
-
- $sql = " AND (NOT `item`.`private`" . $sql_set . ")";
- }
-
- return $sql;
-}
-
-/*
- * Functions used to protect against Cross-Site Request Forgery
- * The security token has to base on at least one value that an attacker can't know - here it's the session ID and the private key.
- * In this implementation, a security token is reusable (if the user submits a form, goes back and resubmits the form, maybe with small changes;
- * or if the security token is used for ajax-calls that happen several times), but only valid for a certain amout of time (3hours).
- * The "typename" seperates the security tokens of different types of forms. This could be relevant in the following case:
- * A security token is used to protekt a link from CSRF (e.g. the "delete this profile"-link).
- * If the new page contains by any chance external elements, then the used security token is exposed by the referrer.
- * Actually, important actions should not be triggered by Links / GET-Requests at all, but somethimes they still are,
- * so this mechanism brings in some damage control (the attacker would be able to forge a request to a form of this type, but not to forms of other types).
- */
-function get_form_security_token($typename = '')
-{
- $a = get_app();
-
- $timestamp = time();
- $sec_hash = hash('whirlpool', $a->user['guid'] . $a->user['prvkey'] . session_id() . $timestamp . $typename);
-
- return $timestamp . '.' . $sec_hash;
-}
-
-function check_form_security_token($typename = '', $formname = 'form_security_token')
-{
- $hash = null;
-
- if (!empty($_REQUEST[$formname])) {
- /// @TODO Careful, not secured!
- $hash = $_REQUEST[$formname];
- }
-
- if (!empty($_SERVER['HTTP_X_CSRF_TOKEN'])) {
- /// @TODO Careful, not secured!
- $hash = $_SERVER['HTTP_X_CSRF_TOKEN'];
- }
-
- if (empty($hash)) {
- return false;
- }
-
- $max_livetime = 10800; // 3 hours
-
- $a = get_app();
-
- $x = explode('.', $hash);
- if (time() > (IntVal($x[0]) + $max_livetime)) {
- return false;
- }
-
- $sec_hash = hash('whirlpool', $a->user['guid'] . $a->user['prvkey'] . session_id() . $x[0] . $typename);
-
- return ($sec_hash == $x[1]);
-}
-
-function check_form_security_std_err_msg()
-{
- return L10n::t("The form security token was not correct. This probably happened because the form has been opened for too long \x28>3 hours\x29 before submitting it.") . EOL;
-}
-
-function check_form_security_token_redirectOnErr($err_redirect, $typename = '', $formname = 'form_security_token')
-{
- if (!check_form_security_token($typename, $formname)) {
- $a = get_app();
- logger('check_form_security_token failed: user ' . $a->user['guid'] . ' - form element ' . $typename);
- logger('check_form_security_token failed: _REQUEST data: ' . print_r($_REQUEST, true), LOGGER_DATA);
- notice(check_form_security_std_err_msg());
- goaway(System::baseUrl() . $err_redirect);
- }
-}
-
-function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'form_security_token')
-{
- if (!check_form_security_token($typename, $formname)) {
- $a = get_app();
- logger('check_form_security_token failed: user ' . $a->user['guid'] . ' - form element ' . $typename);
- logger('check_form_security_token failed: _REQUEST data: ' . print_r($_REQUEST, true), LOGGER_DATA);
- header('HTTP/1.1 403 Forbidden');
- killme();
- }
-}
-
-/**
- * @brief Kills the "Friendica" cookie and all session data
- */
-function nuke_session()
-{
- new_cookie(-3600); // make sure cookie is deleted on browser close, as a security measure
- session_unset();
- session_destroy();
-}
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal;
use Friendica\Util\Network;
+use Friendica\Util\Security;
require_once 'include/enotify.php';
require_once 'include/text.php';
'$preview' => L10n::t('Privacy Statement Preview'),
'$privtext' => $tos->privacy_complete,
'$tostext' => ['tostext', L10n::t('The Terms of Service'), Config::get('system', 'tostext'), L10n::t('Enter the Terms of Service for your node here. You can use BBCode. Headers of sections should be [h2] and below.')],
- '$form_security_token' => get_form_security_token("admin_tos"),
+ '$form_security_token' => Security::get_form_security_token("admin_tos"),
'$submit' => L10n::t('Save Settings'),
]);
}
*/
function admin_page_tos_post(App $a)
{
- check_form_security_token_redirectOnErr('/admin/tos', 'admin_tos');
+ Security::check_form_security_token_redirectOnErr('/admin/tos', 'admin_tos');
if (!x($_POST, "page_tos")) {
return;
'$entries' => $blocklistform,
'$baseurl' => System::baseUrl(true),
'$confirm_delete' => L10n::t('Delete entry from blocklist?'),
- '$form_security_token' => get_form_security_token("admin_blocklist")
+ '$form_security_token' => Security::get_form_security_token("admin_blocklist")
]);
}
return;
}
- check_form_security_token_redirectOnErr('/admin/blocklist', 'admin_blocklist');
+ Security::check_form_security_token_redirectOnErr('/admin/blocklist', 'admin_blocklist');
if (x($_POST['page_blocklist_save'])) {
// Add new item to blocklist
$contact_url = x($_POST, 'contact_url') ? $_POST['contact_url'] : '';
$contacts = x($_POST, 'contacts') ? $_POST['contacts'] : [];
- check_form_security_token_redirectOnErr('/admin/contactblock', 'admin_contactblock');
+ Security::check_form_security_token_redirectOnErr('/admin/contactblock', 'admin_contactblock');
if (x($_POST, 'page_contactblock_block')) {
$contact_id = Contact::getIdForURL($contact_url);
'$h_newblock' => L10n::t('Block New Remote Contact'),
'$th_contacts' => [L10n::t('Photo'), L10n::t('Name'), L10n::t('Address'), L10n::t('Profile URL')],
- '$form_security_token' => get_form_security_token("admin_contactblock"),
+ '$form_security_token' => Security::get_form_security_token("admin_contactblock"),
// values //
'$baseurl' => System::baseUrl(true),
'$intro2' => L10n::t('You need to know the GUID of the item. You can find it e.g. by looking at the display URL. The last part of http://example.com/display/123456 is the GUID, here 123456.'),
'$deleteitemguid' => ['deleteitemguid', L10n::t("GUID"), '', L10n::t("The GUID of the item you want to delete."), 'required', 'autofocus'],
'$baseurl' => System::baseUrl(),
- '$form_security_token' => get_form_security_token("admin_deleteitem")
+ '$form_security_token' => Security::get_form_security_token("admin_deleteitem")
]);
}
return;
}
- check_form_security_token_redirectOnErr('/admin/deleteitem/', 'admin_deleteitem');
+ Security::check_form_security_token_redirectOnErr('/admin/deleteitem/', 'admin_deleteitem');
if (x($_POST['page_deleteitem_submit'])) {
$guid = trim(notags($_POST['deleteitemguid']));
*/
function admin_page_site_post(App $a)
{
- check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
+ Security::check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
if (!empty($_POST['republish_directory'])) {
Worker::add(PRIORITY_LOW, 'Directory');
'$relay_server_tags' => ['relay_server_tags', L10n::t("Server tags"), Config::get('system','relay_server_tags'), L10n::t("Comma separated list of tags for the 'tags' subscription.")],
'$relay_user_tags' => ['relay_user_tags', L10n::t("Allow user tags"), Config::get('system', 'relay_user_tags', true), L10n::t("If enabled, the tags from the saved searches will used for the 'tags' subscription in addition to the 'relay_server_tags'.")],
- '$form_security_token' => get_form_security_token("admin_site"),
+ '$form_security_token' => Security::get_form_security_token("admin_site"),
'$relocate_button' => L10n::t('Start Relocation'),
]);
}
$nu_email = defaults($_POST, 'new_user_email' , '');
$nu_language = Config::get('system', 'language');
- check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
+ Security::check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
if (!($nu_name === "") && !($nu_email === "") && !($nu_nickname === "")) {
try {
}
switch ($a->argv[2]) {
case "delete":
- check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
+ Security::check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
// delete user
User::remove($uid);
notice(L10n::t("User '%s' deleted", $user['username']) . EOL);
break;
case "block":
- check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
+ Security::check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
q("UPDATE `user` SET `blocked` = %d WHERE `uid` = %s",
intval(1 - $user['blocked']),
intval($uid)
'$confirm_delete_multi' => L10n::t('Selected users will be deleted!\n\nEverything these users had posted on this site will be permanently deleted!\n\nAre you sure?'),
'$confirm_delete' => L10n::t('The user {0} will be deleted!\n\nEverything this user has posted on this site will be permanently deleted!\n\nAre you sure?'),
- '$form_security_token' => get_form_security_token("admin_users"),
+ '$form_security_token' => Security::get_form_security_token("admin_users"),
// values //
'$baseurl' => System::baseUrl(true),
}
if (x($_GET, "a") && $_GET['a'] == "t") {
- check_form_security_token_redirectOnErr('/admin/addons', 'admin_themes', 't');
+ Security::check_form_security_token_redirectOnErr('/admin/addons', 'admin_themes', 't');
// Toggle addon status
$idx = array_search($addon, $a->addons);
'$screenshot' => '',
'$readme' => $readme,
- '$form_security_token' => get_form_security_token("admin_themes"),
+ '$form_security_token' => Security::get_form_security_token("admin_themes"),
]);
}
* List addons
*/
if (x($_GET, "a") && $_GET['a'] == "r") {
- check_form_security_token_redirectOnErr(System::baseUrl() . '/admin/addons', 'admin_themes', 't');
+ Security::check_form_security_token_redirectOnErr(System::baseUrl() . '/admin/addons', 'admin_themes', 't');
Addon::reload();
info("Addons reloaded");
goaway(System::baseUrl() . '/admin/addons');
'$addons' => $addons,
'$pcount' => count($addons),
'$noplugshint' => L10n::t('There are currently no addons available on your node. You can find the official addon repository at %1$s and might find other interesting addons in the open addon registry at %2$s', 'https://github.com/friendica/friendica-addons', 'http://addons.friendi.ca'),
- '$form_security_token' => get_form_security_token("admin_themes"),
+ '$form_security_token' => Security::get_form_security_token("admin_themes"),
]);
}
}
if (x($_GET, "a") && $_GET['a'] == "t") {
- check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
+ Security::check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
// Toggle theme status
'$screenshot' => $screenshot,
'$readme' => $readme,
- '$form_security_token' => get_form_security_token("admin_themes"),
+ '$form_security_token' => Security::get_form_security_token("admin_themes"),
]);
}
// reload active themes
if (x($_GET, "a") && $_GET['a'] == "r") {
- check_form_security_token_redirectOnErr(System::baseUrl() . '/admin/themes', 'admin_themes', 't');
+ Security::check_form_security_token_redirectOnErr(System::baseUrl() . '/admin/themes', 'admin_themes', 't');
foreach ($themes as $th) {
if ($th['allowed']) {
Theme::uninstall($th['name']);
'$noplugshint' => L10n::t('No themes found on the system. They should be placed in %1$s', '<code>/view/themes</code>'),
'$experimental' => L10n::t('[Experimental]'),
'$unsupported' => L10n::t('[Unsupported]'),
- '$form_security_token' => get_form_security_token("admin_themes"),
+ '$form_security_token' => Security::get_form_security_token("admin_themes"),
]);
}
function admin_page_logs_post(App $a)
{
if (x($_POST, "page_logs")) {
- check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
+ Security::check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
$logfile = ((x($_POST,'logfile')) ? notags(trim($_POST['logfile'])) : '');
$debugging = ((x($_POST,'debugging')) ? true : false);
'$debugging' => ['debugging', L10n::t("Enable Debugging"), Config::get('system', 'debugging'), ""],
'$logfile' => ['logfile', L10n::t("Log file"), Config::get('system', 'logfile'), L10n::t("Must be writable by web server. Relative to your Friendica top-level directory.")],
'$loglevel' => ['loglevel', L10n::t("Log level"), Config::get('system', 'loglevel'), "", $log_choices],
- '$form_security_token' => get_form_security_token("admin_logs"),
+ '$form_security_token' => Security::get_form_security_token("admin_logs"),
'$phpheader' => L10n::t("PHP logging"),
'$phphint' => L10n::t("To temporarily enable logging of PHP errors and warnings you can prepend the following to the index.php file of your installation. The filename set in the 'error_log' line is relative to the friendica top-level directory and must be writeable by the web server. The option '1' for 'log_errors' and 'display_errors' is to enable these options, set to '0' to disable them."),
'$phplogcode' => "error_reporting(E_ERROR | E_WARNING | E_PARSE);\nini_set('error_log','php.out');\nini_set('log_errors','1');\nini_set('display_errors', '1');",
*/
function admin_page_features_post(App $a)
{
- check_form_security_token_redirectOnErr('/admin/features', 'admin_manage_features');
+ Security::check_form_security_token_redirectOnErr('/admin/features', 'admin_manage_features');
logger('postvars: ' . print_r($_POST, true), LOGGER_DATA);
$tpl = get_markup_template('admin/settings_features.tpl');
$o = replace_macros($tpl, [
- '$form_security_token' => get_form_security_token("admin_manage_features"),
+ '$form_security_token' => Security::get_form_security_token("admin_manage_features"),
'$title' => L10n::t('Manage Additional Features'),
'$features' => $arr,
'$submit' => L10n::t('Save Settings'),
use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Database\DBA;
+use Friendica\Util\Security;
require_once 'include/dba.php';
-require_once 'include/security.php';
function attach_init(App $a)
{
return;
}
- $sql_extra = permissions_sql($r['uid']);
+ $sql_extra = Security::permissions_sql($r['uid']);
// Now we'll see if we can access the attachment
use Friendica\Protocol\DFRN;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal;
+use Friendica\Util\Security;
function cal_init(App $a)
{
}
// get the permissions
- $sql_perms = item_permissions_sql($owner_uid, $remote_contact, $groups);
+ $sql_perms = Security::item_permissions_sql($owner_uid, $remote_contact, $groups);
// we only want to have the events of the profile owner
$sql_extra = " AND `event`.`cid` = 0 " . $sql_perms;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\User;
+use Friendica\Util\Security;
require_once 'mod/settings.php';
return;
}
- check_form_security_token_redirectOnErr('/delegate', 'delegate');
+ Security::check_form_security_token_redirectOnErr('/delegate', 'delegate');
$parent_uid = defaults($_POST, 'parent_user', 0);
$parent_password = defaults($_POST, 'parent_password', '');
}
$o = replace_macros(get_markup_template('delegate.tpl'), [
- '$form_security_token' => get_form_security_token('delegate'),
+ '$form_security_token' => Security::get_form_security_token('delegate'),
'$parent_header' => L10n::t('Parent User'),
'$parent_user' => $parent_user,
'$parent_password' => $parent_password,
use Friendica\Model\Profile;
use Friendica\Protocol\DFRN;
use Friendica\Protocol\ActivityPub;
+use Friendica\Util\Security;
function display_init(App $a)
{
return;
}
- require_once 'include/security.php';
require_once 'include/conversation.php';
$o = '';
$o .= status_editor($a, $x, 0, true);
}
- $sql_extra = item_permissions_sql($a->profile['uid'], $is_remote_contact, $groups);
+ $sql_extra = Security::item_permissions_sql($a->profile['uid'], $is_remote_contact, $groups);
if (local_user() && (local_user() == $a->profile['uid'])) {
$condition = ['parent-uri' => $item_parent_uri, 'uid' => local_user(), 'unseen' => true];
use Friendica\Database\DBA;
use Friendica\Model;
use Friendica\Module;
+use Friendica\Util\Security;
function group_init(App $a) {
if (local_user()) {
}
if (($a->argc == 2) && ($a->argv[1] === 'new')) {
- check_form_security_token_redirectOnErr('/group/new', 'group_edit');
+ Security::check_form_security_token_redirectOnErr('/group/new', 'group_edit');
$name = notags(trim($_POST['groupname']));
$r = Model\Group::create(local_user(), $name);
}
if (($a->argc == 2) && intval($a->argv[1])) {
- check_form_security_token_redirectOnErr('/group', 'group_edit');
+ Security::check_form_security_token_redirectOnErr('/group', 'group_edit');
$r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($a->argv[1]),
'$title' => L10n::t('Create a group of contacts/friends.'),
'$gname' => ['groupname', L10n::t('Group Name: '), '', ''],
'$gid' => 'new',
- '$form_security_token' => get_form_security_token("group_edit"),
+ '$form_security_token' => Security::get_form_security_token("group_edit"),
]);
if (($a->argc == 3) && ($a->argv[1] === 'drop')) {
- check_form_security_token_redirectOnErr('/group', 'group_drop', 't');
+ Security::check_form_security_token_redirectOnErr('/group', 'group_drop', 't');
if (intval($a->argv[2])) {
$r = q("SELECT `name` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1",
}
if (($a->argc > 2) && intval($a->argv[1]) && intval($a->argv[2])) {
- check_form_security_token_ForbiddenOnErr('group_member_change', 't');
+ Security::check_form_security_token_ForbiddenOnErr('group_member_change', 't');
$r = q("SELECT `id` FROM `contact` WHERE `id` = %d AND `uid` = %d and `self` = 0 and `blocked` = 0 AND `pending` = 0 LIMIT 1",
intval($a->argv[2]),
$drop_txt = replace_macros($drop_tpl, [
'$id' => $group['id'],
'$delete' => L10n::t('Delete Group'),
- '$form_security_token' => get_form_security_token("group_drop"),
+ '$form_security_token' => Security::get_form_security_token("group_drop"),
]);
'$gname' => ['groupname', L10n::t('Group Name: '), $group['name'], ''],
'$gid' => $group['id'],
'$drop' => $drop_txt,
- '$form_security_token' => get_form_security_token('group_edit'),
+ '$form_security_token' => Security::get_form_security_token('group_edit'),
'$edit_name' => L10n::t('Edit Group Name'),
'$editable' => 1,
];
'contacts' => [],
];
- $sec_token = addslashes(get_form_security_token('group_member_change'));
+ $sec_token = addslashes(Security::get_form_security_token('group_member_change'));
// Format the data of the group members
foreach ($members as $member) {
use Friendica\Database\DBA;
use Friendica\Protocol\Email;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Security;
function invite_post(App $a)
{
return;
}
- check_form_security_token_redirectOnErr('/', 'send_invite');
+ Security::check_form_security_token_redirectOnErr('/', 'send_invite');
$max_invites = intval(Config::get('system', 'max_invites'));
if (! $max_invites) {
}
$o = replace_macros($tpl, [
- '$form_security_token' => get_form_security_token("send_invite"),
+ '$form_security_token' => Security::get_form_security_token("send_invite"),
'$title' => L10n::t('Send invitations'),
'$recipients' => ['recipients', L10n::t('Enter email addresses, one per line:')],
'$message' => ['message', L10n::t('Your message:'),L10n::t('You are cordially invited to join me and other close friends on Friendica - and help us to create a better social web.') . "\r\n" . "\r\n"
use Friendica\Protocol\Email;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Emailer;
+use Friendica\Util\Security;
require_once 'include/enotify.php';
require_once 'include/text.php';
$allow_comment = local_user() && ($profile_uid == 0) && $parent && in_array($parent_item['network'], [Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::DIASPORA, Protocol::DFRN]);
// Now check that valid personal details have been provided
- if (!can_write_wall($profile_uid) && !$allow_comment) {
+ if (!Security::can_write_wall($profile_uid) && !$allow_comment) {
notice(L10n::t('Permission denied.') . EOL) ;
if (!empty($_REQUEST['return'])) {
* @file mod/manage.php
*/
use Friendica\App;
+use Friendica\Core\Authentication;
use Friendica\Core\Addon;
use Friendica\Core\L10n;
use Friendica\Core\System;
unset($_SESSION['sysmsg_info']);
}
- require_once('include/security.php');
- authenticate_success($r[0], true, true);
+ Authentication::authenticate_success($r[0], true, true);
if ($limited_id) {
$_SESSION['submanage'] = $original_id;
*/
use Friendica\App;
+use Friendica\Core\Authentication;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Core\System;
unset($_SESSION['openid']);
- require_once('include/security.php');
- authenticate_success($r[0],true,true);
+ Authentication::authenticate_success($r[0],true,true);
// just in case there was no return url set
// and we fell through
use Friendica\App;
use Friendica\Database\DBA;
use Friendica\Object\Image;
-
-require_once 'include/security.php';
+use Friendica\Util\Security;
function photo_init(App $a)
{
intval($resolution)
);
if (DBA::isResult($r)) {
- $sql_extra = permissions_sql($r[0]['uid']);
+ $sql_extra = Security::permissions_sql($r[0]['uid']);
// Now we'll see if we can access the photo
$r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `scale` <= %d $sql_extra ORDER BY scale DESC LIMIT 1",
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Map;
use Friendica\Util\Temporal;
+use Friendica\Util\Security;
require_once 'include/items.php';
-require_once 'include/security.php';
function photos_init(App $a) {
return;
}
- require_once 'include/security.php';
require_once 'include/conversation.php';
if (empty($a->data['user'])) {
return;
}
- $sql_extra = permissions_sql($owner_uid, $remote_contact, $groups);
+ $sql_extra = Security::permissions_sql($owner_uid, $remote_contact, $groups);
$o = "";
$tpl = get_markup_template('photo_item.tpl');
$return_url = $a->cmd;
- if ($can_post || can_write_wall($owner_uid)) {
+ if ($can_post || Security::can_write_wall($owner_uid)) {
$like_tpl = get_markup_template('like_noshare.tpl');
$likebuttons = replace_macros($like_tpl, [
'$id' => $link_item['id'],
}
if (!DBA::isResult($items)) {
- if (($can_post || can_write_wall($owner_uid))) {
+ if (($can_post || Security::can_write_wall($owner_uid))) {
$comments .= replace_macros($cmnt_tpl, [
'$return_path' => '',
'$jsreload' => $return_url,
$dislike = format_like($conv_responses['dislike'][$link_item['uri']], $conv_responses['dislike'][$link_item['uri'] . '-l'], 'dislike', $link_item['id']);
}
- if (($can_post || can_write_wall($owner_uid))) {
+ if (($can_post || Security::can_write_wall($owner_uid))) {
$comments .= replace_macros($cmnt_tpl,[
'$return_path' => '',
'$jsreload' => $return_url,
'$comment' => $comment
]);
- if (($can_post || can_write_wall($owner_uid))) {
+ if (($can_post || Security::can_write_wall($owner_uid))) {
$comments .= replace_macros($cmnt_tpl, [
'$return_path' => '',
'$jsreload' => $return_url,
use Friendica\Module\Login;
use Friendica\Protocol\DFRN;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Security;
use Friendica\Protocol\ActivityPub;
function profile_init(App $a)
return Login::form();
}
- require_once 'include/security.php';
require_once 'include/conversation.php';
require_once 'include/items.php';
$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? xmlify($category) : ''));
$a->page['aside'] .= Widget::tagCloud();
- if (can_write_wall($a->profile['profile_uid'])) {
+ if (Security::can_write_wall($a->profile['profile_uid'])) {
$x = [
'is_owner' => $is_owner,
'allow_location' => ($is_owner || $commvisitor) && $a->profile['allow_location'],
// Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
- $sql_extra = item_permissions_sql($a->profile['profile_uid'], $remote_contact, $groups);
+ $sql_extra = Security::item_permissions_sql($a->profile['profile_uid'], $remote_contact, $groups);
$sql_extra2 = '';
if ($update) {
use Friendica\Model\Photo;
use Friendica\Model\Profile;
use Friendica\Object\Image;
+use Friendica\Util\Security;
function profile_photo_init(App $a)
{
return;
}
- check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
+ Security::check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
if (!empty($_POST['cropfinal']) && $_POST['cropfinal'] == 1) {
'$title' => L10n::t('Upload Profile Photo'),
'$submit' => L10n::t('Upload'),
'$profiles' => $profiles,
- '$form_security_token' => get_form_security_token("profile_photo"),
+ '$form_security_token' => Security::get_form_security_token("profile_photo"),
'$select' => sprintf('%s %s', L10n::t('or'),
($newuser) ? '<a href="' . System::baseUrl() . '">' . L10n::t('skip this step') . '</a>' : '<a href="' . System::baseUrl() . '/photos/' . $a->user['nickname'] . '">' . L10n::t('select a photo from your photo albums') . '</a>')
]);
'$image_url' => System::baseUrl() . '/photo/' . $filename,
'$title' => L10n::t('Crop Image'),
'$desc' => L10n::t('Please adjust the image cropping for optimum viewing.'),
- '$form_security_token' => get_form_security_token("profile_photo"),
+ '$form_security_token' => Security::get_form_security_token("profile_photo"),
'$done' => L10n::t('Done Editing')
]);
return $o;
use Friendica\Network\Probe;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal;
+use Friendica\Utill\Security;
use Friendica\Module\Login;
function profiles_init(App $a) {
return; // NOTREACHED
}
- check_form_security_token_redirectOnErr('/profiles', 'profile_drop', 't');
+ Security::check_form_security_token_redirectOnErr('/profiles', 'profile_drop', 't');
// move every contact using this profile as their default to the user default
if (($a->argc > 1) && ($a->argv[1] === 'new')) {
- check_form_security_token_redirectOnErr('/profiles', 'profile_new', 't');
+ Security::check_form_security_token_redirectOnErr('/profiles', 'profile_new', 't');
$r0 = q("SELECT `id` FROM `profile` WHERE `uid` = %d",
intval(local_user()));
if (($a->argc > 2) && ($a->argv[1] === 'clone')) {
- check_form_security_token_redirectOnErr('/profiles', 'profile_clone', 't');
+ Security::check_form_security_token_redirectOnErr('/profiles', 'profile_clone', 't');
$r0 = q("SELECT `id` FROM `profile` WHERE `uid` = %d",
intval(local_user()));
return;
}
- check_form_security_token_redirectOnErr('/profiles', 'profile_edit');
+ Security::check_form_security_token_redirectOnErr('/profiles', 'profile_edit');
$is_default = (($orig[0]['is-default']) ? 1 : 0);
],
'$multi_profiles' => Feature::isEnabled(local_user(), 'multi_profiles'),
- '$form_security_token' => get_form_security_token("profile_edit"),
- '$form_security_token_photo' => get_form_security_token("profile_photo"),
- '$profile_clone_link' => ((Feature::isEnabled(local_user(), 'multi_profiles')) ? 'profiles/clone/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_clone") : ""),
- '$profile_drop_link' => 'profiles/drop/' . $r[0]['id'] . '?t=' . get_form_security_token("profile_drop"),
+ '$form_security_token' => Security::get_form_security_token("profile_edit"),
+ '$form_security_token_photo' => Security::get_form_security_token("profile_photo"),
+ '$profile_clone_link' => ((Feature::isEnabled(local_user(), 'multi_profiles')) ? 'profiles/clone/' . $r[0]['id'] . '?t=' . Security::get_form_security_token("profile_clone") : ""),
+ '$profile_drop_link' => 'profiles/drop/' . $r[0]['id'] . '?t=' . Security::get_form_security_token("profile_drop"),
'$profile_action' => L10n::t('Profile Actions'),
'$banner' => L10n::t('Edit Profile Details'),
'$header' => L10n::t('Edit/Manage Profiles'),
'$chg_photo' => L10n::t('Change profile photo'),
'$cr_new' => L10n::t('Create New Profile'),
- '$cr_new_link' => 'profiles/new?t=' . get_form_security_token("profile_new"),
+ '$cr_new_link' => 'profiles/new?t=' . Security::get_form_security_token("profile_new"),
'$profiles' => $profiles
]);
}
use Friendica\Model\User;
use Friendica\Module\Tos;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Security;
require_once 'include/enotify.php';
function register_post(App $a)
{
- check_form_security_token_redirectOnErr('/register', 'register');
+ Security::check_form_security_token_redirectOnErr('/register', 'register');
$verified = 0;
$blocked = 1;
'$showprivstatement' => Config::get('system', 'tosprivstatement'),
'$privstatement' => $tos->privacy_complete,
'$baseurl' => System::baseurl(),
- '$form_security_token' => get_form_security_token("register"),
+ '$form_security_token' => Security::get_form_security_token("register"),
'$explicit_content' => Config::get('system', 'explicit_content', false),
'$explicit_content_note' => L10n::t('Note: This node explicitly contains adult content')
]);
use Friendica\Protocol\Email;
use Friendica\Util\Network;
use Friendica\Util\Temporal;
+use Friendica\Util\Security;
use Friendica\Module\Login;
function get_theme_config_file($theme)
$old_page_flags = $a->user['page-flags'];
if (($a->argc > 1) && ($a->argv[1] === 'oauth') && x($_POST, 'remove')) {
- check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
+ Security::check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
$key = $_POST['remove'];
DBA::delete('tokens', ['id' => $key, 'uid' => local_user()]);
}
if (($a->argc > 2) && ($a->argv[1] === 'oauth') && ($a->argv[2] === 'edit'||($a->argv[2] === 'add')) && x($_POST, 'submit')) {
- check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
+ Security::check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
$name = defaults($_POST, 'name' , '');
$key = defaults($_POST, 'key' , '');
}
if (($a->argc > 1) && ($a->argv[1] == 'addon')) {
- check_form_security_token_redirectOnErr('/settings/addon', 'settings_addon');
+ Security::check_form_security_token_redirectOnErr('/settings/addon', 'settings_addon');
Addon::callHooks('addon_settings_post', $_POST);
return;
}
if (($a->argc > 1) && ($a->argv[1] == 'connectors')) {
- check_form_security_token_redirectOnErr('/settings/connectors', 'settings_connectors');
+ Security::check_form_security_token_redirectOnErr('/settings/connectors', 'settings_connectors');
if (x($_POST, 'general-submit')) {
PConfig::set(local_user(), 'system', 'disable_cw', intval($_POST['disable_cw']));
}
if (($a->argc > 1) && ($a->argv[1] === 'features')) {
- check_form_security_token_redirectOnErr('/settings/features', 'settings_features');
+ Security::check_form_security_token_redirectOnErr('/settings/features', 'settings_features');
foreach ($_POST as $k => $v) {
if (strpos($k, 'feature_') === 0) {
PConfig::set(local_user(), 'feature', substr($k, 8), ((intval($v)) ? 1 : 0));
}
if (($a->argc > 1) && ($a->argv[1] === 'display')) {
- check_form_security_token_redirectOnErr('/settings/display', 'settings_display');
+ Security::check_form_security_token_redirectOnErr('/settings/display', 'settings_display');
$theme = x($_POST, 'theme') ? notags(trim($_POST['theme'])) : $a->user['theme'];
$mobile_theme = x($_POST, 'mobile_theme') ? notags(trim($_POST['mobile_theme'])) : '';
return; // NOTREACHED
}
- check_form_security_token_redirectOnErr('/settings', 'settings');
+ Security::check_form_security_token_redirectOnErr('/settings', 'settings');
if (x($_POST,'resend_relocate')) {
Worker::add(PRIORITY_HIGH, 'Notifier', 'relocate', local_user());
if (($a->argc > 2) && ($a->argv[2] === 'add')) {
$tpl = get_markup_template('settings/oauth_edit.tpl');
$o .= replace_macros($tpl, [
- '$form_security_token' => get_form_security_token("settings_oauth"),
+ '$form_security_token' => Security::get_form_security_token("settings_oauth"),
'$title' => L10n::t('Add application'),
'$submit' => L10n::t('Save Settings'),
'$cancel' => L10n::t('Cancel'),
$tpl = get_markup_template('settings/oauth_edit.tpl');
$o .= replace_macros($tpl, [
- '$form_security_token' => get_form_security_token("settings_oauth"),
+ '$form_security_token' => Security::get_form_security_token("settings_oauth"),
'$title' => L10n::t('Add application'),
'$submit' => L10n::t('Update'),
'$cancel' => L10n::t('Cancel'),
}
if (($a->argc > 3) && ($a->argv[2] === 'delete')) {
- check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth', 't');
+ Security::check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth', 't');
DBA::delete('clients', ['client_id' => $a->argv[3], 'uid' => local_user()]);
goaway(System::baseUrl(true)."/settings/oauth/");
$tpl = get_markup_template('settings/oauth.tpl');
$o .= replace_macros($tpl, [
- '$form_security_token' => get_form_security_token("settings_oauth"),
+ '$form_security_token' => Security::get_form_security_token("settings_oauth"),
'$baseurl' => System::baseUrl(true),
'$title' => L10n::t('Connected Apps'),
'$add' => L10n::t('Add application'),
$tpl = get_markup_template('settings/addons.tpl');
$o .= replace_macros($tpl, [
- '$form_security_token' => get_form_security_token("settings_addon"),
+ '$form_security_token' => Security::get_form_security_token("settings_addon"),
'$title' => L10n::t('Addon Settings'),
'$settings_addons' => $settings_addons
]);
$tpl = get_markup_template('settings/features.tpl');
$o .= replace_macros($tpl, [
- '$form_security_token' => get_form_security_token("settings_features"),
+ '$form_security_token' => Security::get_form_security_token("settings_features"),
'$title' => L10n::t('Additional Features'),
'$features' => $arr,
'$submit' => L10n::t('Save Settings'),
$mail_disabled_message = (($mail_disabled) ? L10n::t('Email access is disabled on this site.') : '');
$o .= replace_macros($tpl, [
- '$form_security_token' => get_form_security_token("settings_connectors"),
+ '$form_security_token' => Security::get_form_security_token("settings_connectors"),
'$title' => L10n::t('Social Networks'),
$tpl = get_markup_template('settings/display.tpl');
$o = replace_macros($tpl, [
'$ptitle' => L10n::t('Display Settings'),
- '$form_security_token' => get_form_security_token("settings_display"),
+ '$form_security_token' => Security::get_form_security_token("settings_display"),
'$submit' => L10n::t('Save Settings'),
'$baseurl' => System::baseUrl(true),
'$uid' => local_user(),
'$submit' => L10n::t('Save Settings'),
'$baseurl' => System::baseUrl(true),
'$uid' => local_user(),
- '$form_security_token' => get_form_security_token("settings"),
+ '$form_security_token' => Security::get_form_security_token("settings"),
'$nickname_block' => $prof_addr,
'$h_pass' => L10n::t('Password Settings'),
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Item;
+use Friendica\Util\Security;
-require_once 'include/security.php';
require_once 'include/items.php';
function subthread_content(App $a) {
$owner_uid = $item['uid'];
- if (!can_write_wall($owner_uid)) {
+ if (!Security::can_write_wall($owner_uid)) {
return;
}
use Friendica\Model\Item;
use Friendica\Model\Profile;
use Friendica\Protocol\DFRN;
+use Friendica\Util\Security;
require_once 'include/items.php';
-require_once 'include/security.php';
function videos_init(App $a)
{
return;
}
- $sql_extra = permissions_sql($owner_uid, $remote_contact, $groups);
+ $sql_extra = Security::permissions_sql($owner_uid, $remote_contact, $groups);
$o = "";
use Friendica\Core\L10n;
use Friendica\Core\System;
use Friendica\Database\DBA;
+use Friendica\Util\Security;
require_once 'include/dba.php';
-require_once 'include/security.php';
/**
* TagCloud widget
*/
private static function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)
{
- $sql_options = item_permissions_sql($uid);
+ $sql_options = Security::item_permissions_sql($uid);
$limit = $count ? sprintf('LIMIT %d', intval($count)) : '';
if ($flags) {
--- /dev/null
+<?php
+/**
+ * @file /src/Core/Authentication.php
+ */
+
+namespace Friendica\Core;
+
+use Friendica\Core\Addon;
+use Friendica\BaseObject;
+use Friendica\Core\Config;
+use Friendica\Util\DateTimeFormat;
+use Friendica\Database\DBA;
+use Friendica\Core\L10n;
+use Friendica\Core\PConfig;
+
+/**
+* Handle Authentification, Session and Cookies
+*/
+class Authentication extends BaseObject
+{
+ /**
+ * @brief Calculate the hash that is needed for the "Friendica" cookie
+ *
+ * @param array $user Record from "user" table
+ *
+ * @return string Hashed data
+ */
+ public static function cookie_hash($user)
+ {
+ return(hash("sha256", Config::get("system", "site_prvkey") .
+ $user["prvkey"] .
+ $user["password"]));
+ }
+
+ /**
+ * @brief Set the "Friendica" cookie
+ *
+ * @param int $time
+ * @param array $user Record from "user" table
+ */
+ public static function new_cookie($time, $user = [])
+ {
+ if ($time != 0) {
+ $time = $time + time();
+ }
+
+ if ($user) {
+ $value = json_encode(["uid" => $user["uid"],
+ "hash" => self::cookie_hash($user),
+ "ip" => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0')]);
+ } else {
+ $value = "";
+ }
+
+ setcookie("Friendica", $value, $time, "/", "", (Config::get('system', 'ssl_policy') == SSL_POLICY_FULL), true);
+ }
+
+ /**
+ * @brief Sets the provided user's authenticated session
+ *
+ * @todo Should be moved to Friendica\Core\Session once it's created
+ *
+ * @param type $user_record
+ * @param type $login_initial
+ * @param type $interactive
+ * @param type $login_refresh
+ */
+ public static function authenticate_success($user_record, $login_initial = false, $interactive = false, $login_refresh = false)
+ {
+ $a = self::getApp();
+
+ $_SESSION['uid'] = $user_record['uid'];
+ $_SESSION['theme'] = $user_record['theme'];
+ $_SESSION['mobile-theme'] = PConfig::get($user_record['uid'], 'system', 'mobile_theme');
+ $_SESSION['authenticated'] = 1;
+ $_SESSION['page_flags'] = $user_record['page-flags'];
+ $_SESSION['my_url'] = $a->getbaseUrl() . '/profile/' . $user_record['nickname'];
+ $_SESSION['my_address'] = $user_record['nickname'] . '@' . substr($a->getbaseUrl(), strpos($a->getbaseUrl(), '://') + 3);
+ $_SESSION['addr'] = defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0');
+
+ $a->user = $user_record;
+
+ if ($interactive) {
+ if ($a->user['login_date'] <= NULL_DATE) {
+ $_SESSION['return_url'] = 'profile_photo/new';
+ $a->module = 'profile_photo';
+ info(L10n::t("Welcome ") . $a->user['username'] . EOL);
+ info(L10n::t('Please upload a profile photo.') . EOL);
+ } else {
+ info(L10n::t("Welcome back ") . $a->user['username'] . EOL);
+ }
+ }
+
+ $member_since = strtotime($a->user['register_date']);
+ if (time() < ($member_since + ( 60 * 60 * 24 * 14))) {
+ $_SESSION['new_member'] = true;
+ } else {
+ $_SESSION['new_member'] = false;
+ }
+ if (strlen($a->user['timezone'])) {
+ date_default_timezone_set($a->user['timezone']);
+ $a->timezone = $a->user['timezone'];
+ }
+
+ $master_record = $a->user;
+
+ if ((x($_SESSION, 'submanage')) && intval($_SESSION['submanage'])) {
+ $user = DBA::selectFirst('user', [], ['uid' => $_SESSION['submanage']]);
+ if (DBA::isResult($user)) {
+ $master_record = $user;
+ }
+ }
+
+ if ($master_record['parent-uid'] == 0) {
+ // First add our own entry
+ $a->identities = [['uid' => $master_record['uid'],
+ 'username' => $master_record['username'],
+ 'nickname' => $master_record['nickname']]];
+
+ // Then add all the children
+ $r = DBA::select('user', ['uid', 'username', 'nickname'],
+ ['parent-uid' => $master_record['uid'], 'account_removed' => false]);
+ if (DBA::isResult($r)) {
+ $a->identities = array_merge($a->identities, DBA::toArray($r));
+ }
+ } else {
+ // Just ensure that the array is always defined
+ $a->identities = [];
+
+ // First entry is our parent
+ $r = DBA::select('user', ['uid', 'username', 'nickname'],
+ ['uid' => $master_record['parent-uid'], 'account_removed' => false]);
+ if (DBA::isResult($r)) {
+ $a->identities = DBA::toArray($r);
+ }
+
+ // Then add all siblings
+ $r = DBA::select('user', ['uid', 'username', 'nickname'],
+ ['parent-uid' => $master_record['parent-uid'], 'account_removed' => false]);
+ if (DBA::isResult($r)) {
+ $a->identities = array_merge($a->identities, DBA::toArray($r));
+ }
+ }
+
+ $r = DBA::p("SELECT `user`.`uid`, `user`.`username`, `user`.`nickname`
+ FROM `manage`
+ INNER JOIN `user` ON `manage`.`mid` = `user`.`uid`
+ WHERE `user`.`account_removed` = 0 AND `manage`.`uid` = ?",
+ $master_record['uid']
+ );
+ if (DBA::isResult($r)) {
+ $a->identities = array_merge($a->identities, DBA::toArray($r));
+ }
+
+ if ($login_initial) {
+ logger('auth_identities: ' . print_r($a->identities, true), LOGGER_DEBUG);
+ }
+ if ($login_refresh) {
+ logger('auth_identities refresh: ' . print_r($a->identities, true), LOGGER_DEBUG);
+ }
+
+ $contact = DBA::selectFirst('contact', [], ['uid' => $_SESSION['uid'], 'self' => true]);
+ if (DBA::isResult($contact)) {
+ $a->contact = $contact;
+ $a->cid = $contact['id'];
+ $_SESSION['cid'] = $a->cid;
+ }
+
+ header('X-Account-Management-Status: active; name="' . $a->user['username'] . '"; id="' . $a->user['nickname'] . '"');
+
+ if ($login_initial || $login_refresh) {
+ DBA::update('user', ['login_date' => DateTimeFormat::utcNow()], ['uid' => $_SESSION['uid']]);
+
+ // Set the login date for all identities of the user
+ DBA::update('user', ['login_date' => DateTimeFormat::utcNow()],
+ ['parent-uid' => $master_record['uid'], 'account_removed' => false]);
+ }
+
+ if ($login_initial) {
+ /*
+ * If the user specified to remember the authentication, then set a cookie
+ * that expires after one week (the default is when the browser is closed).
+ * The cookie will be renewed automatically.
+ * The week ensures that sessions will expire after some inactivity.
+ */
+ if (!empty($_SESSION['remember'])) {
+ logger('Injecting cookie for remembered user ' . $a->user['nickname']);
+ self::new_cookie(604800, $user_record);
+ unset($_SESSION['remember']);
+ }
+ }
+
+ if ($login_initial) {
+ Addon::callHooks('logged_in', $a->user);
+
+ if (($a->module !== 'home') && isset($_SESSION['return_url'])) {
+ goaway($a->getbaseUrl() . '/' . $_SESSION['return_url']);
+ }
+ }
+ }
+
+ /**
+ * @brief Kills the "Friendica" cookie and all session data
+ */
+ public static function nuke_session()
+ {
+ self::new_cookie(-3600); // make sure cookie is deleted on browser close, as a security measure
+ session_unset();
+ session_destroy();
+ }
+}
+
+?>
use Friendica\BaseObject;
use Friendica\Core\L10n;
use Friendica\Database\DBA;
+use Friendica\Util\Security;
require_once 'boot.php';
require_once 'include/dba.php';
'$createtext' => L10n::t('Create a new group'),
'$creategroup' => L10n::t('Group Name: '),
'$editgroupstext' => L10n::t('Edit groups'),
- '$form_security_token' => get_form_security_token('group_edit'),
+ '$form_security_token' => Security::get_form_security_token('group_edit'),
]);
$uid = local_user();
}
- if (!can_write_wall($uid)) {
+ if (!Security::can_write_wall($uid)) {
logger('like: unable to write on wall ' . $uid);
return false;
}
use Friendica\Object\Image;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
+use Friendica\Util\Security;
require_once 'include/dba.php';
*/
public static function getAlbums($uid, $update = false)
{
- $sql_extra = permissions_sql($uid);
+ $sql_extra = Security::permissions_sql($uid);
$key = "photo_albums:".$uid.":".local_user().":".remote_user();
$albums = Cache::get($key);
use Exception;
use Friendica\BaseModule;
use Friendica\Core\Addon;
+use Friendica\Core\Authentication;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Database\DBA;
use LightOpenID;
require_once 'boot.php';
-require_once 'include/security.php';
require_once 'include/text.php';
/**
}
if (!$remember) {
- new_cookie(0); // 0 means delete on browser exit
+ Authentication::new_cookie(0); // 0 means delete on browser exit
}
// if we haven't failed up this point, log them in.
$_SESSION['remember'] = $remember;
$_SESSION['last_login_date'] = DateTimeFormat::utcNow();
- authenticate_success($record, true, true);
+ Authentication::authenticate_success($record, true, true);
if (x($_SESSION, 'return_url')) {
$return_url = $_SESSION['return_url'];
]
);
if (DBA::isResult($user)) {
- if ($data->hash != cookie_hash($user)) {
+ if ($data->hash != Authentication::cookie_hash($user)) {
logger("Hash for user " . $data->uid . " doesn't fit.");
- nuke_session();
+ Authentication::nuke_session();
goaway(self::getApp()->getBaseURL());
}
// Expires after 7 days by default,
// can be set via system.auth_cookie_lifetime
$authcookiedays = Config::get('system', 'auth_cookie_lifetime', 7);
- new_cookie($authcookiedays * 24 * 60 * 60, $user);
+ Authentication::new_cookie($authcookiedays * 24 * 60 * 60, $user);
// Do the authentification if not done by now
if (!isset($_SESSION) || !isset($_SESSION['authenticated'])) {
- authenticate_success($user);
+ Authentication::authenticate_success($user);
if (Config::get('system', 'paranoia')) {
$_SESSION['addr'] = $data->ip;
if ($check && ($_SESSION['addr'] != $_SERVER['REMOTE_ADDR'])) {
logger('Session address changed. Paranoid setting in effect, blocking session. ' .
$_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
- nuke_session();
+ Authentication::nuke_session();
goaway(self::getApp()->getBaseURL());
}
]
);
if (!DBA::isResult($user)) {
- nuke_session();
+ Authentication::nuke_session();
goaway(self::getApp()->getBaseURL());
}
$_SESSION['last_login_date'] = DateTimeFormat::utcNow();
$login_refresh = true;
}
- authenticate_success($user, false, false, $login_refresh);
+ Authentication::authenticate_success($user, false, false, $login_refresh);
}
}
}
use Friendica\BaseModule;
use Friendica\Core\Addon;
+use Friendica\Core\Authentication;
use Friendica\Core\L10n;
require_once 'boot.php';
public static function init()
{
Addon::callHooks("logging_out");
- nuke_session();
+ Authentication::nuke_session();
info(L10n::t('Logged out.') . EOL);
goaway(self::getApp()->getBaseURL());
}
use Friendica\BaseObject;
use Friendica\Core\Protocol;
use Friendica\Object\Post;
+use Friendica\Util\Security;
require_once 'boot.php';
require_once 'include/text.php';
break;
case 'profile':
$this->profile_owner = $a->profile['profile_uid'];
- $this->writable = can_write_wall($this->profile_owner);
+ $this->writable = Security::can_write_wall($this->profile_owner);
break;
case 'display':
$this->profile_owner = $a->profile['uid'];
- $this->writable = can_write_wall($this->profile_owner) || $writable;
+ $this->writable = Security::can_write_wall($this->profile_owner) || $writable;
break;
case 'community':
$this->profile_owner = 0;
--- /dev/null
+<?php
+/**
+ * @file /src/Util/Security.php
+ */
+
+namespace Friendica\Util;
+
+use Friendica\BaseObject;
+use Friendica\Database\DBA;
+use Friendica\Model\Contact;
+use Friendica\Model\Group;
+use Friendica\Core\L10n;
+use Friendica\Model\PermissionSet;
+use Friendica\Core\System;
+
+/**
+ * Secures that User is allow to do requests
+ */
+class Security extends BaseObject
+{
+ public static function can_write_wall($owner)
+ {
+ static $verified = 0;
+
+ if (!local_user() && !remote_user()) {
+ return false;
+ }
+
+ $uid = local_user();
+ if ($uid == $owner) {
+ return true;
+ }
+
+ if (local_user() && ($owner == 0)) {
+ return true;
+ }
+
+ if (remote_user()) {
+ // use remembered decision and avoid a DB lookup for each and every display item
+ // DO NOT use this function if there are going to be multiple owners
+ // We have a contact-id for an authenticated remote user, this block determines if the contact
+ // belongs to this page owner, and has the necessary permissions to post content
+
+ if ($verified === 2) {
+ return true;
+ } elseif ($verified === 1) {
+ return false;
+ } else {
+ $cid = 0;
+
+ if (!empty($_SESSION['remote'])) {
+ foreach ($_SESSION['remote'] as $visitor) {
+ if ($visitor['uid'] == $owner) {
+ $cid = $visitor['cid'];
+ break;
+ }
+ }
+ }
+
+ if (!$cid) {
+ return false;
+ }
+
+ $r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` INNER JOIN `user` on `user`.`uid` = `contact`.`uid`
+ WHERE `contact`.`uid` = %d AND `contact`.`id` = %d AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
+ AND `user`.`blockwall` = 0 AND `readonly` = 0 AND ( `contact`.`rel` IN ( %d , %d ) OR `user`.`page-flags` = %d ) LIMIT 1",
+ intval($owner),
+ intval($cid),
+ intval(Contact::SHARING),
+ intval(Contact::FRIEND),
+ intval(Contact::PAGE_COMMUNITY)
+ );
+
+ if (DBA::isResult($r)) {
+ $verified = 2;
+ return true;
+ } else {
+ $verified = 1;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /// @TODO $groups should be array
+ public static function permissions_sql($owner_id, $remote_verified = false, $groups = null)
+ {
+ $local_user = local_user();
+ $remote_user = remote_user();
+
+ /**
+ * Construct permissions
+ *
+ * default permissions - anonymous user
+ */
+ $sql = " AND allow_cid = ''
+ AND allow_gid = ''
+ AND deny_cid = ''
+ AND deny_gid = ''
+ ";
+
+ /**
+ * Profile owner - everything is visible
+ */
+ if ($local_user && $local_user == $owner_id) {
+ $sql = '';
+ /**
+ * Authenticated visitor. Unless pre-verified,
+ * check that the contact belongs to this $owner_id
+ * and load the groups the visitor belongs to.
+ * If pre-verified, the caller is expected to have already
+ * done this and passed the groups into this function.
+ */
+ } elseif ($remote_user) {
+ /*
+ * Authenticated visitor. Unless pre-verified,
+ * check that the contact belongs to this $owner_id
+ * and load the groups the visitor belongs to.
+ * If pre-verified, the caller is expected to have already
+ * done this and passed the groups into this function.
+ */
+
+ if (!$remote_verified) {
+ if (DBA::exists('contact', ['id' => $remote_user, 'uid' => $owner_id, 'blocked' => false])) {
+ $remote_verified = true;
+ $groups = Group::getIdsByContactId($remote_user);
+ }
+ }
+
+ if ($remote_verified) {
+ $gs = '<<>>'; // should be impossible to match
+
+ if (is_array($groups)) {
+ foreach ($groups as $g) {
+ $gs .= '|<' . intval($g) . '>';
+ }
+ }
+
+ $sql = sprintf(
+ " AND ( NOT (deny_cid REGEXP '<%d>' OR deny_gid REGEXP '%s')
+ AND ( allow_cid REGEXP '<%d>' OR allow_gid REGEXP '%s' OR ( allow_cid = '' AND allow_gid = '') )
+ )
+ ",
+ intval($remote_user),
+ DBA::escape($gs),
+ intval($remote_user),
+ DBA::escape($gs)
+ );
+ }
+ }
+ return $sql;
+ }
+
+ public static function item_permissions_sql($owner_id, $remote_verified = false, $groups = null)
+ {
+ $local_user = local_user();
+ $remote_user = remote_user();
+
+ /*
+ * Construct permissions
+ *
+ * default permissions - anonymous user
+ */
+ $sql = " AND NOT `item`.`private`";
+
+ // Profile owner - everything is visible
+ if ($local_user && ($local_user == $owner_id)) {
+ $sql = '';
+ } elseif ($remote_user) {
+ /*
+ * Authenticated visitor. Unless pre-verified,
+ * check that the contact belongs to this $owner_id
+ * and load the groups the visitor belongs to.
+ * If pre-verified, the caller is expected to have already
+ * done this and passed the groups into this function.
+ */
+ $set = PermissionSet::get($owner_id, $remote_user, $groups);
+
+ if (!empty($set)) {
+ $sql_set = " OR (`item`.`private` IN (1,2) AND `item`.`wall` AND `item`.`psid` IN (" . implode(',', $set) . "))";
+ } else {
+ $sql_set = '';
+ }
+
+ $sql = " AND (NOT `item`.`private`" . $sql_set . ")";
+ }
+
+ return $sql;
+ }
+
+ /*
+ * Functions used to protect against Cross-Site Request Forgery
+ * The security token has to base on at least one value that an attacker can't know - here it's the session ID and the private key.
+ * In this implementation, a security token is reusable (if the user submits a form, goes back and resubmits the form, maybe with small changes;
+ * or if the security token is used for ajax-calls that happen several times), but only valid for a certain amout of time (3hours).
+ * The "typename" seperates the security tokens of different types of forms. This could be relevant in the following case:
+ * A security token is used to protekt a link from CSRF (e.g. the "delete this profile"-link).
+ * If the new page contains by any chance external elements, then the used security token is exposed by the referrer.
+ * Actually, important actions should not be triggered by Links / GET-Requests at all, but somethimes they still are,
+ * so this mechanism brings in some damage control (the attacker would be able to forge a request to a form of this type, but not to forms of other types).
+ */
+ public static function get_form_security_token($typename = '')
+ {
+ $a = get_app();
+
+ $timestamp = time();
+ $sec_hash = hash('whirlpool', $a->user['guid'] . $a->user['prvkey'] . session_id() . $timestamp . $typename);
+
+ return $timestamp . '.' . $sec_hash;
+ }
+
+ public static function check_form_security_token($typename = '', $formname = 'form_security_token')
+ {
+ $hash = null;
+
+ if (!empty($_REQUEST[$formname])) {
+ /// @TODO Careful, not secured!
+ $hash = $_REQUEST[$formname];
+ }
+
+ if (!empty($_SERVER['HTTP_X_CSRF_TOKEN'])) {
+ /// @TODO Careful, not secured!
+ $hash = $_SERVER['HTTP_X_CSRF_TOKEN'];
+ }
+
+ if (empty($hash)) {
+ return false;
+ }
+
+ $max_livetime = 10800; // 3 hours
+
+ $a = get_app();
+
+ $x = explode('.', $hash);
+ if (time() > (IntVal($x[0]) + $max_livetime)) {
+ return false;
+ }
+
+ $sec_hash = hash('whirlpool', $a->user['guid'] . $a->user['prvkey'] . session_id() . $x[0] . $typename);
+
+ return ($sec_hash == $x[1]);
+ }
+
+ private static function check_form_security_std_err_msg()
+ {
+ return L10n::t("The form security token was not correct. This probably happened because the form has been opened for too long \x28>3 hours\x29 before submitting it.") . EOL;
+ }
+
+ public static function check_form_security_token_redirectOnErr($err_redirect, $typename = '', $formname = 'form_security_token')
+ {
+ if (!check_form_security_token($typename, $formname)) {
+ $a = get_app();
+ logger('check_form_security_token failed: user ' . $a->user['guid'] . ' - form element ' . $typename);
+ logger('check_form_security_token failed: _REQUEST data: ' . print_r($_REQUEST, true), LOGGER_DATA);
+ notice(check_form_security_std_err_msg());
+ goaway(System::baseUrl() . $err_redirect);
+ }
+ }
+
+ public static function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'form_security_token')
+ {
+ if (!check_form_security_token($typename, $formname)) {
+ $a = get_app();
+ logger('check_form_security_token failed: user ' . $a->user['guid'] . ' - form element ' . $typename);
+ logger('check_form_security_token failed: _REQUEST data: ' . print_r($_REQUEST, true), LOGGER_DATA);
+ header('HTTP/1.1 403 Forbidden');
+ killme();
+ }
+ }
+}
+
+?>
\ No newline at end of file