mirror of https://github.com/dirtbags/moth.git
Move CGI routines into common.c
They're still good general-purpose routines, though.
This commit is contained in:
parent
c3bf43b132
commit
5199cf5cac
|
@ -4,8 +4,8 @@ all: $(TARGETS)
|
||||||
|
|
||||||
in.tokend: in.tokend.o xxtea.o
|
in.tokend: in.tokend.o xxtea.o
|
||||||
|
|
||||||
claim.cgi: claim.cgi.o cgi.o common.o
|
claim.cgi: claim.cgi.o common.o
|
||||||
puzzler.cgi: puzzler.cgi.o cgi.o common.o
|
puzzler.cgi: puzzler.cgi.o common.o
|
||||||
pointscli: common.o pointscli.o
|
pointscli: common.o pointscli.o
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
130
src/cgi.c
130
src/cgi.c
|
@ -1,130 +0,0 @@
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#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"
|
|
||||||
"<h1>Method not allowed</h1>\n"
|
|
||||||
"<p>I only speak POST. Sorry.</p>\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"
|
|
||||||
"<!DOCTYPE html>\n"
|
|
||||||
"<html>\n"
|
|
||||||
" <head>\n"
|
|
||||||
" <title>%s</title>\n"
|
|
||||||
" <link rel=\"stylesheet\" href=\"ctf.css\" type=\"text/css\">\n"
|
|
||||||
" </head>\n"
|
|
||||||
" <body>\n"
|
|
||||||
" <h1>%s</h1>\n"),
|
|
||||||
title, title);
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vprintf(fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
printf("\n"
|
|
||||||
" </body>\n"
|
|
||||||
"</html>\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);
|
|
||||||
}
|
|
11
src/cgi.h
11
src/cgi.h
|
@ -1,11 +0,0 @@
|
||||||
#ifndef __CGI_H__
|
|
||||||
#define __CGI_H__
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
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
|
|
|
@ -1,7 +1,4 @@
|
||||||
#include <stdio.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "cgi.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
char const *tokenlog = "/var/lib/ctf/tokend/tokens.log";
|
char const *tokenlog = "/var/lib/ctf/tokend/tokens.log";
|
||||||
|
|
142
src/common.c
142
src/common.c
|
@ -3,12 +3,147 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "cgi.h"
|
|
||||||
#include "common.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"
|
||||||
|
"<h1>Method not allowed</h1>\n"
|
||||||
|
"<p>I only speak POST. Sorry.</p>\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"
|
||||||
|
"<!DOCTYPE html>\n"
|
||||||
|
"<html>\n"
|
||||||
|
" <head>\n"
|
||||||
|
" <title>%s</title>\n"
|
||||||
|
" <link rel=\"stylesheet\" href=\"ctf.css\" type=\"text/css\">\n"
|
||||||
|
" </head>\n"
|
||||||
|
" <body>\n"
|
||||||
|
" <h1>%s</h1>\n"),
|
||||||
|
title, title);
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
printf("\n"
|
||||||
|
" </body>\n"
|
||||||
|
"</html>\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)))
|
#define EOL(c) ((EOF == (c)) || (0 == (c)) || ('\n' == (c)))
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -181,9 +316,8 @@ award_and_log_uniquely(char const *team,
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
/* Make sure they haven't already claimed these points */
|
/* Make sure they haven't already claimed these points */
|
||||||
/* Leave room for a newline later on */
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
len = vsnprintf(line, sizeof(line)-1, fmt, ap);
|
len = vsnprintf(line, sizeof(line), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (sizeof(line) <= len) {
|
if (sizeof(line) <= len) {
|
||||||
cgi_error("Log line too long");
|
cgi_error("Log line too long");
|
||||||
|
@ -213,7 +347,7 @@ award_and_log_uniquely(char const *team,
|
||||||
line[len] = '\n';
|
line[len] = '\n';
|
||||||
lseek(fd, 0, SEEK_END);
|
lseek(fd, 0, SEEK_END);
|
||||||
if (-1 == write(fd, line, len+1)) {
|
if (-1 == write(fd, line, len+1)) {
|
||||||
cgi_error("Unable to log your award");
|
cgi_error("Unable to append log");
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
#ifndef __COMMON_H__
|
#ifndef __COMMON_H__
|
||||||
#define __COMMON_H__
|
#define __COMMON_H__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
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 teamdir "/var/lib/ctf/teams/names"
|
||||||
#define pointsdir "/var/lib/ctf/points/new"
|
#define pointsdir "/var/lib/ctf/points/new"
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "cgi.h"
|
|
||||||
|
|
||||||
char const *logfile = "/var/lib/ctf/puzzler.log";
|
char const *logfile = "/var/lib/ctf/puzzler.log";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue