mirror of https://github.com/dirtbags/moth.git
Modularize + lots of fixes
This commit is contained in:
parent
c246ad4d75
commit
48c6ca0aa2
12
Makefile
12
Makefile
|
@ -1,12 +0,0 @@
|
|||
SUBDIRS = src
|
||||
|
||||
all: build
|
||||
|
||||
include $(addsuffix /*.mk, $(SUBDIRS))
|
||||
|
||||
test: build
|
||||
./test.sh
|
||||
|
||||
build: $(addsuffix -build, $(SUBDIRS))
|
||||
clean: $(addsuffix -clean, $(SUBDIRS))
|
||||
|
37
bin/run-ctf
37
bin/run-ctf
|
@ -1,37 +0,0 @@
|
|||
#! /bin/sh
|
||||
|
||||
# First argument is seconds between running everything
|
||||
period=${1:-60}
|
||||
|
||||
CTF_BASE=${CTF_BASE:-/srv/ctf} export CTF_BASE
|
||||
|
||||
POINTS=$CTF_BASE/points.log
|
||||
SCOREBOARD=$CTF_BASE/www/scoreboard.html
|
||||
PUZZLES=$CTF_BASE/www/puzzles.html
|
||||
|
||||
while true; do
|
||||
start=$(date +%s)
|
||||
next=$(expr $start + $period)
|
||||
|
||||
# Collect any new points
|
||||
for fn in $CTF_BASE/points.new/*; do
|
||||
[ -f $fn ] || continue
|
||||
cat $fn >> $POINTS || break
|
||||
rm $fn
|
||||
done
|
||||
|
||||
if [ $POINTS -nt $SCOREBOARD ]; then
|
||||
$CTF_BASE/sbin/scoreboard < $POINTS > $SCOREBOARD.new
|
||||
mv $SCOREBOARD.new $SCOREBOARD
|
||||
fi
|
||||
|
||||
if [ $CTF_BASE/puzzler.db -nt $PUZZLES ]; then
|
||||
$CTF_BASE/sbin/puzzles.cgi > $PUZZLES.new
|
||||
mv $PUZZLES.new $PUZZLES
|
||||
fi
|
||||
|
||||
now=$(date +%s)
|
||||
if [ $now -lt $next ]; then
|
||||
sleep $(expr $next - $now)
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,32 @@
|
|||
SUBDIRS = src
|
||||
PKGDIR = pkg
|
||||
PACKAGE = mcp.pkg
|
||||
|
||||
all: package
|
||||
|
||||
package: $(PACKAGE)
|
||||
|
||||
$(PACKAGE): build
|
||||
mkdir -p $(PKGDIR)
|
||||
|
||||
cp setup $(PKGDIR)
|
||||
|
||||
find bin -not -name '*~' | cpio -p $(PKGDIR)
|
||||
cp src/in.tokend src/pointscli $(PKGDIR)/bin
|
||||
|
||||
find service -not -name '*~' -not -name '#*' | cpio -p $(PKGDIR)
|
||||
|
||||
find www -not -name '*~' -not -name '#*' | cpio -p $(PKGDIR)
|
||||
cp src/puzzler.cgi src/puzzles.cgi src/claim.cgi $(PKGDIR)/www
|
||||
|
||||
mksquashfs $(PKGDIR) $(PACKAGE) -all-root -noappend
|
||||
|
||||
|
||||
include $(addsuffix /*.mk, $(SUBDIRS))
|
||||
|
||||
test: build
|
||||
./test.sh
|
||||
|
||||
build: $(addsuffix -build, $(SUBDIRS))
|
||||
clean: $(addsuffix -clean, $(SUBDIRS))
|
||||
rm -rf $(PKGDIR) $(PACKAGE)
|
|
@ -8,7 +8,7 @@ fi
|
|||
# Don't overwrite files
|
||||
set -C
|
||||
|
||||
base=${CTF_BASE:-/srv/ctf}
|
||||
base=${CTF_BASE:-/var/lib/ctf}
|
||||
|
||||
# Assign a color. I spent two days selecting this color pallette for
|
||||
# people with protanopia. Please don't change these colors.
|
|
@ -0,0 +1,55 @@
|
|||
#! /bin/sh
|
||||
|
||||
# First argument is seconds between running everything
|
||||
period=${1:-60}
|
||||
|
||||
BIN=${CTF_BASE:-/opt/mcp}/bin
|
||||
WWW=${CTF_BASE:-/var}/www
|
||||
STATE=${CTF_BASE:-/var/lib/ctf}
|
||||
|
||||
NEWPOINTS=$STATE/points.new
|
||||
POINTS=$STATE/points.log
|
||||
SCOREBOARD=$WWW/scoreboard.html
|
||||
PUZZLES=$WWW/puzzles.html
|
||||
TEAMS=$WWW/teams.html
|
||||
|
||||
mkdir -p $NEWPOINTS $STATE/teams/names $STATE/teams/colors
|
||||
touch $POINTS
|
||||
if ! [ -f $SCOREBOARD ]; then
|
||||
$BIN/scoreboard < $POINTS > $SCOREBOARD
|
||||
done
|
||||
|
||||
while true; do
|
||||
start=$(date +%s)
|
||||
next=$(expr $start + $period)
|
||||
|
||||
# Collect any new points
|
||||
for fn in $NEWPOINTS/*; do
|
||||
[ -f $fn ] || continue
|
||||
cat $fn >> $POINTS || break
|
||||
rm $fn
|
||||
done
|
||||
|
||||
# Render scoreboard
|
||||
if [ $POINTS -nt $SCOREBOARD ]; then
|
||||
$BIN/scoreboard < $POINTS > $SCOREBOARD.new
|
||||
mv $SCOREBOARD.new $SCOREBOARD
|
||||
fi
|
||||
|
||||
# Render puzzles list
|
||||
if [ $STATE/puzzler.db -nt $PUZZLES ]; then
|
||||
$WWW/puzzles.cgi > $PUZZLES.new
|
||||
mv $PUZZLES.new $PUZZLES
|
||||
fi
|
||||
|
||||
# Render team names
|
||||
if [ $STATE/teams/names -nt $TEAMS ]; then
|
||||
$BIN/teams.sh > $TEAMS.new
|
||||
mv $TEAMS.new $TEAMS
|
||||
fi
|
||||
|
||||
now=$(date +%s)
|
||||
if [ $now -lt $next ]; then
|
||||
sleep $(expr $next - $now)
|
||||
fi
|
||||
done
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
##
|
||||
##
|
||||
## I'm not happy with how this code looks. I've
|
||||
## I'm not super happy with how this code looks. Rest assured, though,
|
||||
## the C version would look far, far worse.
|
||||
##
|
||||
##
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
#! /bin/sh
|
||||
|
||||
cd /var/lib/ctf/teams/names
|
||||
|
||||
escape () {
|
||||
sed 's/&/\&/g;s/</\</g;s/>/\>/g'
|
||||
}
|
||||
|
@ -27,6 +29,7 @@ done
|
|||
echo "</table>"
|
||||
|
||||
cat <<EOF
|
||||
<p>Use your team's token to claim points.</p>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
|
@ -0,0 +1,5 @@
|
|||
#! /bin/sh -e
|
||||
|
||||
ifconfig eth0 10.0.0.1 netmask 255.0.0.0
|
||||
|
||||
exec inotifyd true $(pwd):x
|
|
@ -0,0 +1,41 @@
|
|||
Umask 026
|
||||
|
||||
Log /dev/stdout
|
||||
ErrorLog /dev/stderr
|
||||
|
||||
User nobody
|
||||
StayRoot On
|
||||
|
||||
Tuning {
|
||||
Timeout 5
|
||||
ScriptTimeout 5
|
||||
}
|
||||
|
||||
Control {
|
||||
ScriptUser ctf
|
||||
|
||||
Types {
|
||||
application/javascript { .js }
|
||||
text/html { .html }
|
||||
text/plain { .txt }
|
||||
text/css { .css }
|
||||
image/png { .png }
|
||||
image/jpeg { .jpg }
|
||||
image/gif { .gif }
|
||||
application/octet-stream { * }
|
||||
}
|
||||
Specials {
|
||||
CGI { .cgi }
|
||||
}
|
||||
IndexNames { index.html }
|
||||
}
|
||||
|
||||
Server {
|
||||
Virtual {
|
||||
AnyHost
|
||||
Control {
|
||||
Alias /
|
||||
Location /var/www
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#! /bin/sh
|
||||
|
||||
exec mathopd -n -f ./mathopd.conf >> /var/log/mathopd.log 2>> /var/log/mathopd.error.log
|
|
@ -0,0 +1,3 @@
|
|||
#! /bin/sh
|
||||
|
||||
exec logger -t mcp
|
|
@ -0,0 +1,4 @@
|
|||
#! /bin/sh
|
||||
|
||||
exec 2>&1
|
||||
exec /opt/mcp/bin/run-ctf
|
|
@ -0,0 +1,3 @@
|
|||
#! /bin/sh
|
||||
|
||||
exec logger -t tokend
|
|
@ -0,0 +1,4 @@
|
|||
#! /bin/sh
|
||||
|
||||
exec 2>&1
|
||||
exec tcpsvd -u ctf 0 1 /opt/mcp/bin/in.tokend
|
|
@ -0,0 +1,8 @@
|
|||
#! /bin/sh
|
||||
|
||||
## Set up this package
|
||||
|
||||
hostname mcp
|
||||
|
||||
cp -r service/* /var/service
|
||||
cp -r www /var
|
|
@ -48,7 +48,7 @@ main(int argc, char *argv[])
|
|||
|
||||
|
||||
/* Does the token exist? */
|
||||
if (! fgrepx(token, srv_path("tokens.db"))) {
|
||||
if (! fgrepx(token, state_path("tokens.db"))) {
|
||||
cgi_page("Token does not exist", "");
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ main(int argc, char *argv[])
|
|||
my_snprintf(line, sizeof(line),
|
||||
"%s %s", team, token);
|
||||
award_and_log_uniquely(team, category, 1,
|
||||
"tokens.db", line);
|
||||
state_path("tokens.db"), line);
|
||||
}
|
||||
}
|
||||
|
|
@ -299,29 +299,51 @@ my_snprintf(char *buf, size_t buflen, char *fmt, ...)
|
|||
}
|
||||
}
|
||||
|
||||
char *
|
||||
srv_path(char const *fmt, ...)
|
||||
static char *
|
||||
mkpath(char const *base, char const *fmt, va_list ap)
|
||||
{
|
||||
char relpath[PATH_MAX];
|
||||
static char path[PATH_MAX];
|
||||
char *srv;
|
||||
char const *var;
|
||||
int len;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(relpath, sizeof(relpath) - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
relpath[sizeof(relpath) - 1] = '\0';
|
||||
|
||||
srv = getenv("CTF_BASE");
|
||||
if (! srv) {
|
||||
srv = "/srv/ctf";
|
||||
var = getenv("CTF_BASE");
|
||||
if (! var) {
|
||||
var = base;
|
||||
}
|
||||
|
||||
my_snprintf(path, sizeof(path), "%s/%s", srv, relpath);
|
||||
my_snprintf(path, sizeof(path), "%s/%s", var, relpath);
|
||||
return path;
|
||||
}
|
||||
|
||||
char *
|
||||
state_path(char const *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = mkpath("/var/lib/ctf", fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
package_path(char const *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = mkpath("/opt", fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
team_exists(char const *teamhash)
|
||||
{
|
||||
|
@ -341,7 +363,7 @@ team_exists(char const *teamhash)
|
|||
}
|
||||
|
||||
/* stat seems to be the preferred way to check for existence. */
|
||||
ret = stat(srv_path("teams/names/%s", teamhash), &buf);
|
||||
ret = stat(state_path("teams/names/%s", teamhash), &buf);
|
||||
if (-1 == ret) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -397,9 +419,9 @@ award_points(char const *teamhash,
|
|||
token log.
|
||||
*/
|
||||
|
||||
filename = srv_path("points.new/%d.%d.%s.%s.%ld",
|
||||
now, getpid(),
|
||||
teamhash, category, points);
|
||||
filename = state_path("points.new/%d.%d.%s.%s.%ld",
|
||||
now, getpid(),
|
||||
teamhash, category, points);
|
||||
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
|
||||
if (-1 == fd) {
|
||||
|
@ -424,11 +446,10 @@ void
|
|||
award_and_log_uniquely(char const *team,
|
||||
char const *category,
|
||||
long points,
|
||||
char const *dbfile,
|
||||
char const *dbpath,
|
||||
char const *line)
|
||||
{
|
||||
char *dbpath = srv_path(dbfile);
|
||||
int fd;
|
||||
int fd;
|
||||
|
||||
/* Make sure they haven't already claimed these points */
|
||||
if (fgrepx(line, dbpath)) {
|
|
@ -7,6 +7,7 @@
|
|||
#define CAT_MAX 40
|
||||
#define TOKEN_MAX 40
|
||||
|
||||
|
||||
int cgi_init(char *global_argv[]);
|
||||
size_t cgi_item(char *str, size_t maxlen);
|
||||
void cgi_head(char *title);
|
||||
|
@ -17,7 +18,8 @@ void cgi_error(char *fmt, ...);
|
|||
|
||||
int fgrepx(char const *needle, char const *filename);
|
||||
int my_snprintf(char *buf, size_t buflen, char *fmt, ...);
|
||||
char *srv_path(char const *fmt, ...);
|
||||
char *state_path(char const *fmt, ...);
|
||||
char *package_path(char const *fmt, ...);
|
||||
int team_exists(char const *teamhash);
|
||||
int award_points(char const *teamhacsh,
|
||||
char const *category,
|
|
@ -94,7 +94,7 @@ main(int argc, char *argv[])
|
|||
int fd;
|
||||
size_t len;
|
||||
|
||||
fd = open(srv_path("token.keys/%s", service), O_RDONLY);
|
||||
fd = open(state_path("token.keys/%.*s", (int)servicelen, service), O_RDONLY);
|
||||
if (-1 == fd) {
|
||||
write(1, "!nosvc", 6);
|
||||
return 0;
|
||||
|
@ -123,8 +123,8 @@ main(int argc, char *argv[])
|
|||
|
||||
/* Append digest to service name. */
|
||||
tokenlen = (size_t)snprintf(token, sizeof(token),
|
||||
"%*s:%s",
|
||||
servicelen, service, digest);
|
||||
"%.*s:%s",
|
||||
(int)servicelen, service, digest);
|
||||
}
|
||||
|
||||
/* Write that token out now. */
|
||||
|
@ -133,7 +133,7 @@ main(int argc, char *argv[])
|
|||
int ret;
|
||||
|
||||
do {
|
||||
fd = open(srv_path("tokens.db"), O_WRONLY | O_CREAT, 0666);
|
||||
fd = open(state_path("tokens.db"), O_WRONLY | O_CREAT, 0666);
|
||||
if (-1 == fd) break;
|
||||
|
||||
ret = lockf(fd, F_LOCK, 0);
|
|
@ -59,10 +59,9 @@ main(int argc, char *argv[])
|
|||
{
|
||||
char needle[400];
|
||||
|
||||
my_snprintf(needle, sizeof(needle),
|
||||
"%ld %s", points, answer);
|
||||
my_snprintf(needle, sizeof(needle), "%ld %s", points, answer);
|
||||
if (! fgrepx(needle,
|
||||
srv_path("packages/%s/answers.txt", category))) {
|
||||
package_path("%s/answers.txt", category))) {
|
||||
cgi_page("Wrong answer", "");
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +72,7 @@ main(int argc, char *argv[])
|
|||
my_snprintf(line, sizeof(line),
|
||||
"%s %s %ld", team, category, points);
|
||||
award_and_log_uniquely(team, category, points,
|
||||
"puzzler.db", line);
|
||||
state_path("puzzler.db"), line);
|
||||
}
|
||||
|
||||
cgi_page("Points awarded",
|
|
@ -58,7 +58,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
{
|
||||
FILE *f = fopen(srv_path("puzzler.db"), "r");
|
||||
FILE *f = fopen(state_path("puzzler.db"), "r");
|
||||
char cat[CAT_MAX];
|
||||
char points_str[11];
|
||||
long points;
|
||||
|
@ -91,7 +91,7 @@ main(int argc, char *argv[])
|
|||
if (f) fclose(f);
|
||||
}
|
||||
|
||||
srv = opendir(srv_path("packages"));
|
||||
srv = opendir(package_path(""));
|
||||
if (NULL == srv) {
|
||||
cgi_error("Cannot opendir(\"/srv\")");
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ main(int argc, char *argv[])
|
|||
well just barge ahead and watch for errors. */
|
||||
|
||||
/* Open /srv/ctf/$cat/puzzles/ */
|
||||
puzzles = opendir(srv_path("packages/%s/puzzles", cat));
|
||||
puzzles = opendir(package_path("%s/puzzles", cat));
|
||||
if (NULL == puzzles) {
|
||||
continue;
|
||||
}
|
|
@ -14,14 +14,14 @@ mkdir -p $CTF_BASE/points.new
|
|||
|
||||
# Set up some packages
|
||||
for cat in cat1 cat2 cat3; do
|
||||
mkdir -p $CTF_BASE/packages/$cat
|
||||
cat >$CTF_BASE/packages/$cat/answers.txt <<EOF
|
||||
mkdir -p $CTF_BASE/$cat
|
||||
cat >$CTF_BASE/$cat/answers.txt <<EOF
|
||||
10 ${cat}answer10
|
||||
20 ${cat}answer20
|
||||
30 ${cat}answer30
|
||||
EOF
|
||||
for i in 10 20 30; do
|
||||
mkdir -p $CTF_BASE/packages/$cat/puzzles/$i
|
||||
mkdir -p $CTF_BASE/$cat/puzzles/$i
|
||||
done
|
||||
done
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
@ -13,7 +13,10 @@
|
|||
<a href="scoreboard.html">Scoreboard</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="puzzles.html">Puzzles</a>
|
||||
<a href="puzzles.cgi">Puzzles</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="teams.html">Teams</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="irc://10.0.0.1/ctf"
|
||||
|
@ -24,8 +27,9 @@
|
|||
<h2>Claim Token</h2>
|
||||
<form action="claim.cgi" method="post">
|
||||
<fieldset>
|
||||
team: <input name="t" size="8"><br>
|
||||
token: <input name="k" size="20">
|
||||
team:<input name="t" size="8">
|
||||
token:<input name="k" size="20">
|
||||
<input type="submit" value="claim">
|
||||
</fieldset>
|
||||
</form>
|
||||
|
Loading…
Reference in New Issue