if (!isset($_USER['theme'])) { $_USER['theme'] = $_CONF['theme']; $_CONF['path_layout'] = $_CONF['path_themes'] . $_USER['theme'] . '/'; $_CONF['layout_url'] = $_CONF['site_url'] . '/layout/' . $_USER['theme']; if ($_CONF['allow_user_themes'] == 1) { if (isset($_COOKIE[$_CONF['cookie_theme']])) { $theme = COM_sanitizeFilename($_COOKIE[$_CONF['cookie_theme']], true); if (is_dir($_CONF['path_themes'] . $theme)) { $_USER['theme'] = $theme; $_CONF['path_layout'] = $_CONF['path_themes'] . $theme . '/'; $_CONF['layout_url'] = $_CONF['site_url'] . '/layout/' . $theme; } } } } COM_resetSpeedlimit('login'); // we are now fully logged in, let's see if there is someplace we need to go.... if (SESS_isSet('login_referer')) { $_SERVER['HTTP_REFERER'] = SESS_getVar('login_referer'); SESS_unSet('login_referer'); } if (!empty($_SERVER['HTTP_REFERER']) && strstr($_SERVER['HTTP_REFERER'], '/users.php') === false && substr($_SERVER['HTTP_REFERER'], 0, strlen($_CONF['site_url'])) == $_CONF['site_url']) { $indexMsg = $_CONF['site_url'] . '/index.php?msg='; if (substr($_SERVER['HTTP_REFERER'], 0, strlen($indexMsg)) == $indexMsg) { echo COM_refresh($_CONF['site_url'] . '/index.php'); } else { // If user is trying to login - force redirect to index.php if (strstr($_SERVER['HTTP_REFERER'], 'mode=login') === false) { // if article - we need to ensure we have the story if (substr($_SERVER['HTTP_REFERER'], 0, strlen($_CONF['site_url'])) == $_CONF['site_url']) { echo COM_refresh(COM_sanitizeUrl($_SERVER['HTTP_REFERER']));
/** * Authenticates the user if authentication headers are present * * Our handling of the speedlimit here requires some explanation ... * Atompub clients will usually try to do everything without logging in first. * Since that would mean that we can't provide feeds for drafts, items with * special permissions, etc. we ask them to log in (PLG_RET_AUTH_FAILED). * That, however, means that every request from an Atompub client will count * as one failed login attempt. So doing a couple of requests in quick * succession will surely get the client blocked. Therefore * - a request without any login credentials counts as one failed login attempt * - a request with wrong login credentials counts as two failed login attempts * - if, after a successful login, we have only one failed attempt on record, * we reset the speedlimit * This still ensures that * - repeated failed logins (without or with invalid credentials) will cause the * client to be blocked eventually * - this can not be used for dictionary attacks * */ function WS_authenticate() { global $_CONF, $_TABLES, $_USER, $_GROUPS, $_RIGHTS, $WS_VERBOSE; $uid = ''; $username = ''; $password = ''; $status = -1; if (isset($_SERVER['PHP_AUTH_USER'])) { $username = COM_applyBasicFilter($_SERVER['PHP_AUTH_USER']); $password = $_SERVER['PHP_AUTH_PW']; if ($WS_VERBOSE) { COM_errorLog("WS: Attempting to log in user '{$username}'"); } /** this does not work! ******************************************************* } elseif (!empty($_SERVER['HTTP_X_WSSE']) && (strpos($_SERVER['HTTP_X_WSSE'], 'UsernameToken') !== false)) { // this is loosely based on a code snippet taken from Elgg (elgg.org) $wsse = str_replace('UsernameToken', '', $_SERVER['HTTP_X_WSSE']); $wsse = explode(',', $wsse); $username = ''; $pwdigest = ''; $created = ''; $nonce = ''; foreach ($wsse as $element) { $element = explode('=', $element); $key = array_shift($element); if (count($element) == 1) { $val = $element[0]; } else { $val = implode('=', $element); } $key = trim($key); $val = trim($val, "\x22\x27"); if ($key == 'Username') { $username = COM_applyBasicFilter($val); } elseif ($key == 'PasswordDigest') { $pwdigest = $val; } elseif ($key == 'Created') { $created = $val; } elseif ($key == 'Nonce') { $nonce = $val; } } if (!empty($username) && !empty($pwdigest) && !empty($created) && !empty($nonce)) { $uname = DB_escapeString($username); $pwd = DB_getItem($_TABLES['users'], 'passwd', "username = '******'"); // ... and here we would need the _unencrypted_ password if (!empty($pwd)) { $mydigest = pack('H*', sha1($nonce . $created . $pwd)); $mydigest = base64_encode($mydigest); if ($pwdigest == $mydigest) { $password = $pwd; } } } if ($WS_VERBOSE) { COM_errorLog("WS: Attempting to log in user '$username' (via WSSE)"); } ******************************************************************************/ } elseif (!empty($_SERVER['REMOTE_USER'])) { /* PHP installed as CGI may not have access to authorization headers of * Apache. In that case, use .htaccess to store the auth header as * explained at * http://wiki.geeklog.net/wiki/index.php/Webservices_API#Authentication */ list($auth_type, $auth_data) = explode(' ', $_SERVER['REMOTE_USER']); list($username, $password) = explode(':', base64_decode($auth_data)); $username = COM_applyBasicFilter($username); if ($WS_VERBOSE) { COM_errorLog("WS: Attempting to log in user '{$username}' (via \$_SERVER['REMOTE_USER'])"); } } else { if ($WS_VERBOSE) { COM_errorLog("WS: No login given"); } // fallthrough (see below) } COM_clearSpeedlimit($_CONF['login_speedlimit'], 'wsauth'); if (COM_checkSpeedlimit('wsauth', $_CONF['login_attempts']) > 0) { WS_error(PLG_RET_PERMISSION_DENIED, 'Speed Limit exceeded'); } if (!empty($username) && !empty($password)) { if ($_CONF['user_login_method']['3rdparty']) { // remote users will have to use username@servicename $u = explode('@', $username); if (count($u) > 1) { $sv = $u[count($u) - 1]; if (!empty($sv)) { $modules = SEC_collectRemoteAuthenticationModules(); foreach ($modules as $smod) { if (strcasecmp($sv, $smod) == 0) { array_pop($u); // drop the service name $uname = implode('@', $u); $status = SEC_remoteAuthentication($uname, $password, $smod, $uid); break; } } } } } if ($status == -1 && $_CONF['user_login_method']['standard']) { $status = SEC_authenticate($username, $password, $uid); } } if ($status == USER_ACCOUNT_ACTIVE) { $_USER = SESS_getUserDataFromId($uid); PLG_loginUser($_USER['uid']); // Global array of groups current user belongs to $_GROUPS = SEC_getUserGroups($_USER['uid']); // Global array of current user permissions [read,edit] $_RIGHTS = explode(',', SEC_getUserPermissions()); if ($_CONF['restrict_webservices']) { if (!SEC_hasRights('webservices.atompub')) { COM_updateSpeedlimit('wsauth'); if ($WS_VERBOSE) { COM_errorLog("WS: User '{$_USER['username']}' ({$_USER['uid']}) does not have permission to use the webservices"); } // reset user, groups, and rights, just in case ... $_USER = array(); $_GROUPS = array(); $_RIGHTS = array(); WS_error(PLG_RET_AUTH_FAILED); } } if ($WS_VERBOSE) { COM_errorLog("WS: User '{$_USER['username']}' ({$_USER['uid']}) successfully logged in"); } // if there were less than 2 failed login attempts, reset speedlimit if (COM_checkSpeedlimit('wsauth', 2) == 0) { if ($WS_VERBOSE) { COM_errorLog("WS: Successful login - resetting speedlimit"); } COM_resetSpeedlimit('wsauth'); } } else { COM_updateSpeedlimit('wsauth'); if (!empty($username) && !empty($password)) { COM_updateSpeedlimit('wsauth'); if ($WS_VERBOSE) { COM_errorLog("WS: Wrong login credentials - counting as 2 failed attempts"); } } elseif ($WS_VERBOSE) { COM_errorLog("WS: Empty login credentials - counting as 1 failed attempt"); } WS_error(PLG_RET_AUTH_FAILED); } }
/** * Authenticates the user if authentication headers are present * * Our handling of the speedlimit here requires some explanation ... * Atompub clients will usually try to do everything without logging in first. * Since that would mean that we can't provide feeds for drafts, items with * special permissions, etc. we ask them to log in (PLG_RET_AUTH_FAILED). * That, however, means that every request from an Atompub client will count * as one failed login attempt. So doing a couple of requests in quick * succession will surely get the client blocked. Therefore * - a request without any login credentials counts as one failed login attempt * - a request with wrong login credentials counts as two failed login attempts * - if, after a successful login, we have only one failed attempt on record, * we reset the speedlimit * This still ensures that * - repeated failed logins (without or with invalid credentials) will cause the * client to be blocked eventually * - this can not be used for dictionary attacks * */ function WS_authenticate() { global $_CONF, $_TABLES, $_USER, $_GROUPS, $_RIGHTS, $WS_VERBOSE; $uid = ''; $username = ''; $password = ''; $status = -1; if (isset($_SERVER['PHP_AUTH_USER'])) { $username = $_SERVER['PHP_AUTH_USER']; $password = $_SERVER['PHP_AUTH_PW']; $username = COM_applyFilter($username); $password = COM_applyFilter($password); if ($WS_VERBOSE) { COM_errorLog("WS: Attempting to log in user '{$username}'"); } } elseif (!empty($_SERVER['REMOTE_USER'])) { /* PHP installed as CGI may not have access to authorization headers of * Apache. In that case, use .htaccess to store the auth header */ list($auth_type, $auth_data) = explode(' ', $_SERVER['REMOTE_USER']); list($username, $password) = explode(':', base64_decode($auth_data)); $username = COM_applyFilter($username); $password = COM_applyFilter($password); if ($WS_VERBOSE) { COM_errorLog("WS: Attempting to log in user '{$username}' (via \$_SERVER['REMOTE_USER'])"); } } else { if ($WS_VERBOSE) { COM_errorLog("WS: No login given"); } // fallthrough (see below) } COM_clearSpeedlimit($_CONF['login_speedlimit'], 'wsauth'); if (COM_checkSpeedlimit('wsauth', $_CONF['login_attempts']) > 0) { WS_error(PLG_RET_PERMISSION_DENIED, 'Speed Limit exceeded'); } if (!empty($username) && !empty($password)) { if ($_CONF['user_login_method']['3rdparty']) { // remote users will have to use username@servicename $u = explode('@', $username); if (count($u) > 1) { $sv = $u[count($u) - 1]; if (!empty($sv)) { $modules = SEC_collectRemoteAuthenticationModules(); foreach ($modules as $smod) { if (strcasecmp($sv, $smod) == 0) { array_pop($u); // drop the service name $uname = implode('@', $u); $status = SEC_remoteAuthentication($uname, $password, $smod, $uid); break; } } } } } if ($status == -1 && $_CONF['user_login_method']['standard']) { $status = SEC_authenticate($username, $password, $uid); } } if ($status == USER_ACCOUNT_ACTIVE) { $_USER = SESS_getUserDataFromId($uid); PLG_loginUser($_USER['uid']); // Global array of groups current user belongs to $_GROUPS = SEC_getUserGroups($_USER['uid']); // Global array of current user permissions [read,edit] $_RIGHTS = explode(',', SEC_getUserPermissions()); if ($_CONF['restrict_webservices']) { if (!SEC_hasRights('webservices.atompub')) { COM_updateSpeedlimit('wsauth'); if ($WS_VERBOSE) { COM_errorLog("WS: User '{$_USER['username']}' ({$_USER['uid']}) does not have permission to use the webservices"); } // reset user, groups, and rights, just in case ... $_USER = array(); $_GROUPS = array(); $_RIGHTS = array(); WS_error(PLG_RET_AUTH_FAILED); } } if ($WS_VERBOSE) { COM_errorLog("WS: User '{$_USER['username']}' ({$_USER['uid']}) successfully logged in"); } // if there were less than 2 failed login attempts, reset speedlimit if (COM_checkSpeedlimit('wsauth', 2) == 0) { if ($WS_VERBOSE) { COM_errorLog("WS: Successful login - resetting speedlimit"); } COM_resetSpeedlimit('wsauth'); } } else { COM_updateSpeedlimit('wsauth'); if (!empty($username) && !empty($password)) { COM_updateSpeedlimit('wsauth'); if ($WS_VERBOSE) { COM_errorLog("WS: Wrong login credentials - counting as 2 failed attempts"); } } elseif ($WS_VERBOSE) { COM_errorLog("WS: Empty login credentials - counting as 1 failed attempt"); } WS_error(PLG_RET_AUTH_FAILED); } }
} $getdata = ''; if (isset($_POST['token_getdata'])) { $getdata = urldecode($_POST['token_getdata']); } $filedata = ''; if (isset($_POST['token_filedata'])) { $filedata = urldecode($_POST['token_filedata']); } $display = COM_siteHeader('menu'); $display .= SEC_reauthform($destination, $LANG20[9], $method, $postdata, $getdata, $filedata); $display .= COM_siteFooter(); echo $display; exit; } COM_resetSpeedlimit('login', $_SERVER['REMOTE_ADDR']); if ($_SYSTEM['admin_session'] != 0) { $token = SEC_createTokenGeneral('administration', $_SYSTEM['admin_session']); SEC_setCookie('token', $token, 0, $_CONF['cookie_path'], $_CONF['cookiedomain'], $_CONF['cookiesecure'], true); } if ($currentUID != $_USER['uid']) { // remove tokens for previous user if ($currentUID > 1) { DB_delete($_TABLES['tokens'], 'owner_id', (int) $currentUID); } echo COM_refresh($destination); exit; } $method = ''; if (isset($_POST['token_requestmethod'])) { $method = COM_applyFilter($_POST['token_requestmethod']);
/** * Merge User Accounts * * This validates the entered password and then merges a remote * account with a local account. * * @return string HTML merge form if error, redirect on success * */ function USER_mergeAccounts() { global $_CONF, $_SYSTEM, $_TABLES, $_USER, $LANG04, $LANG12, $LANG20; $retval = ''; $remoteUID = COM_applyFilter($_POST['remoteuid'], true); $localUID = COM_applyFilter($_POST['localuid'], true); $localpwd = $_POST['localp']; $localResult = DB_query("SELECT * FROM {$_TABLES['users']} WHERE uid=" . (int) $localUID); $localRow = DB_fetchArray($localResult); if (SEC_check_hash($localpwd, $localRow['passwd'])) { // password is valid $sql = "SELECT * FROM {$_TABLES['users']} WHERE remoteusername <> '' and email='" . DB_escapeString($localRow['email']) . "'"; $result = DB_query($sql); $numRows = DB_numRows($result); if ($numRows == 1) { $remoteRow = DB_fetchArray($result); if ($remoteUID == $remoteRow['uid']) { $remoteUID = (int) $remoteRow['uid']; $remoteService = substr($remoteRow['remoteservice'], 6); } else { echo COM_refresh($_CONF['site_url'] . '/index.php'); } } else { echo COM_refresh($_CONF['site_url'] . '/index.php'); } $sql = "UPDATE {$_TABLES['users']} SET remoteusername='******'remoteusername']) . "'," . "remoteservice='" . DB_escapeString($remoteRow['remoteservice']) . "', " . "account_type=3 " . " WHERE uid=" . (int) $localUID; DB_query($sql); $_USER['uid'] = $localRow['uid']; $local_login = true; SESS_completeLogin($localUID); $_GROUPS = SEC_getUserGroups($_USER['uid']); $_RIGHTS = explode(',', SEC_getUserPermissions()); if ($_SYSTEM['admin_session'] > 0 && $local_login) { if (SEC_isModerator() || SEC_hasRights('story.edit,block.edit,topic.edit,user.edit,plugin.edit,user.mail,syndication.edit', 'OR') || count(PLG_getAdminOptions()) > 0) { $admin_token = SEC_createTokenGeneral('administration', $_SYSTEM['admin_session']); SEC_setCookie('token', $admin_token, 0, $_CONF['cookie_path'], $_CONF['cookiedomain'], $_CONF['cookiesecure'], true); } } COM_resetSpeedlimit('login'); // log the user out SESS_endUserSession($remoteUID); // Let plugins know a user is being merged PLG_moveUser($remoteUID, $_USER['uid']); // Ok, now delete everything related to this user // let plugins update their data for this user PLG_deleteUser($remoteUID); if (function_exists('CUSTOM_userDeleteHook')) { CUSTOM_userDeleteHook($remoteUID); } // Call custom account profile delete function if enabled and exists if ($_CONF['custom_registration'] && function_exists('CUSTOM_userDelete')) { CUSTOM_userDelete($remoteUID); } // remove from all security groups DB_delete($_TABLES['group_assignments'], 'ug_uid', $remoteUID); // remove user information and preferences DB_delete($_TABLES['userprefs'], 'uid', $remoteUID); DB_delete($_TABLES['userindex'], 'uid', $remoteUID); DB_delete($_TABLES['usercomment'], 'uid', $remoteUID); DB_delete($_TABLES['userinfo'], 'uid', $remoteUID); // delete user photo, if enabled & exists if ($_CONF['allow_user_photo'] == 1) { $photo = DB_getItem($_TABLES['users'], 'photo', "uid = {$remoteUID}"); USER_deletePhoto($photo, false); } // delete subscriptions DB_delete($_TABLES['subscriptions'], 'uid', $remoteUID); // in case the user owned any objects that require Admin access, assign // them to the Root user with the lowest uid $rootgroup = DB_getItem($_TABLES['groups'], 'grp_id', "grp_name = 'Root'"); $result = DB_query("SELECT DISTINCT ug_uid FROM {$_TABLES['group_assignments']} WHERE ug_main_grp_id = '{$rootgroup}' ORDER BY ug_uid LIMIT 1"); $A = DB_fetchArray($result); $rootuser = $A['ug_uid']; if ($rootuser == '' || $rootuser < 2) { $rootuser = 2; } DB_query("UPDATE {$_TABLES['blocks']} SET owner_id = {$rootuser} WHERE owner_id = {$remoteUID}"); DB_query("UPDATE {$_TABLES['topics']} SET owner_id = {$rootuser} WHERE owner_id = {$remoteUID}"); // now delete the user itself DB_delete($_TABLES['users'], 'uid', $remoteUID); } else { // invalid password - let's try one more time // need to set speed limit and give them 3 tries COM_clearSpeedlimit($_CONF['login_speedlimit'], 'merge'); $last = COM_checkSpeedlimit('merge', 4); if ($last > 0) { COM_setMsg($LANG04[190], 'error'); echo COM_refresh($_CONF['site_url'] . '/users.php'); } else { COM_updateSpeedlimit('merge'); USER_mergeAccountScreen($remoteUID, $localUID, $LANG20[3]); } return $retval; } // can't use COM_setMsg here since the session is being destroyed. echo COM_refresh($_CONF['site_url'] . '/index.php?msg=522'); }
function _reedit($method, $args = array()) { if ($this->_editor_mode == 'submit') { COM_resetSpeedlimit('submit'); } $display = ''; if (method_exists($this, $method)) { switch (count($args)) { case 0: $display = $this->{$method}(); break; case 1: $display = $this->{$method}($args[0]); break; case 2: $display = $this->{$method}($args[0], $args[1]); break; case 3: $display = $this->{$method}($args[0], $args[1], $args[2]); break; default: $display = ''; break; } } COM_output($display); exit; }