b4a29fac93 2009-08-10 drh: /* b4a29fac93 2009-08-10 drh: ** Copyright (c) 2009 D. Richard Hipp b4a29fac93 2009-08-10 drh: ** b4a29fac93 2009-08-10 drh: ** This program is free software; you can redistribute it and/or b4a29fac93 2009-08-10 drh: ** modify it under the terms of the GNU General Public b4a29fac93 2009-08-10 drh: ** License version 2 as published by the Free Software Foundation. b4a29fac93 2009-08-10 drh: ** b4a29fac93 2009-08-10 drh: ** This program is distributed in the hope that it will be useful, b4a29fac93 2009-08-10 drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of b4a29fac93 2009-08-10 drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU b4a29fac93 2009-08-10 drh: ** General Public License for more details. b4a29fac93 2009-08-10 drh: ** b4a29fac93 2009-08-10 drh: ** You should have received a copy of the GNU General Public b4a29fac93 2009-08-10 drh: ** License along with this library; if not, write to the b4a29fac93 2009-08-10 drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, b4a29fac93 2009-08-10 drh: ** Boston, MA 02111-1307, USA. b4a29fac93 2009-08-10 drh: ** b4a29fac93 2009-08-10 drh: ** Author contact information: b4a29fac93 2009-08-10 drh: ** drh@hwaci.com b4a29fac93 2009-08-10 drh: ** http://www.hwaci.com/drh/ b4a29fac93 2009-08-10 drh: ** b4a29fac93 2009-08-10 drh: ******************************************************************************* b4a29fac93 2009-08-10 drh: ** b4a29fac93 2009-08-10 drh: ** This file contains code to a simple text-based CAPTCHA. Though eaily b4a29fac93 2009-08-10 drh: ** defeated by a sophisticated attacker, this CAPTCHA does at least make b4a29fac93 2009-08-10 drh: ** scripting attacks more difficult. b4a29fac93 2009-08-10 drh: */ b4a29fac93 2009-08-10 drh: #include <assert.h> b4a29fac93 2009-08-10 drh: #include "config.h" b4a29fac93 2009-08-10 drh: #include "captcha.h" b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: #if INTERFACE b189acfd7b 2009-08-10 drh: #define CAPTCHA 3 /* Which captcha rendering to use */ b4a29fac93 2009-08-10 drh: #endif b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* b4a29fac93 2009-08-10 drh: ** Convert a hex digit into a value between 0 and 15 b4a29fac93 2009-08-10 drh: */ b4a29fac93 2009-08-10 drh: static int hexValue(char c){ b4a29fac93 2009-08-10 drh: if( c>='0' && c<='9' ){ b4a29fac93 2009-08-10 drh: return c - '0'; b4a29fac93 2009-08-10 drh: }else if( c>='a' && c<='f' ){ b4a29fac93 2009-08-10 drh: return c - 'a' + 10; b4a29fac93 2009-08-10 drh: }else if( c>='A' && c<='F' ){ b4a29fac93 2009-08-10 drh: return c - 'A' + 10; b4a29fac93 2009-08-10 drh: }else{ b4a29fac93 2009-08-10 drh: return 0; b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: #if CAPTCHA==1 b4a29fac93 2009-08-10 drh: /* b4a29fac93 2009-08-10 drh: ** A 4x6 pixel bitmap font for hexadecimal digits b4a29fac93 2009-08-10 drh: */ b4a29fac93 2009-08-10 drh: static const unsigned int aFont1[] = { b4a29fac93 2009-08-10 drh: 0x699996, b4a29fac93 2009-08-10 drh: 0x262227, b4a29fac93 2009-08-10 drh: 0x69124f, b4a29fac93 2009-08-10 drh: 0xf16196, b4a29fac93 2009-08-10 drh: 0x26af22, b4a29fac93 2009-08-10 drh: 0xf8e196, b4a29fac93 2009-08-10 drh: 0x68e996, b4a29fac93 2009-08-10 drh: 0xf12244, b4a29fac93 2009-08-10 drh: 0x696996, b4a29fac93 2009-08-10 drh: 0x699716, b4a29fac93 2009-08-10 drh: 0x699f99, b4a29fac93 2009-08-10 drh: 0xe9e99e, b4a29fac93 2009-08-10 drh: 0x698896, b4a29fac93 2009-08-10 drh: 0xe9999e, b4a29fac93 2009-08-10 drh: 0xf8e88f, b4a29fac93 2009-08-10 drh: 0xf8e888, b4a29fac93 2009-08-10 drh: }; b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* b189acfd7b 2009-08-10 drh: ** Render an 8-character hexadecimal string as ascii art. b4a29fac93 2009-08-10 drh: ** Space to hold the result is obtained from malloc() and should be freed b4a29fac93 2009-08-10 drh: ** by the caller. b4a29fac93 2009-08-10 drh: */ b4a29fac93 2009-08-10 drh: char *captcha_render(const char *zPw){ b4a29fac93 2009-08-10 drh: char *z = malloc( 500 ); b4a29fac93 2009-08-10 drh: int i, j, k, m; b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: k = 0; b4a29fac93 2009-08-10 drh: for(i=0; i<6; i++){ b4a29fac93 2009-08-10 drh: for(j=0; j<8; j++){ b4a29fac93 2009-08-10 drh: unsigned char v = hexValue(zPw[j]); b4a29fac93 2009-08-10 drh: v = (aFont1[v] >> ((5-i)*4)) & 0xf; b4a29fac93 2009-08-10 drh: for(m=8; m>=1; m = m>>1){ b4a29fac93 2009-08-10 drh: if( v & m ){ b4a29fac93 2009-08-10 drh: z[k++] = 'X'; b4a29fac93 2009-08-10 drh: z[k++] = 'X'; b4a29fac93 2009-08-10 drh: }else{ b4a29fac93 2009-08-10 drh: z[k++] = ' '; b4a29fac93 2009-08-10 drh: z[k++] = ' '; b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: z[k++] = ' '; b4a29fac93 2009-08-10 drh: z[k++] = ' '; b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: z[k++] = '\n'; b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: z[k] = 0; b4a29fac93 2009-08-10 drh: return z; b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: #endif /* CAPTCHA==1 */ b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: #if CAPTCHA==2 b4a29fac93 2009-08-10 drh: static const char *azFont2[] = { b4a29fac93 2009-08-10 drh: /* 0 */ b4a29fac93 2009-08-10 drh: " __ ", b4a29fac93 2009-08-10 drh: " / \\ ", b4a29fac93 2009-08-10 drh: "| () |", b4a29fac93 2009-08-10 drh: " \\__/ ", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* 1 */ b4a29fac93 2009-08-10 drh: " _ ", b4a29fac93 2009-08-10 drh: "/ |", b4a29fac93 2009-08-10 drh: "| |", b4a29fac93 2009-08-10 drh: "|_|", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* 2 */ b4a29fac93 2009-08-10 drh: " ___ ", b4a29fac93 2009-08-10 drh: "|_ )", b4a29fac93 2009-08-10 drh: " / / ", b4a29fac93 2009-08-10 drh: "/___|", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* 3 */ b4a29fac93 2009-08-10 drh: " ____", b4a29fac93 2009-08-10 drh: "|__ /", b4a29fac93 2009-08-10 drh: " |_ \\", b4a29fac93 2009-08-10 drh: "|___/", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* 4 */ b4a29fac93 2009-08-10 drh: " _ _ ", b4a29fac93 2009-08-10 drh: "| | | ", b4a29fac93 2009-08-10 drh: "|_ _|", b4a29fac93 2009-08-10 drh: " |_| ", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* 5 */ b4a29fac93 2009-08-10 drh: " ___ ", b4a29fac93 2009-08-10 drh: "| __|", b4a29fac93 2009-08-10 drh: "|__ \\", b4a29fac93 2009-08-10 drh: "|___/", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* 6 */ b4a29fac93 2009-08-10 drh: " __ ", b4a29fac93 2009-08-10 drh: " / / ", b4a29fac93 2009-08-10 drh: "/ _ \\", b4a29fac93 2009-08-10 drh: "\\___/", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* 7 */ b4a29fac93 2009-08-10 drh: " ____ ", b4a29fac93 2009-08-10 drh: "|__ |", b4a29fac93 2009-08-10 drh: " / / ", b4a29fac93 2009-08-10 drh: " /_/ ", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* 8 */ b4a29fac93 2009-08-10 drh: " ___ ", b4a29fac93 2009-08-10 drh: "( _ )", b4a29fac93 2009-08-10 drh: "/ _ \\", b4a29fac93 2009-08-10 drh: "\\___/", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* 9 */ b4a29fac93 2009-08-10 drh: " ___ ", b4a29fac93 2009-08-10 drh: "/ _ \\", b4a29fac93 2009-08-10 drh: "\\_, /", b4a29fac93 2009-08-10 drh: " /_/ ", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* A */ b4a29fac93 2009-08-10 drh: " ", b4a29fac93 2009-08-10 drh: " /\\ ", b4a29fac93 2009-08-10 drh: " / \\ ", b4a29fac93 2009-08-10 drh: "/_/\\_\\", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* B */ b4a29fac93 2009-08-10 drh: " ___ ", b4a29fac93 2009-08-10 drh: "| _ )", b4a29fac93 2009-08-10 drh: "| _ \\", b4a29fac93 2009-08-10 drh: "|___/", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* C */ b4a29fac93 2009-08-10 drh: " ___ ", b4a29fac93 2009-08-10 drh: " / __|", b4a29fac93 2009-08-10 drh: "| (__ ", b4a29fac93 2009-08-10 drh: " \\___|", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* D */ b4a29fac93 2009-08-10 drh: " ___ ", b4a29fac93 2009-08-10 drh: "| \\ ", b4a29fac93 2009-08-10 drh: "| |) |", b4a29fac93 2009-08-10 drh: "|___/ ", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* E */ b4a29fac93 2009-08-10 drh: " ___ ", b4a29fac93 2009-08-10 drh: "| __|", b4a29fac93 2009-08-10 drh: "| _| ", b4a29fac93 2009-08-10 drh: "|___|", b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* F */ b4a29fac93 2009-08-10 drh: " ___ ", b4a29fac93 2009-08-10 drh: "| __|", b4a29fac93 2009-08-10 drh: "| _| ", b4a29fac93 2009-08-10 drh: "|_| ", b4a29fac93 2009-08-10 drh: }; b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* b189acfd7b 2009-08-10 drh: ** Render an 8-digit hexadecimal string as ascii arg. b4a29fac93 2009-08-10 drh: ** Space to hold the result is obtained from malloc() and should be freed b4a29fac93 2009-08-10 drh: ** by the caller. b4a29fac93 2009-08-10 drh: */ b4a29fac93 2009-08-10 drh: char *captcha_render(const char *zPw){ b4a29fac93 2009-08-10 drh: char *z = malloc( 300 ); b4a29fac93 2009-08-10 drh: int i, j, k, m; b4a29fac93 2009-08-10 drh: const char *zChar; b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: k = 0; b4a29fac93 2009-08-10 drh: for(i=0; i<4; i++){ b4a29fac93 2009-08-10 drh: for(j=0; j<8; j++){ b4a29fac93 2009-08-10 drh: unsigned char v = hexValue(zPw[j]); b4a29fac93 2009-08-10 drh: zChar = azFont2[4*v + i]; b4a29fac93 2009-08-10 drh: for(m=0; zChar[m]; m++){ b4a29fac93 2009-08-10 drh: z[k++] = zChar[m]; b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: z[k++] = '\n'; b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: z[k] = 0; b4a29fac93 2009-08-10 drh: return z; b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: #endif /* CAPTCHA==2 */ b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: #if CAPTCHA==3 b189acfd7b 2009-08-10 drh: static const char *azFont3[] = { b189acfd7b 2009-08-10 drh: /* 0 */ b189acfd7b 2009-08-10 drh: " ___ ", b189acfd7b 2009-08-10 drh: " / _ \\ ", b189acfd7b 2009-08-10 drh: "| | | |", b189acfd7b 2009-08-10 drh: "| | | |", b189acfd7b 2009-08-10 drh: "| |_| |", b189acfd7b 2009-08-10 drh: " \\___/ ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* 1 */ b189acfd7b 2009-08-10 drh: " __ ", b189acfd7b 2009-08-10 drh: "/_ |", b189acfd7b 2009-08-10 drh: " | |", b189acfd7b 2009-08-10 drh: " | |", b189acfd7b 2009-08-10 drh: " | |", b189acfd7b 2009-08-10 drh: " |_|", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* 2 */ b189acfd7b 2009-08-10 drh: " ___ ", b189acfd7b 2009-08-10 drh: "|__ \\ ", b189acfd7b 2009-08-10 drh: " ) |", b189acfd7b 2009-08-10 drh: " / / ", b189acfd7b 2009-08-10 drh: " / /_ ", b189acfd7b 2009-08-10 drh: "|____|", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* 3 */ b189acfd7b 2009-08-10 drh: " ____ ", b189acfd7b 2009-08-10 drh: "|___ \\ ", b189acfd7b 2009-08-10 drh: " __) |", b189acfd7b 2009-08-10 drh: " |__ < ", b189acfd7b 2009-08-10 drh: " ___) |", b189acfd7b 2009-08-10 drh: "|____/ ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* 4 */ b189acfd7b 2009-08-10 drh: " _ _ ", b189acfd7b 2009-08-10 drh: "| || | ", b189acfd7b 2009-08-10 drh: "| || |_ ", b189acfd7b 2009-08-10 drh: "|__ _|", b189acfd7b 2009-08-10 drh: " | | ", b189acfd7b 2009-08-10 drh: " |_| ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* 5 */ b189acfd7b 2009-08-10 drh: " _____ ", b189acfd7b 2009-08-10 drh: "| ____|", b189acfd7b 2009-08-10 drh: "| |__ ", b189acfd7b 2009-08-10 drh: "|___ \\ ", b189acfd7b 2009-08-10 drh: " ___) |", b189acfd7b 2009-08-10 drh: "|____/ ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* 6 */ b189acfd7b 2009-08-10 drh: " __ ", b189acfd7b 2009-08-10 drh: " / / ", b189acfd7b 2009-08-10 drh: " / /_ ", b189acfd7b 2009-08-10 drh: "| '_ \\ ", b189acfd7b 2009-08-10 drh: "| (_) |", b189acfd7b 2009-08-10 drh: " \\___/ ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* 7 */ b189acfd7b 2009-08-10 drh: " ______ ", b189acfd7b 2009-08-10 drh: "|____ |", b189acfd7b 2009-08-10 drh: " / / ", b189acfd7b 2009-08-10 drh: " / / ", b189acfd7b 2009-08-10 drh: " / / ", b189acfd7b 2009-08-10 drh: " /_/ ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* 8 */ b189acfd7b 2009-08-10 drh: " ___ ", b189acfd7b 2009-08-10 drh: " / _ \\ ", b189acfd7b 2009-08-10 drh: "| (_) |", b189acfd7b 2009-08-10 drh: " > _ < ", b189acfd7b 2009-08-10 drh: "| (_) |", b189acfd7b 2009-08-10 drh: " \\___/ ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* 9 */ b189acfd7b 2009-08-10 drh: " ___ ", b189acfd7b 2009-08-10 drh: " / _ \\ ", b189acfd7b 2009-08-10 drh: "| (_) |", b189acfd7b 2009-08-10 drh: " \\__, |", b189acfd7b 2009-08-10 drh: " / / ", b189acfd7b 2009-08-10 drh: " /_/ ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* A */ b189acfd7b 2009-08-10 drh: " ", b189acfd7b 2009-08-10 drh: " /\\ ", b189acfd7b 2009-08-10 drh: " / \\ ", b189acfd7b 2009-08-10 drh: " / /\\ \\ ", b189acfd7b 2009-08-10 drh: " / ____ \\ ", b189acfd7b 2009-08-10 drh: "/_/ \\_\\", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* B */ b189acfd7b 2009-08-10 drh: " ____ ", b189acfd7b 2009-08-10 drh: "| _ \\ ", b189acfd7b 2009-08-10 drh: "| |_) |", b189acfd7b 2009-08-10 drh: "| _ < ", b189acfd7b 2009-08-10 drh: "| |_) |", b189acfd7b 2009-08-10 drh: "|____/ ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* C */ b189acfd7b 2009-08-10 drh: " _____ ", b189acfd7b 2009-08-10 drh: " / ____|", b189acfd7b 2009-08-10 drh: "| | ", b189acfd7b 2009-08-10 drh: "| | ", b189acfd7b 2009-08-10 drh: "| |____ ", b189acfd7b 2009-08-10 drh: " \\_____|", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* D */ b189acfd7b 2009-08-10 drh: " _____ ", b189acfd7b 2009-08-10 drh: "| __ \\ ", b189acfd7b 2009-08-10 drh: "| | | |", b189acfd7b 2009-08-10 drh: "| | | |", b189acfd7b 2009-08-10 drh: "| |__| |", b189acfd7b 2009-08-10 drh: "|_____/ ", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* E */ b189acfd7b 2009-08-10 drh: " ______ ", b189acfd7b 2009-08-10 drh: "| ____|", b189acfd7b 2009-08-10 drh: "| |__ ", b189acfd7b 2009-08-10 drh: "| __| ", b189acfd7b 2009-08-10 drh: "| |____ ", b189acfd7b 2009-08-10 drh: "|______|", b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* F */ b189acfd7b 2009-08-10 drh: " ______ ", b189acfd7b 2009-08-10 drh: "| ____|", b189acfd7b 2009-08-10 drh: "| |__ ", b189acfd7b 2009-08-10 drh: "| __| ", b189acfd7b 2009-08-10 drh: "| | ", b189acfd7b 2009-08-10 drh: "|_| ", b189acfd7b 2009-08-10 drh: }; b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: /* b189acfd7b 2009-08-10 drh: ** Render an 8-digit hexadecimal string as ascii arg. b189acfd7b 2009-08-10 drh: ** Space to hold the result is obtained from malloc() and should be freed b189acfd7b 2009-08-10 drh: ** by the caller. b189acfd7b 2009-08-10 drh: */ b189acfd7b 2009-08-10 drh: char *captcha_render(const char *zPw){ b189acfd7b 2009-08-10 drh: char *z = malloc( 600 ); b189acfd7b 2009-08-10 drh: int i, j, k, m; b189acfd7b 2009-08-10 drh: const char *zChar; b189acfd7b 2009-08-10 drh: b189acfd7b 2009-08-10 drh: k = 0; b189acfd7b 2009-08-10 drh: for(i=0; i<6; i++){ b189acfd7b 2009-08-10 drh: for(j=0; j<8; j++){ b189acfd7b 2009-08-10 drh: unsigned char v = hexValue(zPw[j]); b189acfd7b 2009-08-10 drh: zChar = azFont3[6*v + i]; b189acfd7b 2009-08-10 drh: for(m=0; zChar[m]; m++){ b189acfd7b 2009-08-10 drh: z[k++] = zChar[m]; b189acfd7b 2009-08-10 drh: } b189acfd7b 2009-08-10 drh: } b189acfd7b 2009-08-10 drh: z[k++] = '\n'; b189acfd7b 2009-08-10 drh: } b189acfd7b 2009-08-10 drh: z[k] = 0; b189acfd7b 2009-08-10 drh: return z; b189acfd7b 2009-08-10 drh: } b189acfd7b 2009-08-10 drh: #endif /* CAPTCHA==3 */ b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* b4a29fac93 2009-08-10 drh: ** COMMAND: test-captcha b4a29fac93 2009-08-10 drh: */ b4a29fac93 2009-08-10 drh: void test_captcha(void){ b4a29fac93 2009-08-10 drh: int i; b4a29fac93 2009-08-10 drh: unsigned int v; b4a29fac93 2009-08-10 drh: char *z; b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: for(i=2; i<g.argc; i++){ b4a29fac93 2009-08-10 drh: char zHex[30]; b4a29fac93 2009-08-10 drh: v = (unsigned int)atoi(g.argv[i]); b4a29fac93 2009-08-10 drh: sprintf(zHex, "%x", v); b4a29fac93 2009-08-10 drh: z = captcha_render(zHex); b4a29fac93 2009-08-10 drh: printf("%s:\n%s", zHex, z); b4a29fac93 2009-08-10 drh: free(z); b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* b4a29fac93 2009-08-10 drh: ** Compute a seed value for a captcha. The seed is public and is sent b4a29fac93 2009-08-10 drh: ** has a hidden parameter with the page that contains the captcha. Knowledge b4a29fac93 2009-08-10 drh: ** of the seed is insufficient for determining the captcha without additional b4a29fac93 2009-08-10 drh: ** information held only on the server and never revealed. b4a29fac93 2009-08-10 drh: */ b4a29fac93 2009-08-10 drh: unsigned int captcha_seed(void){ b4a29fac93 2009-08-10 drh: unsigned int x; b4a29fac93 2009-08-10 drh: sqlite3_randomness(sizeof(x), &x); b4a29fac93 2009-08-10 drh: x &= 0x7fffffff; b4a29fac93 2009-08-10 drh: return x; b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: /* b4a29fac93 2009-08-10 drh: ** Translate a captcha seed value into the captcha password string. b4a29fac93 2009-08-10 drh: */ b4a29fac93 2009-08-10 drh: char *captcha_decode(unsigned int seed){ b4a29fac93 2009-08-10 drh: const char *zSecret; b4a29fac93 2009-08-10 drh: const char *z; b4a29fac93 2009-08-10 drh: Blob b; b4a29fac93 2009-08-10 drh: static char zRes[20]; b4a29fac93 2009-08-10 drh: b4a29fac93 2009-08-10 drh: zSecret = db_get("captcha-secret", 0); b4a29fac93 2009-08-10 drh: if( zSecret==0 ){ b4a29fac93 2009-08-10 drh: db_multi_exec( b4a29fac93 2009-08-10 drh: "REPLACE INTO config(name,value)" b4a29fac93 2009-08-10 drh: " VALUES('captcha-secret', lower(hex(randomblob(20))));" b4a29fac93 2009-08-10 drh: ); b4a29fac93 2009-08-10 drh: zSecret = db_get("captcha-secret", 0); b4a29fac93 2009-08-10 drh: assert( zSecret!=0 ); b4a29fac93 2009-08-10 drh: } b4a29fac93 2009-08-10 drh: blob_init(&b, 0, 0); b4a29fac93 2009-08-10 drh: blob_appendf(&b, "%s-%x", zSecret, seed); b4a29fac93 2009-08-10 drh: sha1sum_blob(&b, &b); b4a29fac93 2009-08-10 drh: z = blob_buffer(&b); b4a29fac93 2009-08-10 drh: memcpy(zRes, z, 8); b4a29fac93 2009-08-10 drh: zRes[8] = 0; b4a29fac93 2009-08-10 drh: return zRes; b4a29fac93 2009-08-10 drh: }