diff --git a/ctf/flagd.py b/ctf/flagd.py index 6ae444b..f827972 100755 --- a/ctf/flagd.py +++ b/ctf/flagd.py @@ -142,6 +142,8 @@ class FlagServer(asynchat.async_chat): self.inbuf.append(data) def set_flag(self, team): + if not self.cat: + return self.flag = team self.submitter.set_flag(self.cat, team) f = open(os.path.join(flags_dir, self.cat), 'w') diff --git a/pwnables/Makefile b/pwnables/Makefile index 7eca8ef..5327560 100644 --- a/pwnables/Makefile +++ b/pwnables/Makefile @@ -18,4 +18,4 @@ target: $(MAKE) -C daemons TARGET=$(TARGET) install clean: - rm -rf target + rm -rf target pwnables.tce diff --git a/pwnables/skel/usr/lib/www/flag b/pwnables/skel/usr/lib/www/flag new file mode 120000 index 0000000..f4bdb9f --- /dev/null +++ b/pwnables/skel/usr/lib/www/flag @@ -0,0 +1 @@ +/var/lib/cat/flag \ No newline at end of file diff --git a/tanks/Makefile b/tanks/Makefile index 1310b71..4c83034 100644 --- a/tanks/Makefile +++ b/tanks/Makefile @@ -24,7 +24,7 @@ target: $(INSTALL) -d target/usr/lib/www/tanks/ $(INSTALL) www/* target/usr/lib/www/tanks/ - ln -s /var/lib/tanks target/usr/lib/www/tanks/results + ln -s /var/lib/tanks/results target/usr/lib/www/tanks/results $(INSTALL) -d target/usr/lib/python2.6/site-packages/tanks/ $(INSTALL) lib/* target/usr/lib/python2.6/site-packages/tanks/ diff --git a/tanks/lib/Pflanzarr.py b/tanks/lib/Pflanzarr.py index 0922d49..d7d50e0 100644 --- a/tanks/lib/Pflanzarr.py +++ b/tanks/lib/Pflanzarr.py @@ -201,16 +201,25 @@ class Pflanzarr: break winner = random.choice(winners) - html = ['
', + html = ['', + 'Team | Kills | Cause of Death'] for tank in tanks: if tank is winner: - rowStyle = 'style="color:red;"' + rowStyle = 'style="font-weight:bold; '\ + 'background-color:%s"' % tank._color else: - rowStyle = '' + rowStyle = 'style="background-color:%s"' % tank._color + if name: + name = xml.sax.saxutils.escape(tank.name) + else: + name = '#default' html.append(' |
---|---|---|
%s | %d | %s' %
(rowStyle,
- xml.sax.saxutils.escape(tank.name),
+ name,
len(kills[tank]),
xml.sax.saxutils.escape(tank.deathReason)))
diff --git a/tanks/lib/Tank.py b/tanks/lib/Tank.py
index dffa85e..7042a59 100644
--- a/tanks/lib/Tank.py
+++ b/tanks/lib/Tank.py
@@ -75,7 +75,7 @@ class Tank(object):
else:
self._tAngle = tAngle
- self._color = color
+ self.color = color
# You can't fire until fireReady is 0.
self._fireReady = self.FIRE_RATE
@@ -466,7 +466,7 @@ class Tank(object):
# The base body rectangle.
for poly in gm.displacePoly(hood, self.pos, self._limits):
- d.polygon( poly, fill=self._color )
+ d.polygon( poly, fill=self.color )
# The treads
for poly in gm.displacePoly(tread1, self.pos, self._limits) + \
@@ -475,7 +475,7 @@ class Tank(object):
# The turret circle
for poly in gm.displacePoly(self.body, self.pos, self._limits):
- d.ellipse( poly, fill=self._color, outline='black')
+ d.ellipse( poly, fill=self.color, outline='black')
self._drawLaser(d)
@@ -491,7 +491,7 @@ class Tank(object):
if self._fired:
laser = gm.rotatePoly( self.laser, self._angle + self._tAngle )
for poly in gm.displacePoly(laser, self.pos, self._limits):
- drawing.polygon(poly, fill=self._color)
+ drawing.polygon(poly, fill=self.color)
self._fired = False
@@ -522,7 +522,7 @@ class Tank(object):
if self._sensorState[i]:
color = '#000000'
else:
- color = self._color
+ color = self.color
r, angle, width, tAttached = self._sensors[i]
r = int(r)
diff --git a/tanks/run_tanks.py b/tanks/run_tanks.py
index 11c792a..f680bbe 100755
--- a/tanks/run_tanks.py
+++ b/tanks/run_tanks.py
@@ -1,25 +1,91 @@
#! /usr/bin/python
-import time
import optparse
+import shutil
+import time
+import asyncore
+import asynchat
from tanks import Pflanzarr
T = 60*5
+MAX_HIST = 30
+HIST_STEP = 100
+key = 'tanks:::2bac5e912ff2e1ad559b177eb5aeecca'
-parser = optparse.OptionParser('DATA_DIR easy|medium|hard MAX_TURNS')
-opts, args = parser.parse_args()
-if (len(args) != 3) or (args[1] not in ('easy', 'medium', 'hard')):
- parser.error('Wrong number of arguments')
-try:
- turns = int(args[2])
-except:
- parser.error('Invalid number of turns')
+class Flagger(asynchat.async_chat):
+ """Use to connect to flagd and submit the current flag holder."""
-while True:
- start = time.time()
+ def __init__(self, addr, auth):
+ asynchat.async_chat.__init__(self)
+ self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.connect((addr, 6668))
+ self.push(auth + '\n')
+ self.flag = None
+
+ def handle_read(self):
+ msg = self.recv(4096)
+ raise ValueError("Flagger died: %r" % msg)
+
+ def handle_error(self):
+ # If we lose the connection to flagd, nobody can score any
+ # points. Terminate everything.
+ asyncore.close_all()
+ asynchat.async_chat.handle_error(self)
+
+ def set_flag(self, team):
+ if team:
+ eteam = team
+ else:
+ eteam = ''
+ self.push(eteam + '\n')
+ self.flag = team
+
+
+def run_tanks():
p = Pflanzarr.Pflanzarr(args[0], args[1])
p.run(turns)
- diff = time.time() - start
- if diff - T > 0:
- time.sleep( diff - T )
+ path = os.path.join(args[0], 'results')
+ files = os.listdir(path)
+ gameNums = []
+ for file in files:
+ try:
+ gameNums.append( int(file) )
+ except:
+ continue
+
+ gameNums.sort(reverse=True)
+ highest = gameNums[0]
+ for num in gameNums:
+ if highest - MAX_HIST > num and not (num % HIST_STEP == 0):
+ shutil.rmtree(os.path.join(path, num))
+
+ try:
+ winner = open('/var/lib/tanks/winner').read().strip()
+ except:
+ winner = None
+ flagger.set_flag(winner)
+
+
+def main():
+ parser = optparse.OptionParser('DATA_DIR easy|medium|hard MAX_TURNS')
+ opts, args = parser.parse_args()
+ if (len(args) != 3) or (args[1] not in ('easy', 'medium', 'hard')):
+ parser.error('Wrong number of arguments')
+ try:
+ turns = int(args[2])
+ except:
+ parser.error('Invalid number of turns')
+
+
+ flagger = Flagger('localhost', key)
+ lastrun = 0
+ while True:
+ asyncore.loop(60, count=1)
+ now = time.time()
+ if now - lastrun >= 60:
+ run_tanks()
+ lastrun = now
+
+if __name__ == '__main__':
+ main()
diff --git a/tanks/www/results.cgi b/tanks/www/results.cgi
index a17ee77..ceb4ae2 100755
--- a/tanks/www/results.cgi
+++ b/tanks/www/results.cgi
@@ -28,22 +28,28 @@ except:
if not games:
print " No games have occurred yet." + gameNums = [] for game in games: try: - num = int(game) - path = os.path.join( 'results', game, 'results.html') - if os.path.exists( path ): - gameNums.append( int(num) ) - else: - continue - + gameNums.append( int(game) ) except: continue gameNums.sort(reverse=True) +# Don't include games that haven't completed +i = 0 +num = str(gameNums[i]) +for i in range(len(gameNums)): + path = os.path.join( 'results', str(gameNums[i]), 'results.html') ) + if os.path.exists( path ): + break +gameNums = gameNums[i:] + for num in gameNums: print ' %d - ' % num, print 'v' % num, print 'r' % num + +print '' diff --git a/tanksFlagger/Makefile b/tanksFlagger/Makefile new file mode 100644 index 0000000..7bd61de --- /dev/null +++ b/tanksFlagger/Makefile @@ -0,0 +1,20 @@ +FAKE = fakeroot -s fake -i fake +INSTALL = $(FAKE) install -o 100 + +all: tanksFlagger.tce + +push: tanksFlagger.tce + netcat -l -q 0 -p 3333 < tanksFlagger.tce + +tanksFlagger.tce: target + $(FAKE) sh -c 'cd target && tar -czf - .' > $@ + +target: + $(INSTALL) -d target/var/service/tanksFlagger + $(INSTALL) run report_score.py target/var/service/tanksFlagger/ + + $(INSTALL) -d target/var/service/tanksFlagger/log/ + $(INSTALL) log.run target/var/service/tanksFlagger/log/run + +clean: + rm -rf target tanksFlagger.tce fake diff --git a/tanksFlagger/log.run b/tanksFlagger/log.run new file mode 100755 index 0000000..f7a77bf --- /dev/null +++ b/tanksFlagger/log.run @@ -0,0 +1,3 @@ +#! /bin/sh + +exec logger -t tanksFlagger diff --git a/tanks/report_score.py b/tanksFlagger/report_score.py similarity index 100% rename from tanks/report_score.py rename to tanksFlagger/report_score.py diff --git a/tanksFlagger/run b/tanksFlagger/run new file mode 100755 index 0000000..e2eb214 --- /dev/null +++ b/tanksFlagger/run @@ -0,0 +1,5 @@ +#! /bin/sh + +[ -f /var/lib/ctf/disabled/tanks ] && exit 0 + +exec envuidgid ctf python3 report_score.py 2>&1 |