Fully working and somewhat tested, with lua
|
@ -43,5 +43,6 @@ for cat, biggest in pairs(max_by_cat) do
|
||||||
body = body .. "</dd>\n"
|
body = body .. "</dd>\n"
|
||||||
end
|
end
|
||||||
body = body .. "</dl>\n"
|
body = body .. "</dl>\n"
|
||||||
|
body = body .. "<p>Reloading this page periodically may yield updated puzzle lists.</p>"
|
||||||
|
|
||||||
koth.page("Open Puzzles", body)
|
koth.page("Open Puzzles", body)
|
|
@ -1,69 +0,0 @@
|
||||||
#! /bin/sh -e
|
|
||||||
|
|
||||||
# Change to CTF_BASE
|
|
||||||
cd ${CTF_BASE:-.}
|
|
||||||
for i in $(seq 5); do
|
|
||||||
[ -f assigned.txt ] && break
|
|
||||||
cd ..
|
|
||||||
done
|
|
||||||
if ! [ -f assigned.txt ]; then
|
|
||||||
cat <<EOF
|
|
||||||
Content-type: text/html
|
|
||||||
|
|
||||||
Cannot find CTF_BASE
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Read CGI parameters
|
|
||||||
param () {
|
|
||||||
ret=$(echo "$QUERY_STRING" | awk -F '=' -v 'RS=&' -v "k=$1" '($1==k) {print $2;}')
|
|
||||||
ret=$(busybox httpd -d "$ret" || echo "$ret")
|
|
||||||
echo "$ret"
|
|
||||||
}
|
|
||||||
|
|
||||||
team=$(param n)
|
|
||||||
hash=$(param h | tr -dc 0-9a-f)
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
Content-type: text/html
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Team Registration</title>
|
|
||||||
<link rel="stylesheet" href="css/style.css" type="text/css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Team Registration</h1>
|
|
||||||
<section>
|
|
||||||
EOF
|
|
||||||
|
|
||||||
if [ -z "$hash" ] || [ -z "$team" ]; then
|
|
||||||
echo "<h2>Oops!</h2>"
|
|
||||||
echo "<p>Empty field, cannot complete request</p>"
|
|
||||||
elif ! grep -q "^$hash$" assigned.txt; then
|
|
||||||
echo "<h2>Oops!</h2>"
|
|
||||||
echo "<p>That hash has not been assigned.</p>"
|
|
||||||
elif [ -f state/teams/$hash ]; then
|
|
||||||
echo "<h2>Oops!</h2>"
|
|
||||||
echo "<p>That hash has already been registered.</p>"
|
|
||||||
else
|
|
||||||
printf "%s" "$team" > state/teams/$hash
|
|
||||||
echo "<h2>Success!</h2>"
|
|
||||||
echo "<p>Okay, your team has been named and you may begin using your hash!</p>"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
</section>
|
|
||||||
<nav>
|
|
||||||
<ul>
|
|
||||||
<li><a href="register.html">Register</a></li>
|
|
||||||
<li><a href="puzzles.html">Puzzles</a></li>
|
|
||||||
<li><a href="scoreboard.html">Scoreboard</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
EOF
|
|
13
install
|
@ -28,15 +28,6 @@ copy () {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
web () {
|
|
||||||
target=$DESTDIR/www/${1#*/}
|
|
||||||
if older $target $1; then
|
|
||||||
echo "WEB $1"
|
|
||||||
mkdir -p $(dirname $target)
|
|
||||||
cp $1 $target
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
[ -d $DESTDIR/state ] && return
|
[ -d $DESTDIR/state ] && return
|
||||||
echo "SETUP"
|
echo "SETUP"
|
||||||
|
@ -71,8 +62,8 @@ git ls-files | while read fn; do
|
||||||
;;
|
;;
|
||||||
doc/*)
|
doc/*)
|
||||||
;;
|
;;
|
||||||
html/*)
|
www/*)
|
||||||
web $fn
|
copy $fn
|
||||||
;;
|
;;
|
||||||
bin/*)
|
bin/*)
|
||||||
copy $fn
|
copy $fn
|
||||||
|
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
@ -3,8 +3,13 @@
|
||||||
local koth = {}
|
local koth = {}
|
||||||
|
|
||||||
-- cut -d$ANCHOR -f2- | grep -Fx "$NEEDLE"
|
-- cut -d$ANCHOR -f2- | grep -Fx "$NEEDLE"
|
||||||
function anchored_search(haystack, needle, anchor)
|
function koth.anchored_search(haystack, needle, anchor)
|
||||||
for line in io.lines(haystack) do
|
local f, err = io.open(haystack)
|
||||||
|
if (not f) then
|
||||||
|
return false, err
|
||||||
|
end
|
||||||
|
|
||||||
|
for line in f:lines() do
|
||||||
if (anchor) then
|
if (anchor) then
|
||||||
pos = line:find(anchor)
|
pos = line:find(anchor)
|
||||||
if (pos) then
|
if (pos) then
|
||||||
|
@ -13,19 +18,15 @@ function anchored_search(haystack, needle, anchor)
|
||||||
end
|
end
|
||||||
|
|
||||||
if (line == needle) then
|
if (line == needle) then
|
||||||
|
f:close()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
f:close()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function koth.anchored_search(haystack, needle, anchor)
|
|
||||||
local ok, ret = pcall(anchored_search, haystack, needle, anchor)
|
|
||||||
|
|
||||||
return ok and ret
|
|
||||||
end
|
|
||||||
|
|
||||||
function koth.page(title, body)
|
function koth.page(title, body)
|
||||||
if (os.getenv("REQUEST_METHOD")) then
|
if (os.getenv("REQUEST_METHOD")) then
|
||||||
print("Content-type: text/html")
|
print("Content-type: text/html")
|
||||||
|
@ -53,6 +54,8 @@ end
|
||||||
-- We're going to rely on `bin/once` only processing files with the right number of lines.
|
-- We're going to rely on `bin/once` only processing files with the right number of lines.
|
||||||
--
|
--
|
||||||
function koth.award_points(team, category, points, comment)
|
function koth.award_points(team, category, points, comment)
|
||||||
|
team = team:gsub("[^0-9a-f]", "-")
|
||||||
|
|
||||||
local filename = team .. "." .. category .. "." .. points
|
local filename = team .. "." .. category .. "." .. points
|
||||||
local entry = team .. " " .. category .. " " .. points
|
local entry = team .. " " .. category .. " " .. points
|
||||||
|
|
||||||
|
@ -60,8 +63,15 @@ function koth.award_points(team, category, points, comment)
|
||||||
entry = entry .. " " .. comment
|
entry = entry .. " " .. comment
|
||||||
end
|
end
|
||||||
|
|
||||||
local ok = anchored_search("../state/points.log", entry, " ")
|
local f = io.open("../state/teams/" .. team)
|
||||||
if (not ok) then
|
if (f) then
|
||||||
|
f:close()
|
||||||
|
else
|
||||||
|
return false, "No such team"
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok = koth.anchored_search("../state/points.log", entry, " ")
|
||||||
|
if (ok) then
|
||||||
return false, "Points already awarded"
|
return false, "Points already awarded"
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,17 +13,17 @@ category = category:gsub("[^A-Za-z0-9]", "-")
|
||||||
|
|
||||||
-- Check answer
|
-- Check answer
|
||||||
local needle = points .. " " .. answer
|
local needle = points .. " " .. answer
|
||||||
local haystack = "../puzzles/" .. category .. "/answers.txt"
|
local haystack = "../packages/" .. category .. "/answers.txt"
|
||||||
local found = koth.anchored_search(haystack, needle)
|
local found, err = koth.anchored_search(haystack, needle)
|
||||||
|
|
||||||
if (not found) then
|
if (not found) then
|
||||||
koth.page("Wrong answer")
|
koth.page("Wrong answer", err)
|
||||||
end
|
end
|
||||||
|
|
||||||
local ok, err = koth.award_points(team, category, points)
|
local ok, err = koth.award_points(team, category, points)
|
||||||
if (not ok) then
|
if (not ok) then
|
||||||
koth.page("Error awarding points",
|
koth.page("Error awarding points",
|
||||||
"<p>You got the right answer, but something blew up trying to give you points.</p>" ..
|
"<p>You got the right answer, but there was a problem trying to give you points:</p>" ..
|
||||||
"<p>" .. err .. "</p>")
|
"<p>" .. err .. "</p>")
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#! /usr/bin/lua
|
||||||
|
|
||||||
|
local cgi = require "cgi"
|
||||||
|
local koth = require "koth"
|
||||||
|
|
||||||
|
local team = cgi.fields["n"] or ""
|
||||||
|
local hash = cgi.fields["h"] or ""
|
||||||
|
|
||||||
|
hash = hash:match("[0-9a-f]*")
|
||||||
|
|
||||||
|
if ((hash == "") or (team == "")) then
|
||||||
|
koth.page("Invalid Entry", "Oops! Are you sure you got that right?")
|
||||||
|
elseif (not koth.anchored_search("../assigned.txt", hash)) then
|
||||||
|
koth.page("Invalid Hash", "Oops! I don't have a record of that hash. Did you maybe use capital letters accidentally?")
|
||||||
|
end
|
||||||
|
|
||||||
|
local f = io.open("../state/teams/" .. hash)
|
||||||
|
if (f) then
|
||||||
|
f:close()
|
||||||
|
koth.page("Already Exists", "Your team has already been named! Maybe somebody on your team beat you to it.")
|
||||||
|
end
|
||||||
|
|
||||||
|
local f = io.open("../state/teams/" .. hash, "w+")
|
||||||
|
f:write(team)
|
||||||
|
f:close()
|
||||||
|
|
||||||
|
koth.page("Success", "Okay, your team has been named and you may begin using your hash!")
|