Exemplo n.º 1
0
/**
* Will authenticate the username/password combo
*
* Use this before setting the cookie to check if the username password are correct.
*
* @param  mixed $username the user's member name, email or member id
* @param  string $password the password plaintext or encrypted in any of several
*         methods including smf's method: sha1(strtolower($username) . $password)
* @param  bool $encrypted whether the password is encrypted or not. If you get
          this wrong we'll figure it out anyways, just saves some work if it's right
* @return bool whether the user is authenticated or not
* @since  0.1.0
*/
function smfapi_authenticate($username = '', $password = '', $encrypted = true)
{
    global $scripturl, $user_info, $user_settings, $smcFunc;
    global $cookiename, $modSettings, $sc, $sourcedir;
    if ('' == $username || '' == $password) {
        return false;
    }
    // just in case they used the email or member id...
    $data = smfapi_getUserData($username);
    if (empty($data)) {
        return false;
    } else {
        $username = $data['member_name'];
    }
    // load the data up!
    $request = $smcFunc['db_query']('', '
		SELECT passwd, id_member, id_group, lngfile, is_activated, email_address, additional_groups, member_name, password_salt,
			openid_uri, passwd_flood
		FROM {db_prefix}members
		WHERE ' . ($smcFunc['db_case_sensitive'] ? 'LOWER(member_name) = LOWER({string:user_name})' : 'member_name = {string:user_name}') . '
		LIMIT 1', array('user_name' => $smcFunc['db_case_sensitive'] ? strtolower($username) : $username));
    // no user data found... invalid username
    if ($smcFunc['db_num_rows']($request) == 0) {
        return false;
    }
    $user_settings = $smcFunc['db_fetch_assoc']($request);
    $smcFunc['db_free_result']($request);
    if (40 != strlen($user_settings['passwd'])) {
        // invalid hash in the db
        return false;
    }
    // if it's not encrypted, do it now
    if (!$encrypted) {
        $sha_passwd = sha1(strtolower($user_settings['member_name']) . smfapi_unHtmlspecialchars($password));
    } else {
        $sha_passwd = $password;
    }
    // if they match the password/hash is correct
    if ($user_settings['passwd'] == $sha_passwd) {
        $user_info["id"] = $user_settings['id_member'];
        return true;
    } else {
        // try other hashing schemes
        $other_passwords = array();
        // in case they sent the encrypted password into this as unencrypted
        $other_passwords[] = $password;
        // none of the below cases will be used most of the time
        // (because the salt is normally set)
        if ('' == $user_settings['password_salt']) {
            // YaBB SE, Discus, MD5 (used a lot), SHA-1 (used some), SMF 1.0.x,
            // IkonBoard, and none at all
            $other_passwords[] = crypt($password, substr($password, 0, 2));
            $other_passwords[] = crypt($password, substr($user_settings['passwd'], 0, 2));
            $other_passwords[] = md5($password);
            $other_passwords[] = sha1($password);
            $other_passwords[] = md5_hmac($password, strtolower($user_settings['member_name']));
            $other_passwords[] = md5($password . strtolower($user_settings['member_name']));
            $other_passwords[] = md5(md5($password));
            $other_passwords[] = $password;
            // this one is a strange one... MyPHP, crypt() on the MD5 hash
            $other_passwords[] = crypt(md5($password), md5($password));
            // Snitz style - SHA-256.  Technically, this is a downgrade, but most PHP
            // configurations don't support sha256 anyway.
            if (strlen($user_settings['passwd']) == 64 && function_exists('mhash') && defined('MHASH_SHA256')) {
                $other_passwords[] = bin2hex(mhash(MHASH_SHA256, $password));
            }
            // phpBB3 users new hashing.  We now support it as well ;)
            $other_passwords[] = phpBB3_password_check($password, $user_settings['passwd']);
            // APBoard 2 login method
            $other_passwords[] = md5(crypt($password, 'CRYPT_MD5'));
        } elseif (strlen($user_settings['passwd']) == 32) {
            // vBulletin 3 style hashing?  Let's welcome them with open arms \o/
            $other_passwords[] = md5(md5($password) . $user_settings['password_salt']);
            // hmm.. p'raps it's Invision 2 style?
            $other_passwords[] = md5(md5($user_settings['password_salt']) . md5($password));
            // some common md5 ones
            $other_passwords[] = md5($user_settings['password_salt'] . $password);
            $other_passwords[] = md5($password . $user_settings['password_salt']);
        } elseif (strlen($user_settings['passwd']) == 40) {
            // maybe they are using a hash from before the password fix
            $other_passwords[] = sha1(strtolower($user_settings['member_name']) . smfapi_unHtmlspecialchars($password));
            // BurningBoard3 style of hashing
            $other_passwords[] = sha1($user_settings['password_salt'] . sha1($user_settings['password_salt'] . sha1($password)));
            // perhaps we converted to UTF-8 and have a valid password being
            // hashed differently
            if (!empty($modSettings['previousCharacterSet']) && $modSettings['previousCharacterSet'] != 'utf8') {
                // try iconv first, for no particular reason
                if (function_exists('iconv')) {
                    $other_passwords['iconv'] = sha1(strtolower(iconv('UTF-8', $modSettings['previousCharacterSet'], $user_settings['member_name'])) . un_htmlspecialchars(iconv('UTF-8', $modSettings['previousCharacterSet'], $password)));
                }
                // say it aint so, iconv failed
                if (empty($other_passwords['iconv']) && function_exists('mb_convert_encoding')) {
                    $other_passwords[] = sha1(strtolower(mb_convert_encoding($user_settings['member_name'], 'UTF-8', $modSettings['previousCharacterSet'])) . un_htmlspecialchars(mb_convert_encoding($password, 'UTF-8', $modSettings['previousCharacterSet'])));
                }
            }
        }
        // SMF's sha1 function can give a funny result on Linux (not our fault!)
        // if we've now got the real one let the old one be valid!
        if (strpos(strtolower(PHP_OS), 'win') !== 0) {
            require_once $sourcedir . '/Subs-Compat.php';
            $other_passwords[] = sha1_smf(strtolower($user_settings['member_name']) . smfapi_unHtmlspecialchars($password));
        }
        // if ANY of these other hashes match we'll accept it
        if (in_array($user_settings['passwd'], $other_passwords)) {
            // we're not going to update the password or the hash. whatever was
            // used worked, so it will work again through this api, or SMF will
            // update it if the user authenticates through there. No sense messing
            // with it if it's not broken imo. Authentication successful
            $user_info["id"] = $user_settings['id_member'];
            return true;
        }
    }
    //authentication failed
    return false;
}
Exemplo n.º 2
0
 /**
  * @param array $data
  */
 public function OnUserChangePassword(array $data)
 {
     if (!defined('SMF') || SMF != 'API') {
         return;
     }
     if (!smfapi_getUserByUsername($data['user']->username)) {
         if (!$this->addUserToSMF($data['user']->username)) {
             return;
         }
     }
     smfapi_updateMemberData($data['user']->username, array('password' => sha1(strtolower($data['user']->username) . smfapi_unHtmlspecialchars($data['newpassword']))));
     $contexts = $this->smfGetContexts();
     if (in_array($this->modx->context->key, $contexts) && $this->modx->user->username == $data['user']->username) {
         smfapi_logout($data['user']->username);
         smfapi_login($data['user']->username);
         @session_write_close();
     }
 }