From c2ba75793e78afb00223003ddfcbc05714bd01bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Sun, 19 Sep 2021 01:45:42 +0200 Subject: Add simple captcha --- README | 8 ++++---- ctl.c | 58 +++++++++++++++++++++++++++++++++++++++++++++------------- t/head.t | 1 + t/newuser.t | 6 +++++- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/README b/README index 01cf301..93d4c80 100644 --- a/README +++ b/README @@ -9,7 +9,7 @@ It is also rather small: wc -l *.c *.h */*.t */*.lex 101 cforum.c - 267 ctl.c + 299 ctl.c 268 db.c 10 err.c 144 query.c @@ -21,9 +21,9 @@ It is also rather small: 3 t/err.t 1 t/foot.t 29 t/front.t - 14 t/head.t - 34 t/newuser.t + 15 t/head.t + 38 t/newuser.t 28 t/post.t 12 t/user.t 95 mktpl/mktpl.lex - 1080 total + 1117 total diff --git a/ctl.c b/ctl.c index a3eb920..91761cc 100644 --- a/ctl.c +++ b/ctl.c @@ -54,12 +54,14 @@ newpost() void newuser() { - char *confirm, *hlite, msg[128], *name, *full, *p, *pass, *v; +#define MAXMSG 256 + char *captcha, *confirm, *hlite, msg[MAXMSG], *name, *full, *p, *pass, *v; char title[] = "New User"; int i; + struct user *user; *msg = 0; - confirm = hlite = name = full = pass = NULL; + captcha = confirm = hlite = name = full = pass = NULL; if(query.method == GET){ printf("Content-Type: text/html\n\n"); @@ -68,7 +70,7 @@ newuser() } if(query.length > MAXUSERDATA){ - snprintf(msg, 128, "Input exceeded server limitations"); + snprintf(msg, MAXMSG, "Input exceeded server limitations"); printf("Status: 431 Request Header Fields Too Large\n"); printf("Content-Type: text/html\n\n"); #include "t/newuser.tc" @@ -78,6 +80,8 @@ newuser() while(p = nextparam(POST, NULL, MAXUSERDATA)){ if(!(v = split(p))) continue; + if(!captcha && strcmp(p, "captcha") == 0) + captcha = strdup(v); if(!confirm && strcmp(p, "confirm") == 0) confirm = strdup(v); else if(!name && strcmp(p, "name") == 0) @@ -91,6 +95,10 @@ newuser() } /* Decode URL-encoded fields. */ + if(captcha && *captcha) + captcha[urldecode(captcha, -1)] = 0; + if(confirm && *confirm) + confirm[urldecode(confirm, -1)] = 0; if(name && *name) name[urldecode(name, -1)] = 0; if(full && *full) @@ -101,19 +109,19 @@ newuser() /* Constrain lengths of decoded fields. */ if(name && *name && strlen(name)-1 > MAXUSERNAME){ hlite = strdup("name"); - snprintf(msg, 128, "Username longer than %d characters", + snprintf(msg, MAXMSG, "Username longer than %d characters", MAXUSERNAME-1); goto err; } if(full && *full && strlen(full)-1 > MAXUSERFULL){ hlite = strdup("full"); - snprintf(msg, 128, "Full name longer than %d characters", + snprintf(msg, MAXMSG, "Full name longer than %d characters", MAXUSERFULL-1); goto err; } if(pass && *pass && strlen(pass)-1 > MAXUSERPASS){ hlite = strdup("pass"); - snprintf(msg, 128, "Password longer than %d characters", + snprintf(msg, MAXMSG, "Password longer than %d characters", MAXUSERPASS-1); goto err; } @@ -125,7 +133,7 @@ newuser() for(i = 0; name[i]; i++) if(!ISVIS(name[i]) || !(name[i] == '_' || ISALNUM(name[i]))){ hlite = strdup("name"); - snprintf(msg, 128, + snprintf(msg, MAXMSG, "Username may only contain ASCII letters, " "numbers and underscores."); goto err; @@ -134,25 +142,49 @@ newuser() if(!ISVIS(full[i])){ fprintf(stderr, "%d\n", full[i]); hlite = strdup("full"); - snprintf(msg, 128, + snprintf(msg, MAXMSG, "Full name may only contain visible characters"); goto err; } /* Ensure all required fields are there. */ - if(!name || !*name || !pass || !*pass){ - hlite = (!name || !*name)? strdup("name"): strdup("pass"); - snprintf(msg, 128, "Required field missing"); + if(captcha && strcmp(captcha, "9") != 0){ + hlite = strdup("captcha"); + snprintf(msg, MAXMSG, "Incorrectly answered captcha"); + goto err; + } + if(!name || !*name){ + hlite = strdup("name"); + snprintf(msg, MAXMSG, "Username is required"); + goto err; + } + if(!pass || !*pass){ + hlite = strdup("pass"); + snprintf(msg, MAXMSG, "Password is required"); goto err; } if(pass && confirm && strcmp(pass, confirm) != 0){ - snprintf(msg, 128, "Passwords do not match"); + snprintf(msg, MAXMSG, "Passwords do not match"); + goto err; + } + + if(!(user = malloc(sizeof(struct user)))) + err(1, "malloc"); + + user->name = name; + user->full = *full? full: NULL; + user->hash = pass; /* TODO */ + + if(!adduser(user)){ + snprintf(msg, MAXMSG, "Could not add user to database: %s", + sqlite3_errmsg(db)); goto err; } printf("Content-Type: text/html\n\n"); - printf("You are valid\n"); + snprintf(msg, MAXMSG, "SUCCESS: User was added to database"); + #include "t/newuser.tc" return; err: printf("Status: 400 Bad Request\n"); diff --git a/t/head.t b/t/head.t index 7962c5b..4fbd19a 100644 --- a/t/head.t +++ b/t/head.t @@ -4,6 +4,7 @@ <%= title %>