From 2891a07637b63a7b228eaf2a8959d81e51fd2f73 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 24 Jan 2014 12:15:23 +0100 Subject: [PATCH 01/11] [FIX] Bail payouts on failed sendtoaddress calls * [WORKAROUND] Helps for coins that run a bad RPC implementation * Addresses #1406 and wil at least stop double payouts --- cronjobs/payouts.php | 8 ++++---- public/include/config/error_codes.inc.php | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cronjobs/payouts.php b/cronjobs/payouts.php index 87b5e119..5483e3c8 100755 --- a/cronjobs/payouts.php +++ b/cronjobs/payouts.php @@ -68,8 +68,8 @@ if ($setting->getValue('disable_manual_payouts') != 1) { try { $txid = $bitcoin->sendtoaddress($aData['coin_address'], $dBalance - $config['txfee_manual']); } catch (Exception $e) { - $log->logError('Failed to send requested balance to coin address, please check payout process. Does the wallet cover the amount? Error:' . $e->getMessage()); - continue; + $log->logFatal('Failed sending coins to user, aborting due to a coind exception in RPC call. Please check your RPC transactions.'); + $monitoring->endCronjob($cron_name, 'E0078', 1, true); } if ($transaction->addTransaction($aData['account_id'], $dBalance - $config['txfee_manual'], 'Debit_MP', NULL, $aData['coin_address'], $txid) && $transaction->addTransaction($aData['account_id'], $config['txfee_manual'], 'TXFee', NULL, $aData['coin_address'])) { @@ -132,8 +132,8 @@ if ($setting->getValue('disable_auto_payouts') != 1) { try { $txid = $bitcoin->sendtoaddress($aUserData['coin_address'], $dBalance - $config['txfee_auto']); } catch (Exception $e) { - $log->logError('Failed to send requested balance to coin address, please check payout process. Does the wallet cover the amount?'); - continue; + $log->logFatal('Failed sending coins to user, aborting due to a coind exception in RPC call. Please check your RPC transactions.'); + $monitoring->endCronjob($cron_name, 'E0078', 1, true); } // Create transaction record diff --git a/public/include/config/error_codes.inc.php b/public/include/config/error_codes.inc.php index c57e9e3c..9083cf3d 100644 --- a/public/include/config/error_codes.inc.php +++ b/public/include/config/error_codes.inc.php @@ -75,4 +75,5 @@ $aErrorCodes['E0074'] = 'Failed deleting expired tokens'; $aErrorCodes['E0075'] = 'Upgrade required'; $aErrorCodes['E0076'] = 'No coins in wallet available'; $aErrorCodes['E0077'] = 'RPC method or connection failed'; +$aErrorCodes['E0078'] = 'RPC method did not return 200 OK'; ?> From c6e2e062decbe30c4a561ef9c5b7944533bd829e Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 24 Jan 2014 16:19:10 +0100 Subject: [PATCH 02/11] [FIX] Skip prop payouts with 0 valid shares * [FIXED] Do not create 0 amount payout transactions for users w/o valid shares Fixes #1569 once merged. --- cronjobs/proportional_payout.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cronjobs/proportional_payout.php b/cronjobs/proportional_payout.php index 0fbc80cd..e2f7ea25 100755 --- a/cronjobs/proportional_payout.php +++ b/cronjobs/proportional_payout.php @@ -72,6 +72,10 @@ foreach ($aAllBlocks as $iIndex => $aBlock) { // Loop through all accounts that have found shares for this round foreach ($aAccountShares as $key => $aData) { + // Skip users with only invalids + if ($aData['valid'] == 0) { + continue; + } // Skip entries that have no account ID, user deleted? if (empty($aData['id'])) { $log->logInfo('User ' . $aData['username'] . ' does not have an associated account, skipping'); From 3006cb544f08ad9e54324de4d4088676fafc94bc Mon Sep 17 00:00:00 2001 From: xisi Date: Fri, 24 Jan 2014 13:00:24 -0500 Subject: [PATCH 03/11] Reworked csrf tokens, now enabled globally The way this now works is, if csrf is enabled: * Any new or existing template can have csrf protection by adding the hidden input ctoken that's in this batch to its form, removes any logic in templates * Page controllers that already exist have been updated, new ones only require checking if csrf is enabled and valid --- public/include/classes/csrftoken.class.php | 1 + public/include/config/global.inc.dist.php | 8 ++--- public/include/pages/account/edit.inc.php | 24 +++++---------- .../include/pages/account/invitations.inc.php | 12 +------- .../pages/account/notifications.inc.php | 18 +++-------- public/include/pages/account/unlock.inc.php | 16 ++-------- public/include/pages/account/workers.inc.php | 30 ++++++++----------- public/include/pages/contactform.inc.php | 5 ---- .../pages/contactform/contactform.inc.php | 18 +++-------- public/include/pages/home.inc.php | 5 ---- public/include/pages/login.inc.php | 14 ++------- public/include/pages/password.inc.php | 8 ++--- public/include/pages/password/change.inc.php | 17 ++--------- public/include/pages/password/reset.inc.php | 13 +------- public/include/pages/register.inc.php | 5 ---- .../include/pages/register/register.inc.php | 16 ++-------- public/index.php | 6 ++++ public/templates/mobile/login/default.tpl | 2 +- .../mobile/password/change/default.tpl | 2 +- public/templates/mobile/password/default.tpl | 2 +- .../templates/mpos/account/edit/default.tpl | 8 ++--- .../mpos/account/invitations/default.tpl | 2 +- .../mpos/account/notifications/default.tpl | 2 +- .../mpos/account/workers/default.tpl | 4 +-- .../mpos/contactform/contactform/default.tpl | 2 +- public/templates/mpos/contactform/default.tpl | 2 +- public/templates/mpos/login/default.tpl | 2 +- public/templates/mpos/login/small.tpl | 2 +- .../mpos/password/change/default.tpl | 3 +- public/templates/mpos/password/default.tpl | 2 +- public/templates/mpos/register/default.tpl | 2 +- 31 files changed, 69 insertions(+), 184 deletions(-) diff --git a/public/include/classes/csrftoken.class.php b/public/include/classes/csrftoken.class.php index ca303c7b..2e8dc953 100644 --- a/public/include/classes/csrftoken.class.php +++ b/public/include/classes/csrftoken.class.php @@ -4,6 +4,7 @@ if (!defined('SECURITY')) die('Hacking attempt'); class CSRFToken Extends Base { + public $valid = 0; /** * Gets a basic csrf token * @param string $user user or IP/host address diff --git a/public/include/config/global.inc.dist.php b/public/include/config/global.inc.dist.php index 9a465e77..1860f0b4 100644 --- a/public/include/config/global.inc.dist.php +++ b/public/include/config/global.inc.dist.php @@ -126,7 +126,7 @@ $config['twofactor']['options']['withdraw'] = true; $config['twofactor']['options']['changepw'] = true; /** - * CSRF protection config + * CSRF protection * * Explanation: * To help protect against CSRF, we can generate a hash that changes every minute @@ -134,15 +134,11 @@ $config['twofactor']['options']['changepw'] = true; * form is submitted. * * Options: - * enabled = Whether or not we will generate/check for valid CSRF tokens - * disabled_forms = Which forms you want to disable csrf protection on, if enabled - * * Valid options : login, contact, accountedit, workers, notifications, invite, register, passreset, unlockaccount + * enabled = Whether or not we will generate & check for valid CSRF tokens * Default: * enabled = true - * disabled_forms = array(); */ $config['csrf']['enabled'] = true; -$config['csrf']['disabled_forms'] = array(); /** * Lock account after maximum failed logins diff --git a/public/include/pages/account/edit.inc.php b/public/include/pages/account/edit.inc.php index c62e8d4d..ed058175 100644 --- a/public/include/pages/account/edit.inc.php +++ b/public/include/pages/account/edit.inc.php @@ -13,12 +13,6 @@ $oldtoken_cp = (isset($_POST['cp_token']) && $_POST['cp_token'] !== '') ? $_POST $oldtoken_wf = (isset($_POST['wf_token']) && $_POST['wf_token'] !== '') ? $_POST['wf_token'] : @$_GET['wf_token']; $updating = (@$_POST['do']) ? 1 : 0; -// csrf stuff -$csrfenabled = ($config['csrf']['enabled'] && !in_array('accountedit', $config['csrf']['disabled_forms'])) ? 1 : 0; -if ($csrfenabled) { - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'editaccount', @$_POST['ctoken'])) ? 1 : 0; -} - if ($user->isAuthenticated()) { if ($config['twofactor']['enabled']) { $popupmsg = 'E-mail confirmations are required for '; @@ -70,7 +64,7 @@ if ($user->isAuthenticated()) { } if (isset($_POST['do']) && $_POST['do'] == 'genPin') { - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($user->generatePin($_SESSION['USERDATA']['id'], $_POST['currentPassword'])) { $_SESSION['POPUP'][] = array('CONTENT' => 'Your PIN # has been sent to your email.', 'TYPE' => 'success'); } else { @@ -89,7 +83,7 @@ if ($user->isAuthenticated()) { $isvalid = in_array($_POST['utype'],$validtypes); if ($isvalid) { $ctype = strip_tags($_POST['utype']); - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { $send = $user->sendChangeConfigEmail($ctype, $_SESSION['USERDATA']['id']); if ($send) { $_SESSION['POPUP'][] = array('CONTENT' => 'A confirmation was sent to your e-mail, follow that link to continue', 'TYPE' => 'success'); @@ -110,7 +104,7 @@ if ($user->isAuthenticated()) { $dBalance = $aBalance['confirmed']; if ($dBalance > $config['txfee_manual']) { if (!$oPayout->isPayoutActive($_SESSION['USERDATA']['id'])) { - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($iPayoutId = $oPayout->createPayout($_SESSION['USERDATA']['id'], $oldtoken_wf)) { $_SESSION['POPUP'][] = array('CONTENT' => 'Created new manual payout request with ID #' . $iPayoutId); } else { @@ -129,7 +123,7 @@ if ($user->isAuthenticated()) { break; case 'updateAccount': - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($user->updateAccount($_SESSION['USERDATA']['id'], $_POST['paymentAddress'], $_POST['payoutThreshold'], $_POST['donatePercent'], $_POST['email'], $_POST['is_anonymous'], $oldtoken_ea)) { $_SESSION['POPUP'][] = array('CONTENT' => 'Account details updated', 'TYPE' => 'success'); } else { @@ -141,7 +135,7 @@ if ($user->isAuthenticated()) { break; case 'updatePassword': - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($user->updatePassword($_SESSION['USERDATA']['id'], $_POST['currentPassword'], $_POST['newPassword'], $_POST['newPassword2'], $oldtoken_cp)) { $_SESSION['POPUP'][] = array('CONTENT' => 'Password updated', 'TYPE' => 'success'); } else { @@ -185,8 +179,7 @@ if ($user->isAuthenticated() && $config['twofactor']['enabled']) { (!empty($cpprep_sent) && !empty($cpprep_edit)) ? $_SESSION['POPUP'][] = array('CONTENT' => $cpprep_sent, 'TYPE' => 'success'):""; (!empty($cpprep_sent) && empty($cpprep_edit)) ? $_SESSION['POPUP'][] = array('CONTENT' => $message_tokensent_invalid.$messages_tokensent_status['cp'], 'TYPE' => 'success'):""; } - -// csrf stuff +// two-factor stuff $smarty->assign("CHANGEPASSUNLOCKED", $cp_editable); $smarty->assign("WITHDRAWUNLOCKED", $wf_editable); $smarty->assign("DETAILSUNLOCKED", $ea_editable); @@ -194,10 +187,7 @@ $smarty->assign("CHANGEPASSSENT", $cp_sent); $smarty->assign("WITHDRAWSENT", $wf_sent); $smarty->assign("DETAILSSENT", $ea_sent); $smarty->assign("DONATE_THRESHOLD", $config['donate_threshold']); -if ($csrfenabled && !in_array('accountedit', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'editaccount'); - $smarty->assign('CTOKEN', $token); -} + // Tempalte specifics $smarty->assign("CONTENT", "default.tpl"); ?> diff --git a/public/include/pages/account/invitations.inc.php b/public/include/pages/account/invitations.inc.php index 10a85149..0ceb15a8 100644 --- a/public/include/pages/account/invitations.inc.php +++ b/public/include/pages/account/invitations.inc.php @@ -5,15 +5,10 @@ if (!defined('SECURITY')) die('Hacking attempt'); if ($user->isAuthenticated()) { if (!$setting->getValue('disable_invitations')) { - // csrf stuff - $csrfenabled = ($config['csrf']['enabled'] && !in_array('invitations', $config['csrf']['disabled_forms'])) ? 1 : 0; - if ($csrfenabled) { - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'invitations', @$_POST['ctoken'])) ? 1 : 0; - } if ($invitation->getCountInvitations($_SESSION['USERDATA']['id']) >= $config['accounts']['invitations']['count']) { $_SESSION['POPUP'][] = array('CONTENT' => 'You have exceeded the allowed invitations of ' . $config['accounts']['invitations']['count'], 'TYPE' => 'errormsg'); } else if (isset($_POST['do']) && $_POST['do'] == 'sendInvitation') { - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($invitation->sendInvitation($_SESSION['USERDATA']['id'], $_POST['data'])) { $_SESSION['POPUP'][] = array('CONTENT' => 'Invitation sent', 'TYPE' => 'success'); } else { @@ -30,10 +25,5 @@ if ($user->isAuthenticated()) { $_SESSION['POPUP'][] = array('CONTENT' => 'Invitations are disabled', 'TYPE' => 'errormsg'); } } -// csrf token -if ($csrfenabled && !in_array('invitations', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'invitations'); - $smarty->assign('CTOKEN', $token); -} $smarty->assign('CONTENT', 'default.tpl'); ?> diff --git a/public/include/pages/account/notifications.inc.php b/public/include/pages/account/notifications.inc.php index 8de15337..0d0fe7e4 100644 --- a/public/include/pages/account/notifications.inc.php +++ b/public/include/pages/account/notifications.inc.php @@ -7,14 +7,8 @@ if ($user->isAuthenticated()) { $_SESSION['POPUP'][] = array('CONTENT' => 'Notification system disabled by admin.', 'TYPE' => 'info'); $smarty->assign('CONTENT', 'empty'); } else { - // csrf stuff - $csrfenabled = ($config['csrf']['enabled'] && !in_array('notifications', $config['csrf']['disabled_forms'])) ? 1 : 0; - if ($csrfenabled) { - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'editnotifs', @$_POST['ctoken'])) ? 1 : 0; - } - if (@$_REQUEST['do'] == 'save') { - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($notification->updateSettings($_SESSION['USERDATA']['id'], $_REQUEST['data'])) { $_SESSION['POPUP'][] = array('CONTENT' => 'Updated notification settings', 'TYPE' => 'success'); } else { @@ -31,15 +25,11 @@ if ($user->isAuthenticated()) { // Fetch user notification settings $aSettings = $notification->getNotificationSettings($_SESSION['USERDATA']['id']); - - // csrf token - if ($csrfenabled && !in_array('notifications', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'editnotifs'); - $smarty->assign('CTOKEN', $token); - } + $smarty->assign('NOTIFICATIONS', $aNotifications); $smarty->assign('SETTINGS', $aSettings); $smarty->assign('CONTENT', 'default.tpl'); } } -?> + +?> \ No newline at end of file diff --git a/public/include/pages/account/unlock.inc.php b/public/include/pages/account/unlock.inc.php index 9ab0551f..f31a272a 100644 --- a/public/include/pages/account/unlock.inc.php +++ b/public/include/pages/account/unlock.inc.php @@ -3,19 +3,13 @@ // Make sure we are called from index.php if (!defined('SECURITY')) die('Hacking attempt'); -// csrf stuff -$csrfenabled = ($config['csrf']['enabled'] && !in_array('unlockaccount', $config['csrf']['disabled_forms'])) ? 1 : 0; -if ($csrfenabled) { - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'unlockaccount', @$_POST['ctoken'])) ? 1 : 0; -} - // Confirm an account by token if (!isset($_GET['token']) || empty($_GET['token'])) { $_SESSION['POPUP'][] = array('CONTENT' => 'Missing token', 'TYPE' => 'errormsg'); } else if (!$aToken = $oToken->getToken($_GET['token'], 'account_unlock')) { $_SESSION['POPUP'][] = array('CONTENT' => 'Unable to re-activate your account. Invalid token.', 'TYPE' => 'errormsg'); } else { - if (!$csrfenabled || $csrfenabled && !$nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($user->setUserFailed($aToken['account_id'], 0) && $user->setUserPinFailed($aToken['account_id'], 0) && $user->changeLocked($aToken['account_id'])) { $oToken->deleteToken($aToken['token']); $_SESSION['POPUP'][] = array('CONTENT' => 'Account re-activated. Please login.'); @@ -26,10 +20,6 @@ if (!isset($_GET['token']) || empty($_GET['token'])) { $_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'info'); } } -// csrf token -if ($csrfenabled && !in_array('unlockaccount', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'unlockaccount'); - $smarty->assign('CTOKEN', $token); -} $smarty->assign('CONTENT', 'default.tpl'); -?> + +?> \ No newline at end of file diff --git a/public/include/pages/account/workers.inc.php b/public/include/pages/account/workers.inc.php index 89dddf9f..ad266b2b 100644 --- a/public/include/pages/account/workers.inc.php +++ b/public/include/pages/account/workers.inc.php @@ -3,22 +3,21 @@ if (!defined('SECURITY')) die('Hacking attempt'); if ($user->isAuthenticated()) { - // csrf stuff - $csrfenabled = ($config['csrf']['enabled'] && !in_array('workers', $config['csrf']['disabled_forms'])) ? 1 : 0; - if ($csrfenabled) { - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'workers', @$_POST['ctoken'])) ? 1 : 0; - } - switch (@$_REQUEST['do']) { case 'delete': - if ($worker->deleteWorker($_SESSION['USERDATA']['id'], $_GET['id'])) { - $_SESSION['POPUP'][] = array('CONTENT' => 'Worker removed', 'TYPE' => 'success'); + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { + if ($worker->deleteWorker($_SESSION['USERDATA']['id'], $_GET['id'])) { + $_SESSION['POPUP'][] = array('CONTENT' => 'Worker removed', 'TYPE' => 'success'); + } else { + $_SESSION['POPUP'][] = array('CONTENT' => $worker->getError(), 'TYPE' => 'errormsg'); + } } else { - $_SESSION['POPUP'][] = array('CONTENT' => $worker->getError(), 'TYPE' => 'errormsg'); + $_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'info'); } break; + case 'add': - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($worker->addWorker($_SESSION['USERDATA']['id'], $_POST['username'], $_POST['password'])) { $_SESSION['POPUP'][] = array('CONTENT' => 'Worker added', 'TYPE' => 'success'); } else { @@ -28,8 +27,9 @@ if ($user->isAuthenticated()) { $_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'info'); } break; + case 'update': - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($worker->updateWorkers($_SESSION['USERDATA']['id'], @$_POST['data'])) { $_SESSION['POPUP'][] = array('CONTENT' => 'Worker updated', 'TYPE' => 'success'); } else { @@ -46,10 +46,6 @@ if ($user->isAuthenticated()) { $smarty->assign('WORKERS', $aWorkers); } -// csrf token -if ($csrfenabled && !in_array('workers', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'workers'); - $smarty->assign('CTOKEN', $token); -} $smarty->assign('CONTENT', 'default.tpl'); -?> + +?> \ No newline at end of file diff --git a/public/include/pages/contactform.inc.php b/public/include/pages/contactform.inc.php index 821f1a77..b961cfb2 100644 --- a/public/include/pages/contactform.inc.php +++ b/public/include/pages/contactform.inc.php @@ -14,11 +14,6 @@ if ($setting->getValue('disable_contactform')) { require_once(INCLUDE_DIR . '/lib/recaptchalib.php'); $smarty->assign("RECAPTCHA", recaptcha_get_html($setting->getValue('recaptcha_public_key'))); } - // csrf token - if ($config['csrf']['enabled'] && !in_array('contact', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'contact'); - $smarty->assign('CTOKEN', $token); - } // Tempalte specifics $smarty->assign("CONTENT", "default.tpl"); } diff --git a/public/include/pages/contactform/contactform.inc.php b/public/include/pages/contactform/contactform.inc.php index d734874e..19916321 100644 --- a/public/include/pages/contactform/contactform.inc.php +++ b/public/include/pages/contactform/contactform.inc.php @@ -14,12 +14,6 @@ if ($setting->getValue('recaptcha_enabled')) { ); } -// csrf if enabled -$csrfenabled = ($config['csrf']['enabled'] && !in_array('contact', $config['csrf']['disabled_forms'])) ? 1 : 0; -if ($csrfenabled) { - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'contact', @$_POST['ctoken'])) ? 1 : 0; -} - if ($setting->getValue('disable_contactform')) { $_SESSION['POPUP'][] = array('CONTENT' => 'Contactform is currently disabled. Please try again later.', 'TYPE' => 'errormsg'); } else if ($setting->getValue('disable_contactform') && !$user->isAuthenticated(false)) { @@ -29,7 +23,7 @@ if ($setting->getValue('disable_contactform')) { // Check if recaptcha is enabled, process form data if valid if ($rsp->is_valid) { // Check if csrf is enabled and fail if token is invalid - if (!$nocsrf && $csrfenabled) { + if ($config['csrf']['enabled'] && $csrftoken->valid) { $_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'info'); } else { $smarty->assign("RECAPTCHA", recaptcha_get_html($setting->getValue('recaptcha_public_key'))); @@ -50,7 +44,7 @@ if ($setting->getValue('disable_contactform')) { // Captcha disabled } else { // Check if csrf is enabled and fail if token is invalid - if (!$nocsrf && $csrfenabled) { + if ($config['csrf']['enabled'] && !$csrftoken->valid) { $_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'info'); } else if ($mail->contactform($_POST['senderName'], $_POST['senderEmail'], $_POST['senderSubject'], $_POST['senderMessage'])) { $_SESSION['POPUP'][] = array('CONTENT' => 'Thanks for sending your message! We will get back to you shortly'); @@ -60,11 +54,7 @@ if ($setting->getValue('disable_contactform')) { } } -// csrf token -if ($config['csrf']['enabled'] && !in_array('contact', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'contact'); - $smarty->assign('CTOKEN', $token); -} // Tempalte specifics $smarty->assign("CONTENT", "default.tpl"); -?> + +?> \ No newline at end of file diff --git a/public/include/pages/home.inc.php b/public/include/pages/home.inc.php index 3033c160..99c01c04 100644 --- a/public/include/pages/home.inc.php +++ b/public/include/pages/home.inc.php @@ -22,11 +22,6 @@ if (!$smarty->isCached('master.tpl', $smarty_cache_key)) { } else { $debug->append('Using cached page', 3); } -// csrf token -if ($config['csrf']['enabled'] && !in_array('login', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'login'); - $smarty->assign('CTOKEN', $token); -} // Load news entries for Desktop site and unauthenticated users $smarty->assign("CONTENT", "default.tpl"); ?> diff --git a/public/include/pages/login.inc.php b/public/include/pages/login.inc.php index 30f3b832..4d44b338 100644 --- a/public/include/pages/login.inc.php +++ b/public/include/pages/login.inc.php @@ -3,12 +3,6 @@ // Make sure we are called from index.php if (!defined('SECURITY')) die('Hacking attempt'); -// csrf if enabled -$csrfenabled = ($config['csrf']['enabled'] && !in_array('login', $config['csrf']['disabled_forms'])) ? 1 : 0; -if ($csrfenabled) { - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'login', @$_POST['ctoken'])) ? 1 : 0; -} - // ReCaptcha handling if enabled if ($setting->getValue('recaptcha_enabled') && $setting->getValue('recaptcha_enabled_logins')) { require_once(INCLUDE_DIR . '/lib/recaptchalib.php'); @@ -31,7 +25,7 @@ if ($setting->getValue('maintenance') && !$user->isAdmin($user->getUserIdByEmail } else if (!empty($_POST['username']) && !empty($_POST['password'])) { // Check if recaptcha is enabled, process form data if valid if (!$setting->getValue('recaptcha_enabled') || !$setting->getValue('recaptcha_enabled_logins') || ($setting->getValue('recaptcha_enabled') && $setting->getValue('recaptcha_enabled_logins') && $rsp->is_valid)) { - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($user->checkLogin(@$_POST['username'], @$_POST['password']) ) { empty($_POST['to']) ? $to = $_SERVER['SCRIPT_NAME'] : $to = $_POST['to']; $port = ($_SERVER["SERVER_PORT"] == "80" or $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]); @@ -48,11 +42,7 @@ if ($setting->getValue('maintenance') && !$user->isAdmin($user->getUserIdByEmail $_SESSION['POPUP'][] = array('CONTENT' => 'Invalid Captcha, please try again.', 'TYPE' => 'errormsg'); } } -// csrf token -if ($csrfenabled && !in_array('login', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'login'); - $smarty->assign('CTOKEN', $token); -} + // Load login template $smarty->assign('CONTENT', 'default.tpl'); ?> diff --git a/public/include/pages/password.inc.php b/public/include/pages/password.inc.php index adc1047a..d9fe34ce 100644 --- a/public/include/pages/password.inc.php +++ b/public/include/pages/password.inc.php @@ -4,11 +4,7 @@ if (!defined('SECURITY')) die('Hacking attempt'); -// csrf token -if ($config['csrf']['enabled'] && !in_array('passreset', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'resetpass'); - $smarty->assign('CTOKEN', $token); -} // Tempalte specifics $smarty->assign("CONTENT", "default.tpl"); -?> + +?> \ No newline at end of file diff --git a/public/include/pages/password/change.inc.php b/public/include/pages/password/change.inc.php index d99ac744..f622363b 100644 --- a/public/include/pages/password/change.inc.php +++ b/public/include/pages/password/change.inc.php @@ -4,14 +4,7 @@ if (!defined('SECURITY')) die('Hacking attempt'); -// csrf stuff -$csrfenabled = ($config['csrf']['enabled'] && !in_array('passreset', $config['csrf']['disabled_forms'])) ? 1 : 0; -if ($csrfenabled) { - // we have to use editaccount token because this that's where we'll get pushed here from - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'editaccount', @$_POST['ctoken'])) ? 1 : 0; -} - -if (!$csrfenabled || $csrfenabled && $nocsrf) { +if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if (isset($_POST['do']) && $_POST['do'] == 'resetPassword') { if ($user->resetPassword($_POST['token'], $_POST['newPassword'], $_POST['newPassword2'])) { $_SESSION['POPUP'][] = array('CONTENT' => 'Password reset complete! Please login.', 'TYPE' => 'success'); @@ -23,13 +16,7 @@ if (!$csrfenabled || $csrfenabled && $nocsrf) { $_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'info'); } -// csrf token -if ($config['csrf']['enabled'] && !in_array('passreset', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'editaccount'); - $smarty->assign('CTOKEN', $token); -} - // Tempalte specifics $smarty->assign("CONTENT", "default.tpl"); -?> +?> \ No newline at end of file diff --git a/public/include/pages/password/reset.inc.php b/public/include/pages/password/reset.inc.php index 4e9c18b2..0fa2303d 100644 --- a/public/include/pages/password/reset.inc.php +++ b/public/include/pages/password/reset.inc.php @@ -3,14 +3,8 @@ // Make sure we are called from index.php if (!defined('SECURITY')) die('Hacking attempt'); -// csrf stuff -$csrfenabled = ($config['csrf']['enabled'] && !in_array('passreset', $config['csrf']['disabled_forms'])) ? 1 : 0; -if ($csrfenabled) { - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'resetpass', @$_POST['ctoken'])) ? 1 : 0; -} - // Process password reset request -if (!$csrfenabled || $csrfenabled && $nocsrf) { +if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($user->initResetPassword($_POST['username'], $smarty)) { $_SESSION['POPUP'][] = array('CONTENT' => 'Please check your mail account to finish your password reset', 'TYPE' => 'success'); } else { @@ -20,11 +14,6 @@ if (!$csrfenabled || $csrfenabled && $nocsrf) { $_SESSION['POPUP'][] = array('CONTENT' => $csrftoken->getErrorWithDescriptionHTML(), 'TYPE' => 'info'); } -// csrf token -if ($config['csrf']['enabled'] && !in_array('passreset', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'resetpass'); - $smarty->assign('CTOKEN', $token); -} // Tempalte specifics, user default template by parent page $smarty->assign("CONTENT", "../default.tpl"); ?> diff --git a/public/include/pages/register.inc.php b/public/include/pages/register.inc.php index 487e67cb..15d077fe 100644 --- a/public/include/pages/register.inc.php +++ b/public/include/pages/register.inc.php @@ -14,11 +14,6 @@ if ($setting->getValue('lock_registration') && $setting->getValue('disable_invit require_once(INCLUDE_DIR . '/lib/recaptchalib.php'); $smarty->assign("RECAPTCHA", recaptcha_get_html($setting->getValue('recaptcha_public_key'), null, true)); } - // csrf token - if ($config['csrf']['enabled'] && !in_array('register', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'register'); - $smarty->assign('CTOKEN', $token); - } // Load news entries for Desktop site and unauthenticated users $smarty->assign("CONTENT", "default.tpl"); } diff --git a/public/include/pages/register/register.inc.php b/public/include/pages/register/register.inc.php index ef68fe5f..822e13ea 100644 --- a/public/include/pages/register/register.inc.php +++ b/public/include/pages/register/register.inc.php @@ -17,19 +17,13 @@ if ($setting->getValue('recaptcha_enabled') && $setting->getValue('recaptcha_ena $recaptcha = ($rsp->is_valid) ? 1 : 0; } -// csrf if enabled -$csrfenabled = ($config['csrf']['enabled'] && !in_array('register', $config['csrf']['disabled_forms'])) ? 1 : 0; -if ($csrfenabled) { - $nocsrf = ($csrftoken->checkBasic($user->getCurrentIP(), 'register', @$_POST['ctoken'])) ? 1 : 0; -} - if ($setting->getValue('disable_invitations') && $setting->getValue('lock_registration')) { $_SESSION['POPUP'][] = array('CONTENT' => 'Account registration is currently disabled. Please try again later.', 'TYPE' => 'errormsg'); } else if ($setting->getValue('lock_registration') && !$setting->getValue('disable_invitations') && !isset($_POST['token'])) { $_SESSION['POPUP'][] = array('CONTENT' => 'Only invited users are allowed to register.', 'TYPE' => 'errormsg'); } else { // Check if csrf is enabled and fail if token is invalid - if (!$csrfenabled || $csrfenabled && $nocsrf) { + if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) { if ($setting->getValue('recaptcha_enabled') != 1 || $setting->getValue('recaptcha_enabled_registrations') != 1 || $rsp->is_valid) { // Check if recaptcha is enabled, process form data if valid or disabled isset($_POST['token']) ? $token = $_POST['token'] : $token = ''; @@ -46,9 +40,5 @@ if ($setting->getValue('disable_invitations') && $setting->getValue('lock_regist // We load the default registration template instead of an action specific one $smarty->assign("CONTENT", "../default.tpl"); -// csrf token -if ($config['csrf']['enabled'] && !in_array('register', $config['csrf']['disabled_forms'])) { - $token = $csrftoken->getBasic($user->getCurrentIP(), 'register'); - $smarty->assign('CTOKEN', $token); -} -?> + +?> \ No newline at end of file diff --git a/public/index.php b/public/index.php index 76ed9b72..23d7ae1e 100644 --- a/public/index.php +++ b/public/index.php @@ -81,6 +81,12 @@ if (is_dir(INCLUDE_DIR . '/pages/' . $page)) { // Default to empty (nothing) if nothing set or not known $action = (isset($_REQUEST['action']) && !is_array($_REQUEST['action'])) && isset($arrActions[$_REQUEST['action']]) ? $_REQUEST['action'] : ""; +// Check csrf token validity if necessary +if ($config['csrf']['enabled'] && isset($_POST['ctoken']) && !empty($_POST['ctoken']) && !is_array($_POST['ctoken'])) { + $csrftoken->valid = ($csrftoken->checkBasic($user->getCurrentIP(), $arrPages[$page], $_POST['ctoken'])) ? 1 : 0; +} +if ($config['csrf']['enabled']) $smarty->assign('CTOKEN', $csrftoken->getBasic($user->getCurrentIP(), $arrPages[$page])); + // Load the page code setting the content for the page OR the page action instead if set if (!empty($action)) { $debug->append('Loading Action: ' . $action . ' -> ' . $arrActions[$action], 1); diff --git a/public/templates/mobile/login/default.tpl b/public/templates/mobile/login/default.tpl index f1331892..42df1902 100644 --- a/public/templates/mobile/login/default.tpl +++ b/public/templates/mobile/login/default.tpl @@ -1,6 +1,6 @@
- {if $GLOBAL.csrf.enabled && !"login"|in_array:$GLOBAL.csrf.disabled_forms}{/if} +

{nocache}{$RECAPTCHA|default:"" nofilter}{/nocache}
diff --git a/public/templates/mobile/password/change/default.tpl b/public/templates/mobile/password/change/default.tpl index c547b759..30d5119d 100644 --- a/public/templates/mobile/password/change/default.tpl +++ b/public/templates/mobile/password/change/default.tpl @@ -2,7 +2,7 @@ - {if $GLOBAL.csrf.enabled && !"editaccount"|in_array:$GLOBAL.csrf.disabled_forms}{/if} + diff --git a/public/templates/mobile/password/default.tpl b/public/templates/mobile/password/default.tpl index 8e436b24..9b7128ac 100644 --- a/public/templates/mobile/password/default.tpl +++ b/public/templates/mobile/password/default.tpl @@ -1,7 +1,7 @@ -{if $GLOBAL.csrf.enabled && !"passreset"|in_array:$GLOBAL.csrf.disabled_forms}{/if} +

If you have an email set for your account, enter your username to get your password reset

diff --git a/public/templates/mpos/account/edit/default.tpl b/public/templates/mpos/account/edit/default.tpl index 8b2b1dfc..4b7053f5 100644 --- a/public/templates/mpos/account/edit/default.tpl +++ b/public/templates/mpos/account/edit/default.tpl @@ -56,7 +56,7 @@
New Password:
diff --git a/public/templates/mpos/contactform/contactform/default.tpl b/public/templates/mpos/contactform/contactform/default.tpl index 65928029..97397b74 100644 --- a/public/templates/mpos/contactform/contactform/default.tpl +++ b/public/templates/mpos/contactform/contactform/default.tpl @@ -1,7 +1,7 @@ - {if $GLOBAL.csrf.enabled && !"contact"|in_array:$GLOBAL.csrf.disabled_forms}{/if} +

Contact Us

diff --git a/public/templates/mpos/contactform/default.tpl b/public/templates/mpos/contactform/default.tpl index 46669896..39aa3277 100644 --- a/public/templates/mpos/contactform/default.tpl +++ b/public/templates/mpos/contactform/default.tpl @@ -1,7 +1,7 @@ - {if $GLOBAL.csrf.enabled && !"contact"|in_array:$GLOBAL.csrf.disabled_forms}{/if} +

Contact Us

diff --git a/public/templates/mpos/login/default.tpl b/public/templates/mpos/login/default.tpl index 7af2ef48..b9c8ef56 100644 --- a/public/templates/mpos/login/default.tpl +++ b/public/templates/mpos/login/default.tpl @@ -1,7 +1,7 @@
- {if $GLOBAL.csrf.enabled && !"login"|in_array:$GLOBAL.csrf.disabled_forms}{/if} +

Login with existing account

diff --git a/public/templates/mpos/login/small.tpl b/public/templates/mpos/login/small.tpl index 105b83cb..7ed9b55c 100644 --- a/public/templates/mpos/login/small.tpl +++ b/public/templates/mpos/login/small.tpl @@ -2,7 +2,7 @@
- + {if $node|@count > 1}{/if} From 8fbda49fd1741dfe06b64d225abeea44bda5b17c Mon Sep 17 00:00:00 2001 From: xisi Date: Fri, 24 Jan 2014 16:33:55 -0500 Subject: [PATCH 09/11] Don't even need the suppression --- public/templates/mpos/statistics/uptime/default.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/templates/mpos/statistics/uptime/default.tpl b/public/templates/mpos/statistics/uptime/default.tpl index ab6fd700..faeb50b7 100644 --- a/public/templates/mpos/statistics/uptime/default.tpl +++ b/public/templates/mpos/statistics/uptime/default.tpl @@ -24,7 +24,7 @@ {assign var=node value="."|explode:$item.friendlyname} - {if $node|@count > 1}{/if} + {if $node|count > 1}{/if} From 9e6a2a3beacb9de0bb4a408b71dd9e89878a6531 Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sat, 25 Jan 2014 13:10:38 +0100 Subject: [PATCH 10/11] [FIX] Do not treat disabled notification as error Fixes #1582 once merged. --- cronjobs/payouts.php | 2 +- public/include/classes/notification.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cronjobs/payouts.php b/cronjobs/payouts.php index 87b5e119..0b01e1e6 100755 --- a/cronjobs/payouts.php +++ b/cronjobs/payouts.php @@ -82,7 +82,7 @@ if ($setting->getValue('disable_manual_payouts') != 1) { $aMailData['amount'] = $dBalance - $config['txfee_manual']; $aMailData['payout_id'] = $aData['id']; if (!$notification->sendNotification($aData['account_id'], 'manual_payout', $aMailData)) - $log->logError('Failed to send notification email to users address: ' . $aMailData['email']); + $log->logError('Failed to send notification email to users address ' . $aMailData['email'] . ' : ' . $notification->getCronError); // Recheck the users balance to make sure it is now 0 $aBalance = $transaction->getBalance($aData['account_id']); if ($aBalance['confirmed'] > 0) { diff --git a/public/include/classes/notification.class.php b/public/include/classes/notification.class.php index 3db6acf8..dd467634 100644 --- a/public/include/classes/notification.class.php +++ b/public/include/classes/notification.class.php @@ -148,7 +148,7 @@ class Notification extends Mail { } } else { $this->setErrorMessage('User disabled ' . $strType . ' notifications'); - return false; + return true; } $this->setErrorMessage('Error sending mail notification'); return false; From 643c21d3a71411584738aa3e5c7888ad7f080b9d Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Sat, 25 Jan 2014 21:35:02 +0100 Subject: [PATCH 11/11] [UPDATE] Logfile cleanup * [REMOVED] Do not show row headers at each cron run * [REMOVED] Extra newlines in notification cron --- cronjobs/blockupdate.php | 3 ++- cronjobs/findblock.php | 7 ++++--- cronjobs/notifications.php | 16 ++++++++-------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/cronjobs/blockupdate.php b/cronjobs/blockupdate.php index cc94ccbe..bc5d4913 100755 --- a/cronjobs/blockupdate.php +++ b/cronjobs/blockupdate.php @@ -33,8 +33,9 @@ if ( $bitcoin->can_connect() !== true ) { // Fetch all unconfirmed blocks $aAllBlocks = $block->getAllUnconfirmed(max($config['network_confirmations'],$config['confirmations'])); -$log->logInfo("ID\tHeight\tBlockhash\tConfirmations"); +$header = false; foreach ($aAllBlocks as $iIndex => $aBlock) { + !$header ? $log->logInfo("ID\tHeight\tBlockhash\tConfirmations") : $header = true; $aBlockInfo = $bitcoin->getblock($aBlock['blockhash']); // Fetch this blocks transaction details to find orphan blocks $aTxDetails = $bitcoin->gettransaction($aBlockInfo['tx'][0]); diff --git a/cronjobs/findblock.php b/cronjobs/findblock.php index 18d97899..94a05fde 100755 --- a/cronjobs/findblock.php +++ b/cronjobs/findblock.php @@ -42,12 +42,13 @@ if ( $bitcoin->can_connect() === true ){ if (empty($aTransactions['transactions'])) { $log->logDebug('No new RPC transactions since last block'); } else { - // Table header - $log->logInfo("Blockhash\t\tHeight\tAmount\tConfirmations\tDiff\t\tTime"); - + $header = false; // Let us add those blocks as unaccounted foreach ($aTransactions['transactions'] as $iIndex => $aData) { if ( $aData['category'] == 'generate' || $aData['category'] == 'immature' ) { + // Table header, printe once if we found a block + !$header ? $log->logInfo("Blockhash\t\tHeight\tAmount\tConfirmations\tDiff\t\tTime") : $header = true; + $aBlockRPCInfo = $bitcoin->getblock($aData['blockhash']); $config['reward_type'] == 'block' ? $aData['amount'] = $aData['amount'] : $aData['amount'] = $config['reward']; $aData['height'] = $aBlockRPCInfo['height']; diff --git a/cronjobs/notifications.php b/cronjobs/notifications.php index 1c9dbd3d..7baf5bf1 100755 --- a/cronjobs/notifications.php +++ b/cronjobs/notifications.php @@ -33,9 +33,9 @@ $log->logDebug(" IDLE Worker Notifications ..."); // Find all IDLE workers $aWorkers = $worker->getAllIdleWorkers(); if (empty($aWorkers)) { - $log->logDebug(" no idle workers found\n"); + $log->logDebug(" no idle workers found"); } else { - $log->logInfo(" found " . count($aWorkers) . " IDLE workers\n"); + $log->logInfo(" found " . count($aWorkers) . " IDLE workers"); foreach ($aWorkers as $aWorker) { $aData = $aWorker; $aData['username'] = $user->getUserName($aWorker['account_id']); @@ -44,7 +44,7 @@ if (empty($aWorkers)) { $aData['email'] = $user->getUserEmail($aData['username']); $log->logDebug(" " . $aWorker['username'] . "..."); if (!$notification->sendNotification($aWorker['account_id'], 'idle_worker', $aData)) - $log->logDebug(" Failed sending notifications: " . $notification->getCronError() . "\n"); + $log->logDebug(" Failed sending notifications: " . $notification->getCronError()); } } @@ -53,23 +53,23 @@ $log->logDebug(" Reset IDLE Worker Notifications ..."); // We notified, lets check which recovered $aNotifications = $notification->getAllActive('idle_worker'); if (!empty($aNotifications)) { - $log->logInfo(" found " . count($aNotifications) . " active notification(s)\n"); + $log->logInfo(" found " . count($aNotifications) . " active notification(s)"); foreach ($aNotifications as $aNotification) { $aData = json_decode($aNotification['data'], true); $aWorker = $worker->getWorker($aData['id']); $log->logDebug(" " . $aWorker['username'] . " ..."); if ($aWorker['hashrate'] > 0) { if ($notification->setInactive($aNotification['id'])) { - $log->logDebug(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive\n"); + $log->logDebug(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive"); } else { - $log->logError(" failed to update #" . $aNotification['id'] . " for " . $aWorker['username'] . "\n"); + $log->logError(" failed to update #" . $aNotification['id'] . " for " . $aWorker['username']); } } else { - $log->logDebug(" still inactive\n"); + $log->logDebug(" still inactive"); } } } else { - $log->logDebug(" no active IDLE worker notifications\n"); + $log->logDebug(" no active IDLE worker notifications"); } require_once('cron_end.inc.php');
{$node.1}{$node.1}{$CODES[$item.status]} {$item.log.1.datetime|date_format:"%b %d, %Y %H:%M"}
{$node.1}{$node.1}{$CODES[$item.status]} {$item.log.1.datetime|date_format:"%b %d, %Y %H:%M"}