/www/phpbb.store.php
PHP | 451 lines | 210 code | 77 blank | 164 comment | 51 complexity | 14d44ccfe13de50089c39ded4a1d53f0 MD5 | raw file
- <?php
- /*
- * SimpleID
- *
- * Copyright (C) Kelvin Mo 2007-9
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
- /**
- * Functions for persistent storage via the file system.
- *
- * In general, there are three different sets of data which SimpleID needs
- * to store:
- *
- * - transient data (e.g. OpenID associations, sessions, auto-login)
- * - application data (e.g. salt for form tokens)
- * - user data (e.g. user names, passwords and settings)
- *
- * Prior to version 0.7, both transient data and application data are stored
- * using {@link cache.inc}. From version 0.7, application data are now
- * stored separately from the cache.
- *
- * Prior to version 0.7, user data is only stored in the identity file, to which
- * SimpleID cannot write. This means that if the user wishes to change a setting,
- * he or she will need to edit the identity file manually. Other user settings
- * (e.g. RP preferences) are stored using {@link cache.inc}
- *
- * From version 0.7, user data is stored in two files, one is the identity
- * file, the other is the user store file, which SimpleID can write.
- *
- * @package simpleid
- * @filesource
- */
- /**
- * This variable is a cache of SimpleID's application settings. It is populated
- * progressively as {@link store_get()} is called.
- *
- * @global array $simpleid_settings
- */
- $simpleid_settings = array();
- function _clean_username($uid) {
- return trim(strtolower($uid));
- }
- /**
- * Returns whether the user name exists in the user store.
- *
- * @param string $uid the name of the user to check
- * @return bool whether the user name exists
- */
- function store_user_exists($uid) {
- $clean_uid = _clean_username($uid);
- if (_store_is_valid_name($clean_uid)) {
- $q = _store_phpbb_sock()->prepare("SELECT COUNT(*) FROM phpbb_users JOIN phpbb_user_group ON (phpbb_users.user_id = phpbb_user_group.user_id) JOIN phpbb_groups ON (phpbb_user_group.group_id = phpbb_groups.group_id) WHERE (group_name = 'Celostatni forum' or group_name = 'Registrovani priznivci') AND username_clean = ? AND user_type=0");
- $q->execute(array($clean_uid));
- return ( $q->fetchColumn() > 0);
- } else {
- return false;
- }
- }
- /**
- * Loads user data for a specified user name.
- *
- * The user name must exist. You should check whether the user name exists with
- * the {@link store_user_exists()} function
- *
- * @param string $uid the name of the user to load
- * @return mixed data for the specified user
- */
- function store_user_load($uid) {
- $clean_uid = _clean_username($uid);
- if (!store_user_exists($uid)) return array();
- $q = _store_phpbb_sock()->prepare("SELECT username as nickname, CONCAT(REPLACE(LOWER(username_clean),' ','.'),'@pirati.cz') as email,user_lang as language, phpbb_profile_fields_data.pf_fullname as fullname, user_birthday as dob FROM phpbb_users JOIN phpbb_profile_fields_data ON (phpbb_users.user_id = phpbb_profile_fields_data.user_id)JOIN phpbb_user_group ON (phpbb_users.user_id = phpbb_user_group.user_id) JOIN phpbb_groups ON (phpbb_user_group.group_id = phpbb_groups.group_id) WHERE (group_name = 'Celostatni forum' or group_name = 'Registrovani priznivci') AND username_clean = ? AND user_type=0");
- $q->execute(array($clean_uid));
- $sreg = $q->fetch(PDO::FETCH_ASSOC);
- $uid = $sreg['nickname'];
- $store_file = SIMPLEID_STORE_DIR . "/$uid.usrstore";
- if (file_exists($store_file)) {
- $data = unserialize(file_get_contents($store_file));
- } else {
- $data = array();
- }
- $data['sreg'] = $sreg;
- $data['identity'] = preg_replace('/^https/','https', simpleid_url("user/" . rawurlencode($data['sreg']['nickname'])));
- if (preg_match('/^\s*(\d+)\s*-\s*(\d+)\s*-(\d+)$/', $data['sreg']['dob'], $m)) {
- $data['sreg']['dob'] = sprintf("%04d-%02d-%02d", $m[3], $m[2], $m[1]);
- } else {
- unset($data['sreg']['dob']);
- }
- $data['sreg']['fullname'] = html_entity_decode($data['sreg']['fullname']);
- $data['uid'] = $uid;
- return $data;
- }
- /**
- * Returns the time which a user's data has been updated.
- *
- * The user name must exist. You should check whether the user name exists with
- * the {@link store_user_exists()} function.
- *
- * The time returned can be based on the identity file,
- * the user store file, or the latter of the two.
- *
- * @param string $uid the name of the user to obtain the update time
- * @param string $type one of: 'identity' (identity file), 'usrstore' (user store
- * file) or NULL (latter of the two)
- * @return int the updated time
- */
- function store_user_updated_time($uid, $type = NULL) {
- $clean_uid = _clean_username($uid);
- if (!_store_is_valid_name($uid)) return NULL;
- $q = _store_phpbb_sock()->prepare("SELECT user_passchg FROM phpbb_users WHERE username_clean = ? AND user_type=0");
- $q->execute(array($clean_uid));
- $identity_time = $q->fetchColumn();
- $store_file = SIMPLEID_STORE_DIR . "/$uid.usrstore";
- if (file_exists($store_file)) {
- $store_time = filemtime($store_file);
- } else {
- $store_time = NULL;
- }
- if ($type == 'identity') {
- return $identity_time;
- } elseif ($type == 'usrstore') {
- return $store_time;
- } elseif ($type == NULL) {
- return ($identity_time > $store_time) ? $identity_time : $store_time;
- } else {
- return NULL;
- }
- }
- /**
- * Finds the user name from a specified OpenID Identity URI.
- *
- * @param string $identity the Identity URI of the user to load
- * @return string the user name for the Identity URI, or NULL if no user has
- * the specified Identity URI
- */
- function store_get_uid($identity) {
- $r = NULL;
- if (!preg_match('/\/([a-zA-Z .]+)$/', rawurldecode(parse_url($identity, PHP_URL_PATH)), $m))
- return NULL;
- if (preg_replace('/^https/','https', simpleid_url("user/" . rawurlencode($m[1]))) !== $identity)
- return NULL;
- return $m[1];
- }
- /**
- * Finds the user name from a specified client SSL certificate string.
- *
- * The client SSL certificate string comprises the certificate's serial number
- * (in capitals hex notation) and the distinguished name of the certificate's issuer
- * (with components joined using slashes), joined using a semi-colon.
- *
- *
- * @param string $cert the client SSL certificate string of the user to load
- * @return string the user name matching the client SSL certificate string, or NULL if no user has
- * client SSL certificate string
- */
- function store_get_uid_from_cert($cert) {
- return NULL;
- }
- /**
- * Saves user data for a specific user name.
- *
- * This data is stored in the user store file.
- *
- * @param string $uid the name of the user
- * @param array $data the data to save
- * @param array $exclude an array of keys to exclude from the user store file.
- * These are generally keys which are stored in the identity file.
- *
- * @since 0.7
- */
- function store_user_save($uid, $data, $exclude = array()) {
- //$uid = _clean_username($uid);
- foreach ($exclude as $key) {
- if (isset($data[$key])) unset($data[$key]);
- }
- if (!_store_is_valid_name($uid)) {
- trigger_error("Invalid user name for filesystem store", E_USER_ERROR);
- return;
- }
- $store_file = SIMPLEID_STORE_DIR . "/$uid.usrstore";
- $file = fopen($store_file, 'w');
- fwrite($file, serialize($data));
- fclose($file);
- }
- /**
- * Loads an application setting.
- *
- * @param string $name the name of the setting to return
- * @param mixed $default the default value to use if this variable has never been set
- * @return mixed the value of the setting
- *
- */
- function store_get($name, $default = NULL) {
- global $simpleid_settings;
- if (!_store_is_valid_name($name)) return $default;
- if (!isset($simpleid_settings[$name])) {
- $setting_file = SIMPLEID_STORE_DIR . "/$name.setting";
- if (file_exists($setting_file)) {
- $simpleid_settings[$name] = unserialize(file_get_contents($setting_file));
- } else {
- return $default;
- }
- }
- return $simpleid_settings[$name];
- }
- /**
- * Saves an application setting.
- *
- * @param string $name the name of the setting to save
- * @param mixed $value the value of the setting
- *
- */
- function store_set($name, $value) {
- global $simpleid_settings;
- if (!_store_is_valid_name($name)) {
- trigger_error("Invalid setting name for filesystem store", E_USER_ERROR);
- return;
- }
- $simpleid_settings[$name] = $value;
- $setting_file = SIMPLEID_STORE_DIR . "/$name.setting";
- $file = fopen($setting_file, 'w');
- fwrite($file, serialize($value));
- fclose($file);
- }
- /**
- * Deletes an application setting.
- *
- * @param string $name the name of the setting to delete
- *
- */
- function store_del($name) {
- global $simpleid_settings;
- if (!_store_is_valid_name($name)) {
- trigger_error("Invalid setting name for filesystem store", E_USER_ERROR);
- return;
- }
- if (isset($simpleid_settings[$name])) unset($simpleid_settings[$name]);
- $setting_file = SIMPLEID_STORE_DIR . "/$name.setting";
- if (file_exists($setting_file)) unlink($setting_file);
- }
- function store_user_verify_credentials($uid, $credentials)
- {
- $clean_uid = _clean_username($uid);
- $q = _store_phpbb_sock()->prepare("SELECT user_password FROM phpbb_users JOIN phpbb_user_group ON (phpbb_users.user_id = phpbb_user_group.user_id) JOIN phpbb_groups ON (phpbb_user_group.group_id = phpbb_groups.group_id) WHERE (group_name = 'Celostatni forum' or group_name = 'Registrovani priznivci') AND username_clean = ? AND user_type=0");
- $q->execute(array($clean_uid));
- if (!($hash = $q->fetchColumn())) {
- return false;
- }
- if (strlen($hash) != 34) {
- return false;
- }
- $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
- return (_phpbb_hash_crypt_private($credentials['pass'], $hash, $itoa64) === $hash) ? true : false;
- }
- /**
- * Determines whether a name is a valid name for use with this store.
- *
- * For file system storage, a name is not valid if it contains either a
- * directory separator (i.e. / or \).
- *
- * @param string $name the name to check
- * @return boolean whether the name is valid for use with this store
- *
- */
- function _store_is_valid_name($name) {
- return preg_match('!\A[^/\\\\]*\z!', $name);
- }
- function _store_phpbb_sock() {
- $arr = parse_ini_file(__DIR__."/../config/phpbb.store.ini");
- $dsn = "mysql:host=".$arr['dbhost'].";dbname=".$arr['dbbase'].";charset=utf8";
- static $sock = null;
- if ($sock === null) {
- $sock = new PDO($dsn, $arr['dbuser'], $arr['dbpass'], array(
- PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
- PDO::ATTR_PERSISTENT => true,
- ));
- }
- return $sock;
- }
- /**
- * The crypt function/replacement
- * @copyright (c) 2005 phpBB Group
- * @license http://opensource.org/licenses/gpl-license.php GNU Public License
- *
- */
- function _phpbb_hash_crypt_private($password, $setting, &$itoa64)
- {
- $output = '*';
- // Check for correct hash
- if (substr($setting, 0, 3) != '$H$' && substr($setting, 0, 3) != '$P$') {
- return $output;
- }
- $count_log2 = strpos($itoa64, $setting[3]);
- if ($count_log2 < 7 || $count_log2 > 30) {
- return $output;
- }
- $count = 1 << $count_log2;
- $salt = substr($setting, 4, 8);
- if (strlen($salt) != 8) {
- return $output;
- }
- /**
- * We're kind of forced to use MD5 here since it's the only
- * cryptographic primitive available in all versions of PHP
- * currently in use. To implement our own low-level crypto
- * in PHP would result in much worse performance and
- * consequently in lower iteration counts and hashes that are
- * quicker to crack (by non-PHP code).
- */
- if (PHP_VERSION >= 5) {
- $hash = md5($salt . $password, true);
- do {
- $hash = md5($hash . $password, true);
- } while (--$count);
- } else {
- $hash = pack('H*', md5($salt . $password));
- do {
- $hash = pack('H*', md5($hash . $password));
- } while (--$count);
- }
- $output = substr($setting, 0, 12);
- $output .= _phpbb_hash_encode64($hash, 16, $itoa64);
- return $output;
- }
- /**
- * Encode hash
- * * @copyright (c) 2005 phpBB Group
- * @license http://opensource.org/licenses/gpl-license.php GNU Public License
- */
- function _phpbb_hash_encode64($input, $count, &$itoa64)
- {
- $output = '';
- $i = 0;
- do
- {
- $value = ord($input[$i++]);
- $output .= $itoa64[$value & 0x3f];
- if ($i < $count)
- {
- $value |= ord($input[$i]) << 8;
- }
- $output .= $itoa64[($value >> 6) & 0x3f];
- if ($i++ >= $count)
- {
- break;
- }
- if ($i < $count)
- {
- $value |= ord($input[$i]) << 16;
- }
- $output .= $itoa64[($value >> 12) & 0x3f];
- if ($i++ >= $count)
- {
- break;
- }
- $output .= $itoa64[($value >> 18) & 0x3f];
- }
- while ($i < $count);
- return $output;
- }