示例#1
0
def save(irc, source, args):
    """takes no arguments.

    Saves the Automode database to disk."""
    permissions.checkPermissions(irc, source, ['automode.savedb'])
    datastore.save()
    reply(irc, 'Done.')
def cf_add(irc, source, args):
    """<subdomain> <address> --type <type> [--ttl <ttl>]

    Adds a record to a RR group of records. The following options are supported:

    -t / --type : Type of Record (A, AAAA, CNAME)

    -l / --ttl : 'time to live' of record (If not given, ttl is made automatic)
    """
    permissions.checkPermissions(irc, source, ['cloudflare.cf-add'])
    cf = get_cf()
    zone = conf.conf.get("cloudflare", {}).get('target_zone')
    if not zone:
        irc.error("No target zone ID specified! Configure it via a 'cloudflare::target_zone' option.")
        return
    args = cf_add_parser.parse_args(args)

    body = {
        "type":    args.type,
        "name":    args.name,
        "content": args.content,
        "ttl":     args.ttl
    }

    response = cf.zones.dns_records.post(zone, data=body)
    result = response.get("result", [])
    irc.reply("Record Added. %(name)s as %(content)s" % result, private=False)
    irc.reply("Record ID: %(id)s" % result, private=False)
示例#3
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
def depool(irc, source, args):
    """<target subdomain> <source subdomain>

    Removes all entries in the target subdomain that are also present in the source subdomain. This
    can be used to maintain IRC round robins, for example.
    """
    permissions.checkPermissions(irc, source, ['cloudflare.depool'])
    args = depool_parser.parse_args(args)
    cf = get_cf()
    zone = conf.conf.get("cloudflare", {}).get('target_zone')
    if not zone:
        irc.error("No target zone ID specified! Configure it via a 'cloudflare::target_zone' option.")
        return

    base_domain = cf.zones.get(zone)['result']['name']

    # CloudFlare only allows removing entries by ID, so look up the exact record contents we need to remove here.
    get_targets_body = {'name': '%s.%s' % (args.source_subdomain, base_domain)}
    removal_targets = [record['content'] for record in cf.zones.dns_records.get(zone, params=get_targets_body)['result']]

    target_body = {'name': '%s.%s' % (args.target_subdomain, base_domain)}
    # Iterate over all DNS records in the target subdomain
    processed = 0
    for record in cf.zones.dns_records.get(zone, params=target_body)['result']:
        if record['content'] in removal_targets:
            irc.reply('Removing record %s (%s) from target %s' %
                      (record['id'], record['content'], args.target_subdomain))
            response = cf.zones.dns_records.delete(zone, record['id'])
            processed += 1
    else:
        irc.reply('Done, processed %s result(s).' % processed)
示例#5
0
def qdel(irc, source, args):
    """<id>
    Deletes quote #<id> from the database.
    """
    try:
        permissions.checkPermissions(irc, source, ["quotes.admin"])
    except utils.NotAuthorizedError:
        if irc.channels[irc.called_in].isOpPlus(source):
            pass
        else:
            error(irc,
                  "Access denied. You must be a channel op to remove quotes.")
            return
    options = qdel_parser.parse_args(args)
    channel = irc.called_in
    id = options.id
    result = engine.execute(dbq.delete().where(
        and_(dbq.c.id == id, dbq.c.channel == channel))).rowcount
    if result:
        reply(irc, "Done. Quote #%s deleted." % (id))
    else:
        error(
            irc,
            "Error occured when deleting quote. Please contact my Admins (Network Staff) for assistance."
        )
def pool(irc, source, args):
    """<target subdomain> <source subdomain>

    Copies + merges all records from source subdomain into the target subdomain. This can be
    used to maintain IRC round robins, for example.
    """
    permissions.checkPermissions(irc, source, ['cloudflare.pool'])
    args = pool_parser.parse_args(args)
    cf = get_cf()
    zone = conf.conf.get("cloudflare", {}).get('target_zone')
    if not zone:
        irc.error("No target zone ID specified! Configure it via a 'cloudflare::target_zone' option.")
        return

    base_domain = cf.zones.get(zone)['result']['name']
    # API request body
    body = {'name': '%s.%s' % (args.source_subdomain, base_domain)}

    processed = 0
    # Iterate over all DNS records in the source subdomain
    for record in cf.zones.dns_records.get(zone, params=body)['result']:
        irc.reply('Copying record for %s (ttl %s) from %s to %s' %
                  (record['content'], record['ttl'], args.source_subdomain, args.target_subdomain))

        # Switch the record name and add them into the new subdomain
        record['name'] = args.target_subdomain
        cf.zones.dns_records.post(zone, data=record)
        processed += 1
    else:
        irc.reply('Done, processed %s result(s).' % processed)
示例#7
0
def g(irc, source, args):
    """<message text>

    Sends out a Instance-wide notice.
    """
    permissions.checkPermissions(irc, source, ["global.global"])
    message = " ".join(args)
    global_conf = conf.conf.get('global') or {}
    template = string.Template(global_conf.get('format', DEFAULT_FORMAT))

    for name, ircd in world.networkobjects.items():
        if ircd.connected.is_set(
        ):  # Only attempt to send to connected networks
            for channel in ircd.pseudoclient.channels:
                subst = {
                    'sender': irc.getFriendlyName(source),
                    'network': irc.name,
                    'fullnetwork': irc.getFullNetworkName(),
                    'current_channel': channel,
                    'current_network': ircd.name,
                    'current_fullnetwork': ircd.getFullNetworkName(),
                    'text': message
                }

                # Disable relaying or other plugins handling the global message.
                ircd.msg(channel,
                         template.safe_substitute(subst),
                         loopback=False)
示例#8
0
def topic(irc, source, args):
    """<channel> <topic>

    Admin only. Updates the topic in a channel."""
    permissions.checkPermissions(irc, source, ['opercmds.topic'])
    try:
        channel = args[0]
        topic = ' '.join(args[1:])
    except IndexError:
        irc.error("Not enough arguments. Needs 2: channel, topic.")
        return

    if channel not in irc.channels:
        irc.error("Unknown channel %r." % channel)
        return

    irc.proto.topic(irc.pseudoclient.uid, channel, topic)

    irc.reply("Done.")
    irc.callHooks([
        irc.pseudoclient.uid, 'CHANCMDS_TOPIC', {
            'channel': channel,
            'text': topic,
            'setter': source,
            'parse_as': 'TOPIC'
        }
    ])
示例#9
0
def jupe(irc, source, args):
    """<server> [<reason>]

    Admin only, jupes the given server."""

    # Check that the caller is either opered or logged in as admin.
    permissions.checkPermissions(irc, source, ['opercmds.jupe'])

    try:
        servername = args[0]
        reason = ' '.join(args[1:]) or "No reason given"
        desc = "Juped by %s: [%s]" % (irc.getHostmask(source), reason)
    except IndexError:
        irc.error(
            'Not enough arguments. Needs 1-2: servername, reason (optional).')
        return

    if not utils.isServerName(servername):
        irc.error("Invalid server name '%s'." % servername)
        return

    sid = irc.proto.spawnServer(servername, desc=desc)

    irc.callHooks([
        irc.pseudoclient.uid, 'OPERCMDS_SPAWNSERVER', {
            'name': servername,
            'sid': sid,
            'text': desc
        }
    ])

    irc.reply("Done.")
示例#10
0
文件: exec.py 项目: Ro9ueAdmin/PyLink
def _exec(irc, source, args, locals_dict=None):
    """<code>

    Admin-only. Executes <code> in the current PyLink instance. This command performs backslash escaping of characters, so things like \\n and \\ will work.

    \x02**WARNING: THIS CAN BE DANGEROUS IF USED IMPROPERLY!**\x02"""
    permissions.checkPermissions(irc, source, ['exec.exec'])

    # Allow using \n in the code, while escaping backslashes correctly otherwise.
    args = bytes(' '.join(args), 'utf-8').decode("unicode_escape")
    if not args.strip():
        irc.reply('No code entered!')
        return

    log.info('(%s) Executing %r for %s', irc.name, args,
             irc.getHostmask(source))
    if locals_dict is None:
        locals_dict = locals()
    else:
        # Add irc, source, and args to the given locals_dict, to allow basic things like irc.reply()
        # to still work.
        locals_dict['irc'] = irc
        locals_dict['source'] = source
        locals_dict['args'] = args

    exec(args, globals(), locals_dict)

    irc.reply("Done.")
示例#11
0
def part(irc, source, args):
    """<channel> <[-r REASON]>
    Leaves the given channel, with an optional reason.
    
    
    This deletes the channel's row in the database, and persists throughout restarts, reloads, rehashes, etc."""
    permissions.checkPermissions(irc, source, ["quotes.admin"])
    options = part_parser.parse_args(args)
    if options.channel.startswith('#'):
        pass
    else:
        error(irc, "channel names start with a '#'")
        return
    part_reason = None
    if options.reason:
        part_reason = " ".join(options.reason)
        irc.proto.part(quote.uids.get(irc.name), options.channel, part_reason)
    else:
        irc.proto.part(quote.uids.get(irc.name), options.channel, "Requested.")

    delstmt = dbc.delete().where(dbc.c.channel == options.channel)
    result = engine.execute(delstmt).rowcount
    if result > 0:
        reply(irc, "Channel removed")
    else:
        reply(
            irc,
            "We've already left this channel, or haven't joined it in the first place"
        )
示例#12
0
def quit(irc, source, args):
    """<target> [<reason>]

    Admin-only. Quits the PyLink client with nick <target>, if one exists."""
    permissions.checkPermissions(irc, source, ['bots.quit'])

    try:
        nick = args[0]
    except IndexError:
        irc.error("Not enough arguments. Needs 1-2: nick, reason (optional).")
        return
    if irc.pseudoclient.uid == irc.nickToUid(nick):
        irc.error("Cannot quit the main PyLink client!")
        return

    u = irc.nickToUid(nick)

    quitmsg = ' '.join(args[1:]) or 'Client Quit'

    if not irc.isManipulatableClient(u):
        irc.error("Cannot force quit a protected PyLink services client.")
        return

    irc.proto.quit(u, quitmsg)
    irc.reply("Done.")
    irc.callHooks(
        [u, 'PYLINK_BOTSPLUGIN_QUIT', {
            'text': quitmsg,
            'parse_as': 'QUIT'
        }])
示例#13
0
def blcheck(irc, source, args):
    """<ip> <[blacklist]>
    Checks if IP is in all blacklists defined, or in single
    blacklist given as second argument."""
    permissions.checkPermissions(irc, source, ["dnsbl.check"])
    args = dnsbl_check.parse_args(args)
    try: 
        irc.reply(ck(args.ip, args.blacklist))
    except DNSBLError as e:
        irc.error(e)
示例#14
0
def msg(irc, source, args):
    """[<source>] <target> <text>

    Admin-only. Sends message <text> from <source>, where <source> is the nick of a PyLink client. If <source> is not given, it defaults to the main PyLink client."""
    permissions.checkPermissions(irc, source, ['bots.msg'])

    # Because we want the source nick to be optional, this argument parsing gets a bit tricky.
    try:
        msgsource = args[0]
        target = args[1]
        text = ' '.join(args[2:])

        # First, check if the first argument is an existing PyLink client. If it is not,
        # then assume that the first argument was actually the message TARGET.
        sourceuid = irc.nickToUid(msgsource)
        if not irc.isInternalClient(
                sourceuid):  # First argument isn't one of our clients
            raise IndexError

        if not text:
            raise IndexError
    except IndexError:
        try:
            sourceuid = irc.pseudoclient.uid
            target = args[0]
            text = ' '.join(args[1:])
        except IndexError:
            irc.error(
                'Not enough arguments. Needs 2-3: source nick (optional), target, text.'
            )
            return

    if not text:
        irc.error('No text given.')
        return

    if not utils.isChannel(target):
        # Convert nick of the message target to a UID, if the target isn't a channel
        real_target = irc.nickToUid(target)
        if real_target is None:  # Unknown target user, if target isn't a valid channel name
            irc.error('Unknown user %r.' % target)
            return
    else:
        real_target = target

    irc.proto.message(sourceuid, real_target, text)
    irc.reply("Done.")
    irc.callHooks([
        sourceuid, 'PYLINK_BOTSPLUGIN_MSG', {
            'target': real_target,
            'text': text,
            'parse_as': 'PRIVMSG'
        }
    ])
示例#15
0
def part(irc, source, args):
    """[<target>] <channel1>,[<channel2>],... [<reason>]

    Admin-only. Parts <target>, the nick of a PyLink client, from a comma-separated list of channels. If <target> is not given, it defaults to the main PyLink client."""
    permissions.checkPermissions(irc, source, ['bots.part'])

    try:
        nick = args[0]
        clist = args[1]
        # For the part message, join all remaining arguments into one text string
        reason = ' '.join(args[2:])

        # First, check if the first argument is an existing PyLink client. If it is not,
        # then assume that the first argument was actually the channels being parted.
        u = irc.nickToUid(nick)
        if not irc.isInternalClient(
                u):  # First argument isn't one of our clients
            raise IndexError

    except IndexError:  # No nick was given; shift arguments one to the left.
        u = irc.pseudoclient.uid

        try:
            clist = args[0]
        except IndexError:
            irc.error(
                "Not enough arguments. Needs 1-2: nick (optional), comma separated list of channels."
            )
            return
        reason = ' '.join(args[1:])

    clist = clist.split(',')
    if not clist:
        irc.error("No valid channels given.")
        return

    if not (irc.isManipulatableClient(u) or irc.getServiceBot(u)):
        irc.error("Cannot force part a protected PyLink services client.")
        return

    for channel in clist:
        if not utils.isChannel(channel):
            irc.error("Invalid channel name %r." % channel)
            return
        irc.proto.part(u, channel, reason)

    irc.reply("Done.")
    irc.callHooks([
        u, 'PYLINK_BOTSPLUGIN_PART', {
            'channels': clist,
            'text': reason,
            'parse_as': 'PART'
        }
    ])
示例#16
0
def status(irc, source, args):
    """takes no arguments.

    Returns your current PyLink login status."""
    permissions.checkPermissions(irc, source, ['commands.status'])
    identified = irc.users[source].account
    if identified:
        irc.reply('You are identified as \x02%s\x02.' % identified)
    else:
        irc.reply('You are not identified as anyone.')
    irc.reply('Operator access: \x02%s\x02' % bool(irc.isOper(source)))
示例#17
0
def listbls(irc, source, args):
    """takes no arguments
    Lists all blacklists
    """
    permissions.checkPermissions(irc, source, ["dnsbl.bls"])    
    blacklists = Blacklists()
    bls = blacklists._dict()
    replies = []
    for bl, bd in bls['blacklists'].items():
        replies.append("%s — %s" % (bl, bd.get('hostname')))
    for reply in replies:
        irc.reply(reply)
示例#18
0
def showchan(irc, source, args):
    """<channel>

    Shows information about <channel>."""
    permissions.checkPermissions(irc, source, ['commands.showchan'])
    try:
        channel = irc.toLower(args[0])
    except IndexError:
        irc.error("Not enough arguments. Needs 1: channel.")
        return
    if channel not in irc.channels:
        irc.error('Unknown channel %r.' % channel)
        return

    f = lambda s: irc.reply(s, private=True)

    c = irc.channels[channel]
    # Only show verbose info if caller is oper or is in the target channel.
    verbose = source in c.users or irc.isOper(source)
    secret = ('s', None) in c.modes
    if secret and not verbose:
        # Hide secret channels from normal users.
        irc.error('Unknown channel %r.' % channel)
        return

    nicks = [irc.users[u].nick for u in c.users]

    f('Information on channel \x02%s\x02:' % channel)
    if c.topic:
        f('\x02Channel topic\x02: %s' % c.topic)

    # Mark TS values as untrusted on Clientbot and others (where TS is read-only or not trackable)
    f('\x02Channel creation time\x02: %s (%s)%s' % (ctime(
        c.ts), c.ts, ' [UNTRUSTED]' if not irc.proto.hasCap('has-ts') else ''))

    # Show only modes that aren't list-style modes.
    modes = irc.joinModes([m for m in c.modes if m[0] not in irc.cmodes['*A']],
                          sort=True)
    f('\x02Channel modes\x02: %s' % modes)
    if verbose:
        nicklist = []
        # Iterate over the user list, sorted by nick.
        for user, nick in sorted(zip(c.users, nicks),
                                 key=lambda userpair: userpair[1].lower()):
            for pmode in c.getPrefixModes(user):
                # Show prefix modes in order from highest to lowest.
                nick = irc.prefixmodes.get(irc.cmodes.get(pmode, ''),
                                           '') + nick
            nicklist.append(nick)

        while nicklist[:20]:  # 20 nicks per line to prevent message cutoff.
            f('\x02User list\x02: %s' % ' '.join(nicklist[:20]))
            nicklist = nicklist[20:]
示例#19
0
def checkban(irc, source, args):
    """<banmask (nick!user@host or user@host)> [<nick or hostmask to check>]

    Oper only. If a nick or hostmask is given, return whether the given banmask will match it. Otherwise, returns a list of connected users that would be affected by such a ban, up to 50 results."""
    permissions.checkPermissions(irc, source, ['opercmds.checkban'])

    try:
        banmask = args[0]
    except IndexError:
        irc.error(
            "Not enough arguments. Needs 1-2: banmask, nick or hostmask to check (optional)."
        )
        return

    try:
        targetmask = args[1]
    except IndexError:
        # No hostmask was given, return a list of affected users.

        irc.msg(source,
                "Checking for hosts that match \x02%s\x02:" % banmask,
                notice=True)

        results = 0
        for uid, userobj in irc.users.copy().items():
            if irc.matchHost(banmask, uid):
                if results < 50:  # XXX rather arbitrary limit
                    s = "\x02%s\x02 (%s@%s) [%s] {\x02%s\x02}" % (
                        userobj.nick, userobj.ident, userobj.host,
                        userobj.realname,
                        irc.getFriendlyName(irc.getServer(uid)))

                    # Always reply in private to prevent information leaks.
                    irc.reply(s, private=True)
                results += 1
        else:
            if results:
                irc.msg(source,
                        "\x02%s\x02 out of \x02%s\x02 results shown." %
                        (min([results, 50]), results),
                        notice=True)
            else:
                irc.msg(source, "No results found.", notice=True)
    else:
        # Target can be both a nick (of an online user) or a hostmask. irc.matchHost() handles this
        # automatically.
        if irc.matchHost(banmask, targetmask):
            irc.reply('Yes, \x02%s\x02 matches \x02%s\x02.' %
                      (targetmask, banmask))
        else:
            irc.reply('No, \x02%s\x02 does not match \x02%s\x02.' %
                      (targetmask, banmask))
示例#20
0
def getquotes(irc, source, args):
    """<channel>
    Get the list of quotes for a certain channel.
    """
    permissions.checkPermissions(irc, source, ["quotes.admin"])
    options = getqs_parser.parse_args(args)
    s = select([dbq.c.id]).where(dbq.c.channel == options.channel)
    result = engine.execute(s)
    qlist = [x[0] for x in result]
    if qlist == []:
        reply(irc, "No quotes exist for that channel.")
    else:
        reply(irc, squishids(qlist))
示例#21
0
def spawnclient(irc, source, args):
    """<nick> <ident> <host>

    Admin-only. Spawns the specified client on the PyLink server.
    Note: this doesn't check the validity of any fields you give it!"""
    permissions.checkPermissions(irc, source, ['bots.spawnclient'])
    try:
        nick, ident, host = args[:3]
    except ValueError:
        irc.error("Not enough arguments. Needs 3: nick, user, host.")
        return
    irc.proto.spawnClient(nick, ident, host, manipulatable=True)
    irc.reply("Done.")
示例#22
0
def remrec(irc, source, args):
    """<blacklist> <record>
    Removes record from blacklist.
    """
    permissions.checkPermissions(irc, source, ["dnsbl.rrem"])
    args = dnsbl_remrec.parse_args(args)
    bls = Blacklists()
    config = bls._dict()
    try:
        del config['blacklists'][args.blacklist]['records'][args.record]
        bls.dump(config)
        irc.reply("Record Reply removed.")
    except KeyError:
        irc.error("Reply did not exist.")
示例#23
0
def rembl(irc, source, args):
    """<blacklist>
    Removes BLACKLIST.
    """
    permissions.checkPermissions(irc, source, ["dnsbl.rem"])
    args = dnsbl_rembl.parse_args(args)
    bls = Blacklists()
    config = bls._dict()
    try:
        del config['blacklists'][args.blacklist]
        bls.dump(config)
        irc.reply("Blacklist removed.")
    except KeyError:
        irc.error("Supposed blacklist %s did/does not exist." % args.blacklist)
示例#24
0
def stats(irc, source, args):
    """takes no arguments
    Returns stats on the quotes and channels in the database.
    """
    permissions.checkPermissions(irc, source, ["quotes.admin"])
    statdict = {}
    statdict["total_quote_count"] = engine.execute(
        dbq.count()).fetchall()[0][0]
    statdict["total_channel_count"] = engine.execute(
        dbc.count()).fetchall()[0][0]
    reply(
        irc,
        "Quotes: %(total_quote_count)s / Channels: %(total_channel_count)s" %
        (statdict))
示例#25
0
def getquote(irc, source, args):
    """<channel> <[options]> <query>
    Looks up a quote in the database for the given channel.

    In addition to just running the command with a quote ID,
    you are able to use the following switch arguments.


    -i/--id:
    Look up a quote by quote ID. (default)

    -w/--wildcard:
    Look up quotes by quote text searching.

    -b/--by:
    Look up quotes by the submitter's hostmask
    """
    permissions.checkPermissions(irc, source, ["quotes.admin"])
    options = getq_parser.parse_args(args)
    channel = options.channel
    if options.id and not options.wildcard and not options.by:
        try:
            id = int(options.query)
            s = select([dbq]).where(
                and_(
                    dbq.c.id == id,
                    dbq.c.channel == options.channel,
                ))
            result = engine.execute(s).fetchone()
            if result == None:
                error(irc, "No quote under that id.")
            else:
                reply(irc, format(dict(result.items()), chan=True))
        except ValueError:
            error(irc, "ID must be an integer!")
    elif options.wildcard:
        regex = options.query
        s = select([dbq.c.id]).where(
            and_(dbq.c.quote.like("%{}%".format(options.query)),
                 dbq.c.channel == options.channel))
        result = engine.execute(s).fetchall()
        qlist = [x[0] for x in result]
        if qlist == []:
            error(irc, "No quotes available.")
        else:
            reply(irc, "Quote IDs: {}".format(squishids(qlist)))
    elif options.by:
        by = options.query
        s = dbq.select().where(
            and_(dbq.c.added_by == by, dbq.c.channel == options.channel))
示例#26
0
def reloadproto(irc, source, args):
    """<protocol module name>

    Reloads the given protocol module without restart. You will have to manually disconnect and reconnect any network using the module for changes to apply."""
    permissions.checkPermissions(irc, source, ['networks.reloadproto'])
    try:
        name = args[0]
    except IndexError:
        irc.error('Not enough arguments (needs 1: protocol module name)')
        return

    proto = utils.getProtocolModule(name)
    importlib.reload(proto)

    irc.reply("Done. You will have to manually disconnect and reconnect any network using the %r module for changes to apply." % name)
示例#27
0
def addbl(irc, source, args):
    """<blacklist> <hostname>
    Adds BLACKLIST with hostname HOSTNAME.
    """
    permissions.checkPermissions(irc, source, ["dnsbl.add"])    
    args = dnsbl_addbl.parse_args(args)
    bls = Blacklists()
    config = bls._dict()
    try:
        config['blacklists'][args.blacklist] = {}
        config['blacklists'][args.blacklist]['hostname'] = args.hostname
        irc.reply("Blacklist %s added with hostname %s" % (args.blacklist, args.hostname))
        bls.dump(config)
    except KeyError as e:
        irc.error("Key %s does not exist. Ruh-roh" % e)
示例#28
0
def cf_rem(irc, source, args):
    """<record id>

    Removes a record by its ID (Use the "rr-show" command to display a list of records).
    """
    permissions.checkPermissions(irc, source, ['cloudflare.cf-rem'])
    zone = conf.conf.get("cloudflare", {}).get('target_zone')
    cf = get_cf()
    if not zone:
        irc.error("No target zone ID specified! Configure it via a 'cloudflare::target_zone' option.")
        return
    args = cf_rem_parser.parse_args(args)

    response = cf.zones.dns_records.delete(zone, args.id)
    result = response["result"]
    irc.reply("Record Removed. ID: %(id)s" % result, private=False)
示例#29
0
文件: exec.py 项目: Ro9ueAdmin/PyLink
def inject(irc, source, args):
    """<text>

    Admin-only. Injects raw text into the running PyLink protocol module, replying with the hook data returned.

    \x02**WARNING: THIS CAN BREAK YOUR NETWORK IF USED IMPROPERLY!**\x02"""
    permissions.checkPermissions(irc, source, ['exec.inject'])

    args = ' '.join(args)
    if not args.strip():
        irc.reply('No text entered!')
        return

    log.info('(%s) Injecting raw text %r into protocol module for %s',
             irc.name, args, irc.getHostmask(source))
    irc.reply(irc.runline(args))
示例#30
0
def delquote(irc, source, args):
    """<channel> <id>
    Deletes the given <id> from the database for <channel>
    """
    permissions.checkPermissions(irc, source, ["quotes.admin"])
    options = delq_parser.parse_args(args)
    channel = options.channel
    id = options.id
    result = engine.execute(dbq.delete().where(
        and_(
            dbq.c.id == id,
            dbq.c.channel == channel,
        ))).rowcount
    if result:
        reply(irc, "Done. Quote #%s deleted." % (id))
    else:
        error(irc, "No quote under that id.")
示例#31
0
def _check_logout_access(irc, source, target, perms):
    """
    Checks whether the source UID has access to log out the target UID.
    This returns True if the source user has a permission specified,
    or if the source and target are both logged in and have the same account.
    """
    assert source in irc.users, "Unknown source user"
    assert target in irc.users, "Unknown target user"
    try:
        permissions.checkPermissions(irc, source, perms)
    except utils.NotAuthorizedError:
        if irc.users[source].account and (irc.users[source].account
                                          == irc.users[target].account):
            return True
        else:
            raise
    else:
        return True
示例#32
0
def listrec(irc, source, args):
    """<blacklist>
    Lists all records for a blacklist
    """
    permissions.checkPermissions(irc, source, ["dnsbl.rlist"])    
    args = dnsbl_listrec.parse_args(args)
    bls = Blacklists()
    config = bls._dict()
    records = []
    try:
        for k, v in config['blacklists'][args.blacklist]['records'].items():
            records.append('%s - %s' % (k, v))
        msg_bls = 'Records: %s' % (' \xB7 '.join(records))
        irc.reply(msg_bls)
    except KeyError:
        if opts.blacklist:
            if config.get('blacklists').get(opts.blacklist):
                irc.reply("%s doesn't have a records section.")
示例#33
0
def loglevel(irc, source, args):
    """<level>

    Sets the log level to the given <level>. <level> must be either DEBUG, INFO, WARNING, ERROR, or CRITICAL.
    If no log level is given, shows the current one."""
    permissions.checkPermissions(irc, source, ['commands.loglevel'])
    try:
        level = args[0].upper()
        try:
            loglevel = loglevels[level]
        except KeyError:
            irc.error('Unknown log level "%s".' % level)
            return
        else:
            world.console_handler.setLevel(loglevel)
            irc.reply("Done.")
    except IndexError:
        irc.reply(world.console_handler.level)
示例#34
0
文件: exec.py 项目: Ro9ueAdmin/PyLink
def raw(irc, source, args):
    """<text>

    Admin-only. Sends raw text to the uplink IRC server.

    \x02**WARNING: THIS CAN BREAK YOUR NETWORK IF USED IMPROPERLY!**\x02"""
    permissions.checkPermissions(irc, source, ['exec.raw'])

    args = ' '.join(args)
    if not args.strip():
        irc.reply('No text entered!')
        return

    log.debug('(%s) Sending raw text %r to IRC for %s', irc.name, args,
              irc.getHostmask(source))
    irc.send(args)

    irc.reply("Done.")
示例#35
0
def cf_show(irc, source, args):
    """[<subdomain>] [--type <type>] [--content <record content>] [--order <sort order>]

    Searches CloudFlare DNS records. The following options are supported:

    -t / --type : Type of record

    -c / --content : Content of record / IP

    -o / --order : Order by ... (type, content, name)
    """
    permissions.checkPermissions(irc, source, ['cloudflare.cf-show'])
    cf = get_cf()
    zone = conf.conf.get("cloudflare", {}).get('target_zone')
    if not zone:
        irc.error("No target zone ID specified! Configure it via a 'cloudflare::target_zone' option.")
        return

    args = cf_show_parser.parse_args(args)

    body = {
        "order": args.order,
        "type":  args.type
    }

    if args.subdomain:
        # Add the domain to the lookup name so that less typing is needed.
        base_domain = cf.zones.get(zone)['result']['name']
        body["name"] = '%s.%s' % (args.subdomain, base_domain)
    if args.content:
        body["content"] = args.content

    response = cf.zones.dns_records.get(zone, params=body)

    count = response.get("result_info", {}).get("count", 0)
    result = response.get("result", [])
    irc.reply("Found %d records" % count, private=False)
    for res in result:
        irc.reply("\x02Name\x02: %(name)s \x02Content\x02: %(content)s" % res, private=False)
        irc.reply("\x02ID\x02: %(id)s" % res, private=False)