diff options
author | John Ankarström <john@ankarstrom.se> | 2021-09-19 01:45:42 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2021-09-19 01:45:42 +0200 |
commit | c2ba75793e78afb00223003ddfcbc05714bd01bf (patch) | |
tree | 1037691fa9cdb7e47258b678cc6a5a70107c85c5 | |
parent | 4b838fced8cd5fd2c24300e3f9132a1474051a76 (diff) | |
download | cforum-c2ba75793e78afb00223003ddfcbc05714bd01bf.tar.gz |
Add simple captcha
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | ctl.c | 58 | ||||
-rw-r--r-- | t/head.t | 1 | ||||
-rw-r--r-- | t/newuser.t | 6 |
4 files changed, 55 insertions, 18 deletions
@@ -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 @@ -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"); @@ -4,6 +4,7 @@ <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <title><%= title %></title> <style type="text/css"> + form.hlite-captcha #captcha, form.hlite-confirm #confirm, form.hlite-name #name, form.hlite-full #full, diff --git a/t/newuser.t b/t/newuser.t index e62fdc2..7d53f0c 100644 --- a/t/newuser.t +++ b/t/newuser.t @@ -10,7 +10,7 @@ <td><input type="text" name="name" value="<% if(name) printhtml(name); %>"></td> </tr> <tr id="full"> - <td><label for="full">Full Name</label></td> + <td><label for="full">Full name</label></td> <td><input type="text" name="full" value="<% if(full) printhtml(full); %>"></td> <td><small>(optional)</small></td> </tr> @@ -22,6 +22,10 @@ <td><label for="confirm">Confirm</label></td> <td><input type="password" name="confirm" value=""></td> </tr> + <tr id="captcha"> + <td><label for="captcha">What is 2 + 7?</label></td> + <td><input type="text" name="captcha" value="<% if(captcha) printhtml(captcha); %>"></td> + </tr> </table> <p>By clicking <i>Create</i>, you confirm</p> <ol> |