mirror of https://github.com/dirtbags/moth.git
Merge branch 'master' of ssh://fozzie/home/neale/projects/ctf
This commit is contained in:
commit
3d4b401396
1
Makefile
1
Makefile
|
@ -10,7 +10,6 @@ CACHE = cache
|
||||||
# The end result
|
# The end result
|
||||||
BIN = bin
|
BIN = bin
|
||||||
|
|
||||||
|
|
||||||
all: packages
|
all: packages
|
||||||
|
|
||||||
dist: ctf-install.zip
|
dist: ctf-install.zip
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,15 @@
|
||||||
|
IPv6 in Dirtbags CTF
|
||||||
|
====================
|
||||||
|
|
||||||
|
The contest network uses IPs in the unique local address space
|
||||||
|
fd82:b410:3441::/48. Each team gets a /64 internal subnet, with
|
||||||
|
their team number (generally the same as the switch port).
|
||||||
|
|
||||||
|
Each subnet's gateway is ::1.
|
||||||
|
|
||||||
|
Team 5, in switch port 5, on VLAN 5, gets fd82:b410:3441:5::/64.
|
||||||
|
|
||||||
|
Server network is fd84:b410:3441::/64 (AKA fd84:b410:3441:0::/64). To
|
||||||
|
make things easier to type, use hosts in the /112. The MCP server lives
|
||||||
|
at fd84:b410:3441::2.
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
00ADMIN_PKGDIR = $(TARGET)/00admin
|
||||||
|
|
||||||
|
00admin-install:
|
||||||
|
$(call COPYTREE, packages/00admin/service, $(00ADMIN_PKGDIR)/service)
|
||||||
|
|
||||||
|
PACKAGES += 00admin
|
|
@ -0,0 +1,14 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
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$bEGCYemG$pAo9KXWQKgQNijRGKSb7e1' | chpasswd --encrypted
|
||||||
|
|
||||||
|
# Bring up the NIC; this will get us at least a link-local address, and
|
||||||
|
# hopefully a global address with stateless autoconfiguration.
|
||||||
|
ip link set eth0 up
|
||||||
|
|
||||||
|
exec dropbear -r ./rsa.key -E -F
|
|
@ -1,20 +0,0 @@
|
||||||
ARMADILLO_PKGDIR = $(TARGET)/armadillo
|
|
||||||
|
|
||||||
armadillo-install: armadillo-build
|
|
||||||
mkdir -p $(ARMADILLO_PKGDIR)
|
|
||||||
|
|
||||||
mkdir -p $(ARMADILLO_PKGDIR)/bin/
|
|
||||||
$(MAKE) -C packages/armadillo/src install DESTDIR=$(CURDIR)/$(ARMADILLO_PKGDIR)
|
|
||||||
|
|
||||||
$(call COPYTREE, packages/armadillo/tokens, $(ARMADILLO_PKGDIR)/tokens)
|
|
||||||
|
|
||||||
$(call COPYTREE, packages/armadillo/service, $(ARMADILLO_PKGDIR)/service)
|
|
||||||
|
|
||||||
armadillo-clean:
|
|
||||||
rm -rf $(ARMADILLO_PKGDIR)
|
|
||||||
$(MAKE) -C packages/armadillo/src clean
|
|
||||||
|
|
||||||
armadillo-build:
|
|
||||||
$(MAKE) -C packages/armadillo/src build
|
|
||||||
|
|
||||||
PACKAGES += armadillo
|
|
|
@ -1 +0,0 @@
|
||||||
10.0.0.3/24
|
|
|
@ -1,4 +0,0 @@
|
||||||
.::7777::-.
|
|
||||||
/:'////' `::>/|/
|
|
||||||
.', |||| `/( e\
|
|
||||||
-==~-'`-Xm````-mr' `-_\
|
|
|
@ -1,4 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
[ -f motd ] && cat motd
|
|
||||||
exec chroot /mnt/pwnables-root login -f alice
|
|
|
@ -1,40 +0,0 @@
|
||||||
#! /bin/sh -e
|
|
||||||
|
|
||||||
# Configure IP address
|
|
||||||
IP=$(cat ip.txt)
|
|
||||||
ip addr add $IP label eth0:armadillo dev eth0
|
|
||||||
|
|
||||||
# Set up chroot environment
|
|
||||||
# We never umount any of this since it's all just in RAM
|
|
||||||
mkdir -p /mnt/armadillo-root
|
|
||||||
grep -q armadillo-root /proc/mounts || mount -o bind / /mnt/armadillo-root
|
|
||||||
grep -q armadillo-var /proc/mounts || mount -t tmpfs -o size=5m,mode=0755 armadillo-var /mnt/armadillo-root/var
|
|
||||||
grep -q armadillo-tmp /proc/mounts || mount -t tmpfs -o size=15k armadillo-tmp /mnt/armadillo-root/tmp
|
|
||||||
grep -q armadillo-home /proc/mounts || mount -t tmpfs -o size=5m,mode=0755 armadillo-home /mnt/armadillo-root/home
|
|
||||||
|
|
||||||
# Make some skeleton junk
|
|
||||||
install -o root -m 0755 -d /mnt/armadillo-root/var/lib
|
|
||||||
install -o root -m 0755 -d /mnt/armadillo-root/var/lib/ctf
|
|
||||||
install -o root -m 0755 -d /mnt/armadillo-root/var/lib/ctf/tokens
|
|
||||||
install -o root -m 0755 -d /mnt/armadillo-root/var/log
|
|
||||||
install -o root -m 0755 -d /mnt/armadillo-root/var/spool
|
|
||||||
install -o root -m 0755 -d /mnt/armadillo-root/var/cache
|
|
||||||
install -o root -m 0777 -d /mnt/armadillo-root/var/run
|
|
||||||
install -o root -m 0777 -d /mnt/armadillo-root/var/cache
|
|
||||||
|
|
||||||
# Install the binaries
|
|
||||||
install -o root -d /mnt/armadillo-root/home/alice/
|
|
||||||
install -o bob -m 0111 /opt/armadillo/bin/gimmie /mnt/armadillo-root/home/alice/
|
|
||||||
install -o bob -m 0111 /opt/armadillo/bin/dillo /mnt/armadillo-root/home/alice/
|
|
||||||
|
|
||||||
# straceme and killme need to be suid, to prevent LD_PRELOAD
|
|
||||||
install -o bob -m 04111 /opt/armadillo/bin/straceme /mnt/armadillo-root/home/alice/
|
|
||||||
install -o bob -m 04111 /opt/armadillo/bin/killme /mnt/armadillo-root/home/alice/
|
|
||||||
|
|
||||||
# Set up links for tokens
|
|
||||||
mkdir -p /var/lib/ctf/tokens
|
|
||||||
for puzzle in gimmie straceme killme dillo; do
|
|
||||||
ln -sf /mnt/armadillo-root/var/lib/ctf/tokens/$puzzle /var/lib/ctf/tokens/$puzzle
|
|
||||||
done
|
|
||||||
|
|
||||||
exec tcpsvd -C 5:"Let's not be greedy" ${IP%/*} 23 /sbin/telnetd -l ./pwnie
|
|
|
@ -1,17 +0,0 @@
|
||||||
CFLAGS = -Wall -Werror
|
|
||||||
TARGETS = gimmie straceme killme dillo
|
|
||||||
|
|
||||||
all: build
|
|
||||||
|
|
||||||
build: $(TARGETS)
|
|
||||||
|
|
||||||
gimmie: gimmie.o token.o arc4.o
|
|
||||||
straceme: straceme.o token.o arc4.o
|
|
||||||
killme: killme.o token.o arc4.o
|
|
||||||
dillo: dillo.o token.o arc4.o
|
|
||||||
|
|
||||||
install: $(TARGETS)
|
|
||||||
install -m 0755 $(TARGETS) $(DESTDIR)/bin
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.o $(TARGETS)
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/arc4.c
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/arc4.h
|
|
|
@ -1,22 +0,0 @@
|
||||||
#! /usr/bin/python
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
# In the actual contest you'd want to run netcat or just
|
|
||||||
# open your own TCP connection to port 23 and run commands.
|
|
||||||
d = subprocess.Popen(['./dillo'],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stdin=subprocess.PIPE)
|
|
||||||
o = d.stdout
|
|
||||||
i = d.stdin
|
|
||||||
|
|
||||||
c = o.read(1)
|
|
||||||
v = chr(ord(c) ^ 0x20)
|
|
||||||
i.write(v)
|
|
||||||
|
|
||||||
o.readline()
|
|
||||||
o.readline()
|
|
||||||
o.readline()
|
|
||||||
o.readline()
|
|
||||||
o.readline()
|
|
||||||
d.poll()
|
|
|
@ -1,59 +0,0 @@
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "arc4.h"
|
|
||||||
#include "token.h"
|
|
||||||
|
|
||||||
const uint8_t key[] =
|
|
||||||
{0xa5, 0xb1, 0x6f, 0xce,
|
|
||||||
0x59, 0x2d, 0xb1, 0xe9,
|
|
||||||
0x4b, 0x07, 0x91, 0x6d,
|
|
||||||
0x9f, 0x3b, 0xc8, 0xc6};
|
|
||||||
|
|
||||||
const char dillo[] =
|
|
||||||
(" .::7777::-.\n"
|
|
||||||
" /:'////' `::>/|/\n"
|
|
||||||
" .', |||| `/( e\\\n"
|
|
||||||
" -==~-'`-Xm````-mr' `-_\\\n");
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
uint8_t v;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Pick a random non-zero xor value */
|
|
||||||
do {
|
|
||||||
v = arc4_rand8();
|
|
||||||
} while (! v);
|
|
||||||
|
|
||||||
|
|
||||||
/* Print the dillo */
|
|
||||||
for (i = 0; dillo[i]; i += 1) {
|
|
||||||
struct timespec req = {0, 33333333};
|
|
||||||
uint8_t c = dillo[i];
|
|
||||||
|
|
||||||
if ('\n' != c) {
|
|
||||||
c ^= v;
|
|
||||||
}
|
|
||||||
write(1, &c, 1);
|
|
||||||
nanosleep(&req, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a single byte; strace will help with solution */
|
|
||||||
{
|
|
||||||
uint8_t c;
|
|
||||||
|
|
||||||
read(0, &c, 1);
|
|
||||||
if (c != v) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-1 == print_token("dillo", key, sizeof(key))) {
|
|
||||||
write(2, "Something is broken; I can't read my token.\n", 44);
|
|
||||||
return 69;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <sysexits.h>
|
|
||||||
#include "token.h"
|
|
||||||
|
|
||||||
uint8_t const key[] = {0x5f, 0x64, 0x13, 0x29,
|
|
||||||
0x2e, 0x46, 0x76, 0xcd,
|
|
||||||
0x65, 0xff, 0xe8, 0x03,
|
|
||||||
0xa4, 0xa9, 0x4f, 0xd9};
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
if (-1 == print_token("gimmie", key, sizeof(key))) {
|
|
||||||
fprintf(stderr, "Something is broken; I can't read my token.\n");
|
|
||||||
return EX_UNAVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
#include <signal.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sysexits.h>
|
|
||||||
#include "arc4.h"
|
|
||||||
#include "token.h"
|
|
||||||
|
|
||||||
#define ROUNDS 20
|
|
||||||
|
|
||||||
uint8_t const key[] = {0x51, 0x91, 0x6d, 0x81,
|
|
||||||
0x14, 0x21, 0xf8, 0x95,
|
|
||||||
0xb8, 0x09, 0x87, 0xa6,
|
|
||||||
0xa8, 0xb0, 0xa0, 0x46};
|
|
||||||
|
|
||||||
int lastsig;
|
|
||||||
|
|
||||||
void
|
|
||||||
handler(int signum)
|
|
||||||
{
|
|
||||||
lastsig = signum;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 1; i < 8; i += 1) {
|
|
||||||
signal(i, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ROUNDS; i += 1) {
|
|
||||||
int desired = (arc4_rand8() % 7) + 1;
|
|
||||||
|
|
||||||
lastsig = 0;
|
|
||||||
printf("%d\n", desired);
|
|
||||||
fflush(stdout);
|
|
||||||
if (i == 0) {
|
|
||||||
sleep(5);
|
|
||||||
} else {
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
if (0 == lastsig) {
|
|
||||||
printf("Too slow.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (lastsig != desired) {
|
|
||||||
printf("Wrong one.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-1 == print_token("killme", key, sizeof(key))) {
|
|
||||||
fprintf(stderr, "Something is broken; I can't read my token.\n");
|
|
||||||
return EX_UNAVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <sysexits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "token.h"
|
|
||||||
|
|
||||||
uint8_t const key[] = {0x30, 0x00, 0x55, 0x0f,
|
|
||||||
0xc2, 0xf6, 0x52, 0x2a,
|
|
||||||
0x31, 0xfd, 0x00, 0x92,
|
|
||||||
0x9d, 0x49, 0x24, 0xce};
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
/* Check argv[1].
|
|
||||||
*
|
|
||||||
* If no args, argv[1] will be NULL, which causes a segfault.
|
|
||||||
* This is what we want.
|
|
||||||
*
|
|
||||||
* To pass this, run ./straceme $$.
|
|
||||||
* But you have to do it from a shell script, because if you run
|
|
||||||
* strace ./straceme $$
|
|
||||||
* getppid() will return the PID of strace!
|
|
||||||
*/
|
|
||||||
if (getppid() != atoi(argv[1])) {
|
|
||||||
write(2, "argv[1] incorrect\n", 18);
|
|
||||||
return EX_USAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read an rc file.
|
|
||||||
*
|
|
||||||
* To pass this, set $HOME to someplace you have access.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
char fn[128];
|
|
||||||
char bs[1000];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
len = snprintf(fn, sizeof(fn) - 1, "%s/.stracemerc", getenv("HOME"));
|
|
||||||
if (len < 0) {
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
fn[len] = '\0';
|
|
||||||
|
|
||||||
if (-1 == (fd = open(fn, O_RDONLY))) {
|
|
||||||
fd = open("/etc/stracemerc", O_RDONLY);
|
|
||||||
}
|
|
||||||
if (-1 == fd) {
|
|
||||||
return EX_NOINPUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We don't actually care about contents */
|
|
||||||
read(fd, bs, sizeof(bs));
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read in category name from fd 5
|
|
||||||
*
|
|
||||||
* echo -n straceme > foo.txt
|
|
||||||
* ./straceme $$ 5< foo.txt
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
char cat[50];
|
|
||||||
int catlen;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
catlen = read(5, cat, sizeof(cat) - 1);
|
|
||||||
for (i = 0; i < catlen; i += 1) {
|
|
||||||
if (! isalnum(cat[i])) break;
|
|
||||||
}
|
|
||||||
cat[i] = '\0';
|
|
||||||
|
|
||||||
if (-1 == print_token(cat, key, sizeof(key))) {
|
|
||||||
write(2, "Something is broken; I can't read my token.\n", 44);
|
|
||||||
return 69;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/token.c
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/token.h
|
|
|
@ -1 +0,0 @@
|
||||||
pwnables
|
|
|
@ -1 +0,0 @@
|
||||||
<EFBFBD><EFBFBD>t322<EFBFBD>/<2F>0<EFBFBD>g<EFBFBD><67>ji
|
|
|
@ -1 +0,0 @@
|
||||||
_d).Fvヘe<EFBE8D><65>、ゥOル
|
|
|
@ -1 +0,0 @@
|
||||||
pwnables
|
|
|
@ -1 +0,0 @@
|
||||||
<EFBFBD><EFBFBD>t322<EFBFBD>/<2F>0<EFBFBD>g<EFBFBD><67>ji
|
|
|
@ -1 +0,0 @@
|
||||||
Q<EFBFBD>m<EFBFBD>!ј<>И <09>ІЈА F
|
|
|
@ -1 +0,0 @@
|
||||||
pwnables
|
|
|
@ -1 +0,0 @@
|
||||||
<EFBFBD><EFBFBD>t322<EFBFBD>/<2F>0<EFBFBD>g<EFBFBD><67>ji
|
|
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
pwnables
|
|
|
@ -1 +0,0 @@
|
||||||
<EFBFBD><EFBFBD>t322<EFBFBD>/<2F>0<EFBFBD>g<EFBFBD><67>ji
|
|
Binary file not shown.
|
@ -1,17 +0,0 @@
|
||||||
CTFBASE_PKGDIR = $(TARGET)/ctfbase
|
|
||||||
|
|
||||||
ctfbase-install: ctfbase-build
|
|
||||||
mkdir -p $(CTFBASE_PKGDIR)/bin/
|
|
||||||
|
|
||||||
$(call COPYTREE, packages/ctfbase/service, $(CTFBASE_PKGDIR)/service)
|
|
||||||
|
|
||||||
cp packages/ctfbase/src/arc4 $(CTFBASE_PKGDIR)/bin/
|
|
||||||
|
|
||||||
ctfbase-clean:
|
|
||||||
rm -rf $(CTFBASE_PKGDIR)
|
|
||||||
$(MAKE) -C packages/ctfbase/src clean
|
|
||||||
|
|
||||||
ctfbase-build:
|
|
||||||
$(MAKE) -C packages/ctfbase/src build
|
|
||||||
|
|
||||||
PACKAGES += ctfbase
|
|
|
@ -1,13 +0,0 @@
|
||||||
#! /bin/sh -e
|
|
||||||
|
|
||||||
PATH=/bin:/opt/ctfbase/bin; export PATH
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
# Fetch list of teams
|
|
||||||
teams=/var/lib/ctf/teams.txt
|
|
||||||
rm -f $teams.tmp
|
|
||||||
wget -q -O $teams.tmp http://10.0.0.2/teams.txt && \
|
|
||||||
mv $teams.tmp $teams
|
|
||||||
|
|
||||||
sleep 60
|
|
||||||
done
|
|
|
@ -1,12 +0,0 @@
|
||||||
#! /bin/sh -e
|
|
||||||
|
|
||||||
exec 2>&1
|
|
||||||
|
|
||||||
# Set up networking for all CTF ips
|
|
||||||
ip link set eth0 up
|
|
||||||
if ! ip route | grep -q default; then
|
|
||||||
ip route add default via 10.0.0.1 || exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
install -o root -m 0755 -d /var/lib/ctf/tokens
|
|
||||||
exec ./ctfd
|
|
|
@ -1,4 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
iptables -D INPUT -s 10.0.0.0/16 --proto tcp --dport 55 -j ACCEPT
|
|
||||||
iptables -D INPUT --proto tcp --dport 55 -j REJECT
|
|
|
@ -1,6 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
exec 2>&1
|
|
||||||
iptables -A INPUT -s 10.0.0.0/16 --proto tcp --dport 22 -j ACCEPT
|
|
||||||
iptables -A INPUT --proto tcp --dport 22 -j REJECT
|
|
||||||
exec dropbear -r ./rsa.key -E -F
|
|
|
@ -1,7 +0,0 @@
|
||||||
build: arc4
|
|
||||||
|
|
||||||
arc4: arc4.c
|
|
||||||
arc4: CFLAGS += -DARC4_MAIN
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.o arc4
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/arc4.c
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/arc4.h
|
|
|
@ -1,8 +0,0 @@
|
||||||
fireeye-source:
|
|
||||||
fireeye-build:
|
|
||||||
|
|
||||||
fireeye-install: packages/fireeye/tokens.txt
|
|
||||||
mkdir -p $(TARGET)/fireeye/
|
|
||||||
cp $< $(TARGET)/fireeye/
|
|
||||||
|
|
||||||
PACKAGES += fireeye
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,13 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
for i in $(seq 100); do
|
||||||
|
if [ $(expr $i % 15) = 0 ]; then
|
||||||
|
echo 'FizzBuzz'
|
||||||
|
elif [ $(expr $i % 3) = 0 ]; then
|
||||||
|
echo 'Fizz'
|
||||||
|
elif [ $(expr $i % 5) = 0 ]; then
|
||||||
|
echo 'Buzz'
|
||||||
|
else
|
||||||
|
echo $i
|
||||||
|
fi
|
||||||
|
done
|
|
@ -0,0 +1,29 @@
|
||||||
|
FIZZBUZZ_PKGDIR = $(TARGET)/fizzbuzz
|
||||||
|
FIZZBUZZ_BUILDDIR = $(BUILD)/fizzbuzz
|
||||||
|
|
||||||
|
$(FIZZBUZZ_BUILDDIR)/token.enc: packages/fizzbuzz/tokens.txt
|
||||||
|
$(FIZZBUZZ_BUILDDIR)/token.enc: packages/fizzbuzz/fizzbuzz-client.sh
|
||||||
|
$(FIZZBUZZ_BUILDDIR)/token.enc: $(FIZZBUZZ_BUILDDIR)/fizzbuzz-native
|
||||||
|
packages/fizzbuzz/fizzbuzz-client.sh | $(FIZZBUZZ_BUILDDIR)/fizzbuzz-native 3< packages/fizzbuzz/tokens.txt > $@
|
||||||
|
|
||||||
|
$(FIZZBUZZ_BUILDDIR)/fizzbuzz-native: packages/fizzbuzz/src/fizzbuzz.c
|
||||||
|
@ mkdir -p $(@D)
|
||||||
|
cc -o $@ $<
|
||||||
|
|
||||||
|
fizzbuzz-install: fizzbuzz-build
|
||||||
|
mkdir -p $(FIZZBUZZ_PKGDIR)/bin/
|
||||||
|
|
||||||
|
$(call COPYTREE, packages/fizzbuzz/service, $(FIZZBUZZ_PKGDIR)/service)
|
||||||
|
|
||||||
|
cp packages/fizzbuzz/tokens.txt $(FIZZBUZZ_PKGDIR)/
|
||||||
|
cp $(FIZZBUZZ_BUILDDIR)/token.enc $(FIZZBUZZ_PKGDIR)/
|
||||||
|
cp packages/fizzbuzz/src/fizzbuzz $(FIZZBUZZ_PKGDIR)/bin/
|
||||||
|
|
||||||
|
fizzbuzz-clean:
|
||||||
|
rm -rf $(FIZZBUZZ_PKGDIR) $(FIZZBUZZ_BUILDDIR)
|
||||||
|
$(MAKE) -C packages/fizzbuzz/src clean
|
||||||
|
|
||||||
|
fizzbuzz-build: $(FIZZBUZZ_BUILDDIR)/token.enc
|
||||||
|
$(MAKE) -C packages/fizzbuzz/src build
|
||||||
|
|
||||||
|
PACKAGES += fizzbuzz
|
|
@ -0,0 +1 @@
|
||||||
|
fd84:b410:3441::a0d/64
|
|
@ -0,0 +1,8 @@
|
||||||
|
#! /bin/sh -e
|
||||||
|
|
||||||
|
exec 2>&1
|
||||||
|
|
||||||
|
IP=$(cat ip.txt)
|
||||||
|
ip addr add $IP dev eth0 || true
|
||||||
|
|
||||||
|
exec tcpsvd -u nobody ${IP%/*} 1013 /opt/fizzbuzz/bin/fizzbuzz 3</opt/fizzbuzz/token.enc
|
|
@ -1,12 +1,9 @@
|
||||||
CFLAGS = -Wall -Werror
|
CFLAGS = -Wall -Werror
|
||||||
LDFLAGS = -static
|
TARGETS = fizzbuzz
|
||||||
TARGETS = logger
|
|
||||||
|
|
||||||
all: build
|
all: build
|
||||||
build: $(TARGETS)
|
build: $(TARGETS)
|
||||||
|
|
||||||
logger: logger.o arc4.o token.o
|
|
||||||
|
|
||||||
install: $(TARGETS)
|
install: $(TARGETS)
|
||||||
install -m 0755 $(TARGETS) $(DESTDIR)/bin
|
install -m 0755 $(TARGETS) $(DESTDIR)/bin
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How this works:
|
||||||
|
*
|
||||||
|
* You have to provide this with the output of a fizzbuzz program to get
|
||||||
|
* it to decode the token.
|
||||||
|
*
|
||||||
|
* Provide the encoded token on fd 3, and it will output the decode
|
||||||
|
* provided correct input. If you provided the decoded token, it will
|
||||||
|
* encode it. In other words, encode(x) = decode(x).
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Here's a fizzbuzz program in bourne shell:
|
||||||
|
*
|
||||||
|
* for i in $(seq 100); do
|
||||||
|
* if [ $(expr $i % 15) = 0 ]; then
|
||||||
|
* echo 'FizzBuzz'
|
||||||
|
* elif [ $(expr $i % 3) = 0 ]; then
|
||||||
|
* echo 'Fizz'
|
||||||
|
* elif [ $(expr $i % 5) = 0 ]; then
|
||||||
|
* echo 'Buzz'
|
||||||
|
* else
|
||||||
|
* echo $i
|
||||||
|
* fi
|
||||||
|
* done
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
char craptable[] = {
|
||||||
|
0x64, 0xd4, 0x11, 0x55, 0x50, 0x16, 0x61, 0x02,
|
||||||
|
0xf7, 0xfd, 0x63, 0x36, 0xd9, 0xa6, 0xf2, 0x29,
|
||||||
|
0xad, 0xfb, 0xed, 0x7a, 0x06, 0x91, 0xe7, 0x67,
|
||||||
|
0x80, 0xb6, 0x53, 0x2c, 0x43, 0xf9, 0x3c, 0xf2,
|
||||||
|
0x83, 0x5c, 0x25, 0xee, 0x21
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char token[100];
|
||||||
|
size_t tokenlen;
|
||||||
|
|
||||||
|
{
|
||||||
|
FILE *tokenin = fdopen(3, "r");
|
||||||
|
|
||||||
|
if (! tokenin) {
|
||||||
|
printf("Somebody didn't read the instructions.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenlen = fread(token, 1, sizeof(token), tokenin);
|
||||||
|
fclose(tokenin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i=1; i <= 100; i += 1) {
|
||||||
|
char l[100];
|
||||||
|
|
||||||
|
fgets(l, sizeof(l), stdin);
|
||||||
|
|
||||||
|
if (0 == i % 15) {
|
||||||
|
if (0 != strcmp("FizzBuzz\n", l)) break;
|
||||||
|
} else if (0 == i % 3) {
|
||||||
|
if (0 != strcmp("Fizz\n", l)) break;
|
||||||
|
} else if (0 == i % 5) {
|
||||||
|
if (0 != strcmp("Buzz\n", l)) break;
|
||||||
|
} else {
|
||||||
|
if (atoi(l) != i) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
token[i % tokenlen] ^= i;
|
||||||
|
token[i % tokenlen] ^= craptable[i % sizeof(craptable)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (101 == i) {
|
||||||
|
fwrite(token, tokenlen, 1, stdout);
|
||||||
|
} else {
|
||||||
|
printf("Next time, FizzBuzz me.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
net:xuhen-fizuv-syvex
|
|
@ -25,4 +25,4 @@ inferno-install: $(INFERNO_BUILDDIR)/build
|
||||||
inferno-clean:
|
inferno-clean:
|
||||||
rm -rf $(INFERNO_PKGDIR) $(INFERNO_BUILDDIR)
|
rm -rf $(INFERNO_PKGDIR) $(INFERNO_BUILDDIR)
|
||||||
|
|
||||||
PACKAGES += inferno
|
PACKAGES += inferno
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
IRCD_PKGDIR = $(TARGET)/ircd
|
IRCD_PKGDIR = $(TARGET)/ircd
|
||||||
IRCD_BUILDDIR = $(BUILD)/ircd
|
IRCD_BUILDDIR = $(BUILD)/ircd
|
||||||
IRCD_VERSION = 17.1
|
IRCD_VERSION = 18
|
||||||
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)
|
||||||
|
|
||||||
# Prevents automake from mangling cross-compiled binary names
|
# Prevents automake from mangling cross-compiled binary names
|
||||||
IRCD_CC_HOST := $(shell $(CC) -v 2>&1 | awk '/Target:/{print $$2}')
|
IRCD_CC_HOST := $(shell $(CC) -v 2>&1 | awk '/Target:/{print $$2}')
|
||||||
IRCD_CONF_OPT := --host=i686-unknown-linux-uclibc --program-transform-name=
|
|
||||||
|
|
||||||
ircd-install: ircd-build
|
ircd-install: ircd-build
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ $(IRCD_BUILDDIR)/source: $(IRCD_TAR)
|
||||||
|
|
||||||
ircd-build: $(IRCD_BUILDDIR)/built
|
ircd-build: $(IRCD_BUILDDIR)/built
|
||||||
$(IRCD_BUILDDIR)/built: $(IRCD_BUILDDIR)/source
|
$(IRCD_BUILDDIR)/built: $(IRCD_BUILDDIR)/source
|
||||||
cd $(IRCD_SRCDIR) && ./configure $(IRCD_CONF_OPT)
|
cd $(IRCD_SRCDIR) && ./configure $(CONFIG_XCOMPILE_FLAGS) --enable-ipv6
|
||||||
$(MAKE) -C $(IRCD_SRCDIR)
|
$(MAKE) -C $(IRCD_SRCDIR)
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
|
@ -36,4 +35,4 @@ ircd-install: ircd-build
|
||||||
ircd-clean:
|
ircd-clean:
|
||||||
rm -rf $(IRCD_BUILDDIR)
|
rm -rf $(IRCD_BUILDDIR)
|
||||||
|
|
||||||
PACKAGES += ircd
|
PACKAGES += ircd
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
fd84:b410:3441::6/64
|
|
@ -1,8 +1,12 @@
|
||||||
[Global]
|
[Global]
|
||||||
Name = irc.ctf
|
Name = irc.ctf
|
||||||
Info = CTF IRC
|
Info = CTF IRC
|
||||||
OperCanUseMode = yes
|
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
|
||||||
|
|
||||||
[Operator]
|
[Operator]
|
||||||
Name = oper
|
Name = oper
|
||||||
Password = opsplz
|
Password = operpass
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
exec 2>&1
|
exec 2>&1
|
||||||
exec /opt/ircd/bin/ngircd --config ./ngircd.conf --nodaemon
|
|
||||||
|
IP=$(cat ip.txt)
|
||||||
|
ip addr add $IP label eth0:ircd dev eth0
|
||||||
|
ip monitor | grep -q $IP
|
||||||
|
|
||||||
|
adduser -S -H -u 65534 nobody
|
||||||
|
adduser -S -H irc
|
||||||
|
|
||||||
|
exec setuidgid irc /opt/ircd/bin/ngircd --config ./ngircd.conf --nodaemon
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
LIBCAP_PKGDIR = $(TARGET)/libcap
|
||||||
|
LIBCAP_BUILDDIR = $(BUILD)/libcap
|
||||||
|
LIBCAP_VERSION = 2.22
|
||||||
|
LIBCAP_TAR = $(CACHE)/libcap-$(LIBCAP_VERSION).tar.gz
|
||||||
|
# XXX: kernel.org was down when I wrote this, but is the canonical source
|
||||||
|
LIBCAP_URL = http://ftp.debian.org/debian/pool/main/libc/libcap2/libcap2_$(LIBCAP_VERSION).orig.tar.gz
|
||||||
|
LIBCAP_SRCDIR = $(LIBCAP_BUILDDIR)/libcap-$(LIBCAP_VERSION)
|
||||||
|
|
||||||
|
LIBCAP_LDFLAGS = -L$(CURDIR)/$(LIBCAP_SRCDIR)/libcap
|
||||||
|
LIBCAP_CFLAGS = -I$(CURDIR)/$(LIBCAP_SRCDIR)/libcap/include
|
||||||
|
|
||||||
|
$(LIBCAP_TAR):
|
||||||
|
mkdir -p $(@D)
|
||||||
|
wget -O $@ $(LIBCAP_URL)
|
||||||
|
|
||||||
|
libcap-source: $(LIBCAP_BUILDDIR)/source
|
||||||
|
$(LIBCAP_BUILDDIR)/source: $(LIBCAP_TAR)
|
||||||
|
mkdir -p $(@D)
|
||||||
|
zcat $< | ( cd $(@D) && tar xf -)
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
|
||||||
|
# This library's build sort of blows.
|
||||||
|
libcap-build: $(LIBCAP_BUILDDIR)/built
|
||||||
|
$(LIBCAP_BUILDDIR)/built: $(LIBCAP_BUILDDIR)/source
|
||||||
|
$(MAKE) -C $(LIBCAP_SRCDIR)/libcap _makenames
|
||||||
|
$(MAKE) -C $(LIBCAP_SRCDIR) CC=$(CC)
|
||||||
|
touch $@
|
|
@ -1,20 +0,0 @@
|
||||||
LOGGER_PKGDIR = $(TARGET)/logger
|
|
||||||
|
|
||||||
logger-install: logger-build
|
|
||||||
mkdir -p $(LOGGER_PKGDIR)
|
|
||||||
|
|
||||||
mkdir -p $(LOGGER_PKGDIR)/bin/
|
|
||||||
$(MAKE) -C packages/logger/src install DESTDIR=$(CURDIR)/$(LOGGER_PKGDIR)
|
|
||||||
|
|
||||||
$(call COPYTREE, packages/logger/tokens, $(LOGGER_PKGDIR)/tokens)
|
|
||||||
|
|
||||||
$(call COPYTREE, packages/logger/service, $(LOGGER_PKGDIR)/service)
|
|
||||||
|
|
||||||
logger-clean:
|
|
||||||
rm -rf $(LOGGER_PKGDIR)
|
|
||||||
$(MAKE) -C packages/logger/src clean
|
|
||||||
|
|
||||||
logger-build:
|
|
||||||
$(MAKE) -C packages/logger/src build
|
|
||||||
|
|
||||||
PACKAGES += logger
|
|
|
@ -1 +0,0 @@
|
||||||
10.0.0.14/24
|
|
|
@ -1,6 +0,0 @@
|
||||||
#! /bin/sh -e
|
|
||||||
|
|
||||||
exec 2>&1
|
|
||||||
IP=$(cat ip.txt)
|
|
||||||
ip addr add $IP label eth0:logger dev eth0
|
|
||||||
exec tcpsvd ${IP%/*} 1958 /opt/logger/bin/logger
|
|
|
@ -1,20 +0,0 @@
|
||||||
Base64 code was taken from
|
|
||||||
http://cvs.savannah.gnu.org/viewvc/*checkout*/gnulib/gnulib/lib/base64.c?revision=HEAD
|
|
||||||
|
|
||||||
/* base64.c -- Encode binary data using printable characters.
|
|
||||||
Copyright (C) 1999, 2000, 2001, 2004, 2005, 2006 Free Software
|
|
||||||
Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/arc4.c
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/arc4.h
|
|
|
@ -1,652 +0,0 @@
|
||||||
/** logger.c - generate fake log messages (part of dirtbags CTF)
|
|
||||||
*
|
|
||||||
* Author: Neale Pickett <neale@lanl.gov>
|
|
||||||
*
|
|
||||||
* This software has been authored by an employee or employees of Los
|
|
||||||
* Alamos National Security, LLC, operator of the Los Alamos National
|
|
||||||
* Laboratory (LANL) under Contract No. DE-AC52-06NA25396 with the
|
|
||||||
* U.S. Department of Energy. The U.S. Government has rights to use,
|
|
||||||
* reproduce, and distribute this software. The public may copy,
|
|
||||||
* distribute, prepare derivative works and publicly display this
|
|
||||||
* software without charge, provided that this Notice and any statement
|
|
||||||
* of authorship are reproduced on all copies. Neither the Government
|
|
||||||
* nor LANS makes any warranty, express or implied, or assumes any
|
|
||||||
* liability or responsibility for the use of this software. If
|
|
||||||
* software is modified to produce derivative works, such modified
|
|
||||||
* software should be clearly marked, so as not to confuse it with the
|
|
||||||
* version available from LANL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef STANDALONE
|
|
||||||
# define TOKEN_MAX 50
|
|
||||||
#else
|
|
||||||
# include "token.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PID_MAX 32768
|
|
||||||
#define QSIZE 200
|
|
||||||
#define MSGS_PER_SEC_MIN 10
|
|
||||||
#define MSGS_PER_SEC_MAX 40
|
|
||||||
|
|
||||||
const uint8_t key[] = {0x99, 0xeb, 0xc0, 0xce,
|
|
||||||
0xe0, 0xc9, 0xed, 0x5b,
|
|
||||||
0xbd, 0xc8, 0xb5, 0xfd,
|
|
||||||
0xdd, 0x0b, 0x03, 0x10};
|
|
||||||
|
|
||||||
/* Storage space for tokens */
|
|
||||||
char token[3][TOKEN_MAX];
|
|
||||||
|
|
||||||
void
|
|
||||||
read_tokens()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ssize_t len;
|
|
||||||
char name[40];
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(token)/sizeof(*token); i += 1) {
|
|
||||||
#ifdef STANDALONE
|
|
||||||
strcpy(token[i], "logger:xylep-donut-nanox");
|
|
||||||
#else
|
|
||||||
/* This can't grow beyond 40. Think about it. */
|
|
||||||
sprintf(name, "logger%d", i);
|
|
||||||
|
|
||||||
len = get_token(token[i], sizeof(token[i]), name, key, sizeof(key));
|
|
||||||
if ((-1 == len) || (len >= sizeof(token[i]))) abort();
|
|
||||||
token[i][len] = '\0';
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Base 64 (GPL: see COPYING)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* C89 compliant way to cast 'char' to 'unsigned char'. */
|
|
||||||
static inline unsigned char
|
|
||||||
to_uchar (char ch)
|
|
||||||
{
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
|
|
||||||
If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
|
|
||||||
possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
|
|
||||||
terminate the output buffer. */
|
|
||||||
void
|
|
||||||
base64_encode (const char *in, size_t inlen,
|
|
||||||
char *out, size_t outlen)
|
|
||||||
{
|
|
||||||
static const char b64str[64] =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
|
|
||||||
while (inlen && outlen) {
|
|
||||||
*out++ = b64str[(to_uchar(in[0]) >> 2) & 0x3f];
|
|
||||||
if (!--outlen)
|
|
||||||
break;
|
|
||||||
*out++ = b64str[((to_uchar(in[0]) << 4)
|
|
||||||
+ (--inlen ? to_uchar(in[1]) >> 4 : 0))
|
|
||||||
& 0x3f];
|
|
||||||
if (!--outlen)
|
|
||||||
break;
|
|
||||||
*out++ = (inlen
|
|
||||||
? b64str[((to_uchar(in[1]) << 2)
|
|
||||||
+ (--inlen ? to_uchar(in[2]) >> 6 : 0))
|
|
||||||
& 0x3f]
|
|
||||||
: '=');
|
|
||||||
if (!--outlen)
|
|
||||||
break;
|
|
||||||
*out++ = inlen ? b64str[to_uchar(in[2]) & 0x3f] : '=';
|
|
||||||
if (!--outlen)
|
|
||||||
break;
|
|
||||||
if (inlen)
|
|
||||||
inlen--;
|
|
||||||
if (inlen)
|
|
||||||
in += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outlen)
|
|
||||||
*out = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bubble Babble
|
|
||||||
*/
|
|
||||||
char const consonants[] = "bcdfghklmnprstvz";
|
|
||||||
char const vowels[] = "aeiouy";
|
|
||||||
|
|
||||||
#define bubblebabble_len(n) (6*(((n)/2)+1))
|
|
||||||
|
|
||||||
/** Compute bubble babble for input buffer.
|
|
||||||
*
|
|
||||||
* The generated output will be of length 6*((inlen/2)+1), including the
|
|
||||||
* trailing NULL.
|
|
||||||
*
|
|
||||||
* Test vectors:
|
|
||||||
* `' (empty string) `xexax'
|
|
||||||
* `1234567890' `xesef-disof-gytuf-katof-movif-baxux'
|
|
||||||
* `Pineapple' `xigak-nyryk-humil-bosek-sonax'
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
bubblebabble(unsigned char *out,
|
|
||||||
unsigned char const *in,
|
|
||||||
const size_t inlen)
|
|
||||||
{
|
|
||||||
size_t pos = 0;
|
|
||||||
int seed = 1;
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
out[pos++] = 'x';
|
|
||||||
while (1) {
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
if (i == inlen) {
|
|
||||||
out[pos++] = vowels[seed % 6];
|
|
||||||
out[pos++] = 'x';
|
|
||||||
out[pos++] = vowels[seed / 6];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = in[i++];
|
|
||||||
out[pos++] = vowels[(((c >> 6) & 3) + seed) % 6];
|
|
||||||
out[pos++] = consonants[(c >> 2) & 15];
|
|
||||||
out[pos++] = vowels[((c & 3) + (seed / 6)) % 6];
|
|
||||||
if (i == inlen) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
seed = ((seed * 5) + (c * 7) + in[i]) % 36;
|
|
||||||
|
|
||||||
c = in[i++];
|
|
||||||
out[pos++] = consonants[(c >> 4) & 15];
|
|
||||||
out[pos++] = '-';
|
|
||||||
out[pos++] = consonants[c & 15];
|
|
||||||
}
|
|
||||||
|
|
||||||
out[pos++] = 'x';
|
|
||||||
out[pos] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
randint(int max)
|
|
||||||
{
|
|
||||||
return random() % max;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define itokenlen 5
|
|
||||||
|
|
||||||
char const *
|
|
||||||
bogus_token()
|
|
||||||
{
|
|
||||||
static char token[TOKEN_MAX];
|
|
||||||
unsigned char crap[itokenlen];
|
|
||||||
unsigned char digest[bubblebabble_len(itokenlen)];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(crap); i += 1 ) {
|
|
||||||
crap[i] = (unsigned char)randint(256);
|
|
||||||
}
|
|
||||||
bubblebabble(digest, (unsigned char *)&crap, itokenlen);
|
|
||||||
snprintf(token, sizeof(token), "bogus:%s", digest);
|
|
||||||
token[sizeof(token) - 1] = '\0';
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define choice(a) (a[randint(sizeof(a)/sizeof(*a))])
|
|
||||||
|
|
||||||
char const *users[] = {"alice", "bob", "carol", "dave",
|
|
||||||
"eve", "fran", "gordon",
|
|
||||||
"isaac", "justin", "mallory",
|
|
||||||
"oscar", "pat", "steve",
|
|
||||||
"trent", "vanna", "walter", "zoe"};
|
|
||||||
|
|
||||||
|
|
||||||
char const *
|
|
||||||
user()
|
|
||||||
{
|
|
||||||
return choice(users);
|
|
||||||
}
|
|
||||||
|
|
||||||
char const *filenames[] = {"about", "request", "page", "buttons",
|
|
||||||
"images", "overview"};
|
|
||||||
char const *extensions[] = {"html", "htm", "jpg", "png", "css", "cgi"};
|
|
||||||
char const *fields[] = {"q", "s", "search", "id", "req", "oid", "pmt",
|
|
||||||
"u", "page", "xxnp", "stat", "jk", "ttb",
|
|
||||||
"access", "domain", "needle", "service", "client"};
|
|
||||||
char const *values[] = {"1", "turnip", "chupacabra", "58", "identify",
|
|
||||||
"parthenon", "jellyfish", "pullman", "auth",
|
|
||||||
"xa4Jmwl", "cornmeal", "ribbon", "49299248",
|
|
||||||
"javaWidget", "crashdump", "priority",
|
|
||||||
"blogosphere"};
|
|
||||||
|
|
||||||
char const *
|
|
||||||
url()
|
|
||||||
{
|
|
||||||
static char url[200];
|
|
||||||
int i, parts;
|
|
||||||
|
|
||||||
strcpy(url, "/");
|
|
||||||
|
|
||||||
parts = randint(4);
|
|
||||||
for (i = 0; i < parts; i += 1) {
|
|
||||||
if (i > 0) {
|
|
||||||
strcat(url, "/");
|
|
||||||
}
|
|
||||||
strcat(url, choice(filenames));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (randint(5) > 1) {
|
|
||||||
if (i > 0) {
|
|
||||||
strcat(url, ".");
|
|
||||||
strcat(url, choice(extensions));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
parts = randint(8) + 1;
|
|
||||||
for (i = 0; i < parts; i += 1) {
|
|
||||||
if (0 == i) {
|
|
||||||
strcat(url, "?");
|
|
||||||
} else {
|
|
||||||
strcat(url, "&");
|
|
||||||
}
|
|
||||||
strcat(url, choice(fields));
|
|
||||||
strcat(url, "=");
|
|
||||||
strcat(url, choice(values));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct message {
|
|
||||||
time_t when;
|
|
||||||
char text[300];
|
|
||||||
struct message *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Allocate some messages */
|
|
||||||
struct message heap[QSIZE];
|
|
||||||
|
|
||||||
struct message *pool;
|
|
||||||
struct message *queue;
|
|
||||||
|
|
||||||
struct message *
|
|
||||||
get_message()
|
|
||||||
{
|
|
||||||
struct message *ret = pool;
|
|
||||||
|
|
||||||
if (pool) {
|
|
||||||
pool = pool->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
free_message(struct message *msg)
|
|
||||||
{
|
|
||||||
if (msg) {
|
|
||||||
msg->next = pool;
|
|
||||||
pool = msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Either get count messages, or don't get any at all. */
|
|
||||||
int
|
|
||||||
get_many_messages(struct message **msgs, size_t count)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i += 1) {
|
|
||||||
msgs[i] = get_message();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == msgs[i-1]) {
|
|
||||||
for (i = 0; i < count; i += 1) {
|
|
||||||
free_message(msgs[i]);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
enqueue_message(struct message *msg)
|
|
||||||
{
|
|
||||||
struct message *cur;
|
|
||||||
|
|
||||||
/* In some cases, we want msg to be at the head */
|
|
||||||
if ((NULL == queue) || (queue->when > msg->when)) {
|
|
||||||
msg->next = queue;
|
|
||||||
queue = msg;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find where to stick it */
|
|
||||||
for (cur = queue; NULL != cur->next; cur = cur->next) {
|
|
||||||
if (cur->next->when > msg->when) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Insert it after cur */
|
|
||||||
msg->next = cur->next;
|
|
||||||
cur->next = msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
enqueue_messages(struct message **msgs, size_t count)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i += 1) {
|
|
||||||
enqueue_message(msgs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct message *
|
|
||||||
dequeue_message(time_t now)
|
|
||||||
{
|
|
||||||
if ((NULL != queue) && (queue->when <= now)) {
|
|
||||||
struct message *ret = queue;
|
|
||||||
|
|
||||||
queue = queue->next;
|
|
||||||
free_message(ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int pid = 52;
|
|
||||||
time_t then = time(NULL) - 100; /* Assure we get new tokens right away */
|
|
||||||
|
|
||||||
/* Seed RNG */
|
|
||||||
srandom(then);
|
|
||||||
|
|
||||||
/* Initialize free messages */
|
|
||||||
{
|
|
||||||
pool = &(heap[0]);
|
|
||||||
for (i = 0; i < QSIZE - 1; i += 1) {
|
|
||||||
heap[i].next = &(heap[i+1]);
|
|
||||||
}
|
|
||||||
heap[i].next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now let's make some crap! */
|
|
||||||
while (! feof(stdout)) {
|
|
||||||
struct message *msg;
|
|
||||||
time_t now = time(NULL);
|
|
||||||
int i, max;
|
|
||||||
|
|
||||||
/* Print messages */
|
|
||||||
while ((msg = dequeue_message(now))) {
|
|
||||||
char ftime[80];
|
|
||||||
struct tm *tm;
|
|
||||||
|
|
||||||
tm = gmtime(&msg->when);
|
|
||||||
if (! tm) {
|
|
||||||
snprintf(ftime, sizeof(ftime), "%ld", now);
|
|
||||||
} else {
|
|
||||||
strftime(ftime, sizeof(ftime), "%b %d %T", tm);
|
|
||||||
}
|
|
||||||
printf("%s loghost %s\n", ftime, msg->text);
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
/* Time for new tokens? */
|
|
||||||
if (then + 60 <= now) {
|
|
||||||
read_tokens();
|
|
||||||
then = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make some messages */
|
|
||||||
max = MSGS_PER_SEC_MIN + randint(MSGS_PER_SEC_MAX - MSGS_PER_SEC_MIN);
|
|
||||||
|
|
||||||
for (i = 0; i < max; i += 1) {
|
|
||||||
time_t start = now + 1;
|
|
||||||
struct message *messages[10];
|
|
||||||
|
|
||||||
/* Increment the PID */
|
|
||||||
pid = (pid + 1 + randint(20)) % PID_MAX;
|
|
||||||
|
|
||||||
switch (randint(90)) {
|
|
||||||
case 0:
|
|
||||||
/* Internal diagnostic! */
|
|
||||||
if (-1 != get_many_messages(messages, 1)) {
|
|
||||||
int queued, pooled;
|
|
||||||
struct message *msg;
|
|
||||||
|
|
||||||
for (pooled = 0, msg = pool;
|
|
||||||
msg;
|
|
||||||
msg = msg->next, pooled += 1);
|
|
||||||
/* Start at one because of this message */
|
|
||||||
for (queued = 1, msg = queue;
|
|
||||||
msg;
|
|
||||||
msg = msg->next, queued += 1);
|
|
||||||
|
|
||||||
messages[0]->when = now;
|
|
||||||
snprintf(messages[0]->text, sizeof(messages[0]->text),
|
|
||||||
"DEBUG: %d in pool, %d in queue (%d total)",
|
|
||||||
pooled, queued, pooled + queued);
|
|
||||||
enqueue_messages(messages, 1);
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
/* Lame-o "token" service */
|
|
||||||
if (-1 != get_many_messages(messages, 1)) {
|
|
||||||
messages[0]->when = start;
|
|
||||||
snprintf(messages[0]->text, sizeof(messages[0]->text),
|
|
||||||
"tokenserv[%d]: token is %s",
|
|
||||||
pid, token[0]);
|
|
||||||
enqueue_messages(messages, 1);
|
|
||||||
}
|
|
||||||
/* Always follow this with a couple lines of fluff so it's
|
|
||||||
not the last thing in a batch */
|
|
||||||
max += 2;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
/* IMAP */
|
|
||||||
{
|
|
||||||
char const *mytoken;
|
|
||||||
char const *u;
|
|
||||||
char btoken[TOKEN_MAX * 2];
|
|
||||||
|
|
||||||
if (randint(5) == 0) {
|
|
||||||
mytoken = token[1];
|
|
||||||
u = "token";
|
|
||||||
} else {
|
|
||||||
mytoken = bogus_token();
|
|
||||||
u = user();
|
|
||||||
}
|
|
||||||
base64_encode(mytoken, strlen(mytoken), btoken, sizeof(btoken));
|
|
||||||
|
|
||||||
if (-1 != get_many_messages(messages, 2)) {
|
|
||||||
const int offset=15;
|
|
||||||
|
|
||||||
messages[0]->when = start;
|
|
||||||
snprintf(messages[0]->text, sizeof(messages[0]->text),
|
|
||||||
"imapd[%d]: Login: user=%s method=PLAIN token1=%.*s",
|
|
||||||
pid, u, offset, btoken);
|
|
||||||
|
|
||||||
messages[1]->when = start + 4 + randint(60);
|
|
||||||
snprintf(messages[1]->text, sizeof(messages[1]->text),
|
|
||||||
"imapd[%d]: Disconnected: Logged out token2=%s",
|
|
||||||
pid, btoken + offset);
|
|
||||||
|
|
||||||
enqueue_messages(messages, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
/* IRC */
|
|
||||||
if (-1 != get_many_messages(messages, 3)) {
|
|
||||||
int connection = randint(512);
|
|
||||||
int port = randint(65536);
|
|
||||||
|
|
||||||
messages[0]->when = start;
|
|
||||||
snprintf(messages[0]->text, sizeof(messages[0]->text),
|
|
||||||
"ircd: Accepted connection %d from %d.%d.%d.%d:%d on socket %d.",
|
|
||||||
connection,
|
|
||||||
randint(256), randint(256),
|
|
||||||
randint(256), randint(256),
|
|
||||||
port,
|
|
||||||
randint(256));
|
|
||||||
|
|
||||||
messages[1]->when = start + randint(5);
|
|
||||||
snprintf(messages[1]->text, sizeof(messages[1]->text),
|
|
||||||
"ircd: User \"%s!~%s@dirtbags.net\" registered (connection %d).",
|
|
||||||
user(), user(), connection);
|
|
||||||
|
|
||||||
|
|
||||||
messages[2]->when = messages[1]->when + randint(600);
|
|
||||||
snprintf(messages[2]->text, sizeof(messages[2]->text),
|
|
||||||
"ircd: Shutting down connection %d (Got QUIT command.) with dirtbags.net:%d.",
|
|
||||||
connection, port);
|
|
||||||
|
|
||||||
enqueue_messages(messages, 3);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
/* cron */
|
|
||||||
if (-1 != get_many_messages(messages, 1)) {
|
|
||||||
messages[0]->when = start;
|
|
||||||
snprintf(messages[0]->text, sizeof(messages[0]->text),
|
|
||||||
"/USR/SBIN/CRON[%d]: (root) CMD ( /opt/bloatware/cleanup.sh )",
|
|
||||||
pid);
|
|
||||||
enqueue_messages(messages, 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
/* sudo */
|
|
||||||
if (-1 != get_many_messages(messages, 1)) {
|
|
||||||
char const *u = user();
|
|
||||||
|
|
||||||
messages[0]->when = start;
|
|
||||||
snprintf(messages[0]->text, sizeof(messages[0]->text),
|
|
||||||
"sudo: %12s : TTY=pts/%d ; PWD=/home/%s ; USER=root; COMMAND=/usr/bin/less /var/log/syslog",
|
|
||||||
u, randint(12), u);
|
|
||||||
enqueue_messages(messages, 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 6 ... 20:
|
|
||||||
/* SMTP */
|
|
||||||
{
|
|
||||||
char const *mytoken;
|
|
||||||
size_t tokenlen;
|
|
||||||
char const *host;
|
|
||||||
size_t hostlen;
|
|
||||||
char const *from;
|
|
||||||
size_t fromlen;
|
|
||||||
char const *to;
|
|
||||||
int is_token;
|
|
||||||
|
|
||||||
if (randint(10) == 0) {
|
|
||||||
is_token = 1;
|
|
||||||
mytoken = token[2];
|
|
||||||
} else {
|
|
||||||
is_token = 0;
|
|
||||||
mytoken = bogus_token();
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenlen = strlen(mytoken);
|
|
||||||
host = mytoken;
|
|
||||||
hostlen = tokenlen/3;
|
|
||||||
from = mytoken + hostlen;
|
|
||||||
fromlen = tokenlen/3;
|
|
||||||
to = mytoken + hostlen + fromlen;
|
|
||||||
|
|
||||||
if (-1 != get_many_messages(messages, 8)) {
|
|
||||||
int o1 = randint(256);
|
|
||||||
int o2 = randint(256);
|
|
||||||
int o3 = randint(256);
|
|
||||||
int o4 = randint(256);
|
|
||||||
long int mid = random();
|
|
||||||
long int mid2 = random();
|
|
||||||
|
|
||||||
messages[0]->when = start;
|
|
||||||
snprintf(messages[0]->text, sizeof(messages[0]->text),
|
|
||||||
"smtp/smtpd[%d]: connect from %.*s[%d.%d.%d.%d]",
|
|
||||||
pid, hostlen, host, o1, o2, o3, o4);
|
|
||||||
|
|
||||||
messages[1]->when = messages[0]->when + randint(1);
|
|
||||||
snprintf(messages[1]->text, sizeof(messages[1]->text),
|
|
||||||
"smtp/smtpd[%d]: %08lX: client=%.*s[%d.%d.%d.%d]",
|
|
||||||
pid, mid, hostlen, host, o1, o2, o3, o4);
|
|
||||||
|
|
||||||
messages[2]->when = messages[1]->when + 2 + randint(3);
|
|
||||||
snprintf(messages[2]->text, sizeof(messages[2]->text),
|
|
||||||
"smtp/smtpd[%d]: disconnect from [%d.%d.%d.%d]",
|
|
||||||
pid, o1, o2, o3, o4);
|
|
||||||
|
|
||||||
pid = (pid + 1 + randint(5)) % PID_MAX;
|
|
||||||
messages[3]->when = messages[1]->when + 1 + randint(2);
|
|
||||||
snprintf(messages[3]->text, sizeof(messages[3]->text),
|
|
||||||
"smtp/cleanup[%d]: %08lX: message-id=<%08lx@junkmail.spam>",
|
|
||||||
pid, mid, mid2);
|
|
||||||
|
|
||||||
pid = (pid + 1 + randint(5)) % PID_MAX;
|
|
||||||
messages[4]->when = messages[3]->when + randint(1);
|
|
||||||
snprintf(messages[4]->text, sizeof(messages[4]->text),
|
|
||||||
"smtp/qmgr[%d]: %08lX: from=<%.*s@junkmail.spam>, size=%d, nrcpt=1 (queue active)",
|
|
||||||
pid, mid, fromlen, from, randint(6000));
|
|
||||||
|
|
||||||
messages[5]->when = messages[4]->when + 2 + randint(2);
|
|
||||||
snprintf(messages[5]->text, sizeof(messages[5]->text),
|
|
||||||
"smtp/qmgr[%d]: %08lX: removed",
|
|
||||||
pid, mid);
|
|
||||||
|
|
||||||
messages[6]->when = messages[4]->when + randint(1);
|
|
||||||
snprintf(messages[6]->text, sizeof(messages[6]->text),
|
|
||||||
"smtp/deliver(%s): msgid=<%08lx@junkmail.spam>: saved to INBOX",
|
|
||||||
to, mid2);
|
|
||||||
|
|
||||||
pid = (pid + 1 + randint(5)) % PID_MAX;
|
|
||||||
messages[7]->when = messages[4]->when + randint(1);
|
|
||||||
snprintf(messages[7]->text, sizeof(messages[7]->text),
|
|
||||||
"smtp/local[%d]: %08lX: to <%s@dirtbags.net>, relay=local, dsn=2.0.0, status=sent (delivered to command /usr/bin/deliver)",
|
|
||||||
pid, mid, to);
|
|
||||||
|
|
||||||
enqueue_messages(messages, 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 21 ... 30:
|
|
||||||
/* ssh */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* HTTP */
|
|
||||||
if (-1 != get_many_messages(messages, 1)) {
|
|
||||||
messages[0]->when = start;
|
|
||||||
snprintf(messages[0]->text, sizeof(messages[0]->text),
|
|
||||||
"httpd[%d]: %d.%d.%d.%d\t-\tdirtbags.net\t80\tGET\t%s\t-\tHTTP/1.1\t200\t%d\t-\tMozilla/5.0",
|
|
||||||
pid,
|
|
||||||
randint(256), randint(256),
|
|
||||||
randint(256), randint(256),
|
|
||||||
url(), randint(4000) + 378);
|
|
||||||
enqueue_messages(messages, 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
struct timespec t = { 1, 0 };
|
|
||||||
|
|
||||||
nanosleep(&t, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/token.c
|
|
|
@ -1 +0,0 @@
|
||||||
../../../src/token.h
|
|
|
@ -1 +0,0 @@
|
||||||
logger
|
|
|
@ -1 +0,0 @@
|
||||||
S゙*郢シ緩ミ7<EFBE90>k<13>
|
|
|
@ -1 +0,0 @@
|
||||||
™כְ־אֹם[½ָµ<C2B5>
|
|
|
@ -1 +0,0 @@
|
||||||
logger
|
|
|
@ -1 +0,0 @@
|
||||||
S゙*郢シ緩ミ7<EFBE90>k<13>
|
|
|
@ -1 +0,0 @@
|
||||||
™כְ־אֹם[½ָµ<C2B5>
|
|
|
@ -1 +0,0 @@
|
||||||
logger
|
|
|
@ -1 +0,0 @@
|
||||||
S゙*郢シ緩ミ7<EFBE90>k<13>
|
|
|
@ -1 +0,0 @@
|
||||||
™כְ־אֹם[½ָµ<C2B5>
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
LXC_PKGDIR = $(TARGET)/lxc
|
||||||
|
LXC_BUILDDIR = $(BUILD)/lxc
|
||||||
|
LXC_VERSION = 0.7.5
|
||||||
|
LXC_TAR = $(CACHE)/lxc-$(LXC_VERSION).tar.gz
|
||||||
|
LXC_URL = http://lxc.sourceforge.net/download/lxc/lxc-$(LXC_VERSION).tar.gz
|
||||||
|
LXC_SRCDIR = $(LXC_BUILDDIR)/lxc-$(LXC_VERSION)
|
||||||
|
|
||||||
|
LXC_COMMANDS = attach cgroup checkpoint console execute freeze
|
||||||
|
LXC_COMMANDS += info init kill monitor restart start stop
|
||||||
|
LXC_COMMANDS += unfreeze unshare wait
|
||||||
|
|
||||||
|
LXC_PROGRAMS = $(addprefix $(LXC_SRCDIR)/src/lxc/lxc-, $(LXC_COMMANDS))
|
||||||
|
|
||||||
|
|
||||||
|
# Prevents automake from mangling cross-compiled binary names
|
||||||
|
LXC_CC_HOST := $(shell $(CC) -v 2>&1 | awk '/Target:/{print $$2}')
|
||||||
|
LXC_CONF_OPT := --host=i386-unknown-linux-uclibc --program-transform-name=
|
||||||
|
|
||||||
|
lxc-install: lxc-build
|
||||||
|
|
||||||
|
$(LXC_TAR):
|
||||||
|
@ mkdir -p $(@D)
|
||||||
|
wget -O $@ $(LXC_URL)
|
||||||
|
|
||||||
|
lxc-source: $(LXC_BUILDDIR)/source
|
||||||
|
$(LXC_BUILDDIR)/source: $(LXC_TAR)
|
||||||
|
mkdir -p $(LXC_BUILDDIR)
|
||||||
|
zcat $(LXC_TAR) | (cd $(LXC_BUILDDIR) && tar xf -)
|
||||||
|
cp packages/lxc/utmp.c $(LXC_SRCDIR)/src/lxc/
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
lxc-build: $(LXC_BUILDDIR)/built
|
||||||
|
$(LXC_BUILDDIR)/built: $(LXC_BUILDDIR)/source libcap-build
|
||||||
|
cd $(LXC_SRCDIR) && CFLAGS="$(LIBCAP_CFLAGS)" LDFLAGS="$(LIBCAP_LDFLAGS) -Xlinker -rpath -Xlinker /opt/lxc/lib" ./configure $(CONFIG_XCOMPILE_FLAGS)
|
||||||
|
$(MAKE) -C $(LXC_SRCDIR)
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
lxc-install: lxc-build
|
||||||
|
mkdir -p $(LXC_PKGDIR)/lib
|
||||||
|
cp $(LXC_SRCDIR)/src/lxc/liblxc.so $(LXC_PKGDIR)/lib/liblxc.so.0
|
||||||
|
cp $(LIBCAP_SRCDIR)/libcap/libcap.so.* $(LXC_PKGDIR)/lib
|
||||||
|
|
||||||
|
mkdir -p $(LXC_PKGDIR)/bin
|
||||||
|
cp $(LXC_PROGRAMS) $(LXC_PKGDIR)/bin
|
||||||
|
|
||||||
|
# $(call COPYTREE, packages/lxc/service, $(LXC_PKGDIR)/service)
|
||||||
|
|
||||||
|
lxc-clean:
|
||||||
|
rm -rf $(LXC_BUILDDIR)
|
||||||
|
|
||||||
|
|
||||||
|
LIBCAP_PKGDIR = $(TARGET)/libcap
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* Detecting runlevels from utmp is straight up bullshit, you.
|
||||||
|
|
||||||
|
1. runit doesn't have run levels
|
||||||
|
2. dbtl doesn't write utmp
|
||||||
|
3. even if it did, it doesn't have the glibc functions this code
|
||||||
|
wants
|
||||||
|
*/
|
||||||
|
int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
|
||||||
|
struct lxc_handler *handler) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -45,13 +45,9 @@ 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=$(echo "not a nonce:::$1" | md5sum | cut -b 1-8)
|
hash=$(dd if=/dev/urandom count=1 2>/dev/null | 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
|
||||||
|
|
||||||
echo "Registered with hash: $hash"
|
echo "Registered with hash: $hash"
|
||||||
|
|
||||||
# Create encrypted listing of teams
|
|
||||||
ls $base/teams/names | KEY="Too much cheese." arc4 > $www/teams.txt.$$
|
|
||||||
mv $www/teams.txt.$$ $www/teams.txt
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#! /usr/bin/awk -f
|
#! /bin/awk -f
|
||||||
|
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
|
|
|
@ -1,27 +1,28 @@
|
||||||
MCP_PKGDIR = $(TARGET)/mcp
|
MCP_PKGDIR = $(TARGET)/mcp
|
||||||
MCP_BUILDDIR = $(BUILD)/mcp
|
MCP_BUILDDIR = $(BUILD)/mcp
|
||||||
|
|
||||||
MCP_FNORD_VERSION = 1.10
|
|
||||||
MCP_FNORD_TARBALL = fnord-$(MCP_FNORD_VERSION).tar.bz2
|
|
||||||
MCP_FNORD_TARCACHE = $(CACHE)/$(MCP_FNORD_TARBALL)
|
|
||||||
MCP_FNORD_URL = http://www.fefe.de/fnord/$(MCP_FNORD_TARBALL)
|
|
||||||
MCP_FNORD_SRCDIR = $(MCP_BUILDDIR)/fnord-$(MCP_FNORD_VERSION)
|
|
||||||
|
|
||||||
$(MCP_FNORD_TARCACHE):
|
##
|
||||||
@ mkdir -p $(@D)
|
## XXX: clean up fnord like router.mk
|
||||||
wget -O $@ $(MCP_FNORD_URL)
|
##
|
||||||
|
|
||||||
|
FNORD_CACHE = $(CACHE)/fnord.git
|
||||||
|
FNORD_BUILDDIR = $(MCP_BUILDDIR)/fnord
|
||||||
|
FNORD_URL = http://woozle.org/~neale/projects/fnord
|
||||||
|
|
||||||
|
$(FNORD_CACHE):
|
||||||
|
git clone --bare $(FNORD_URL) $@
|
||||||
|
|
||||||
mcp-source: $(MCP_BUILDDIR)/source
|
mcp-source: $(MCP_BUILDDIR)/source
|
||||||
$(MCP_BUILDDIR)/source: $(MCP_FNORD_TARCACHE)
|
$(MCP_BUILDDIR)/source: $(FNORD_CACHE)
|
||||||
mkdir -p $(@D)
|
mkdir -p $(@D)
|
||||||
bzcat $< | (cd $(@D) && tar xf -)
|
git clone $(FNORD_CACHE) $(@D)/fnord
|
||||||
(cd $(@D)/fnord-$(MCP_FNORD_VERSION) && patch -p 1) < packages/mcp/fnord.patch
|
|
||||||
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-$(MCP_FNORD_VERSION) DIET= CC=$(CC) fnord-cgi
|
$(MAKE) -C $(MCP_BUILDDIR)/fnord DIET= CC=$(CC) fnord-cgi
|
||||||
|
|
||||||
|
|
||||||
mcp-install: $(MCP_BUILDDIR)/build
|
mcp-install: $(MCP_BUILDDIR)/build
|
||||||
|
@ -31,12 +32,10 @@ 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-$(MCP_FNORD_VERSION)/fnord-cgi $(MCP_PKGDIR)/bin/
|
cp $(MCP_BUILDDIR)/fnord/fnord-cgi $(MCP_PKGDIR)/bin/
|
||||||
|
|
||||||
$(call COPYTREE, packages/mcp/service, $(MCP_PKGDIR)/service)
|
$(call COPYTREE, packages/mcp/service, $(MCP_PKGDIR)/service)
|
||||||
|
|
||||||
$(call COPYTREE, packages/mcp/tokend.keys, $(MCP_PKGDIR)/tokend.keys)
|
|
||||||
|
|
||||||
$(call COPYTREE, packages/mcp/www, $(MCP_PKGDIR)/www)
|
$(call COPYTREE, packages/mcp/www, $(MCP_PKGDIR)/www)
|
||||||
cp packages/mcp/src/puzzler.cgi $(MCP_PKGDIR)/www/
|
cp packages/mcp/src/puzzler.cgi $(MCP_PKGDIR)/www/
|
||||||
cp packages/mcp/src/claim.cgi $(MCP_PKGDIR)/www/
|
cp packages/mcp/src/claim.cgi $(MCP_PKGDIR)/www/
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
fd84:b410:3441::2/64
|
|
@ -2,11 +2,13 @@
|
||||||
|
|
||||||
exec 2>&1
|
exec 2>&1
|
||||||
|
|
||||||
ip addr add 10.0.0.2/16 label eth0:mcp dev eth0
|
# Bring up address
|
||||||
|
IP=$(cat ip.txt)
|
||||||
install -d /var/www
|
ip addr add $IP dev eth0
|
||||||
|
ip monitor | grep -q $IP
|
||||||
|
|
||||||
# Link in puzzles and web pages
|
# Link in puzzles and web pages
|
||||||
|
install -d /var/www
|
||||||
for d in /opt/*; do
|
for d in /opt/*; do
|
||||||
if [ -d $d/puzzles ]; then
|
if [ -d $d/puzzles ]; then
|
||||||
ln -sf $d/puzzles /var/www/$(basename $d)
|
ln -sf $d/puzzles /var/www/$(basename $d)
|
||||||
|
@ -16,8 +18,4 @@ for d in /opt/*; do
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
exec tcpsvd -u ctf ${IP%/*} 80 /opt/mcp/bin/fnord-cgi /var/www
|
||||||
mkdir -p sites
|
|
||||||
cd sites
|
|
||||||
ln -sf /var/www default
|
|
||||||
exec tcpsvd -u ctf 10.0.0.2 80 /opt/mcp/bin/fnord-cgi
|
|
||||||
|
|
|
@ -1,28 +1,14 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
# First argument is seconds between running everything
|
fn=$2/$3
|
||||||
period=${1:-60}
|
|
||||||
|
|
||||||
NEWPOINTS=/var/lib/ctf/points.new
|
|
||||||
POINTS=/var/lib/ctf/points.log
|
POINTS=/var/lib/ctf/points.log
|
||||||
SCOREBOARD=/var/www/scoreboard.html
|
SCOREBOARD=/var/www/scoreboard.html
|
||||||
|
|
||||||
if ! [ -f $SCOREBOARD ]; then
|
cat $fn >> $POINTS || break
|
||||||
/opt/mcp/bin/scoreboard < $POINTS > $SCOREBOARD
|
rm $fn
|
||||||
|
|
||||||
|
# Render scoreboard
|
||||||
|
if [ $POINTS -nt $SCOREBOARD ]; then
|
||||||
|
/opt/mcp/bin/scoreboard < $POINTS > $SCOREBOARD.new && mv $SCOREBOARD.new $SCOREBOARD
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while true; do
|
|
||||||
# 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
|
|
||||||
/opt/mcp/bin/scoreboard < $POINTS > $SCOREBOARD.new && mv $SCOREBOARD.new $SCOREBOARD
|
|
||||||
fi
|
|
||||||
|
|
||||||
sleep $period
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,13 +1,52 @@
|
||||||
#! /bin/sh
|
#! /bin/sh -e
|
||||||
|
|
||||||
exec 2>&1
|
exec 2>&1
|
||||||
|
|
||||||
install -o ctf -m 0755 -d /var/lib/ctf/points.new
|
install -d /var/lib/ctf
|
||||||
|
|
||||||
|
# Create CTF and nobody users
|
||||||
|
touch /etc/group /etc/passwd
|
||||||
|
addgroup -g 65534 nogroup || true
|
||||||
|
adduser -D -S -h /var/lib/ctf -H ctf || true
|
||||||
|
adduser -D -g nogroup -u 65534 -h /tmp -H nobody || true
|
||||||
|
|
||||||
|
# Set up base directories
|
||||||
|
NEWDIR=/var/lib/ctf/points.new
|
||||||
|
install -d /var/www
|
||||||
|
install -d /var/lib/ctf
|
||||||
|
install -o ctf -m 0755 -d $NEWDIR
|
||||||
install -o ctf -m 0755 -d /var/lib/ctf/points.tmp
|
install -o ctf -m 0755 -d /var/lib/ctf/points.tmp
|
||||||
|
|
||||||
|
# Make tokens database now, this is as good a time as any
|
||||||
|
TOKENS=/var/lib/ctf/tokens.db
|
||||||
|
for fn in $TOKENS /opt/*/tokens.txt; do
|
||||||
|
[ -f "$fn" ] || continue
|
||||||
|
cat $fn
|
||||||
|
done | sort | uniq > $TOKENS.new
|
||||||
|
mv $TOKENS.new $TOKENS
|
||||||
|
|
||||||
|
# Create some files
|
||||||
|
CLAIM=/var/lib/ctf/claim.db
|
||||||
|
touch $CLAIM
|
||||||
|
chown ctf $CLAIM
|
||||||
touch /var/lib/ctf/points.log
|
touch /var/lib/ctf/points.log
|
||||||
|
|
||||||
# Re-populate teams list for tanks
|
# Generate preliminary scoreboard
|
||||||
ls $base/teams/names | KEY="Too much cheese." /opt/mcp/bin/arc4 > $www/teams.txt.$$
|
if ! [ -f /var/www/scoreboard.html ]; then
|
||||||
mv $www/teams.txt.$$ $www/teams.txt
|
/opt/mcp/bin/scoreboard < /dev/null > /var/www/scoreboard.html
|
||||||
|
fi
|
||||||
|
|
||||||
exec ./pointsd
|
|
||||||
|
if [ -x /sbin/inotifyd ]; then
|
||||||
|
exec /sbin/inotifyd ./pointsd $NEWDIR:y
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Simulate inotifyd
|
||||||
|
cd $NEWDIR
|
||||||
|
while true; do
|
||||||
|
for fn in *; do
|
||||||
|
[ -f "$fn" ] || continue
|
||||||
|
./pointsd m $NEWDIR $fn
|
||||||
|
done
|
||||||
|
sleep 7
|
||||||
|
done
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
exec 2>&1
|
exec 2>&1
|
||||||
|
|
||||||
DB=/var/lib/ctf/puzzles.db
|
install -d /var/www
|
||||||
|
|
||||||
mkdir -p /var/www
|
# Install truncates files
|
||||||
|
DB=/var/lib/ctf/puzzles.db
|
||||||
touch $DB
|
touch $DB
|
||||||
chown ctf $DB
|
chown ctf $DB
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
exec svlogd -tt $PWD
|
|
|
@ -1,20 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
exec 2>&1
|
|
||||||
|
|
||||||
ip addr add 10.0.0.2/16 label eth0:mcp dev eth0
|
|
||||||
|
|
||||||
DB=/var/lib/ctf/tokens.db
|
|
||||||
|
|
||||||
if [ ! -f $DB ]; then
|
|
||||||
# Append any package-provided tokens
|
|
||||||
cat /opt/*/tokens.txt >$DB 2>/dev/null
|
|
||||||
chown ctf $DB
|
|
||||||
fi
|
|
||||||
|
|
||||||
for fn in /var/lib/ctf/tokens.db /var/lib/ctf/claim.db; do
|
|
||||||
touch $fn
|
|
||||||
chown ctf $fn
|
|
||||||
done
|
|
||||||
|
|
||||||
exec tcpsvd -u ctf 0 1 /opt/mcp/bin/in.tokend
|
|
|
@ -19,8 +19,8 @@
|
||||||
<a href="scoring.html">About scoring</a>
|
<a href="scoring.html">About scoring</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="irc://10.0.0.2/ctf"
|
<a href="irc://[fd84:b410:3441::6]/ctf"
|
||||||
title="IRC on 10.0.0.2, channel #ctf">Contest chat</a>
|
title="IRC on fd84:b410:3441::6, channel #ctf">Contest chat</a>
|
||||||
carries important announcements, and sometimes clues and
|
carries important announcements, and sometimes clues and
|
||||||
puzzles.
|
puzzles.
|
||||||
</li>
|
</li>
|
||||||
|
@ -42,16 +42,14 @@
|
||||||
|
|
||||||
<h2>Rules</h2>
|
<h2>Rules</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
|
||||||
No ARP-level attacks: this includes IP spoofing.
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
No DoS attacks.
|
No DoS attacks.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Do not attack machines outside the contest network
|
Contest servers lie within <samp>fd84:b410:3441::/112</samp>.
|
||||||
(10.<i>x</i>.<i>x</i>.<i>x</i>). Low ports (under 1024) do not
|
Do not attack machines outside <samp>fd84:b410:3441::/48</samp>.
|
||||||
run contest categories.
|
Low ports (under 1024) do not run contest categories, don't
|
||||||
|
waste your time.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Consider the contest network hostile. It is up to you to
|
Consider the contest network hostile. It is up to you to
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
MULTICASTER_PKGDIR = $(TARGET)/multicaster
|
||||||
|
|
||||||
|
multicaster-install: multicaster-build
|
||||||
|
mkdir -p $(MULTICASTER_PKGDIR)
|
||||||
|
cp packages/multicaster/tokens.txt $(MULTICASTER_PKGDIR)
|
||||||
|
|
||||||
|
$(call COPYTREE, packages/multicaster/service, $(MULTICASTER_PKGDIR)/service)
|
||||||
|
|
||||||
|
mkdir -p $(MULTICASTER_PKGDIR)/bin/
|
||||||
|
$(MAKE) -C packages/multicaster/src install DESTDIR=$(CURDIR)/$(MULTICASTER_PKGDIR)
|
||||||
|
|
||||||
|
multicaster-clean:
|
||||||
|
rm -rf $(MULTICASTER_PKGDIR)
|
||||||
|
$(MAKE) -C packages/multicaster/src clean
|
||||||
|
|
||||||
|
multicaster-build:
|
||||||
|
$(MAKE) -C packages/multicaster/src build
|
||||||
|
|
||||||
|
PACKAGES += multicaster
|
|
@ -0,0 +1 @@
|
||||||
|
fd84:b410:3441::4e11/64
|
|
@ -0,0 +1,8 @@
|
||||||
|
#! /bin/sh -e
|
||||||
|
|
||||||
|
exec 2>&1
|
||||||
|
|
||||||
|
IP=$(cat ip.txt)
|
||||||
|
ip addr add $IP dev eth0 || true
|
||||||
|
|
||||||
|
exec setuidgid ctf /opt/multicaster/bin/multicaster ff15::62c 1580 </opt/multicaster/tokens.txt
|
|
@ -0,0 +1,11 @@
|
||||||
|
CFLAGS = -Wall -Werror
|
||||||
|
TARGETS = multicaster
|
||||||
|
|
||||||
|
all: build
|
||||||
|
build: $(TARGETS)
|
||||||
|
|
||||||
|
install: $(TARGETS)
|
||||||
|
install -m 0755 $(TARGETS) $(DESTDIR)/bin
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(TARGETS)
|
|
@ -0,0 +1,121 @@
|
||||||
|
/* multicast_client.c
|
||||||
|
* Adopted from tmouse's client/server example code
|
||||||
|
* found at http://cboard.cprogramming.com/showthread.php?t=67469
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h> /* for printf() and fprintf() */
|
||||||
|
#include <stdlib.h> /* for atoi() and exit() */
|
||||||
|
#include <string.h> /* for memset() */
|
||||||
|
#include <time.h> /* for timestamps */
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void DieWithError(const char* errorMessage)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", errorMessage);
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int sock; /* Socket */
|
||||||
|
char* multicastIP; /* Arg: IP Multicast Address */
|
||||||
|
char* multicastPort; /* Arg: Port */
|
||||||
|
struct addrinfo * multicastAddr = {0}; /* Multicast Address */
|
||||||
|
struct addrinfo * localAddr; /* Local address to bind to */
|
||||||
|
struct addrinfo hints = { 0 }; /* Hints for name lookup */
|
||||||
|
|
||||||
|
if ( argc != 3 )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Usage: %s <Multicast IP> <Multicast Port>\n", argv[0]);
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
multicastIP = argv[1]; /* First arg: Multicast IP address */
|
||||||
|
multicastPort = argv[2]; /* Second arg: Multicast port */
|
||||||
|
|
||||||
|
/* Resolve the multicast group address */
|
||||||
|
hints.ai_family = PF_INET6;
|
||||||
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
if ( getaddrinfo(multicastIP, NULL, &hints, &multicastAddr) != 0 ) DieWithError("getaddrinfo() failed");
|
||||||
|
|
||||||
|
/* Get a local address with the same family as our multicast group */
|
||||||
|
hints.ai_family = multicastAddr->ai_family;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE; /* Return an address we can bind to */
|
||||||
|
if ( getaddrinfo(NULL, multicastPort, &hints, &localAddr) != 0 )
|
||||||
|
{
|
||||||
|
DieWithError("getaddrinfo() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create socket for receiving datagrams */
|
||||||
|
if ( (sock = socket(localAddr->ai_family, localAddr->ai_socktype, 0)) == -1 )
|
||||||
|
{
|
||||||
|
DieWithError("socket() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
const int trueValue = 1;
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &trueValue, sizeof(trueValue));
|
||||||
|
#ifdef __APPLE__
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const void *) &trueValue, sizeof(trueValue));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Bind to the multicast port */
|
||||||
|
if ( bind(sock, localAddr->ai_addr, localAddr->ai_addrlen) != 0 )
|
||||||
|
{
|
||||||
|
DieWithError("bind() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Join the multicast group. */
|
||||||
|
if ((multicastAddr->ai_family == PF_INET6)&&(multicastAddr->ai_addrlen == sizeof(struct sockaddr_in6)))
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(multicastAddr->ai_addr);
|
||||||
|
struct ipv6_mreq multicastRequest; /* Multicast address join structure */
|
||||||
|
|
||||||
|
/* Specify the multicast group */
|
||||||
|
memcpy(&multicastRequest.ipv6mr_multiaddr, &((struct sockaddr_in6*)(multicastAddr->ai_addr))->sin6_addr, sizeof(multicastRequest.ipv6mr_multiaddr));
|
||||||
|
|
||||||
|
printf("scope_id: %d\n", addr->sin6_scope_id);
|
||||||
|
|
||||||
|
/* Accept multicast from any interface */
|
||||||
|
multicastRequest.ipv6mr_interface = addr->sin6_scope_id;
|
||||||
|
|
||||||
|
/* Join the multicast address */
|
||||||
|
if ( setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*) &multicastRequest, sizeof(multicastRequest)) != 0 ) DieWithError("setsockopt(IPV6_JOIN_GROUP) failed");
|
||||||
|
}
|
||||||
|
else DieWithError("Not IPv6");
|
||||||
|
|
||||||
|
freeaddrinfo(localAddr);
|
||||||
|
freeaddrinfo(multicastAddr);
|
||||||
|
|
||||||
|
for (;;) /* Run forever */
|
||||||
|
{
|
||||||
|
char recvString[500]; /* Buffer for received string */
|
||||||
|
int recvStringLen; /* Length of received string */
|
||||||
|
struct sockaddr_in6 from;
|
||||||
|
socklen_t fromlen = sizeof(from);
|
||||||
|
char sendString[] = "Token: banana\n";
|
||||||
|
char errorString[] = "That is not correct! Try again!\n";
|
||||||
|
|
||||||
|
/* Receive a single datagram from the server */
|
||||||
|
if ((recvStringLen = recvfrom(sock, recvString, sizeof(recvString) - 1, 0, (struct sockaddr *)&from, &fromlen)) < 0) DieWithError("recvfrom() failed");
|
||||||
|
recvString[recvStringLen] = '\0';
|
||||||
|
if(strcmp(recvString, "hello")==0) {
|
||||||
|
printf("Correct!!\n");
|
||||||
|
// printf("Token: banana\n");
|
||||||
|
sendto(sock, sendString, sizeof(sendString) - 1, 0, (struct sockaddr *)&from, fromlen);
|
||||||
|
} else {
|
||||||
|
// printf("That isn't correct! Try again!\n");
|
||||||
|
sendto(sock, errorString, sizeof(errorString) - 1, 0, (struct sockaddr *)&from, fromlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the received string */
|
||||||
|
printf("Received string [%s]\n", recvString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOT REACHED */
|
||||||
|
close(sock);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* multicast_server.c
|
||||||
|
* Adapted from tmouse's IPv6 client/server example code
|
||||||
|
* found at http://cboard.cprogramming.com/showthread.php?t=67469
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h> /* for fprintf() */
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdlib.h> /* for atoi() and exit() */
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void DieWithError(const char* errorMessage)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", errorMessage);
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int sock; /* Socket */
|
||||||
|
char* multicastIP; /* Arg: IP Multicast address */
|
||||||
|
char* multicastPort; /* Arg: Server port */
|
||||||
|
char* sendString; /* Arg: String to multicast */
|
||||||
|
size_t sendStringLen; /* Length of string to multicast */
|
||||||
|
struct addrinfo * multicastAddr; /* Multicast address */
|
||||||
|
struct addrinfo hints = { 0 }; /* Hints for name lookup */
|
||||||
|
|
||||||
|
if ( argc != 4 )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s <Multicast Address> <Port> <Send String>\n", argv[0]);
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
multicastIP = argv[1]; /* First arg: multicast IP address */
|
||||||
|
multicastPort = argv[2]; /* Second arg: multicast port */
|
||||||
|
sendString = argv[3]; /* Third arg: String to multicast */
|
||||||
|
sendStringLen = strlen(sendString); /* Find length of sendString */
|
||||||
|
|
||||||
|
/* Resolve destination address for multicast datagrams */
|
||||||
|
hints.ai_family = PF_INET6;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
|
if (getaddrinfo(multicastIP, multicastPort, &hints, &multicastAddr) != 0) DieWithError("getaddrinfo() failed");
|
||||||
|
|
||||||
|
/* Create socket for sending multicast datagrams */
|
||||||
|
if ((sock = socket(multicastAddr->ai_family, multicastAddr->ai_socktype, 0)) == -1) DieWithError("socket() failed");
|
||||||
|
|
||||||
|
int hops = 5;
|
||||||
|
if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) != 0) DieWithError("setsockopt(MULTICAST_HOPS) failed");
|
||||||
|
|
||||||
|
for (;;) /* Run forever */
|
||||||
|
{
|
||||||
|
int sendLen = sendto(sock, sendString, sendStringLen, 0, multicastAddr->ai_addr, multicastAddr->ai_addrlen);
|
||||||
|
if (sendLen == sendStringLen )
|
||||||
|
{
|
||||||
|
printf("Sent [%s] (%i bytes) to %s, port %s\n", sendString, sendLen, multicastIP, multicastPort);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DieWithError("sendto() sent a different number of bytes than expected");
|
||||||
|
}
|
||||||
|
sleep(1); /* Multicast sendString in datagram to clients every second */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOT REACHED */
|
||||||
|
freeaddrinfo(multicastAddr);
|
||||||
|
close(sock);
|
||||||
|
return 0;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue