Convert flagd to use medusa

This commit is contained in:
Neale Pickett 2009-08-31 21:15:13 -06:00
parent efe3f5c5b9
commit c2d685005b
2 changed files with 132 additions and 56 deletions

170
flagd.py
View File

@ -1,8 +1,9 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import socketserver import asyncore
import threading import asynchat
import queue import socket
import functools
import time import time
import hmac import hmac
import optparse import optparse
@ -14,63 +15,129 @@ key = b'My First Shared Secret (tm)'
def hexdigest(data): def hexdigest(data):
return hmac.new(key, data).hexdigest() return hmac.new(key, data).hexdigest()
house = 'dirtbags' # House team name class Submitter(asyncore.dispatcher):
flags = {} def __init__(self, host='localhost', port=6667):
toscore = queue.Queue(50) asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_DGRAM)
self.connect((host, port))
self.pending = []
self.unacked = {}
self.flags = {}
self.lastupdate = 0
self.lastretrans = 0
self.id = 0
class Submitter(threading.Thread): def submit(self, now, cat, team, score):
def run(self): q = points.encode_request(self.id, now, cat, team, score)
self.sock = pointscli.makesock('localhost') self.id += 1
while True: self.pending.append(q)
self.unacked[id] = q
def writable(self):
print('writable?')
now = int(time.time())
if now >= self.lastupdate + 60:
for cat, team in self.flags.items():
self.submit(now, cat, team, 1)
self.lastupdate = now
if now > self.lastretrans:
for id, q in self.unacked.items():
self.pending.append(q)
self.lastretrans = now
ret = bool(self.pending)
print(ret)
return ret
def handle_write(self):
dgram = self.pending.pop(0)
self.socket.send(dgram)
def handle_read(self):
dgram, peer = self.socket.recvfrom(4096)
try: try:
delay = 60 - (time.time() % 60) id, txt = points.decode_response(dgram)
cat, team = toscore.get(True, delay) except ValueError:
self.submit(cat, team) # Ignore invalid packets
except queue.Empty: return
self.once()
def once(self):
global flags
global toscore
for cat, team in flags.items():
self.submit(cat, team)
def submit(self, cat, team):
try: try:
pointscli.submit(self.sock, cat, team, 1) del self.unacked[id]
except: except KeyError:
traceback.print_exc() pass
if txt != 'OK':
raise ValueError(txt)
def set_flag(self, cat, team):
now = int(time.time())
team = team or points.house
self.flags[cat] = team
self.submit(now, cat, team, 1)
class CategoryHandler(socketserver.StreamRequestHandler): class Listener(asyncore.dispatcher):
def handle(self): def __init__(self, connection_factory, host='localhost', port=6668):
global flags asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((host, port))
self.listen(4)
self.connection_factory = connection_factory
def handle_accept(self):
conn, addr = self.accept()
self.connection_factory(conn)
class FlagServer(asynchat.async_chat):
def __init__(self, submitter, sock):
asynchat.async_chat.__init__(self, sock=sock)
self.set_terminator(b'\n')
self.submitter = submitter
self.flag = None
self.inbuf = []
self.cat = None
def err(self, txt):
e = ('ERROR: Closing Link: %s\n' % txt)
self.push(e.encode('utf-8'))
self.close()
def collect_incoming_data(self, data):
if len(self.inbuf) > 10:
return self.err('max sendq exceeded')
self.inbuf.append(data)
def set_flag(self, team):
self.flag = team
if self.cat:
self.submitter.set_flag(self.cat, team)
def found_terminator(self):
data = b''.join(self.inbuf)
self.inbuf = []
if not self.cat:
try: try:
catpass = self.rfile.readline().strip() cat, passwd = data.split(b':::')
cat, passwd = catpass.split(b':::')
passwd = passwd.decode('utf-8') passwd = passwd.decode('utf-8')
if passwd != hexdigest(cat): if passwd != hexdigest(cat):
self.wfile.write(b'ERROR :Closing Link: Invalid password\n') return self.err('Invalid password')
return self.cat = cat.decode('utf-8')
cat = cat.decode('utf-8') except ValueError:
except ValueError as foo: return self.err('Invalid command')
self.wfile.write(b'ERROR :Closing Link: Invalid command\n') self.set_flag(None)
return else:
team = data.strip().decode('utf-8')
self.set_flag(team)
flags[cat] = house def handle_close(self):
while True: self.set_flag(None)
team = self.rfile.readline().strip().decode('utf-8')
if not team:
break
flags[cat] = team
toscore.put((cat, team)) # score a point immediately
flags[cat] = house
class MyServer(socketserver.ThreadingTCPServer):
allow_reuse_address = True
def start():
submitter = Submitter()
server = Listener(functools.partial(FlagServer, submitter))
return (submitter, server)
def main(): def main():
p = optparse.OptionParser() p = optparse.OptionParser()
@ -81,11 +148,8 @@ def main():
print('%s:::%s' % (opts.cat, hexdigest(opts.cat.encode('utf-8')))) print('%s:::%s' % (opts.cat, hexdigest(opts.cat.encode('utf-8'))))
return return
submitter = Submitter() start()
submitter.start() asyncore.loop()
server = MyServer(('', 6668), CategoryHandler)
server.serve_forever()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

12
ubersrv.py Executable file
View File

@ -0,0 +1,12 @@
#! /usr/bin/env python3
import asyncore
import pointsd
import flagd
def main():
pointsd.start()
flagd.start()
asyncore.loop(timeout=30, use_poll=True)
main()