From 2236f60cfa5814f74719ecb2641130cb32e6aa36 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sat, 25 Nov 2017 18:05:32 -0500 Subject: [PATCH 1/9] Add new legacy password field --- boot.php | 2 +- include/dbstructure.php | 1 + update.php | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/boot.php b/boot.php index 9cdaefb212..5ee4d5f4a2 100644 --- a/boot.php +++ b/boot.php @@ -45,7 +45,7 @@ define('FRIENDICA_PLATFORM', 'Friendica'); define('FRIENDICA_CODENAME', 'Asparagus'); define('FRIENDICA_VERSION', '3.6-dev'); define('DFRN_PROTOCOL_VERSION', '2.23'); -define('DB_UPDATE_VERSION', 1235); +define('DB_UPDATE_VERSION', 1236); /** * @brief Constant with a HTML line break. diff --git a/include/dbstructure.php b/include/dbstructure.php index dde3dc6f18..65dda55c37 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -1682,6 +1682,7 @@ function db_definition() { "guid" => array("type" => "varchar(64)", "not null" => "1", "default" => ""), "username" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "password" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), + "legacy_password" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"), "nickname" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "email" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "openid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), diff --git a/update.php b/update.php index 5cf9bbc2d4..7530d1a386 100644 --- a/update.php +++ b/update.php @@ -1,6 +1,6 @@ Date: Sun, 26 Nov 2017 14:18:45 -0500 Subject: [PATCH 2/9] Fix formatting - include/auth.php - include/oauth.php - include/user.php - mod/removeme.php - src/Worker/Queue.php --- include/auth.php | 88 +++++++++++++++++++------------------------ include/oauth.php | 90 -------------------------------------------- include/user.php | 15 ++++---- mod/removeme.php | 20 +++++----- src/Worker/Queue.php | 34 +++++++++-------- 5 files changed, 73 insertions(+), 174 deletions(-) diff --git a/include/auth.php b/include/auth.php index f852ea28a5..90509468c5 100644 --- a/include/auth.php +++ b/include/auth.php @@ -5,8 +5,8 @@ use Friendica\Core\System; use Friendica\Core\Config; use Friendica\Database\DBM; -require_once('include/security.php'); -require_once('include/datetime.php'); +require_once 'include/security.php'; +require_once 'include/datetime.php'; // When the "Friendica" cookie is set, take the value to authenticate and renew the cookie. if (isset($_COOKIE["Friendica"])) { @@ -19,7 +19,7 @@ if (isset($_COOKIE["Friendica"])) { if ($r) { if ($data->hash != cookie_hash($r[0])) { - logger("Hash for user ".$data->uid." doesn't fit."); + logger("Hash for user " . $data->uid . " doesn't fit."); nuke_session(); goaway(System::baseUrl()); } @@ -28,14 +28,15 @@ if (isset($_COOKIE["Friendica"])) { // 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, $r[0]); + new_cookie($authcookiedays * 24 * 60 * 60, $r[0]); // Do the authentification if not done by now if (!isset($_SESSION) || !isset($_SESSION['authenticated'])) { authenticate_success($r[0]); - if (Config::get('system','paranoia')) + if (Config::get('system', 'paranoia')) { $_SESSION['addr'] = $data->ip; + } } } } @@ -44,18 +45,16 @@ if (isset($_COOKIE["Friendica"])) { // login/logout -if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params') || ($_POST['auth-params'] !== 'login'))) { - - if ((x($_POST,'auth-params') && ($_POST['auth-params'] === 'logout')) || ($a->module === 'logout')) { - +if (isset($_SESSION) && x($_SESSION, 'authenticated') && (!x($_POST, 'auth-params') || ($_POST['auth-params'] !== 'login'))) { + if ((x($_POST, 'auth-params') && ($_POST['auth-params'] === 'logout')) || ($a->module === 'logout')) { // process logout request call_hooks("logging_out"); nuke_session(); - info(t('Logged out.').EOL); + info(t('Logged out.') . EOL); goaway(System::baseUrl()); } - if (x($_SESSION,'visitor_id') && !x($_SESSION,'uid')) { + if (x($_SESSION, 'visitor_id') && !x($_SESSION, 'uid')) { $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($_SESSION['visitor_id']) ); @@ -64,15 +63,13 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params' } } - if (x($_SESSION,'uid')) { - + if (x($_SESSION, 'uid')) { // already logged in user returning - - $check = Config::get('system','paranoia'); + $check = Config::get('system', 'paranoia'); // extra paranoia - if the IP changed, log them out if ($check && ($_SESSION['addr'] != $_SERVER['REMOTE_ADDR'])) { - logger('Session address changed. Paranoid setting in effect, blocking session. '. - $_SESSION['addr'].' != '.$_SERVER['REMOTE_ADDR']); + logger('Session address changed. Paranoid setting in effect, blocking session. ' . + $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']); nuke_session(); goaway(System::baseUrl()); } @@ -91,61 +88,54 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params' // stays logged in for a long time, e.g. with "Remember Me" $login_refresh = false; if (!x($_SESSION['last_login_date'])) { - $_SESSION['last_login_date'] = datetime_convert('UTC','UTC'); + $_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC'); } - if (strcmp(datetime_convert('UTC','UTC','now - 12 hours'), $_SESSION['last_login_date']) > 0) { - - $_SESSION['last_login_date'] = datetime_convert('UTC','UTC'); + if (strcmp(datetime_convert('UTC', 'UTC', 'now - 12 hours'), $_SESSION['last_login_date']) > 0) { + $_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC'); $login_refresh = true; } authenticate_success($r[0], false, false, $login_refresh); } } else { - session_unset(); + if (x($_POST, 'password') && strlen($_POST['password'])) { + $encrypted = hash('whirlpool', trim($_POST['password'])); + } else { + if ((x($_POST, 'openid_url')) && strlen($_POST['openid_url']) || + (x($_POST, 'username')) && strlen($_POST['username'])) { - if (x($_POST,'password') && strlen($_POST['password'])) - $encrypted = hash('whirlpool',trim($_POST['password'])); - else { - if ((x($_POST,'openid_url')) && strlen($_POST['openid_url']) || - (x($_POST,'username')) && strlen($_POST['username'])) { + $noid = Config::get('system', 'no_openid'); - $noid = Config::get('system','no_openid'); - - $openid_url = trim((strlen($_POST['openid_url'])?$_POST['openid_url']:$_POST['username'])); + $openid_url = trim((strlen($_POST['openid_url']) ? $_POST['openid_url'] : $_POST['username'])); // validate_url alters the calling parameter - $temp_string = $openid_url; // if it's an email address or doesn't resolve to a URL, fail. - - if ($noid || strpos($temp_string,'@') || !validate_url($temp_string)) { + if ($noid || strpos($temp_string, '@') || !validate_url($temp_string)) { $a = get_app(); - notice(t('Login failed.').EOL); + notice(t('Login failed.') . EOL); goaway(System::baseUrl()); // NOTREACHED } // Otherwise it's probably an openid. - try { require_once('library/openid.php'); $openid = new LightOpenID; $openid->identity = $openid_url; $_SESSION['openid'] = $openid_url; $_SESSION['remember'] = $_POST['remember']; - $openid->returnUrl = System::baseUrl(true).'/openid'; + $openid->returnUrl = System::baseUrl(true) . '/openid'; goaway($openid->authUrl()); } catch (Exception $e) { - notice(t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'

'.t('The error message was:').' '.$e->getMessage()); + notice(t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.') . '

' . t('The error message was:') . ' ' . $e->getMessage()); } // NOTREACHED } } - if (x($_POST,'auth-params') && $_POST['auth-params'] === 'login') { - + if (x($_POST, 'auth-params') && $_POST['auth-params'] === 'login') { $record = null; $addon_auth = array( @@ -162,12 +152,11 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params' * and later plugins should not interfere with an earlier one that succeeded. * */ - call_hooks('authenticate', $addon_auth); - if ($addon_auth['authenticated'] && count($addon_auth['user_record'])) + if ($addon_auth['authenticated'] && count($addon_auth['user_record'])) { $record = $addon_auth['user_record']; - else { + } else { // process normal login request @@ -178,23 +167,24 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params' dbesc(trim($_POST['username'])), dbesc($encrypted) ); - if (DBM::is_result($r)) + if (DBM::is_result($r)) { $record = $r[0]; + } } if (!$record || !count($record)) { - logger('authenticate: failed login attempt: '.notags(trim($_POST['username'])).' from IP '.$_SERVER['REMOTE_ADDR']); - notice(t('Login failed.').EOL); + logger('authenticate: failed login attempt: ' . notags(trim($_POST['username'])) . ' from IP ' . $_SERVER['REMOTE_ADDR']); + notice(t('Login failed.') . EOL); goaway(System::baseUrl()); } - if (! $_POST['remember']) { + if (!$_POST['remember']) { new_cookie(0); // 0 means delete on browser exit } // if we haven't failed up this point, log them in. $_SESSION['remember'] = $_POST['remember']; - $_SESSION['last_login_date'] = datetime_convert('UTC','UTC'); + $_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC'); authenticate_success($record, true, true); } } @@ -202,8 +192,8 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params' /** * @brief Kills the "Friendica" cookie and all session data */ -function nuke_session() { - +function nuke_session() +{ new_cookie(-3600); // make sure cookie is deleted on browser close, as a security measure session_unset(); session_destroy(); diff --git a/include/oauth.php b/include/oauth.php index c6993d05b0..8834b93555 100644 --- a/include/oauth.php +++ b/include/oauth.php @@ -182,93 +182,3 @@ class FKOAuth1 extends OAuthServer { } } -/* -class FKOAuth2 extends OAuth2 { - - private function db_secret($client_secret){ - return hash('whirlpool',$client_secret); - } - - public function addClient($client_id, $client_secret, $redirect_uri) { - $client_secret = $this->db_secret($client_secret); - $r = q("INSERT INTO clients (client_id, pw, redirect_uri) VALUES ('%s', '%s', '%s')", - dbesc($client_id), - dbesc($client_secret), - dbesc($redirect_uri) - ); - - return $r; - } - - protected function checkClientCredentials($client_id, $client_secret = NULL) { - $client_secret = $this->db_secret($client_secret); - - $r = q("SELECT pw FROM clients WHERE client_id = '%s'", - dbesc($client_id)); - - if ($client_secret === NULL) - return $result !== FALSE; - - return $result["client_secret"] == $client_secret; - } - - protected function getRedirectUri($client_id) { - $r = q("SELECT redirect_uri FROM clients WHERE client_id = '%s'", - dbesc($client_id)); - if ($r === FALSE) - return FALSE; - - return isset($r[0]["redirect_uri"]) && $r[0]["redirect_uri"] ? $r[0]["redirect_uri"] : NULL; - } - - protected function getAccessToken($oauth_token) { - $r = q("SELECT client_id, expires, scope FROM tokens WHERE id = '%s'", - dbesc($oauth_token)); - - if (DBM::is_result($r)) - return $r[0]; - return null; - } - - - - protected function setAccessToken($oauth_token, $client_id, $expires, $scope = NULL) { - $r = q("INSERT INTO tokens (id, client_id, expires, scope) VALUES ('%s', '%s', %d, '%s')", - dbesc($oauth_token), - dbesc($client_id), - intval($expires), - dbesc($scope)); - - return $r; - } - - protected function getSupportedGrantTypes() { - return array( - OAUTH2_GRANT_TYPE_AUTH_CODE, - ); - } - - - protected function getAuthCode($code) { - $r = q("SELECT id, client_id, redirect_uri, expires, scope FROM auth_codes WHERE id = '%s'", - dbesc($code)); - - if (DBM::is_result($r)) - return $r[0]; - return null; - } - - protected function setAuthCode($code, $client_id, $redirect_uri, $expires, $scope = NULL) { - $r = q("INSERT INTO auth_codes - (id, client_id, redirect_uri, expires, scope) VALUES - ('%s', '%s', '%s', %d, '%s')", - dbesc($code), - dbesc($client_id), - dbesc($redirect_uri), - intval($expires), - dbesc($scope)); - return $r; - } - -} -*/ diff --git a/include/user.php b/include/user.php index be03637df9..d82671b86b 100644 --- a/include/user.php +++ b/include/user.php @@ -4,13 +4,12 @@ use Friendica\Core\Config; use Friendica\Core\System; use Friendica\Database\DBM; -require_once('include/network.php'); -require_once('include/plugin.php'); -require_once('include/text.php'); -require_once('include/pgettext.php'); -require_once('include/datetime.php'); -require_once('include/enotify.php'); - +require_once 'include/network.php'; +require_once 'include/plugin.php'; +require_once 'include/text.php'; +require_once 'include/pgettext.php'; +require_once 'include/datetime.php'; +require_once 'include/enotify.php'; function create_user($arr) { @@ -388,7 +387,7 @@ function user_create_self_contact($uid) { * @param string $email * @param string $sitename * @param string $username - * @return NULL|boolean from notification() and email() inherited + * @return NULL|boolean from notification() and email() inherited */ function send_register_pending_eml($email, $sitename, $username) { $body = deindent(t(' diff --git a/mod/removeme.php b/mod/removeme.php index b1ad2e5ca0..2f4349a704 100644 --- a/mod/removeme.php +++ b/mod/removeme.php @@ -4,21 +4,21 @@ use Friendica\App; use Friendica\Core\System; use Friendica\Model\User; -function removeme_post(App $a) { - - if (! local_user()) { +function removeme_post(App $a) +{ + if (!local_user()) { return; } - if (x($_SESSION,'submanage') && intval($_SESSION['submanage'])) { + if (x($_SESSION, 'submanage') && intval($_SESSION['submanage'])) { return; } - if ((! x($_POST,'qxz_password')) || (! strlen(trim($_POST['qxz_password'])))) { + if ((!x($_POST, 'qxz_password')) || (!strlen(trim($_POST['qxz_password'])))) { return; } - if ((! x($_POST,'verify')) || (! strlen(trim($_POST['verify'])))) { + if ((!x($_POST, 'verify')) || (!strlen(trim($_POST['verify'])))) { return; } @@ -32,12 +32,11 @@ function removeme_post(App $a) { User::remove($a->user['uid']); // NOTREACHED } - } -function removeme_content(App $a) { - - if (! local_user()) { +function removeme_content(App $a) +{ + if (!local_user()) { goaway(System::baseUrl()); } @@ -59,5 +58,4 @@ function removeme_content(App $a) { )); return $o; - } diff --git a/src/Worker/Queue.php b/src/Worker/Queue.php index c15ccfb986..73726098e9 100644 --- a/src/Worker/Queue.php +++ b/src/Worker/Queue.php @@ -1,4 +1,5 @@ PRIORITY_LOW, 'dont_fork' => true), "Queue", (int)$q_item['id']); + logger('Call queue for id ' . $q_item['id']); + Worker::add(array('priority' => PRIORITY_LOW, 'dont_fork' => true), "Queue", (int) $q_item['id']); } } return; @@ -88,10 +90,10 @@ class Queue { return; } - $dead = Cache::get($cachekey_deadguy.$c[0]['notify']); + $dead = Cache::get($cachekey_deadguy . $c[0]['notify']); if (!is_null($dead) && $dead) { - logger('queue: skipping known dead url: '.$c[0]['notify']); + logger('queue: skipping known dead url: ' . $c[0]['notify']); update_queue_time($q_item['id']); return; } @@ -99,17 +101,17 @@ class Queue { $server = PortableContact::detectServer($c[0]['url']); if ($server != "") { - $vital = Cache::get($cachekey_server.$server); + $vital = Cache::get($cachekey_server . $server); if (is_null($vital)) { - logger("Check server ".$server." (".$c[0]["network"].")"); + logger("Check server " . $server . " (" . $c[0]["network"] . ")"); $vital = PortableContact::checkServer($server, $c[0]["network"], true); - Cache::set($cachekey_server.$server, $vital, CACHE_QUARTER_HOUR); + Cache::set($cachekey_server . $server, $vital, CACHE_QUARTER_HOUR); } if (!is_null($vital) && !$vital) { - logger('queue: skipping dead server: '.$server); + logger('queue: skipping dead server: ' . $server); update_queue_time($q_item['id']); return; } @@ -134,24 +136,24 @@ class Queue { switch ($contact['network']) { case NETWORK_DFRN: - logger('queue: dfrndelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); + logger('queue: dfrndelivery: item ' . $q_item['id'] . ' for ' . $contact['name'] . ' <' . $contact['url'] . '>'); $deliver_status = DFRN::deliver($owner, $contact, $data); if ($deliver_status == (-1)) { update_queue_time($q_item['id']); - Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); + Cache::set($cachekey_deadguy . $contact['notify'], true, CACHE_QUARTER_HOUR); } else { remove_queue_item($q_item['id']); } break; case NETWORK_OSTATUS: if ($contact['notify']) { - logger('queue: slapdelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); + logger('queue: slapdelivery: item ' . $q_item['id'] . ' for ' . $contact['name'] . ' <' . $contact['url'] . '>'); $deliver_status = slapper($owner, $contact['notify'], $data); if ($deliver_status == (-1)) { update_queue_time($q_item['id']); - Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); + Cache::set($cachekey_deadguy . $contact['notify'], true, CACHE_QUARTER_HOUR); } else { remove_queue_item($q_item['id']); } @@ -159,12 +161,12 @@ class Queue { break; case NETWORK_DIASPORA: if ($contact['notify']) { - logger('queue: diaspora_delivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); + logger('queue: diaspora_delivery: item ' . $q_item['id'] . ' for ' . $contact['name'] . ' <' . $contact['url'] . '>'); $deliver_status = Diaspora::transmit($owner, $contact, $data, $public, true); if ($deliver_status == (-1)) { update_queue_time($q_item['id']); - Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); + Cache::set($cachekey_deadguy . $contact['notify'], true, CACHE_QUARTER_HOUR); } else { remove_queue_item($q_item['id']); } @@ -182,7 +184,7 @@ class Queue { } break; } - logger('Deliver status '.(int)$deliver_status.' for item '.$q_item['id'].' to '.$contact['name'].' <'.$contact['url'].'>'); + logger('Deliver status ' . (int) $deliver_status . ' for item ' . $q_item['id'] . ' to ' . $contact['name'] . ' <' . $contact['url'] . '>'); return; } From 483603e77cd5e6c216213b54f1ef0b241cfaf5aa Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 26 Nov 2017 14:25:25 -0500 Subject: [PATCH 3/9] Add User::authenticate() --- src/Model/User.php | 51 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/Model/User.php b/src/Model/User.php index 01bcce28d9..a7f59b6a3d 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -1,22 +1,71 @@ $user_info, + 'blocked' => 0, + 'account_expired' => 0, + 'account_removed' => 0, + 'verified' => 1 + ], + ['limit' => 1] + ); + } elseif (is_string($user_info)) { + $user = dba::fetch_first('SELECT `uid`, `password` + FROM `user` + WHERE (`email` = ? OR `username` = ? OR `nickname` = ?) + AND `blocked` = 0 + AND `account_expired` = 0 + AND `account_removed` = 0 + AND `verified` = 1 + LIMIT 1', + $user_info, + $user_info, + $user_info + ); + } else { + $user = $user_info; + } + + if (!DBM::isResult($user) || !isset($user['uid']) || !isset($user['password'])) { + return false; + } + + $password_hashed = hash('whirlpool', $password); + + if ($password_hashed !== $user['password']) { + return false; + } + + return $user['uid']; + } + /** * @param object $uid user to remove * @return void From ec6f5193e20ad0e37daf2b855d59fdf03ae4111d Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 26 Nov 2017 14:46:08 -0500 Subject: [PATCH 4/9] Switch to User::authenticate - Removed hash('whirlpool') to check password --- include/api.php | 15 +++------ include/auth.php | 75 +++++++++++++++++++++------------------------ mod/removeme.php | 4 +-- mod/settings.php | 9 ++---- src/Util/ExAuth.php | 5 +-- 5 files changed, 46 insertions(+), 62 deletions(-) diff --git a/include/api.php b/include/api.php index a5e8063848..e0dc413c2a 100644 --- a/include/api.php +++ b/include/api.php @@ -12,6 +12,7 @@ use Friendica\Core\Config; use Friendica\Core\NotificationsManager; use Friendica\Core\Worker; use Friendica\Database\DBM; +use Friendica\Model\User; use Friendica\Network\HTTPException; use Friendica\Network\HTTPException\BadRequestException; use Friendica\Network\HTTPException\ForbiddenException; @@ -190,7 +191,6 @@ function api_login(App $a) $user = $_SERVER['PHP_AUTH_USER']; $password = $_SERVER['PHP_AUTH_PW']; - $encrypted = hash('whirlpool', trim($password)); // allow "user@server" login (but ignore 'server' part) $at = strstr($user, "@", true); @@ -218,16 +218,9 @@ function api_login(App $a) if (($addon_auth['authenticated']) && (count($addon_auth['user_record']))) { $record = $addon_auth['user_record']; } else { - // process normal login request - $r = q( - "SELECT * FROM `user` WHERE (`email` = '%s' OR `nickname` = '%s') - AND `password` = '%s' AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1", - dbesc(trim($user)), - dbesc(trim($user)), - dbesc($encrypted) - ); - if (DBM::is_result($r)) { - $record = $r[0]; + $user_id = User::authenticate(trim($user), trim($password)); + if ($user_id) { + $record = dba::select('user', [], ['uid' => $user_id], ['limit' => 1]); } } diff --git a/include/auth.php b/include/auth.php index 90509468c5..181ba71a62 100644 --- a/include/auth.php +++ b/include/auth.php @@ -4,6 +4,7 @@ use Friendica\App; use Friendica\Core\System; use Friendica\Core\Config; use Friendica\Database\DBM; +use Friendica\Model\User; require_once 'include/security.php'; require_once 'include/datetime.php'; @@ -98,41 +99,44 @@ if (isset($_SESSION) && x($_SESSION, 'authenticated') && (!x($_POST, 'auth-param } } else { session_unset(); - if (x($_POST, 'password') && strlen($_POST['password'])) { - $encrypted = hash('whirlpool', trim($_POST['password'])); - } else { - if ((x($_POST, 'openid_url')) && strlen($_POST['openid_url']) || - (x($_POST, 'username')) && strlen($_POST['username'])) { + if ( + !(x($_POST, 'password') && strlen($_POST['password'])) + && ( + x($_POST, 'openid_url') && strlen($_POST['openid_url']) + || x($_POST, 'username') && strlen($_POST['username']) + ) + ) { + $noid = Config::get('system', 'no_openid'); - $noid = Config::get('system', 'no_openid'); + $openid_url = trim(strlen($_POST['openid_url']) ? $_POST['openid_url'] : $_POST['username']); - $openid_url = trim((strlen($_POST['openid_url']) ? $_POST['openid_url'] : $_POST['username'])); + // validate_url alters the calling parameter - // validate_url alters the calling parameter - $temp_string = $openid_url; + $temp_string = $openid_url; - // if it's an email address or doesn't resolve to a URL, fail. - if ($noid || strpos($temp_string, '@') || !validate_url($temp_string)) { - $a = get_app(); - notice(t('Login failed.') . EOL); - goaway(System::baseUrl()); - // NOTREACHED - } + // if it's an email address or doesn't resolve to a URL, fail. - // Otherwise it's probably an openid. - try { - require_once('library/openid.php'); - $openid = new LightOpenID; - $openid->identity = $openid_url; - $_SESSION['openid'] = $openid_url; - $_SESSION['remember'] = $_POST['remember']; - $openid->returnUrl = System::baseUrl(true) . '/openid'; - goaway($openid->authUrl()); - } catch (Exception $e) { - notice(t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.') . '

' . t('The error message was:') . ' ' . $e->getMessage()); - } + if ($noid || strpos($temp_string, '@') || !validate_url($temp_string)) { + $a = get_app(); + notice(t('Login failed.') . EOL); + goaway(System::baseUrl()); // NOTREACHED } + + // Otherwise it's probably an openid. + + try { + require_once('library/openid.php'); + $openid = new LightOpenID; + $openid->identity = $openid_url; + $_SESSION['openid'] = $openid_url; + $_SESSION['remember'] = $_POST['remember']; + $openid->returnUrl = System::baseUrl(true) . '/openid'; + goaway($openid->authUrl()); + } catch (Exception $e) { + notice(t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.') . '

' . t('The error message was:') . ' ' . $e->getMessage()); + } + // NOTREACHED } if (x($_POST, 'auth-params') && $_POST['auth-params'] === 'login') { @@ -157,18 +161,9 @@ if (isset($_SESSION) && x($_SESSION, 'authenticated') && (!x($_POST, 'auth-param if ($addon_auth['authenticated'] && count($addon_auth['user_record'])) { $record = $addon_auth['user_record']; } else { - - // process normal login request - - $r = q("SELECT `user`.*, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey` - FROM `user` WHERE (`email` = '%s' OR `nickname` = '%s') - AND `password` = '%s' AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1", - dbesc(trim($_POST['username'])), - dbesc(trim($_POST['username'])), - dbesc($encrypted) - ); - if (DBM::is_result($r)) { - $record = $r[0]; + $user_id = User::authenticate(trim($_POST['username']), trim($_POST['password'])); + if ($user_id) { + $record = dba::select('user', [], ['uid' => $user_id], ['limit' => 1]); } } diff --git a/mod/removeme.php b/mod/removeme.php index 2f4349a704..bf5969982a 100644 --- a/mod/removeme.php +++ b/mod/removeme.php @@ -26,9 +26,7 @@ function removeme_post(App $a) return; } - $encrypted = hash('whirlpool',trim($_POST['qxz_password'])); - - if ((strlen($a->user['password'])) && ($encrypted === $a->user['password'])) { + if (User::authenticate($a->user['uid'], trim($_POST['qxz_password']))) { User::remove($a->user['uid']); // NOTREACHED } diff --git a/mod/settings.php b/mod/settings.php index 6a32b7ed0d..7628f77825 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -9,6 +9,7 @@ use Friendica\Core\Config; use Friendica\Core\PConfig; use Friendica\Database\DBM; use Friendica\Model\GlobalContact; +use Friendica\Model\User; require_once 'include/group.php'; @@ -371,7 +372,6 @@ function settings_post(App $a) { $newpass = $_POST['password']; $confirm = $_POST['confirm']; - $oldpass = hash('whirlpool', $_POST['opassword']); $err = false; if ($newpass != $confirm) { @@ -386,8 +386,7 @@ function settings_post(App $a) { // check if the old password was supplied correctly before // changing it to the new value - $r = q("SELECT `password` FROM `user`WHERE `uid` = %d LIMIT 1", intval(local_user())); - if ($oldpass != $r[0]['password']) { + if (User::authenticate(intval(local_user()), $_POST['opassword'])) { notice(t('Wrong password.') . EOL); $err = true; } @@ -501,9 +500,7 @@ function settings_post(App $a) { if ($email != $a->user['email']) { $email_changed = true; // check for the correct password - $r = q("SELECT `password` FROM `user`WHERE `uid` = %d LIMIT 1", intval(local_user())); - $password = hash('whirlpool', $_POST['mpassword']); - if ($password != $r[0]['password']) { + if (!User::authenticate(intval(local_user()), $_POST['mpassword'])) { $err .= t('Wrong Password') . EOL; $email = $a->user['email']; } diff --git a/src/Util/ExAuth.php b/src/Util/ExAuth.php index aa3300c4e9..f4dc7c052b 100644 --- a/src/Util/ExAuth.php +++ b/src/Util/ExAuth.php @@ -37,6 +37,7 @@ namespace Friendica\Util; use Friendica\Core\Config; use Friendica\Core\PConfig; use Friendica\Database\DBM; +use Friendica\Model\User; use dba; require_once 'include/dba.php'; @@ -217,8 +218,8 @@ class ExAuth $aUser = dba::select('user', ['uid', 'password'], ['nickname' => $sUser], ['limit' => 1]); if (DBM::is_result($aUser)) { - $uid = $aUser['uid']; - $Error = $aUser['password'] != hash('whirlpool', $aCommand[3]); + $uid = User::authenticate($aUser, $aCommand[3]); + $Error = $uid === false; } else { $this->writeLog(LOG_WARNING, 'user not found: ' . $sUser); $Error = true; From 2196a0577b29dcec1ba4d2c32be10fa5f0e91034 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 26 Nov 2017 14:55:47 -0500 Subject: [PATCH 5/9] Remove unused upubkey and uprvkey from queries - Switched queries to new dba::* functions --- include/auth.php | 40 +++++++++++++++++++++++++++------------- include/security.php | 2 +- mod/openid.php | 3 ++- mod/settings.php | 4 ++-- src/Model/User.php | 11 +++++------ src/Worker/Delivery.php | 2 +- src/Worker/Notifier.php | 4 ++-- src/Worker/Queue.php | 26 +++++++++----------------- 8 files changed, 49 insertions(+), 43 deletions(-) diff --git a/include/auth.php b/include/auth.php index 181ba71a62..5da71ef6e1 100644 --- a/include/auth.php +++ b/include/auth.php @@ -13,13 +13,21 @@ require_once 'include/datetime.php'; if (isset($_COOKIE["Friendica"])) { $data = json_decode($_COOKIE["Friendica"]); if (isset($data->uid)) { - $r = q("SELECT `user`.*, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey` - FROM `user` WHERE `uid` = %d AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1", - intval($data->uid) + + $user = dba::select('user', + [], + [ + 'uid' => intval($data->uid), + 'blocked' => 0, + 'account_expired' => 0, + 'account_removed' => 0, + 'verified' => 1, + ], + ['limit' => 1] ); - if ($r) { - if ($data->hash != cookie_hash($r[0])) { + if (DBM::is_result($user)) { + if ($data->hash != cookie_hash($user)) { logger("Hash for user " . $data->uid . " doesn't fit."); nuke_session(); goaway(System::baseUrl()); @@ -29,11 +37,11 @@ if (isset($_COOKIE["Friendica"])) { // 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, $r[0]); + new_cookie($authcookiedays * 24 * 60 * 60, $user); // Do the authentification if not done by now if (!isset($_SESSION) || !isset($_SESSION['authenticated'])) { - authenticate_success($r[0]); + authenticate_success($user); if (Config::get('system', 'paranoia')) { $_SESSION['addr'] = $data->ip; @@ -75,12 +83,18 @@ if (isset($_SESSION) && x($_SESSION, 'authenticated') && (!x($_POST, 'auth-param goaway(System::baseUrl()); } - $r = q("SELECT `user`.*, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey` - FROM `user` WHERE `uid` = %d AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1", - intval($_SESSION['uid']) + $user = dba::select('user', + [], + [ + 'uid' => intval($_SESSION['uid']), + 'blocked' => 0, + 'account_expired' => 0, + 'account_removed' => 0, + 'verified' => 1, + ], + ['limit' => 1] ); - - if (!DBM::is_result($r)) { + if (!DBM::is_result($user)) { nuke_session(); goaway(System::baseUrl()); } @@ -95,7 +109,7 @@ if (isset($_SESSION) && x($_SESSION, 'authenticated') && (!x($_POST, 'auth-param $_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC'); $login_refresh = true; } - authenticate_success($r[0], false, false, $login_refresh); + authenticate_success($user, false, false, $login_refresh); } } else { session_unset(); diff --git a/include/security.php b/include/security.php index 18793ce060..6f6ef94b69 100644 --- a/include/security.php +++ b/include/security.php @@ -15,7 +15,7 @@ use Friendica\Database\DBM; */ function cookie_hash($user) { return(hash("sha256", Config::get("system", "site_prvkey"). - $user["uprvkey"]. + $user["prvkey"]. $user["password"])); } diff --git a/mod/openid.php b/mod/openid.php index 45b80638d5..613cd222f6 100644 --- a/mod/openid.php +++ b/mod/openid.php @@ -33,7 +33,8 @@ function openid_content(App $a) { // mod/settings.php in 8367cad so it might have left mixed // records in the user table // - $r = q("SELECT *, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey` FROM `user` + $r = q("SELECT * + FROM `user` WHERE ( `openid` = '%s' OR `openid` = '%s' ) AND `blocked` = 0 AND `account_expired` = 0 AND `account_removed` = 0 AND `verified` = 1 diff --git a/mod/settings.php b/mod/settings.php index 7628f77825..8ad82b023d 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -506,14 +506,14 @@ function settings_post(App $a) { } // check the email is valid if (!valid_email($email)) { - $err .= t(' Not valid email.'); + $err .= t('Invalid email.'); } // ensure new email is not the admin mail //if ((x($a->config, 'admin_email')) && (strcasecmp($email, $a->config['admin_email']) == 0)) { if (x($a->config, 'admin_email')) { $adminlist = explode(",", str_replace(" ", "", strtolower($a->config['admin_email']))); if (in_array(strtolower($email), $adminlist)) { - $err .= t(' Cannot change to that email.'); + $err .= t('Cannot change to that email.'); $email = $a->user['email']; } } diff --git a/src/Model/User.php b/src/Model/User.php index a7f59b6a3d..87663dbe5f 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -78,21 +78,20 @@ class User logger('Removing user: ' . $uid); - $r = dba::select('user', array(), array('uid' => $uid), array("limit" => 1)); + $user = dba::select('user', [], ['uid' => $uid], ['limit' => 1]); - call_hooks('remove_user', $r); + call_hooks('remove_user', $user); // save username (actually the nickname as it is guaranteed // unique), so it cannot be re-registered in the future. - - dba::insert('userd', array('username' => $r['nickname'])); + dba::insert('userd', ['username' => $user['nickname']]); // The user and related data will be deleted in "cron_expire_and_remove_users" (cronjobs.php) - q("UPDATE `user` SET `account_removed` = 1, `account_expires_on` = UTC_TIMESTAMP() WHERE `uid` = %d", intval($uid)); + dba::update('user', ['account_removed' => 1, 'account_expires_on' => datetime_convert()], ['uid' => intval($uid)]); Worker::add(PRIORITY_HIGH, "Notifier", "removeme", $uid); // Send an update to the directory - Worker::add(PRIORITY_LOW, "Directory", $r['url']); + Worker::add(PRIORITY_LOW, "Directory", $user['url']); if ($uid == local_user()) { unset($_SESSION['authenticated']); diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index 216d2520d9..c47e98287b 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -140,7 +140,7 @@ class Delivery { } } - $r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`, + $r = q("SELECT `contact`.*, `user`.`prvkey` AS `uprvkey`, `user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`, `user`.`page-flags`, `user`.`account-type`, `user`.`prvnets` FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid` diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index ac8cf123c5..b261b32fc0 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -108,7 +108,7 @@ class Notifier { $recipients[] = $suggest[0]['cid']; $item = $suggest[0]; } elseif ($cmd === 'removeme') { - $r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`, + $r = q("SELECT `contact`.*, `user`.`prvkey` AS `uprvkey`, `user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`, `user`.`page-flags`, `user`.`prvnets`, `user`.`account-type`, `user`.`guid` FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid` @@ -173,7 +173,7 @@ class Notifier { } - $r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`, + $r = q("SELECT `contact`.*, `user`.`prvkey` AS `uprvkey`, `user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`, `user`.`page-flags`, `user`.`prvnets`, `user`.`account-type` FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid` diff --git a/src/Worker/Queue.php b/src/Worker/Queue.php index 73726098e9..f09def003d 100644 --- a/src/Worker/Queue.php +++ b/src/Worker/Queue.php @@ -80,33 +80,29 @@ class Queue $q_item = $r[0]; - $c = q( - "SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", - intval($q_item['cid']) - ); - - if (!DBM::is_result($c)) { + $contact = dba::select('contact', [], ['id' => intval($q_item['cid'])], ['limit' => 1]); + if (!DBM::is_result($contact)) { remove_queue_item($q_item['id']); return; } - $dead = Cache::get($cachekey_deadguy . $c[0]['notify']); + $dead = Cache::get($cachekey_deadguy . $contact['notify']); if (!is_null($dead) && $dead) { - logger('queue: skipping known dead url: ' . $c[0]['notify']); + logger('queue: skipping known dead url: ' . $contact['notify']); update_queue_time($q_item['id']); return; } - $server = PortableContact::detectServer($c[0]['url']); + $server = PortableContact::detectServer($contact['url']); if ($server != "") { $vital = Cache::get($cachekey_server . $server); if (is_null($vital)) { - logger("Check server " . $server . " (" . $c[0]["network"] . ")"); + logger("Check server " . $server . " (" . $contact["network"] . ")"); - $vital = PortableContact::checkServer($server, $c[0]["network"], true); + $vital = PortableContact::checkServer($server, $contact["network"], true); Cache::set($cachekey_server . $server, $vital, CACHE_QUARTER_HOUR); } @@ -117,12 +113,8 @@ class Queue } } - $u = q( - "SELECT `user`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey` - FROM `user` WHERE `uid` = %d LIMIT 1", - intval($c[0]['uid']) - ); - if (!DBM::is_result($u)) { + $user = dba::select('user', [], ['uid' => intval($contact['uid'])], ['limit' => 1]); + if (!DBM::is_result($user)) { remove_queue_item($q_item['id']); return; } From 456dfbe48602592b4412291ea9164c0da489ee82 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 26 Nov 2017 14:56:50 -0500 Subject: [PATCH 6/9] Forgotten change in src/Worker/Queue.php --- src/Worker/Queue.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Worker/Queue.php b/src/Worker/Queue.php index f09def003d..f2da800077 100644 --- a/src/Worker/Queue.php +++ b/src/Worker/Queue.php @@ -119,10 +119,9 @@ class Queue return; } - $data = $q_item['content']; - $public = $q_item['batch']; - $contact = $c[0]; - $owner = $u[0]; + $data = $q_item['content']; + $public = $q_item['batch']; + $owner = $user; $deliver_status = 0; From 2a60146a434c56e6e739afd6788e98b202a91ba2 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 26 Nov 2017 15:45:59 -0500 Subject: [PATCH 7/9] Revert "Add new legacy password field" This reverts commit 2236f60cfa5814f74719ecb2641130cb32e6aa36. --- boot.php | 2 +- include/dbstructure.php | 1 - update.php | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/boot.php b/boot.php index 5ee4d5f4a2..9cdaefb212 100644 --- a/boot.php +++ b/boot.php @@ -45,7 +45,7 @@ define('FRIENDICA_PLATFORM', 'Friendica'); define('FRIENDICA_CODENAME', 'Asparagus'); define('FRIENDICA_VERSION', '3.6-dev'); define('DFRN_PROTOCOL_VERSION', '2.23'); -define('DB_UPDATE_VERSION', 1236); +define('DB_UPDATE_VERSION', 1235); /** * @brief Constant with a HTML line break. diff --git a/include/dbstructure.php b/include/dbstructure.php index 65dda55c37..dde3dc6f18 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -1682,7 +1682,6 @@ function db_definition() { "guid" => array("type" => "varchar(64)", "not null" => "1", "default" => ""), "username" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "password" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "legacy_password" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"), "nickname" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "email" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "openid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), diff --git a/update.php b/update.php index 7530d1a386..5cf9bbc2d4 100644 --- a/update.php +++ b/update.php @@ -1,6 +1,6 @@ Date: Sun, 26 Nov 2017 15:51:07 -0500 Subject: [PATCH 8/9] Fix function name typo --- src/Model/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/User.php b/src/Model/User.php index 87663dbe5f..3fa3948621 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -53,7 +53,7 @@ class User $user = $user_info; } - if (!DBM::isResult($user) || !isset($user['uid']) || !isset($user['password'])) { + if (!DBM::is_result($user) || !isset($user['uid']) || !isset($user['password'])) { return false; } From ced1063a10909fd10c8dcfb0331e86fb0fa208d5 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 27 Nov 2017 08:17:56 -0500 Subject: [PATCH 9/9] Improved dba calls - Removed intval calls - Used boolean values for params when relevant --- include/auth.php | 20 ++++++++++---------- src/Model/User.php | 2 +- src/Worker/Queue.php | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/auth.php b/include/auth.php index 5da71ef6e1..a02c18d1db 100644 --- a/include/auth.php +++ b/include/auth.php @@ -17,11 +17,11 @@ if (isset($_COOKIE["Friendica"])) { $user = dba::select('user', [], [ - 'uid' => intval($data->uid), - 'blocked' => 0, - 'account_expired' => 0, - 'account_removed' => 0, - 'verified' => 1, + 'uid' => $data->uid, + 'blocked' => false, + 'account_expired' => false, + 'account_removed' => false, + 'verified' => true, ], ['limit' => 1] ); @@ -86,11 +86,11 @@ if (isset($_SESSION) && x($_SESSION, 'authenticated') && (!x($_POST, 'auth-param $user = dba::select('user', [], [ - 'uid' => intval($_SESSION['uid']), - 'blocked' => 0, - 'account_expired' => 0, - 'account_removed' => 0, - 'verified' => 1, + 'uid' => $_SESSION['uid'], + 'blocked' => false, + 'account_expired' => false, + 'account_removed' => false, + 'verified' => true, ], ['limit' => 1] ); diff --git a/src/Model/User.php b/src/Model/User.php index 3fa3948621..b2beb8e19b 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -87,7 +87,7 @@ class User dba::insert('userd', ['username' => $user['nickname']]); // The user and related data will be deleted in "cron_expire_and_remove_users" (cronjobs.php) - dba::update('user', ['account_removed' => 1, 'account_expires_on' => datetime_convert()], ['uid' => intval($uid)]); + dba::update('user', ['account_removed' => true, 'account_expires_on' => datetime_convert()], ['uid' => $uid]); Worker::add(PRIORITY_HIGH, "Notifier", "removeme", $uid); // Send an update to the directory diff --git a/src/Worker/Queue.php b/src/Worker/Queue.php index f2da800077..35642ae729 100644 --- a/src/Worker/Queue.php +++ b/src/Worker/Queue.php @@ -80,7 +80,7 @@ class Queue $q_item = $r[0]; - $contact = dba::select('contact', [], ['id' => intval($q_item['cid'])], ['limit' => 1]); + $contact = dba::select('contact', [], ['id' => $q_item['cid']], ['limit' => 1]); if (!DBM::is_result($contact)) { remove_queue_item($q_item['id']); return; @@ -113,7 +113,7 @@ class Queue } } - $user = dba::select('user', [], ['uid' => intval($contact['uid'])], ['limit' => 1]); + $user = dba::select('user', [], ['uid' => $contact['uid']], ['limit' => 1]); if (!DBM::is_result($user)) { remove_queue_item($q_item['id']); return;