From ae31e19f92e717919ac8e3db9039eb38d2b89aae Mon Sep 17 00:00:00 2001 From: in2 Date: Thu, 7 Mar 2002 15:13:44 +0000 Subject: Initial revision git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- mbbsd/register.c | 339 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 mbbsd/register.c (limited to 'mbbsd/register.c') diff --git a/mbbsd/register.c b/mbbsd/register.c new file mode 100644 index 00000000..e9c25be5 --- /dev/null +++ b/mbbsd/register.c @@ -0,0 +1,339 @@ +/* $Id: register.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#define _XOPEN_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "common.h" +#include "proto.h" + +extern char *str_new; +extern char *msg_uid; +extern int t_lines, t_columns; /* Screen size / width */ +extern char *str_mail_address; + +/* password encryption */ +static char pwbuf[14]; + +char *genpasswd(char *pw) { + if(pw[0]) { + char saltc[2], c; + int i; + + i = 9 * getpid(); + saltc[0] = i & 077; + saltc[1] = (i >> 6) & 077; + + for(i = 0; i < 2; i++) { + c = saltc[i] + '.'; + if(c > '9') + c += 7; + if(c > 'Z') + c += 6; + saltc[i] = c; + } + strcpy(pwbuf, pw); + return crypt(pwbuf, saltc); + } + return ""; +} + +int checkpasswd(char *passwd, char *test) { + char *pw; + + strncpy(pwbuf, test, 14); + pw = crypt(pwbuf, passwd); + return (!strncmp(pw, passwd, 14)); +} + +/* 檢查 user 註冊情況 */ +int bad_user_id(char *userid) { + int len, i; + len = strlen(userid); + + if(len < 2) + return 1; + + if (not_alpha(userid[0])) + return 1; + for (i=1; iuserid[0] == '\0') || (urec->userlevel & PERM_XEMPT) + /*|| (urec->userlevel & PERM_LOGINOK)*/ + || !strcmp(STR_GUEST,urec->userid)) + return 999999; + value = (clock - urec->lastlogin) / 60; /* minutes */ + + /* new user should register in 30 mins */ + if(strcmp(urec->userid, str_new) == 0) + return 30 - value; +#if 0 + if (!urec->numlogins) /* 未 login 成功者,不保留 */ + return -1; + if (urec->numlogins <= 3) /* #login 少於三者,保留 20 天 */ + return 20 * 24 * 60 - value; +#endif + /* 未完成註冊者,保留 15 天 */ + /* 一般情況,保留 120 天 */ + return (urec->userlevel & PERM_LOGINOK ? 120 : 15) * 24 * 60 - value; +} + +int check_and_expire_account(int uid,userec_t *urec) +{ + userec_t zerorec; + time_t now=time(NULL); + char genbuf[200],genbuf2[200]; + int val; + if((val = compute_user_value(urec, now)) < 0) { + sprintf(genbuf, "#%d %-12s %15.15s %d %d %d", + uid, urec->userid, ctime(&(urec->lastlogin)) + 4, + urec->numlogins, urec->numposts, val); + if(val > -1 * 60 * 24 * 365) { + memset(&zerorec, 0, sizeof(zerorec)); + log_usies("CLEAN", genbuf); + sprintf(genbuf, "home/%c/%s", urec->userid[0], + urec->userid); + sprintf(genbuf2, "tmp/%s", urec->userid); + if(dashd(genbuf) && Rename(genbuf, genbuf2)) { + sprintf(genbuf, "/bin/rm -fr home/%c/%s >/dev/null 2>&1", + urec->userid[0],urec->userid); + system(genbuf); + } + passwd_update(uid, &zerorec); + remove_from_uhash(uid - 1); + add_to_uhash(uid - 1, ""); + } + else + { + val=0; + log_usies("DATED", genbuf); + } + } + return val; +} + +extern char *fn_passwd; + +int getnewuserid() { + char genbuf[50]; + static char *fn_fresh = ".fresh"; + userec_t utmp,zerorec; + time_t clock; + struct stat st; + int fd, i; + + memset(&zerorec, 0, sizeof(zerorec)); + clock = time(NULL); + + /* Lazy method : 先找尋已經清除的過期帳號 */ + if((i = searchnewuser(0)) == 0) { + /* 每 1 個小時,清理 user 帳號一次 */ + if((stat(fn_fresh, &st) == -1) || (st.st_mtime < clock - 3600)) { + if((fd = open(fn_fresh, O_RDWR | O_CREAT, 0600)) == -1) + return -1; + write(fd, ctime(&clock), 25); + close(fd); + log_usies("CLEAN", "dated users"); + + fprintf(stdout, "尋找新帳號中, 請稍待片刻...\n\r"); + + if((fd = open(fn_passwd, O_RDWR | O_CREAT, 0600)) == -1) + return -1; + + /* 不曉得為什麼要從 2 開始... Ptt:因為SYSOP在1 */ + for(i = 2; i <= MAX_USERS; i++) { + passwd_query(i, &utmp); + check_and_expire_account(i,&utmp); + } + } + } + + passwd_lock(); + i = searchnewuser(1); + if((i <= 0) || (i > MAX_USERS)) { + passwd_unlock(); + if(more("etc/user_full", NA) == -1) + fprintf(stdout, "抱歉,使用者帳號已經滿了,無法註冊新的帳號\n\r"); + safe_sleep(2); + exit(1); + } + + sprintf(genbuf, "uid %d", i); + log_usies("APPLY", genbuf); + + strcpy(zerorec.userid, str_new); + zerorec.lastlogin = clock; + passwd_update(i, &zerorec); + setuserid(i, zerorec.userid); + passwd_unlock(); + return i; +} + +void new_register() { + extern userec_t xuser; + userec_t newuser; + char passbuf[STRLEN]; + int allocid, try, id; + + memset(&newuser, 0, sizeof(newuser)); + more("etc/register", NA); + try = 0; + while(1) { + if(++try >= 6) { + outs("\n您嘗試錯誤的輸入太多,請下次再來吧\n"); + refresh(); + + pressanykey(); + oflush(); + exit(1); + } + getdata(17, 0, msg_uid, newuser.userid, IDLEN + 1, DOECHO); + + if(bad_user_id(newuser.userid)) + outs("無法接受這個代號,請使用英文字母,並且不要包含空格\n"); + else if ((id=getuser(newuser.userid)) && + (id=check_and_expire_account(id,&xuser))>=0) + { + if(id==999999) + outs("此代號已經有人使用 是不死之身"); + else + { + sprintf(passbuf,"此代號已經有人使用 還有%d天才過期 \n",id/(60*24)); + outs(passbuf); + } + } + else + break; + } + + try = 0; + while(1) { + if(++try >= 6) { + outs("\n您嘗試錯誤的輸入太多,請下次再來吧\n"); + refresh(); + + pressanykey(); + oflush(); + exit(1); + } + if((getdata(19, 0, "請設定密碼:", passbuf, PASSLEN, NOECHO) < 3) || + !strcmp(passbuf, newuser.userid)) { + outs("密碼太簡單,易遭入侵,至少要 4 個字,請重新輸入\n"); + continue; + } + strncpy(newuser.passwd, passbuf, PASSLEN); + getdata(20, 0, "請檢查密碼:", passbuf, PASSLEN, NOECHO); + if(strncmp(passbuf, newuser.passwd, PASSLEN)) { + outs("密碼輸入錯誤, 請重新輸入密碼.\n"); + continue; + } + passbuf[8] = '\0'; + strncpy(newuser.passwd, genpasswd(passbuf), PASSLEN); + break; + } + newuser.userlevel = PERM_DEFAULT; + newuser.uflag = COLOR_FLAG | BRDSORT_FLAG | MOVIE_FLAG; + newuser.firstlogin = newuser.lastlogin = time(NULL); + newuser.money = 0; + newuser.pager = 1; + allocid = getnewuserid(); + if(allocid > MAX_USERS || allocid <= 0) { + fprintf(stderr, "本站人口已達飽和!\n"); + exit(1); + } + + if(passwd_update(allocid, &newuser) == -1) { + fprintf(stderr, "客滿了,再見!\n"); + exit(1); + } + setuserid(allocid, newuser.userid); + if(!dosearchuser(newuser.userid)) { + fprintf(stderr, "無法建立帳號\n"); + exit(1); + } +} + +extern userec_t cuser; + +void check_register() { + char *ptr = NULL; + + stand_title("請詳細填寫個人資料"); + + while(strlen(cuser.username) < 2) + getdata(2, 0, "綽號暱稱:", cuser.username, 24, DOECHO); + + for(ptr = cuser.username; *ptr; ptr++) { + if (*ptr == 9) /* TAB convert */ + *ptr = ' '; + } + while(strlen(cuser.realname) < 4) + getdata(4, 0, "真實姓名:", cuser.realname, 20, DOECHO); + + while(strlen(cuser.address) < 8) + getdata(6, 0, "聯絡地址:", cuser.address, 50, DOECHO); + + + if(!strchr(cuser.email, '@')) { + bell(); + move(t_lines - 4, 0); + prints("※ 為了您的權益,請填寫真實的 E-mail address, " + "以資確認閣下身份,\n" + "格式為 \033[44muser@domain_name\033[0m 或 \033[44muser" + "@\\[ip_number\\]\033[0m。\n\n" + "※ 如果您真的沒有 E-mail,請直接按 [return] 即可。"); + + do { + getdata(8, 0, "電子信箱:", cuser.email, 50, DOECHO); + if(!cuser.email[0]) + sprintf(cuser.email, "%s%s", cuser.userid, str_mail_address); + } while(!strchr(cuser.email, '@')); + + } + if(!HAS_PERM(PERM_SYSOP) && !HAS_PERM(PERM_LOGINOK)) { + /* 回覆過身份認證信函,或曾經 E-mail post 過 */ + clear(); + move(9,3); + prints("請詳填寫\033[32m註冊申請單\033[m," + "通告站長以獲得進階使用權力。\n\n\n\n"); + u_register(); + } + +#ifdef NEWUSER_LIMIT + if(!(cuser.userlevel & PERM_LOGINOK) && !HAS_PERM(PERM_SYSOP)) { + if(cuser.lastlogin - cuser.firstlogin < 3 * 86400) + cuser.userlevel &= ~PERM_POST; + more("etc/newuser", YEA); + } +#endif +} -- cgit v1.2.3