diff --git a/Makefile b/Makefile index d644fd8..e6dd21d 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,10 @@ target: $(PYC) $(INSTALL) -d $(PYCDIR)/ctf $(INSTALL) $(PYC) $(PYCDIR)/ctf + $(INSTALL) -d $(DESTDIR)/usr/lib/python2.6/site-packages/ctf + $(INSTALL) ctf/__init__.py $(DESTDIR)/usr/lib/python2.6/site-packages/ctf + $(INSTALL) ctf/config.py $(DESTDIR)/usr/lib/python2.6/site-packages/ctf + $(INSTALL) -d $(DESTDIR)/usr/sbin $(INSTALL) ctfd.py $(DESTDIR)/usr/sbin $(INSTALL) new-contest $(DESTDIR)/usr/sbin diff --git a/ctf.css b/ctf.css index d3c033a..0d6ed28 100644 --- a/ctf.css +++ b/ctf.css @@ -7,7 +7,7 @@ html { body { font-family: sans-serif; color: #fff; - margin: 50px 0 0 100px; + margin: 50px 0 0 110px; padding: 10px; max-width: 700px; } @@ -30,6 +30,54 @@ h1:first-child:before { content: "Capture The Flag: "; } +/*** left side bar ***/ + +#navigation { + position: absolute; + background: #222; + opacity: 0.9; + top: 80px; + left: 0px; + padding: 0; +} + +#navigation h3 { + font-size: 100%; + border-bottom: 2px solid #444; +} + +#navigation ul { + list-style: none; + padding: 0; + margin: 0; +} + +#navigation li a { + display: block; + height: 25px; + width: 90px; + padding: 5px; + margin: 5px; + background: inherit; + border-right: 4px solid #444; + color: #999; + text-transform: lowercase; + font-size: 0.9em; +} + +#navigation li a:hover { + color: #f4f4f4; + background: #333; + border-right: 4px solid #2a2; +} + +#navigation li .active { + color: #999; + background: #333; + border-right: 4px solid #444; +} + + /**** body ****/ a img { @@ -64,6 +112,39 @@ th, td { vertical-align: top; } +p { + line-height: 1.4em; + margin-bottom: 20px; + color: #f4f4f4; +} + +hr { + border: 1px solid #444; +} + +dt { + white-space: pre; + background-color: #333; + padding: 5px; + border: 2px solid green; + border-bottom: none; + font-weight: bold; +} + +dd { + border: 2px solid green; + margin: 0px; + padding: 5px; + background-color: #282828; +} + + +/**** special cases ****/ + +.wide { + max-width: inherit; +} + .scoreboard { background: #222; } @@ -72,24 +153,20 @@ th, td { height: 400px; } -p { - line-height: 1.4em; - margin-bottom: 20px; - color: #f4f4f4; -} - .solved { text-decoration: line-through; } table.pollster { - margin-left: 5em; + margin-left: 5em; } table.pollster td { - padding: 2px 1em 2px 5px; + padding: 2px 1em 2px 5px; } table.pollster thead { - font-weight: bold; + font-weight: bold; } + + diff --git a/ctf/config.py b/ctf/config.py index 65f9ae2..1bdbe96 100755 --- a/ctf/config.py +++ b/ctf/config.py @@ -28,27 +28,33 @@ if 'home' in os.environ.get('SCRIPT_FILENAME', ''): } else: # An actual installation - config = {'global': - {'data_dir': '/var/lib/ctf', - 'base_url': '/', - 'css_url': '/ctf.css', - 'disabled_dir': '/var/lib/ctf/disabled', - 'flags_dir': '/var/lib/ctf/flags', - 'house_team': 'dirtbags', - 'passwd': '/var/lib/ctf/passwd', - 'team_colors': team_colors, - 'poll_interval': 60, - 'poll_timeout': 0.5, - 'heartbeat_dir': '/var/lib/pollster', - 'poll_dir': '/var/lib/www', - }, - 'puzzler': - {'dir': '/usr/lib/www/puzzler', - 'cgi_url': '/puzzler.cgi', - 'base_url': '/puzzler', - 'keys_file': '/usr/lib/ctf/puzzler.keys', - }, - } + config = { + 'global': + { + 'data_dir': '/var/lib/ctf', + 'base_url': '/', + 'css_url': '/ctf.css', + 'disabled_dir': '/var/lib/ctf/disabled', + 'flags_dir': '/var/lib/ctf/flags', + 'house_team': 'dirtbags', + 'passwd': '/var/lib/ctf/passwd', + 'team_colors': team_colors, + }, + 'pollster': + { + 'poll_interval': 60, + 'poll_timeout': 0.5, + 'heartbeat_dir': '/var/lib/pollster', + 'results': '/var/lib/pollster/status.html', + }, + 'puzzler': + { + 'dir': '/usr/lib/www/puzzler', + 'cgi_url': '/puzzler.cgi', + 'base_url': '/puzzler', + 'keys_file': '/usr/lib/ctf/puzzler.keys', + }, + } def get(section, key): return config[section][key] @@ -71,22 +77,45 @@ def datafile(filename): def url(path): return base_url + path -def start_html(title): +def start_html(title, hdr='', cls='', links=[], links_title=None): + ret = [] if os.environ.get('GATEWAY_INTERFACE'): - print('Content-type: text/html') - print() - print(''' + ret.append('Content-type: text/html') + ret.append('') + ret.append('''
-