回精華區
作者itoc, 信區: itoc
標題[功能] bhttpd.c 點選網址認證
時間04/05/12
作者: itoc (cygreadline4.dll) 看板: plan
標題: [功能] 點選網址認證
時間: 2004/05/12 Wed 11:14:48                           Updated: 2004/05/19

  點選認證信中的網址就通過認證
  當然,前提是要有掛 bhttpd

: mail.c:bsmtp()

#ifdef EMAIL_JUSTIFY
  char subject[80];
+ char regkey[10];
#endif

  ...
  ...

-   archiv32(str_hash(rcpt, cuser.tvalid), buf);
-   sprintf(title, TAG_VALID " %s(%s) [VALID]", cuser.userid, buf);
+   archiv32(str_hash(rcpt, cuser.tvalid), regkey);
+   sprintf(title, TAG_VALID " %s(%s) [VALID]", cuser.userid, regkey);

  ...
  ...

    if (method & MQ_JUSTIFY)    /* 身分認證信函 */
    {
      fprintf(fw, " ID: %s (%s)  E-mail: %s\r\n\r\n",
        cuser.userid, cuser.username, rcpt);
      // 如果 bhttpd 不是開在 port 80,例如是 port 8080,那麼這裡要改成 
      // http://"MYHOSTNAME":8080/register/%s&%s" 
+     fprintf(fw, " 您可以直接點選 http://"MYHOSTNAME"/register/%s&%s"
+       "來通過認證\r\n\r\n", cuser.userid, regkey);
    }

: bhttpd.c 一開始的註解

  http://my.domain/image/filename              顯示圖檔
+ http://my.domain/register/userid&regkey      線上認證

: bhttpd.c:main()

  WebKeyFunc cmd[] =
  {
    ...
    ...
    "/image/", html_image,
+   "/register/", html_register,

    NULL, html_mainpage
  };

: bhttpd.c 加這一段在 main() 前面

/*-------------------------------------------------------*/
/* 認證                                                  */
/*-------------------------------------------------------*/


static int
is_badid(userid)
  char *userid;
{
  int ch;
  char *str;

  ch = strlen(userid);
  if (ch < 2 || ch > IDLEN)
    return 1;

  if (!is_alpha(*userid))
    return 1;

  str = userid;
  while (ch = *(++str))
  {
    if (!is_alnum(ch))
      return 1;
  }
  return 0;
}


static void
justify_user(userid, email)
  char *userid, *email;
{
  char fpath[64];
  HDR hdr;
  FILE *fp;

  /* 寄認證通過信給使用者 */
  usr_fpath(fpath, userid, FN_DIR);
  if (!hdr_stamp(fpath, HDR_LINK, &hdr, FN_ETC_JUSTIFIED))
  {
    strcpy(hdr.title, "您已經通過身分認證了!");
    strcpy(hdr.owner, STR_SYSOP);
    hdr.xmode = MAIL_NOREPLY;
    rec_add(fpath, &hdr, sizeof(HDR));
  }

  /* 記錄在 FN_JUSTIFY */
  usr_fpath(fpath, userid, FN_JUSTIFY);
  if (fp = fopen(fpath, "a"))
  {
    fprintf(fp, "RPY: %s\n", email);
    fclose(fp);
  }
}


static void
register_neck()
{
  printf("<br>\r\n"
    "<table cellspacing=0 cellpadding=1 border=0 width=80%%>\r\n"
    "<tr>\r\n"
    "  <td width=100%% align=middle bgcolor="HCOLOR_NECK">認證系統</td>"
    "</tr>\r\n"
    "</table>\r\n"
    "<br>\r\n");
}


static void
html_register(str)
  char *str;
{
  char userid[IDLEN + 1 + 7 + 1];  /* userid&regkey */
  char fpath[64], *ptr;
  int fd;
  ACCT acct;

  out_head("認證系統");

  if (!*str)
    return;

  str_ncpy(userid, str, sizeof(userid));

  if (!(ptr = strchr(userid, '&')))
    return;
  *ptr = '\0';

  if (is_badid(userid))
    return;

  register_neck();

  usr_fpath(fpath, userid, FN_ACCT);
  if ((fd = open(fpath, O_RDWR, 0600)) >= 0)
  {
    if (read(fd, &acct, sizeof(ACCT)) == sizeof(ACCT))
    {
      if (str_hash(acct.email, acct.tvalid) == chrono32(ptr))/* regkey 正確 */
      {
        /* 提升權限 */
        acct.userlevel |= PERM_VALID;
        time(&acct.tvalid);
        lseek(fd, (off_t) 0, SEEK_SET);
        write(fd, &acct, sizeof(ACCT));

        justify_user(userid, acct.email);
        printf("恭喜您已經認證通過\r\n");
      }
    }
  }

  register_neck();
}

--
□ 本文章由 itocitoc.Dorm11.NCTU.edu.tw 發表
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻