/** * A static method for processing preference values from a UI form, and * updating the preference values in the database. * * @static * @param array $aElementNames An array of HTML form element names, which * are also the preference value names. * @param array $aCheckboxes An array of the above HTML form element * names which are checkboxes, as these will not * be set in the form POST if unchecked, and * so need to be treated differently. * @return boolean True on success, false otherwise. */ function processPreferencesFromForm($aElementNames, $aCheckboxes) { phpAds_registerGlobalUnslashed('token'); if (!phpAds_SessionValidateToken($GLOBALS['token'])) { return false; } // Get all of the preference types that exist $aPreferenceTypes = array(); $doPreferences = OA_Dal::factoryDO('preferences'); $doPreferences->find(); if ($doPreferences->getRowCount() < 1) { return false; } while ($doPreferences->fetch()) { $aPreference = $doPreferences->toArray(); $aPreferenceTypes[$aPreference['preference_name']] = array('preference_id' => $aPreference['preference_id'], 'account_type' => $aPreference['account_type']); } // Are there any preference types in the system? if (empty($aPreferenceTypes)) { return false; } // Get the type of the current accout $currentAccountType = OA_Permission::getAccountType(); // Get the current account's ID $currentAccountId = OA_Permission::getAccountId(); // Get the parent account preferences $aParentPreferences = OA_Preferences::loadPreferences(false, true, true); // Prepare the preference values that should be saved or deleted $aSavePreferences = array(); $aDeletePreferences = array(); foreach ($aElementNames as $preferenceName) { // Ensure that the current account has permission to process // the preference type $access = OA_Preferences::hasAccess($currentAccountType, $aPreferenceTypes[$preferenceName]['account_type']); if ($access == false) { // Don't process this value continue; } // Register the HTML element value phpAds_registerGlobalUnslashed($preferenceName); // Is the HTML element value a checkbox, and unset? if (isset($aCheckboxes[$preferenceName]) && !isset($GLOBALS[$preferenceName])) { // Set the value of the element to the false string "" $GLOBALS[$preferenceName] = ''; } else { if (isset($aCheckboxes[$preferenceName]) && $GLOBALS[$preferenceName]) { // Set the value of the element to the true string "1" $GLOBALS[$preferenceName] = '1'; } } // Was the HTML element value set? if (isset($GLOBALS[$preferenceName])) { // Is the preference value different from the parent value? if (!isset($aParentPreferences[$preferenceName]) || $GLOBALS[$preferenceName] != $aParentPreferences[$preferenceName]) { // The preference value is different from the parent, so it // needs to be stored $aSavePreferences[$preferenceName] = $GLOBALS[$preferenceName]; } else { if ($currentAccountType != OA_ACCOUNT_ADMIN) { // The preference value is not different from the parent, so // it should be deleted if not the admin account (in case it // exists for the account, and so would not inherit correctly // if the admin account changes preferences) $aDeletePreferences[$preferenceName] = $GLOBALS[$preferenceName]; } } } } // Save the required preferences foreach ($aSavePreferences as $preferenceName => $preferenceValue) { $doAccount_preference_assoc = OA_Dal::factoryDO('account_preference_assoc'); $doAccount_preference_assoc->account_id = $currentAccountId; $doAccount_preference_assoc->preference_id = $aPreferenceTypes[$preferenceName]['preference_id']; $doAccount_preference_assoc->find(); if ($doAccount_preference_assoc->getRowCount() != 1) { // Insert the preference $doAccount_preference_assoc->value = $preferenceValue; $result = $doAccount_preference_assoc->insert(); if ($result === false) { return false; } } else { // Update the preference $doAccount_preference_assoc->fetch(); $doAccount_preference_assoc->value = $preferenceValue; $result = $doAccount_preference_assoc->update(); if ($result === false) { return false; } } } // Delete the required preferences foreach ($aDeletePreferences as $preferenceName => $preferenceValue) { $doAccount_preference_assoc = OA_Dal::factoryDO('account_preference_assoc'); $doAccount_preference_assoc->account_id = $currentAccountId; $doAccount_preference_assoc->preference_id = $aPreferenceTypes[$preferenceName]['preference_id']; $doAccount_preference_assoc->find(); if ($doAccount_preference_assoc->getRowCount() == 1) { // Delete the preference $result = $doAccount_preference_assoc->delete(); if ($result === false) { return false; } } } return true; }
/** * Validates user data - required for linking new users * * @param string $login * @param string $password * @return array Array containing error strings or empty * array if no validation errors were found */ function validateUsersData($data) { if (empty($data['userid'])) { $this->validateUsersLogin($data['login']); $this->validateUsersPasswords($data['passwd'], $data['passwd2']); $this->validateUsersPassword($data['passwd']); } $this->validateUsersEmail($data['email_address']); if (!phpAds_SessionValidateToken($data['token'])) { $this->addValidationError('Invalid request token'); } return $this->getValidationErrors(); }
/** * CVE-2013-5954 * * Helper method which checks if the correct session token is present * when CRUD actions (generally deletes) are performed using a GET instead * of a POST (for historical reasons). Allows the CSRF vulnerabilities * reported in CVE-2013-5954 to be closed off without the required (and * eventually needed) refactoring of the enture UI to a proper MVC * framework. */ public static function checkSessionToken() { $token = isset($_GET['token']) ? $_GET['token'] : false; OA_Permission::enforceTrue(phpAds_SessionValidateToken($token)); }
/** * check uploaded file * check file contents * unpack file contents * * @param array $aFile * @return boolean */ function unpackPlugin($aFile, $overwrite = true, $checkOnly = false) { //OA::logMem('enter unpackPlugin'); $this->_switchToPluginLog(); try { phpAds_registerGlobalUnslashed('token'); if (OA_INSTALLATION_STATUS == OA_INSTALLATION_STATUS_INSTALLED && !phpAds_SessionValidateToken($GLOBALS['token'])) { throw new Exception('Invalid request token'); } if ($this->configLocked) { throw new Exception('Configuration file is locked unable to unpack' . $aFile['name']); } if (!@file_exists($aFile['tmp_name'])) { throw new Exception('Failed to read the uploaded file'); } if (!$this->_unpack($aFile, $overwrite, $checkOnly)) { throw new Exception('The uploaded file ' . $aFile['name'] . ' was not unpacked'); } $result = true; } catch (Exception $e) { $this->_logError($e->getMessage()); $result = false; } //OA::logMem('exit unpackPlugin'); $this->_switchToDefaultLog(); return $result; }
/** * CVE-2013-5954 * * Helper method which checks if the correct session token is present * when CRUD actions (generally deletes) are performed using a GET instead * of a POST (for historical reasons). Allows the CSRF vulnerabilities * reported in CVE-2013-5954 to be closed off without the required (and * eventually needed) refactoring of the enture UI to a proper MVC * framework. */ public static function checkSessionToken() { if ($_SERVER['REQUEST_METHOD'] == 'POST') { $token = isset($_POST['token']) ? $_POST['token'] : false; } else { $token = isset($_GET['token']) ? $_GET['token'] : false; } OA_Permission::enforceTrue(phpAds_SessionValidateToken($token)); }
/** * A method for processing settings values from a UI form, and updating the settings * values in the configuration file. * * @param array $aElements An array of arrays, indexed by the HTML form element names, * and then the top level configuration file item, containing * the configuration file key. * * The inner array can also contain the fixed keys "preg_match" * and "preg_replace", and the values will be used as a preg * pattern on the actual value. * * The inner array can also contain the fixed key "bool", in * which case the value will be treated as a true/false * element from the HTML form. * * The inner array can also contain the fixed keys "preg_split" * and "merge", and the preg_split value will be used to split * the actual value into an array, and then remove any empty * values from the result, and then the resulting array will be * merged with the merge value, and stored. The "merge_unique" * value can also be set to true, in which case only unique * values will be stored from the split array values. * * For example: * array( * delivery_cacheExpire => array( * delivery => acls * preg_match => #/$# * preg_replace => * ) * ) * * This array would store the value from the "delivery_cacheExpire" HTML form element * in the configuration file under the [delivery] section, acls key; but the value stored * would have the "/" character, if it existed, removed from the end of the string value * stored. * * @return boolean True if the configuration file was saved correctly, false otherwise. */ function processSettingsFromForm($aElementNames) { phpAds_registerGlobalUnslashed('token'); if (!phpAds_SessionValidateToken($GLOBALS['token'])) { return false; } foreach ($aElementNames as $htmlElement => $aConfigInfo) { // Register the HTML element value MAX_commonRegisterGlobalsArray(array($htmlElement)); // Was the HTML element value set? if (isset($GLOBALS[$htmlElement])) { reset($aConfigInfo); if (isset($aConfigInfo['preg_match'])) { $preg_match = $aConfigInfo['preg_match']; unset($aConfigInfo['preg_match']); } if (isset($aConfigInfo['preg_replace'])) { $preg_replace = $aConfigInfo['preg_replace']; unset($aConfigInfo['preg_replace']); } $value = stripslashes($GLOBALS[$htmlElement]); if (isset($preg_match) && isset($preg_replace)) { $value = preg_replace($preg_match, $preg_replace, $value); } unset($preg_match); unset($preg_replace); if (isset($aConfigInfo['bool'])) { $value = 'true'; } if (!empty($aConfigInfo['trim'])) { $value = trim($value); } unset($aConfigInfo['bool']); if (isset($aConfigInfo['preg_split']) && isset($aConfigInfo['merge'])) { $pregSplit = $aConfigInfo['preg_split']; $merge = $aConfigInfo['merge']; $mergeUnique = false; if ($aConfigInfo['merge_unique']) { $mergeUnique = true; } unset($aConfigInfo['preg_split']); unset($aConfigInfo['merge']); unset($aConfigInfo['merge_unique']); foreach ($aConfigInfo as $levelKey => $itemKey) { $aValues = preg_split($pregSplit, $value); if ($mergeUnique) { $aValues = array_unique($aValues); } if (!empty($aConfigInfo['trim'])) { array_walk($aValues, 'trim'); } $aEmptyKeys = array_keys($aValues, ''); $counter = -1; foreach ($aEmptyKeys as $key) { $counter++; array_splice($aValues, $key - $counter, 1); } $value = implode($merge, $aValues); $this->settingChange($levelKey, $itemKey, $value); } } else { unset($aConfigInfo['preg_split']); unset($aConfigInfo['merge']); unset($aConfigInfo['merge_unique']); foreach ($aConfigInfo as $levelKey => $itemKey) { $this->settingChange($levelKey, $itemKey, $value); } } } else { // The element may required "false" to be stored if (isset($aConfigInfo['bool'])) { unset($aConfigInfo['bool']); foreach ($aConfigInfo as $levelKey => $itemKey) { $this->settingChange($levelKey, $itemKey, 'false'); } } } } $writeResult = $this->writeConfigChange(); return $writeResult; }