diff --git a/src/Makefile b/src/Makefile index 4416543..59108f7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,8 +4,8 @@ all: $(TARGETS) in.tokend: in.tokend.o xxtea.o -claim.cgi: claim.cgi.o cgi.o common.o -puzzler.cgi: puzzler.cgi.o cgi.o common.o +claim.cgi: claim.cgi.o common.o +puzzler.cgi: puzzler.cgi.o common.o pointscli: common.o pointscli.o clean: diff --git a/src/cgi.c b/src/cgi.c deleted file mode 100644 index 6d2383d..0000000 --- a/src/cgi.c +++ /dev/null @@ -1,130 +0,0 @@ -#include -#include -#include -#include "cgi.h" - -static size_t inlen = 0; - -int -cgi_init() -{ - char *rm = getenv("REQUEST_METHOD"); - - if (! (rm && (0 == strcmp(rm, "POST")))) { - printf("405 Method not allowed\r\n" - "Allow: POST\r\n" - "Content-type: text/html\r\n" - "\r\n" - "

Method not allowed

\n" - "

I only speak POST. Sorry.

\n"); - return -1; - } - - inlen = atoi(getenv("CONTENT_LENGTH")); - - return 0; -} - -static int -read_char() -{ - if (inlen) { - inlen -= 1; - return getchar(); - } - return EOF; -} - -static char -tonum(int c) -{ - if ((c >= '0') && (c <= '9')) { - return c - '0'; - } - if ((c >= 'a') && (c <= 'f')) { - return 10 + c - 'a'; - } - if ((c >= 'A') && (c <= 'F')) { - return 10 + c - 'A'; - } - return 0; -} - -static char -read_hex() -{ - int a = read_char(); - int b = read_char(); - - return tonum(a)*16 + tonum(b); -} - -/* Read a key or a value. Since & and = aren't supposed to appear - outside of boundaries, we can use the same function for both. -*/ -size_t -cgi_item(char *str, size_t maxlen) -{ - int c; - size_t pos = 0; - - while (1) { - c = read_char(); - switch (c) { - case EOF: - case '=': - case '&': - str[pos] = '\0'; - return pos; - case '%': - c = read_hex(); - break; - case '+': - c = ' '; - break; - } - if (pos < maxlen - 1) { - str[pos] = c; - pos += 1; - } - } -} - -void -cgi_page(char *title, char *fmt, ...) -{ - va_list ap; - - printf(("Content-type: text/html\r\n" - "\r\n" - "\n" - "\n" - " \n" - " %s\n" - " \n" - " \n" - " \n" - "

%s

\n"), - title, title); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - printf("\n" - " \n" - "\n"); - exit(0); -} - -void -cgi_error(char *fmt, ...) -{ - va_list ap; - - printf("500 Internal Error\r\n" - "Content-type: text/plain\r\n" - "\r\n"); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - exit(0); -} diff --git a/src/cgi.h b/src/cgi.h deleted file mode 100644 index 6be7099..0000000 --- a/src/cgi.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __CGI_H__ -#define __CGI_H__ - -#include - -int cgi_init(); -size_t cgi_item(char *str, size_t maxlen); -void cgi_page(char *title, char *fmt, ...); -void cgi_error(char *fmt, ...); - -#endif diff --git a/src/claim.cgi.c b/src/claim.cgi.c index f087166..08e18ef 100644 --- a/src/claim.cgi.c +++ b/src/claim.cgi.c @@ -1,7 +1,4 @@ -#include -#include -#include -#include "cgi.h" +#include #include "common.h" char const *tokenlog = "/var/lib/ctf/tokend/tokens.log"; diff --git a/src/common.c b/src/common.c index ab5e98b..c443b5d 100644 --- a/src/common.c +++ b/src/common.c @@ -3,12 +3,147 @@ #include #include #include +#include #include #include #include -#include "cgi.h" #include "common.h" +/* + * CGI + */ +static size_t inlen = 0; + +int +cgi_init() +{ + char *rm = getenv("REQUEST_METHOD"); + + if (! (rm && (0 == strcmp(rm, "POST")))) { + printf("405 Method not allowed\r\n" + "Allow: POST\r\n" + "Content-type: text/html\r\n" + "\r\n" + "

Method not allowed

\n" + "

I only speak POST. Sorry.

\n"); + return -1; + } + + inlen = atoi(getenv("CONTENT_LENGTH")); + + return 0; +} + +static int +read_char() +{ + if (inlen) { + inlen -= 1; + return getchar(); + } + return EOF; +} + +static char +tonum(int c) +{ + if ((c >= '0') && (c <= '9')) { + return c - '0'; + } + if ((c >= 'a') && (c <= 'f')) { + return 10 + c - 'a'; + } + if ((c >= 'A') && (c <= 'F')) { + return 10 + c - 'A'; + } + return 0; +} + +static char +read_hex() +{ + int a = read_char(); + int b = read_char(); + + return tonum(a)*16 + tonum(b); +} + +/* Read a key or a value. Since & and = aren't supposed to appear + outside of boundaries, we can use the same function for both. +*/ +size_t +cgi_item(char *str, size_t maxlen) +{ + int c; + size_t pos = 0; + + while (1) { + c = read_char(); + switch (c) { + case EOF: + case '=': + case '&': + str[pos] = '\0'; + return pos; + case '%': + c = read_hex(); + break; + case '+': + c = ' '; + break; + } + if (pos < maxlen - 1) { + str[pos] = c; + pos += 1; + } + } +} + +void +cgi_page(char *title, char *fmt, ...) +{ + va_list ap; + + printf(("Content-type: text/html\r\n" + "\r\n" + "\n" + "\n" + " \n" + " %s\n" + " \n" + " \n" + " \n" + "

%s

\n"), + title, title); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("\n" + " \n" + "\n"); + exit(0); +} + +void +cgi_error(char *fmt, ...) +{ + va_list ap; + + printf("500 Internal Error\r\n" + "Content-type: text/plain\r\n" + "\r\n"); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + exit(0); +} + + +/* + * Common routines + */ + + #define EOL(c) ((EOF == (c)) || (0 == (c)) || ('\n' == (c))) int @@ -181,9 +316,8 @@ award_and_log_uniquely(char const *team, va_list ap; /* Make sure they haven't already claimed these points */ - /* Leave room for a newline later on */ va_start(ap, fmt); - len = vsnprintf(line, sizeof(line)-1, fmt, ap); + len = vsnprintf(line, sizeof(line), fmt, ap); va_end(ap); if (sizeof(line) <= len) { cgi_error("Log line too long"); @@ -213,7 +347,7 @@ award_and_log_uniquely(char const *team, line[len] = '\n'; lseek(fd, 0, SEEK_END); if (-1 == write(fd, line, len+1)) { - cgi_error("Unable to log your award"); + cgi_error("Unable to append log"); } close(fd); } diff --git a/src/common.h b/src/common.h index a119289..b64a9f9 100644 --- a/src/common.h +++ b/src/common.h @@ -1,6 +1,14 @@ #ifndef __COMMON_H__ #define __COMMON_H__ +#include + +int cgi_init(); +size_t cgi_item(char *str, size_t maxlen); +void cgi_page(char *title, char *fmt, ...); +void cgi_error(char *fmt, ...); + + #define teamdir "/var/lib/ctf/teams/names" #define pointsdir "/var/lib/ctf/points/new" diff --git a/src/puzzler.cgi.c b/src/puzzler.cgi.c index 844cf5b..29b522d 100644 --- a/src/puzzler.cgi.c +++ b/src/puzzler.cgi.c @@ -1,10 +1,5 @@ -#include -#include -#include -#include #include #include "common.h" -#include "cgi.h" char const *logfile = "/var/lib/ctf/puzzler.log";