示例#1
0
    async def get_login(self, name: str, phash: str) -> Optional[Player]:
        # Only used cached results - the user should have
        # logged into bancho at least once. (This does not
        # mean they're logged in now).

        # Let them pass as a string for ease of access
        phash = phash.encode()

        bcrypt_cache = glob.cache['bcrypt']

        if phash not in bcrypt_cache:
            # User has not logged in through bancho.
            return

        res = await glob.db.fetch(
            'SELECT pw_hash FROM users '
            'WHERE name_safe = %s', [Player.make_safe(name)])

        if not res:
            # Could not find user in the DB.
            return

        if bcrypt_cache[phash] != res['pw_hash']:
            # Password bcrypts do not match.
            return

        return await self.get_by_name(name)
示例#2
0
    async def get_by_name(self, name: str, sql: bool = False) -> Player:
        name_safe = Player.make_safe(name)

        for p in self.players:
            if p.safe_name == name_safe:
                return p

        if not sql:
            # don't fetch from sql
            # if not specified.
            return

        # try to get from sql.
        res = await glob.db.fetch(
            'SELECT id, priv, silence_end '
            'FROM users WHERE name_safe = %s', [name_safe])

        return Player(**res, name=name) if res else None
示例#3
0
        for p in self.players:
            if p not in immune:
                p.enqueue(data)

    async def get(self, sql: bool = False, **kwargs) -> Optional[Player]:
        for attr in ('token', 'id', 'name'):
            if val := kwargs.pop(attr, None):
                break
        else:
            raise ValueError(
                'must provide valid kwarg (token, id, name) to get()')

        if attr == 'name':
            # name -> safe_name
            attr = 'safe_name'
            val = Player.make_safe(val)

        for p in self.players:
            if getattr(p, attr) == val:
                return p

        if not sql:
            # don't fetch from sql
            # if not specified
            return

        # try to get from sql.
        res = await glob.db.fetch(
            'SELECT id, name, priv, pw_bcrypt, silence_end '
            f'FROM users WHERE {attr} = %s', [val])
示例#4
0
    display_city = s[2] == '1'

    # Client hashes contain a few values useful to us.
    # [0]: md5(osu path)
    # [1]: adapters (network physical addresses delimited by '.')
    # [2]: md5(adapters)
    # [3]: md5(uniqueid) (osu! uninstall id)
    # [4]: md5(uniqueid2) (disk signature/serial num)
    client_hashes = s[3].split(':')[:-1]
    client_hashes.pop(1)  # no need for non-md5 adapters

    pm_private = s[4] == '1'

    p_row = await glob.db.fetch(
        'SELECT id, name, priv, pw_hash, silence_end '
        'FROM users WHERE name_safe = %s', [Player.make_safe(username)])

    if not p_row:
        # no account by this name exists.
        return packets.userID(-1), 'no'

    # get our bcrypt cache.
    bcrypt_cache = glob.cache['bcrypt']

    # their account exists in sql.
    # check their account status & credentials against db.

    if pw_hash in bcrypt_cache:  # ~0.01 ms
        # cache hit - this saves ~200ms on subsequent logins.
        if bcrypt_cache[pw_hash] != p_row['pw_hash']:
            # password wrong
示例#5
0
    # Client hashes contain a few values useful to us.
    # [0]: md5(osu path)
    # [1]: adapters (network physical addresses delimited by '.')
    # [2]: md5(adapters)
    # [3]: md5(uniqueid) (osu! uninstall id)
    # [4]: md5(uniqueid2) (disk signature/serial num)
    client_hashes = s[3].split(':')[:-1]
    client_hashes.pop(1)  # no need for non-md5 adapters

    pm_private = s[4] == '1'

    res = await glob.db.fetch(
        'SELECT id, name, priv, pw_hash, '
        'silence_end FROM users '
        'WHERE name_safe = %s', [Player.make_safe(username)])

    # get our bcrypt cache.
    bcrypt_cache = glob.cache['bcrypt']

    if res:
        # account exists.
        # check their account status & credentials against db.
        if not res['priv'] & Privileges.Normal:
            return await packets.userID(-3), 'no'

        # password is incorrect.
        if pw_hash in bcrypt_cache:  # ~0.01 ms
            # cache hit - this saves ~200ms on subsequent logins.
            if bcrypt_cache[pw_hash] != res['pw_hash']:
                return await packets.userID(-1), 'no'
示例#6
0
    # Client hashes contain a few values useful to us.
    # [0]: md5(osu path)
    # [1]: adapters (network physical addresses delimited by '.')
    # [2]: md5(adapters)
    # [3]: md5(uniqueid) (osu! uninstall id)
    # [4]: md5(uniqueid2) (disk signature/serial num)
    client_hashes = s[3].split(':')[:-1]
    client_hashes.pop(1) # no need for non-md5 adapters

    pm_private = s[4] == '1'

    user_info = await glob.db.fetch(
        'SELECT id, name, priv, pw_bcrypt, silence_end '
        'FROM users WHERE safe_name = %s',
        [Player.make_safe(username)]
    )

    if not user_info:
        # no account by this name exists.
        return packets.userID(-1), 'no'

    # get our bcrypt cache.
    bcrypt_cache = glob.cache['bcrypt']
    pw_bcrypt = user_info['pw_bcrypt'].encode()
    user_info['pw_bcrypt'] = pw_bcrypt

    # check credentials against db.
    # algorithms like these are intentionally
    # designed to be slow; we'll cache the
    # results to speed up subsequent logins.