summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pttbbs/mbbsd/mail.c148
1 files changed, 137 insertions, 11 deletions
diff --git a/pttbbs/mbbsd/mail.c b/pttbbs/mbbsd/mail.c
index 415865b2..e86107a7 100644
--- a/pttbbs/mbbsd/mail.c
+++ b/pttbbs/mbbsd/mail.c
@@ -445,18 +445,104 @@ send_inner_mail(const char *fpath, const char *title, const char *receiver) {
return 0;
}
+static char *
+gen_auth_code(const char *prefix, char *buf, int length) {
+ // prevent ambigious characters: oOlI
+ const char *alphabets = "abcdefghjkmnpqrstuvwxyz";
+ int i;
+
+ if (!prefix)
+ prefix = "";
+
+ strlcpy(buf, prefix, length);
+ buf[length-1] = 0;
+ for (i = strlen(prefix); i < length - 1; i++)
+ buf[i] = alphabets[random() % strlen(alphabets)];
+ return buf;
+}
+
////////////////////////////////////////////////////////////////////////
// User-interface procedures
int
setforward(void) {
char buf[PATHLEN], ip[50] = "", yn[4];
FILE *fp;
+ const char *fn_forward_auth = ".secure/forward_auth",
+ *fn_forward_auth_dir = ".secure",
+ *fn_forward = ".forward";
+ char auth_code[16] = "";
+ time4_t auth_time = 0;
+ const char *prefix = "va";
if (!HasBasicUserPerm(PERM_LOGINOK))
return DONOTHING;
- vs_hdr("設定自動轉寄");
+ // There may be race condition but that's probably ok.
+ setuserfile(buf, fn_forward_auth);
+ if (dashs(buf) > 0) {
+ // load forward auth
+ fp = fopen(buf, "rt");
+ auth_time = dasht(buf);
+ if (fp) {
+ fgets(ip, sizeof(ip), fp);
+ fgets(auth_code, sizeof(auth_code), fp);
+ fclose(fp);
+ chomp(ip);
+ chomp(auth_code);
+ } else {
+ unlink(buf);
+ }
+ }
+
+ // verify auth
+ if (*ip && *auth_code) {
+ char input[sizeof(auth_code)] = "";
+ int days = (now - auth_time) / DAY_SECONDS;
+ vs_hdr("驗證自動轉寄");
+ prints("\n轉寄信箱: %s\n", ip);
+
+ if (getdata(4, 0, "請輸入上面轉寄信箱收到的的驗證碼: ", input,
+ sizeof(input), LCECHO) &&
+ strcmp(auth_code, input) == 0) {
+ outs(ANSI_COLOR(1;32) "確認驗證成功\!" ANSI_RESET "\n");
+ unlink(buf);
+ // write auth!
+ setuserfile(buf, fn_forward);
+ fp = fopen(buf, "wt");
+ if (fp) {
+ fputs(ip, fp);
+ fclose(fp);
+ vmsgf("轉寄信箱已設定為 %s", ip);
+ } else {
+ vmsg("系統異常 - 轉寄信箱設定失敗。");
+ }
+ return FULLUPDATE;
+ }
+
+ // incorrect code.
+ outs("驗證碼錯誤。\n");
+ if (!str_starts_with(input, prefix))
+ prints("驗證碼應為 %s 開頭的字串。\n", prefix);
+
+ // valid for at least one day.
+ if (days > 1) {
+ if (getdata(10, 0, "要重寄信箱或換信箱嗎? [y/N]", yn, sizeof(yn),
+ LCECHO) && yn[0] == 'y') {
+ unlink(buf);
+ } else {
+ return FULLUPDATE;
+ }
+ } else {
+ outs("請確認收到信件後再輸入驗證碼。\n"
+ "若一直無法收到,可於一天後換信箱或重發。\n");
+ pressanykey();
+ return FULLUPDATE;
+ }
+ }
+
+ // create new one.
+ vs_hdr("設定自動轉寄");
outs(ANSI_COLOR(1;31) "\n\n"
"由於許\多使用者有意或無意的設定錯誤間接造成自動轉寄被惡意使用,\n"
"本站基於安全性及防止廣告信的考量,\n"
@@ -464,11 +550,14 @@ setforward(void) {
"不便之處請多見諒。\n"
ANSI_RESET "\n");
- setuserfile(buf, ".forward");
+ setuserfile(buf, fn_forward);
if ((fp = fopen(buf, "r"))) {
fscanf(fp, "%" toSTR(sizeof(ip)) "s", ip);
fclose(fp);
}
+ chomp(ip);
+ prints("目前設定自動轉寄為: %s",
+ dashf(buf) ? ip : ANSI_COLOR(1;31)"(關閉)" ANSI_RESET);
getdata_buf(b_lines - 1, 0, "請輸入自動轉寄的Email: ",
ip, sizeof(ip), DOECHO);
strip_blank(ip, ip);
@@ -478,26 +567,63 @@ setforward(void) {
strchr(ip, '@') == NULL) {
unlink(buf);
vmsg("禁止自動轉寄給站內其它使用者");
- return 0;
+ return FULLUPDATE;
}
if (invalidaddr(ip)) {
vmsg("Email 輸入錯誤");
- return 0;
+ return FULLUPDATE;
}
getdata(b_lines, 0, "確定開啟自動轉信?(Y/n)", yn, sizeof(yn),
LCECHO);
- if (yn[0] != 'n' && (fp = fopen(buf, "w"))) {
- fputs(ip, fp);
- fclose(fp);
- vmsg("設定完成!");
- return 0;
- }
+ if (*yn != 'n') {
+ char authtemp[PATHLEN];
+ setuserfile(buf, fn_forward_auth_dir);
+ Mkdir(buf);
+ setuserfile(buf, fn_forward_auth);
+ fp = fopen(buf, "wt");
+ if (!fp) {
+ vmsg("系統錯誤 - 無法設定自動轉信。");
+ return FULLUPDATE;
+ }
+ gen_auth_code(prefix, auth_code, sizeof(auth_code));
+ strlcpy(authtemp, buf, sizeof(authtemp));
+ strlcat(authtemp, ".tmp", sizeof(authtemp));
+ fprintf(fp, "%s\n%s\n", ip, auth_code);
+ fclose(fp);
+ fp = fopen(authtemp, "wt");
+ if (!fp) {
+ unlink(buf);
+ vmsg("系統錯誤 - 無法送出確認信。");
+ return FULLUPDATE;
+ }
+ snprintf(buf, sizeof(buf), BBSNAME " 自動轉寄確認 (%s)",
+ cuser.userid);
+ fprintf(fp,
+ BBSNAME " 自動轉寄確認\n\n"
+ "使用者 %s 要求自動轉寄至此信箱 %s\n"
+ "若這不是您的帳號,請直接刪除此信件。\n"
+ "若確定要開啟自動轉寄,"
+ "請輸入下行 %s 開頭的驗證碼到自動轉寄設定:\n"
+ " %s\n", cuser.userid, ip, prefix, auth_code);
+ fclose(fp);
+ bsmtp(authtemp, buf, ip, cuser.userid);
+ unlink(authtemp);
+ vs_hdr("確認信件已寄出");
+ prints("\n\n"
+ ANSI_COLOR(1;33)
+ "為確認 Email 的正確性,系統已寄出一份含驗證碼的確認信,\n"
+ "標題為: %s\n"
+ "自動轉寄在完成確認前不會啟用。\n" ANSI_RESET
+ "請在收到該信件後再次進入設定轉寄信箱並輸入驗證碼。\n", buf);
+ pressanykey();
+ return FULLUPDATE;
+ }
}
unlink(buf);
vmsg("取消自動轉信!");
- return 0;
+ return FULLUPDATE;
}
int