commit 59fd57bc074b31e440734865a371f79fb480e6eb Author: Grégory Soutadé Date: Thu Nov 8 19:18:12 2012 +0100 Initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..609f093 --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ + +gcaptchaz: gcaptchaz.c + gcc $^ -o $@ -lm -lfreetype -lpng -lgd -ggdb -Wall diff --git a/gcaptchaz.c b/gcaptchaz.c new file mode 100644 index 0000000..9f5404a --- /dev/null +++ b/gcaptchaz.c @@ -0,0 +1,253 @@ +#include +#include +#include +#include +#include +#include + +/* + This code is only a C implementation (with some minor modifications) of this captcha generator : + http://logz.org/captchaz/ + + Copyright November 2012 Grégory Soutadé + Copyright July 2007 Loz + + LICENCE : Copyleft, Licence Art Libre (http://artlibre.org/licence/lal) + + Modifications : + * Group letters + * Add another layer for letter rendering (more confusing) + * Change start, not appropriate for big fonts + * Change min/max font size + + You need libgd2-xpm-dev package + + It's recommanded the included font "scrawl.ttf" + */ + +#define MAX(a, b) (((a) >= (b)) ? (a) : (b)) + +// If not defined +/* int overflow2(int a, int b) */ +/* { */ +/* if(a < 0 || b < 0) { */ +/* fprintf(stderr, "gd warning: one parameter to a memory allocation multiplication is negative, failing operation gracefully\n"); */ +/* return 1; */ +/* } */ +/* if(b == 0) */ +/* return 0; */ +/* if(a > 0xFFFFFFFF / b) { */ +/* fprintf(stderr, "gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n"); */ +/* return 1; */ +/* } */ +/* return 0; */ +/* } */ + +static int my_rand(int min, int max) +{ + int val; + struct timeval tv; + static unsigned int seed = 0; + int interval; + + if (seed == 0) + { + gettimeofday(&tv, NULL); + seed = tv.tv_usec; + } + + val = rand_r(&seed); + + if (min < 0) + { + if (max < 0) + interval = -(min-max); + else + interval = max-min; + } + else + interval = max-min; + + val = (int)(((double)val/(double)RAND_MAX)*(double)(interval)); + + val += min; + + /* printf("rand [%d..%d] %d\n", min, max, val); */ + + return val; +} + +static inline int random_color(gdImagePtr im, int a, int b) { + return gdImageColorAllocate(im, my_rand(a,b), my_rand(a,b), my_rand(a,b)); +} + +static int generate_captcha(int width, int height, int inverse, char* font, char* phrase, char* out) +{ + gdImagePtr im; + int R, c1, c2; + int wd, x, y, w1, w2, limit, n, p, r, g, b; + int size, half, len; + double rotation; + char letter[2] = {0, 0}; + int brect[8]; + char* error; + const double rad = 3.14/(double)180; + +// initialize in-memory image with gd library + im = gdImageCreateTrueColor(width, height); + + R = (inverse) ? 0xFF : 0x00; + + gdImageFilledRectangle(im, 0, 0, width, height, random_color(im, 222^R, 255^R)); + + c1 = my_rand(150^R, 185^R); + c2 = my_rand(195^R, 230^R); + +// encolour bg + wd=20; x=0; + while (x < width) + { + gdImageFilledRectangle(im, x, 0, x+wd, height, random_color(im, 222^R, 255^R)); + x += wd; + wd += MAX(10, my_rand(0, 20) - 10); + } + + // make interesting background I, lines + wd=4; w1=0; w2=0; + for(x=0; x height) && (x > height)) // ??? + break; + } + + // more disturbing II, random letters + limit = my_rand(30, 90); + for(n=0; n /dev/null +if [ ! $? -eq 0 ] ; then + echo $res + exit 1 +fi + +text=`echo $res | cut -d\" -f2` + +# Do verification +if [ $do_check -eq 1 ] ; then + emacs "$out/captcha.png" + + echo -n "Enter CAPTCHA value : " + read user + + if [ "$user" != "$text" ] ; then + echo "CAPTCHA failed" + rm -f "$out/captcha.png" + exit 1 + fi + + echo "CAPTCHA OK" +fi + +# Encrypt captcha's value to generate captcha's name +key=`echo -n $pass | md5sum | cut -d' ' -f1` +enc=`echo -n $text | openssl enc -aes-128-ecb -nosalt -K $key -iv $key` +enc=`echo -n $enc | hexdump -e '"%02x"'` +mv "$out/captcha.png" "$out/$enc.png" diff --git a/scrawl.ttf b/scrawl.ttf new file mode 100644 index 0000000..1ef4878 Binary files /dev/null and b/scrawl.ttf differ