globalforest/cncbot.py

92 lines
3.2 KiB
Python
Raw Normal View History

2020-10-17 12:22:22 -04:00
import pydle
2020-10-25 16:05:46 -04:00
import asyncio
from asyncio import new_event_loop, gather, get_event_loop, sleep
2020-10-17 12:22:22 -04:00
import random
import string
2020-10-25 16:05:46 -04:00
import time
2020-10-17 12:22:22 -04:00
2020-10-18 19:16:32 -04:00
CNC_HOST='dark.deflax.net'
CNC_CHANNEL='#izba'
2020-10-17 12:22:22 -04:00
ADMIN_NICKNAMES = [ 'afx' ]
2020-10-18 19:16:32 -04:00
MOTD='] Forest CnC ready!'
2020-10-17 12:22:22 -04:00
def get_random_string(length):
letters = string.ascii_lowercase
result_str = ''.join(random.choice(letters) for i in range(length))
return result_str
2020-10-25 16:05:46 -04:00
class ForestBot(pydle.Client):
2020-10-17 12:22:22 -04:00
async def on_connect(self):
await super().on_connect()
2020-10-18 19:16:32 -04:00
await self.join(CNC_CHANNEL)
await self.message(CNC_CHANNEL, MOTD)
2020-10-17 12:22:22 -04:00
async def is_admin(self, nickname):
"""
Check whether or not a user has administrative rights for this bot.
This is a blocking function: use a coroutine to call it.
See pydle's documentation on blocking functionality for details.
"""
admin = False
# Check the WHOIS info to see if the source has identified with NickServ.
# This is a blocking operation, so use yield.
if nickname in ADMIN_NICKNAMES:
info = await self.whois(nickname)
2020-10-18 19:16:32 -04:00
print('] Detected privileged request from {}'.format(info))
2020-10-17 12:22:22 -04:00
admin = info['identified']
return admin
async def on_message(self, target, source, message):
await super().on_message(target, source, message)
2020-10-18 13:53:02 -04:00
2020-10-18 19:16:32 -04:00
# Print help
if message.startswith('help {}'.format(self.nickname)):
await self.message(target, '] cnc usage:')
await self.message(target, '] help - displays help')
await self.message(target, '] id - cnc user info')
2020-10-25 16:05:46 -04:00
await self.message(target, '] dump - dump cnc log')
2020-10-18 19:16:32 -04:00
# Show user info
if message.startswith('id {}'.format(self.nickname)):
2020-10-17 12:22:22 -04:00
admin = await self.is_admin(source)
if admin:
2020-10-18 19:16:32 -04:00
await self.message(target, '] You are an administrator. :)'.format(source))
2020-10-17 12:22:22 -04:00
else:
2020-10-18 19:16:32 -04:00
await self.message(target, '] You are NOT an administrator. :('.format(source))
2020-10-25 16:05:46 -04:00
if message.startswith('dump {}'.format(self.nickname)):
admin = await self.is_admin(source)
if admin:
await self.dumplog(target)
2020-10-25 21:48:06 -04:00
else:
await self.message(target, '] You are NOT an administrator. :('.format(source))
2020-10-25 16:05:46 -04:00
async def dumplog(self, target):
2020-10-25 21:48:06 -04:00
sleep_time = 1
2020-10-25 16:05:46 -04:00
while True:
msg = self.queue.get()
2020-10-25 21:48:06 -04:00
await asyncio.sleep(sleep_time)
2020-10-25 16:05:46 -04:00
await self.message(target, msg)
if len(msg) == 0:
break
def run(self, *args, **kwargs):
self.queue = kwargs['extqueue']
2020-10-25 21:48:06 -04:00
loop = self.eventloop
#loop.run_until_complete(self.connect(*args, **kwargs))
loop.run_until_complete(self.connect(*args))
2020-10-25 16:05:46 -04:00
try:
2020-10-25 21:48:06 -04:00
loop.run_forever()
2020-10-25 16:05:46 -04:00
finally:
2020-10-25 21:48:06 -04:00
loop.stop()
2020-10-25 16:05:46 -04:00
def CnCApp(queue):
botnick = 'cnc_' + get_random_string(8)
botnick_fallback = [botnick + '_re']
cnc = ForestBot(botnick, botnick_fallback, botnick, botnick, None)
cnc.run(CNC_HOST, tls=False, tls_verify=False, extqueue=queue)
2020-10-18 13:53:02 -04:00
if __name__ == '__main__':
CnCApp()