diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-05-10 13:18:29 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-05-10 13:18:29 +0800 |
commit | 9bc937664cf3876c082742ff7d26fd99d4e201d6 (patch) | |
tree | 64f1dcddf2fd1e1c7ec8183c82683cdb469c6305 | |
parent | a4ba6b74f6dc61cec1a6b258e1609d9f7f7ef8a5 (diff) | |
download | pttbbs-9bc937664cf3876c082742ff7d26fd99d4e201d6.tar pttbbs-9bc937664cf3876c082742ff7d26fd99d4e201d6.tar.gz pttbbs-9bc937664cf3876c082742ff7d26fd99d4e201d6.tar.bz2 pttbbs-9bc937664cf3876c082742ff7d26fd99d4e201d6.tar.lz pttbbs-9bc937664cf3876c082742ff7d26fd99d4e201d6.tar.xz pttbbs-9bc937664cf3876c082742ff7d26fd99d4e201d6.tar.zst pttbbs-9bc937664cf3876c082742ff7d26fd99d4e201d6.zip |
- (exp) register: add figlet captcha system
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4285 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r-- | mbbsd/register.c | 175 |
1 files changed, 167 insertions, 8 deletions
diff --git a/mbbsd/register.c b/mbbsd/register.c index 38ed3cae..b3ba087f 100644 --- a/mbbsd/register.c +++ b/mbbsd/register.c @@ -14,9 +14,13 @@ #define FN_REJECT_NOTES "etc/reg_reject.notes" +#define FN_JOBSPOOL_DIR "jobspool/" + // #define DBG_DISABLE_CHECK // disable all input checks // #define DBG_DRYRUN // Dry-run test (mainly for RegForm2) +#define MSG_ERR_MAXTRIES "�z���տ��~����J���ƤӦh�A�ФU���A�ӧa" + //////////////////////////////////////////////////////////////////////////// // Password Hash //////////////////////////////////////////////////////////////////////////// @@ -311,7 +315,7 @@ static char * getregfile(char *buf) { // not in user's home because s/he could zip his/her home - snprintf(buf, PATHLEN, "jobspool/.regcode.%s", cuser.userid); + snprintf(buf, PATHLEN, FN_JOBSPOOL_DIR ".regcode.%s", cuser.userid); return buf; } @@ -366,6 +370,155 @@ delregcodefile(void) unlink(fpath); } + +//////////////////////////////////////////////////////////////////////////// +// Figlet Captcha System +//////////////////////////////////////////////////////////////////////////// +#ifdef USE_FIGLET_CAPCTHA + +int +gen_captcha(char *buf, int szbuf, char *fpath) +{ + const char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int calphas = strlen(alphabet); + char cmd[PATHLEN], opts[PATHLEN]; + int i, coptSpace, coptFont; + static const char *optSpace[] = { + "-S", "-s", "-k", "-W", "-o", + NULL + }; + static const char *optFont[] = { + "banner", "big", "slant", "small", + "smslant", "standard", + // block family + "block", "lean", + // shadow family + // "shadow", "smshadow", + // mini (better with large spacing) + // "mini", + NULL + }; + + // fill captcha code + for (i = 0; i < szbuf-1; i++) + buf[i] = alphabet[random() % calphas]; + buf[i] = 0; // szbuf-1 + + // decide options + coptSpace = coptFont = 0; + while (optSpace[coptSpace]) coptSpace++; + while (optFont[coptFont]) coptFont++; + snprintf(opts, sizeof(opts), + "%s -f %s", + optSpace[random() % coptSpace], + optFont [random() % coptFont ]); + + // create file + snprintf(fpath, PATHLEN, FN_JOBSPOOL_DIR ".captcha.%s", buf); + snprintf(cmd, sizeof(cmd), FIGLET_PATH " %s %s > %s", + opts, buf, fpath); + + // vmsg(cmd); + if (system(cmd) != 0) + return 0; + + return 1; +} + + +static int +_vgetcb_data_upper(int key, VGET_RUNTIME *prt, void *instance) +{ + if (key >= 'a' && key <= 'z') + key = toupper(key); + if (key < 'A' || key > 'Z') + { + bell(); + return VGETCB_NEXT; + } + return VGETCB_NONE; +} + +static int +_vgetcb_data_post(int key, VGET_RUNTIME *prt, void *instance) +{ + char *s = prt->buf; + while (*s) + { + if (isascii(*s) && islower(*s)) + *s = toupper(*s); + s++; + } + return VGETCB_NONE; +} + + +int verify_captcha() +{ + char captcha[7] = "", code[STRLEN]; + char fpath[PATHLEN]; + VGET_CALLBACKS vge = { NULL, _vgetcb_data_upper, _vgetcb_data_post }; + int tries = 0, i; + + do { + // create new captcha + if (tries % 2 == 0 || !captcha[0]) + { + // if generation failed, skip captcha. + if (!gen_captcha(captcha, sizeof(captcha), fpath) || + !dashf(fpath)) + return 1; + + // prompt user about captcha + vs_hdr("CAPTCHA �{�ҵ{��"); + outs("���F�T�{�z�����U�{�ǡA�п�J�U���ϼ���ܪ���r�C\n" + "�ϼ˥u�|�Ѥj�g�� A-Z �^��r���զ��C\n\n"); + show_file(fpath, 4, b_lines-5, SHOWFILE_ALLOW_ALL); + unlink(fpath); + } + + // each run waits 10 seconds. + for (i = 10; i > 0; i--) + { + move(b_lines-1, 0); clrtobot(); + prints("�ХJ���ˬd�W�����ϧΡA %d ����Y�i��J...", i); + // flush out current input + doupdate(); + peek_input(0.1f, Ctrl('C')); + drop_input(); + sleep(1); + } + + // input captcha + move(b_lines-1, 0); clrtobot(); + prints("�п�J�ϼ���ܪ� %d �ӭ^��r��: ", strlen(captcha)); + vgetstring(code, strlen(captcha)+1, 0, "", &vge, NULL); + + if (code[0] && strcasecmp(code, captcha) == 0) + break; + + // error case. + if (++tries >= 20) + return 0; + + // error + vmsg("��J���~�A�Э��աC�`�N�զ���r���O�j�g�^��r���C"); + + } while (1); + + clear(); + return 1; +} +#else // NO CAPTCHA + +int +verify_captcha() +{ + return 1; +} + +#endif + //////////////////////////////////////////////////////////////////////////// // Justify Utilities //////////////////////////////////////////////////////////////////////////// @@ -546,7 +699,7 @@ new_register(void) int minute; if (++try >= 6) { - vmsg("�z���տ��~����J�Ӧh�A�ФU���A�ӧa"); + vmsg(MSG_ERR_MAXTRIES); exit(1); } getdata(17, 0, msg_uid, newuser.userid, @@ -574,7 +727,7 @@ new_register(void) try = 0; while (1) { if (++try >= 6) { - vmsg("�z���տ��~����J�Ӧh�A�ФU���A�ӧa"); + vmsg(MSG_ERR_MAXTRIES); exit(1); } move(20, 0); clrtoeol(); @@ -608,7 +761,7 @@ new_register(void) while (strlen(newuser.nickname) < 2) { if (++try > 10) { - vmsg("�z���տ��~����J�Ӧh�A�ФU���A�ӧa"); + vmsg(MSG_ERR_MAXTRIES); exit(1); } getdata(19, 0, "�︹�ʺ١G", newuser.nickname, @@ -619,7 +772,7 @@ new_register(void) while (strlen(newuser.realname) < 4) { if (++try > 10) { - vmsg("�z���տ��~����J�Ӧh�A�ФU���A�ӧa"); + vmsg(MSG_ERR_MAXTRIES); exit(1); } getdata(20, 0, "�u��m�W�G", newuser.realname, @@ -638,7 +791,7 @@ new_register(void) // do not use isvalidaddr to check, // because that requires foreign info. if (++try > 10) { - vmsg("�z���տ��~����J�Ӧh�A�ФU���A�ӧa"); + vmsg(MSG_ERR_MAXTRIES); exit(1); } getdata(21, 0, "�p���a�}�G", newuser.address, @@ -652,10 +805,10 @@ new_register(void) int y, m, d; if (++try > 20) { - vmsg("�z���տ��~����J�Ӧh�A�ФU���A�ӧa"); + vmsg(MSG_ERR_MAXTRIES); exit(1); } - getdata(22, 0, "�ͤ� (�褸�~/��/��, �p 1984/02/29)�G", birthday, + getdata(22, 0, "�ͤ� (�褸�~/��/��, �p 1901/02/29)�G", birthday, sizeof(birthday), DOECHO); if (ParseDate(birthday, &y, &m, &d)) { @@ -670,6 +823,12 @@ new_register(void) newuser.day = (unsigned char)d; } + if (!verify_captcha()) + { + vmsg(MSG_ERR_MAXTRIES); + exit(1); + } + setupnewuser(&newuser); if( (uid = initcuser(newuser.userid)) < 0) { |