123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- from __future__ import print_function
- import willie
- import netaddr
- import urllib2
- import re
- import os
- import subprocess
- import socket
- import SocketServer
- import threading
- msgserver = None
- # TODO: move into config file :)
- msgserver_known_senders = {
- "127.0.0.1": "localhost",
- "10.132.254.1": "gw01",
- "10.132.254.2": "gw02",
- "10.132.254.3": "gw03",
- "10.132.254.80": "public"
- }
- class MsgHandler(SocketServer.BaseRequestHandler):
- def handle(self):
- self.data = self.request.recv(2048).strip()
- sender = self.client_address[0]
- if sender in msgserver_known_senders:
- sender = msgserver_known_senders[sender]
- bot = self.server.bot
- if bot is None:
- print("ERROR: No bot in handle() :-(")
- return
- target = bot.config.core.owner
- if bot.config.has_section('ffpb') and not (bot.config.ffpb.msg_target is None):
- target = bot.config.ffpb.msg_target
- bot.msg(target, "[{0}] {1}".format(sender,self.data))
- class ThreadingTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
- pass
- def setup(bot):
- global msgserver
- if bot.config.has_section('ffpb') and bot.config.ffpb.msg_enable:
- host = "localhost"
- port = 4342
- if not bot.config.ffpb.msg_host is None: host = bot.config.ffpb.msg_host
- if not bot.config.ffpb.msg_port is None: port = int(bot.config.ffpb.msg_port)
- msgserver = ThreadingTCPServer((host,port), MsgHandler)
- msgserver.bot = bot
- ip, port = msgserver.server_address
- print("Messaging server listening on {}:{}".format(ip,port))
- msgserver_thread = threading.Thread(target=msgserver.serve_forever)
- msgserver_thread.daemon = True
- msgserver_thread.start()
- def shutdown(bot):
- global msgserver
- if not msgserver is None:
- msgserver.shutdown()
- print("Closed messaging server.")
- msgserver = None
- @willie.module.commands('status')
- def ffpb_status(bot, trigger):
- """Status des FFPB-Netzes: Anzahl (aktiver) Knoten + Clients"""
- response = urllib2.urlopen('http://nodecount.paderborn.freifunk.net/')
- html = response.read()
- m = re.search('<div id="nodecount">\s*(\d+)\s*</div>', html)
- nodecount = int(m.group(1))
- bot.say('nodecount = {}'.format(nodecount))
- def ffpb_get_address(name):
- peerfilename = '/home/ffpb-statusbot/knoten/' + name
- peer_mac = None
- if os.path.exists(peerfilename):
- peerfile = open(peerfilename, "r")
- for line in peerfile:
- if line.startswith("# MAC:"):
- peer_mac = line[6:].strip()
- peerfile.close()
- print("peer '", name, "': file '", peerfilename, "', MAC ", peer_mac, sep='')
- if not (peer_mac is None):
- return str(netaddr.EUI(peer_mac).ipv6_link_local())
- return None
- @willie.module.commands('ping')
- def ffpb_ping(bot, trigger):
- """Ping FFPB-Knoten"""
- target_name = trigger.group(2)
- if target_name is None or len(target_name) == 0:
- bot.say('Alter, wen soll ich denn pingen? Einmal mit Profis arbeiten -.-')
- return
- target = ffpb_get_address(target_name)
- if target is None:
- bot.say('Kein Plan wer mit \'' + target_name + '\' gemeint ist :/')
- return
- if target.startswith('fe80::'):
- target = 'fdca:ffee:ff12:132:' + target[6:]
- print("ping '", target , '"', sep='')
- result = os.system('ping6 -c 1 -W 2 ' + target + ' 2>/dev/null')
- if result == 0:
- bot.say('Knoten "' + target_name + '" antwortet \o/')
- elif result == 1 or result == 256:
- bot.say('Keine Antwort von "' + target_name + '" :-(')
- else:
- bot.say('Uh oh, irgendwas ist kaputt. Chef, ping result = ' + str(result) + ' - darf ich das essen?')
-
- @willie.module.commands('exec-on-peer')
- def ffpb_remoteexec(bot, trigger):
- """Remote Execution fuer FFPB_Knoten"""
- bot_params = trigger.group(2).split(' ',1)
- if len(bot_params) != 2:
- bot.say('Wenn du nicht sagst wo mach ich remote execution bei dir!')
- bot.say('Tipp: !exec-on-peer <peer> <cmd>')
- return
- target_name = bot_params[0]
- target_cmd = bot_params[1]
- if not trigger.admin:
- bot.say('Captcha required: https://xkcd.com/565/')
- return
- target = ffpb_get_address(target_name)
- if target is None:
- bot.say('Kein Plan wer mit \'' + target_name + '\' gemeint ist :/')
- if target.startswith('fe80::'):
- target = 'fdca:ffee:ff12:132:' + target[6:]
- cmd = 'ssh -6 -l root ' + target + ' -- "' + target_cmd + '"'
- print("REMOTE EXEC = " + cmd)
- try:
- result = subprocess.check_output(['ssh', '-6n', '-l', 'root', '-o', 'BatchMode=yes', '-o','StrictHostKeyChecking=no', target, target_cmd], stderr=subprocess.STDOUT, shell=False)
- lines = str(result).splitlines()
- bot.say('exec-on-peer(' + target_name + '): ' + str(len(lines)) + ' Zeilen (zeige max. 8):')
- for line in lines[0:8]:
- bot.say(line)
-
- except subprocess.CalledProcessError, e:
- bot.say('Fehler '+str(e.returncode)+' bei exec-on-peer('+target_name+'): ' + e.output)
|