Esempio n. 1
0
def checkAccess(irc, uid, channel, command):
    """Checks the caller's access to Automode."""
    # Automode defines the following permissions, where <command> is either "manage", "list",
    # "sync", "clear", "remotemanage", "remotelist", "remotesync", "remoteclear":
    # - automode.<command> OR automode.<command>.*: ability to <command> automode on all channels.
    # - automode.<command>.relay_owned: ability to <command> automode on channels owned via Relay.
    #   If Relay isn't loaded, this permission check FAILS.
    # - automode.<command>.#channel: ability to <command> automode on the given channel.
    # - automode.savedb: ability to save the automode DB.
    log.debug('(%s) Automode: checking access for %s/%s for %s capability on %s', irc.name, uid,
              irc.getHostmask(uid), command, channel)

    baseperm = 'automode.%s' % command
    try:
        # First, check the catch all and channel permissions.
        perms = [baseperm, baseperm+'.*', '%s.%s' % (baseperm, channel)]
        return permissions.checkPermissions(irc, uid, perms)
    except utils.NotAuthorizedError:
        if not command.startswith('remote'):
            # Relay-based ACL checking only works with local calls.
            log.debug('(%s) Automode: falling back to automode.%s.relay_owned', irc.name, command)
            permissions.checkPermissions(irc, uid, [baseperm+'.relay_owned'], also_show=perms)

            relay = world.plugins.get('relay')
            if relay is None:
                raise utils.NotAuthorizedError("You are not authorized to use Automode when Relay is "
                                               "disabled. You are missing one of the following "
                                               "permissions: %s or %s.%s" % (baseperm, baseperm, channel))
            elif (irc.name, channel) not in relay.db:
                raise utils.NotAuthorizedError("The network you are on does not own the relay channel %s." % channel)
            return True
        raise
Esempio n. 2
0
def identify(irc, source, args):
    """<username> <password>

    Logs in to PyLink using the configured administrator account."""
    if irc.is_channel(irc.called_in):
        irc.reply('Error: This command must be sent in private. '
                  '(Would you really type a password inside a channel?)')
        return
    try:
        username, password = args[0], args[1]
    except IndexError:
        irc.reply('Error: Not enough arguments.')
        return

    # Process new-style accounts.
    if check_login(username, password):
        _irc_try_login(irc, source, username)
        return

    # Process legacy logins (login:user).
    if username.lower() == conf.conf['login'].get(
            'user',
            '').lower() and password == conf.conf['login'].get('password'):
        realuser = conf.conf['login']['user']
        _irc_try_login(irc, source, realuser, skip_checks=True)
        return

    # Username not found or password incorrect.
    log.warning("(%s) Failed login to %r from %s", irc.name, username,
                irc.get_hostmask(source))
    raise utils.NotAuthorizedError('Bad username or password.')
Esempio n. 3
0
def checkPermissions(irc, uid, perms, also_show=[]):
    """
    Checks permissions of the caller. If the caller has any of the permissions listed in perms,
    this function returns True. Otherwise, NotAuthorizedError is raised.
    """
    # For old (< 1.1 login blocks):
    # If the user is logged in, they automatically have all permissions.
    if irc.matchHost('$pylinkacc', uid) and conf.conf['login'].get('user'):
        log.debug(
            'permissions: overriding permissions check for old-style admin user %s',
            irc.getHostmask(uid))
        return True

    # Iterate over all hostmask->permission list mappings.
    for host, permlist in permissions.copy().items():
        log.debug('permissions: permlist for %s: %s', host, permlist)
        if irc.matchHost(host, uid):
            # Now, iterate over all the perms we are looking for.
            for perm in permlist:
                # Use irc.matchHost to expand globs in an IRC-case insensitive and wildcard
                # friendly way. e.g. 'xyz.*.#Channel\' will match 'xyz.manage.#channel|' on IRCds
                # using the RFC1459 casemapping.
                log.debug(
                    'permissions: checking if %s glob matches anything in %s',
                    perm, permlist)
                if any(irc.matchHost(perm, p) for p in perms):
                    return True
    raise utils.NotAuthorizedError(
        "You are missing one of the following permissions: %s" %
        (', '.join(perms + also_show)))
Esempio n. 4
0
def verifyHash(password, passhash):
    """Checks whether the password given matches the hash."""
    if password:
        if not pwd_context:
            raise utils.NotAuthorizedError("Cannot log in to an account with a hashed password "
                                           "because passlib is not installed.")

        return pwd_context.verify(password, passhash)
    return False  # No password given!
Esempio n. 5
0
def _irc_try_login(irc, source, username, skip_checks=False):
    """Internal function to process logins via IRC."""
    if irc.is_internal_client(source):
        irc.error("Cannot use 'identify' via a command proxy.")
        return

    if not skip_checks:
        logindata = _get_account(username)

        network_filter = logindata.get('networks')
        require_oper = logindata.get('require_oper', False)
        hosts_filter = logindata.get('hosts', [])

        if network_filter and irc.name not in network_filter:
            log.warning(
                "(%s) Failed login to %r from %s (wrong network: networks filter says %r but we got %r)",
                irc.name, username, irc.get_hostmask(source),
                ', '.join(network_filter), irc.name)
            raise utils.NotAuthorizedError(
                "Account is not authorized to login on this network.")

        elif require_oper and not irc.is_oper(source):
            log.warning("(%s) Failed login to %r from %s (needs oper)",
                        irc.name, username, irc.get_hostmask(source))
            raise utils.NotAuthorizedError("You must be opered.")

        elif hosts_filter and not any(
                irc.match_host(host, source) for host in hosts_filter):
            log.warning("(%s) Failed login to %r from %s (hostname mismatch)",
                        irc.name, username, irc.get_hostmask(source))
            raise utils.NotAuthorizedError("Hostname mismatch.")

    irc.users[source].account = username
    irc.reply('Successfully logged in as %s.' % username)
    log.info("(%s) Successful login to %r by %s", irc.name, username,
             irc.get_hostmask(source))
    return True
Esempio n. 6
0
def check_permissions(irc, uid, perms, also_show=[]):
    """
    Checks permissions of the caller. If the caller has any of the permissions listed in perms,
    this function returns True. Otherwise, NotAuthorizedError is raised.
    """
    # For old (< 1.1 login blocks):
    # If the user is logged in, they automatically have all permissions.
    olduser = conf.conf['login'].get('user')
    if olduser and irc.match_host('$pylinkacc:%s' % olduser, uid):
        log.debug(
            'permissions: overriding permissions check for old-style admin user %s',
            irc.get_hostmask(uid))
        return True

    permissions = defaultdict(set)
    # Enumerate the configured permissions list.
    for k, v in (conf.conf.get('permissions') or {}).items():
        permissions[k] |= set(v)

    # Merge in default permissions if enabled.
    if conf.conf.get('permissions_merge_defaults', True):
        for k, v in default_permissions.items():
            permissions[k] |= v

    for host, permlist in permissions.items():
        log.debug('permissions: permlist for %s: %s', host, permlist)
        if irc.match_host(host, uid):
            # Now, iterate over all the perms we are looking for.
            for perm in permlist:
                # Use irc.match_host to expand globs in an IRC-case insensitive and wildcard
                # friendly way. e.g. 'xyz.*.#Channel\' will match 'xyz.manage.#channel|' on IRCds
                # using the RFC1459 casemapping.
                log.debug(
                    'permissions: checking if %s glob matches anything in %s',
                    perm, permlist)
                if any(irc.match_host(perm, p) for p in perms):
                    return True
    raise utils.NotAuthorizedError(
        "You are missing one of the following permissions: %s" %
        (', '.join(perms + also_show)))