nocem.c
上传用户:minyiyu
上传日期:2018-12-24
资源大小:864k
文件大小:13k
- /*
- NoCeM-INNBBSD
- Yen-Ming Lee <leeym@cae.ce.ntu.edu.tw>
- NCMparse(), NCMverify(), NCMcancel(): return 0 success, otherwise fail;
- */
- /*
- This patch is came from <leeym@cae.ce.ntu.edu.tw>, please view COPYRIGHT.nocem
- for Copyright notice.
- $Id: nocem.c,v 1.3 2000/02/14 05:52:44 edwardc Exp $
- */
- #include "nocem.h"
- #ifdef USE_NCM_PATCH /* for FB3 */
- #undef PGP2
- int ncmdebug = 0;
- char NCMVER[8];
- char ISSUER[STRLEN];
- char TYPE[8];
- char ACTION[8];
- char NCMID[STRLEN];
- char COUNT[8];
- char THRESHOLD[STRLEN];
- char KEYID[16];
- char SPAMMID_NOW[STRLEN];
- char SPAMMID[MAXSPAMMID][STRLEN];
- int NNTP = -1;
- FILE *NNTPrfp = NULL;
- FILE *NNTPwfp = NULL;
- char NNTPbuffer[1024];
- int num_spammid = 0;
- char errmsg[1024] = "nothing";
- /* ------------------------------------------------------------------ */
- /* NCM initial and maintain */
- /* ------------------------------------------------------------------ */
- static int
- ncm_bytypecmp(a,b)
- ncmperm_t **a, **b;
- {
- return strcasecmp((*a)->type, (*b)->type);
- }
- static int
- ncmcmp(a,b)
- ncmperm_t *a, *b;
- {
- return strcasecmp(a->issuer, b->issuer);
- }
- #if 0
- ncmperm_t *search_issuer(issuer)
- char *issuer;
- {
- ncmperm_t ncmt, *find;
- ncmt.issuer = "*";
- find = (ncmperm_t*)bsearch((char*)&ncmt, NCMPERM, NCMCOUNT, sizeof(ncmperm_t), ncmcmp);
- if (find)
- return find;
- ncmt.issuer = issuer;
- find = (ncmperm_t*)bsearch((char*)&ncmt, NCMPERM, NCMCOUNT, sizeof(ncmperm_t), ncmcmp);
- return find;
- }
- #else
- ncmperm_t *search_issuer(issuer)
- char *issuer;
- {
- ncmperm_t ncmt, *find;
- int i;
- for (i = 0; i < NCMCOUNT; i++)
- {
- find = &NCMPERM[i];
- if (strstr(find->issuer, "*"))
- return find;
- if (strstr(issuer,find->issuer))
- return find;
- }
- return NULL;
- }
- #endif
- int
- readNCMfile(inndhome)
- char *inndhome;
- {
- FILE *fp;
- char buff[256];
- struct stat st;
- int i, count;
- char *ptr, *ncmpermptr;
- sprintf(buff,"%s/ncmperm.bbs", inndhome);
- fp = fopen(buff,"r");
- if (fp == NULL) {
- fprintf(stderr,"read fail %s",buff);
- return -1;
- }
- if (fstat(fileno(fp),&st) != 0) {
- fprintf(stderr,"stat fail %s", buff);
- return -1;
- }
- if (NCMPERM_BUF == NULL) {
- NCMPERM_BUF = (char*) mymalloc( st.st_size +1);
- } else {
- NCMPERM_BUF = (char*) myrealloc( NCMPERM_BUF, st.st_size +1);
- }
- i = 0, count =0;
- while (fgets(buff, sizeof buff, fp) != NULL) {
- if (buff[0] == '#') continue;
- if (buff[0] == 'n') continue;
- strcpy(NCMPERM_BUF+i, buff);
- i += strlen(buff);
- count ++;
- }
- fclose(fp);
- if (NCMPERM == NULL) {
- NCMPERM = (ncmperm_t*) mymalloc(sizeof(ncmperm_t) * (count+1));
- NCMPERM_BYTYPE = (ncmperm_t**) mymalloc(sizeof(ncmperm_t*) * (count+1));
- } else {
- NCMPERM = (ncmperm_t*) myrealloc(NCMPERM, sizeof(ncmperm_t) * (count+1));
- NCMPERM_BYTYPE = (ncmperm_t**) myrealloc(NCMPERM_BYTYPE, sizeof(ncmperm_t*) * (count+1));
- }
- NCMCOUNT = 0;
- for (ptr = NCMPERM_BUF; (ncmpermptr = (char*)strchr(ptr,'n')) != NULL; ptr = ncmpermptr +1, NCMCOUNT++) {
- char *nptr;
- *ncmpermptr = ' ';
- NCMPERM[NCMCOUNT].issuer = "";
- NCMPERM[NCMCOUNT].type = "";
- NCMPERM[NCMCOUNT].perm = 0;
- NCMPERM_BYTYPE[NCMCOUNT] = NCMPERM+NCMCOUNT;
- for (nptr= ptr ;*nptr && (*nptr == 't'); ) nptr++;
- if (*nptr == ' ') continue;
- NCMPERM[NCMCOUNT].issuer = nptr;
- for (nptr++; *nptr && !(*nptr == 't'); ) nptr++;
- if (*nptr == ' ') continue;
- *nptr = ' ';
- for (nptr++ ;*nptr && (*nptr == 't'); ) nptr++;
- if (*nptr == ' ') continue;
- NCMPERM[NCMCOUNT].type = nptr;
- for (nptr++; *nptr && !(*nptr == 't'); ) nptr++;
- if (*nptr == ' ') continue;
- *nptr = ' ';
- for (nptr++;*nptr && (*nptr == 't'); ) nptr++;
- if (*nptr == ' ') continue;
- NCMPERM[NCMCOUNT].perm = (strstr(nptr, "y") || strstr(nptr, "Y"));
- for (nptr++; *nptr && !strchr("rn",*nptr); ) nptr++;
- /*if (*nptr == ' ') continue;*/
- *nptr = ' ';
- }
- qsort(NCMPERM, NCMCOUNT, sizeof(ncmperm_t), ncmcmp);
- qsort(NCMPERM_BYTYPE, NCMCOUNT, sizeof(ncmperm_t*), ncm_bytypecmp);
- NCMregister();
- return 0;
- }
- NCMupdate(char *issuer, char *type)
- {
- FILE *fp;
- char buff[256];
- sprintf(buff,"%s/ncmperm.bbs", INNDHOME);
- if (!isfile(buff))
- {
- if ((fp = fopen(buff, "w")) == NULL)
- {
- fprintf(stderr,"write fail %s",buff);
- return -1;
- }
- fprintf(fp, "# This is ncmperm.bbs, it's auto-generated by program for first timen");
- fprintf(fp, "# The columns *MUST* be separated by [TAB]n");
- fprintf(fp, "# If you wanna accept someone's NoCeM notice, change his perm from 'no' to 'yes'n");
- fprintf(fp, "# put "*" in Issuer column means to match alln");
- fprintf(fp, "# Any questions ? please e-mail %sn", LeeymEMAIL);
- fprintf(fp, "# IssuerttTypetPermn");
- fflush(fp);
- fclose(fp);
- bbslog("NCMupdate create %sn", buff);
- }
- if ((fp = fopen(buff, "a")) == NULL)
- {
- fprintf(stderr,"attach fail %s",buff);
- return -1;
- }
- fprintf(fp, "%stt%stnon", issuer, type);
- fflush(fp);
- fclose(fp);
- bbslog("NCMupdate add Issuer: %s , Type: %sn", ISSUER, TYPE);
- sleep(1);
- if (readNCMfile(INNDHOME) == -1)
- bbslog("fail to readNCMfilen");
- }
- #ifdef SOLARIS
- int
- tcpcommand(char *arg, ...)
- {
- va_list ap;
- register char *fmt;
- char *ptr;
- va_start(ap, arg);
- fmt = va_arg(ap, char *);
- #else
- int
- tcpcommand(va_alist)
- va_dcl
- {
- va_list ap;
- register char *fmt;
- char *ptr;
- va_start(ap);
- fmt = va_arg(ap, char *);
- #endif
- vfprintf(NNTPwfp, fmt, ap);
- fprintf(NNTPwfp, "rn");
- fflush(NNTPwfp);
- fgets(NNTPbuffer, sizeof NNTPbuffer, NNTPrfp);
- ptr = strchr(NNTPbuffer, 'r');
- if (ptr)
- *ptr = ' ';
- ptr = strchr(NNTPbuffer, 'n');
- if (ptr)
- *ptr = ' ';
- va_end(ap);
- return atoi(NNTPbuffer);
- }
- int
- NCMregister()
- {
- int status;
- time_t now = time(NULL);
- char hbuf[80];
- gethostname(hbuf, 80);
- if (!strcmp(hbuf, LeeymBBS))
- return 1;
- if ((NNTP = inetclient(LeeymBBS, "7777", "tcp")) < 0)
- {
- bbslog("NCMregister :Err: server %s %s error: cant connectn", LeeymBBS, "7777");
- return 0;
- }
- if (!(NNTPrfp = fdopen(NNTP, "r")) || !(NNTPwfp = fdopen(NNTP, "w")))
- {
- bbslog("NCMregister :Err: fdopen failedn");
- return 0;
- }
- fgets(NNTPbuffer, sizeof NNTPbuffer, NNTPrfp);
- if (atoi(NNTPbuffer) != 200)
- {
- bbslog("NCMregister :Err: server error: %s", NNTPbuffer);
- return 0;
- }
- status = tcpcommand("ADDHIST <%d-%s> NCMregister/%s/%s",
- now, hbuf, VERSION, NCMINNBBSVER);
- status = tcpcommand("QUIT");
- fclose(NNTPwfp);
- fclose(NNTPrfp);
- close(NNTP);
- return 1;
- }
- /* ------------------------------------------------------------------ */
- /* PGP verify */
- /* ------------------------------------------------------------------ */
- #ifdef PGP5
- int
- run_pgp(char *cmd, FILE **in, FILE **out)
- {
- int pin[2], pout[2], child_pid;
- char PGPPATH[80];
- sprintf(PGPPATH, "%s/.pgp", BBSHOME);
- setenv("PGPPATH", PGPPATH, 1);
- *in = *out = NULL;
- pipe(pin);
- pipe(pout);
- if(!(child_pid = fork()))
- {
- /*We're the child.*/
- close(pin[1]);
- dup2(pin[0], 0);
- close(pin[0]);
- close(pout[0]);
- dup2(pout[1], 1);
- close(pout[1]);
- execl("/bin/sh", "sh", "-c", cmd, NULL);
- _exit(127);
- }
- /*Only get here if we're the parent.*/
- close(pout[1]);
- *out = fdopen(pout[0], "r");
- close(pin[0]);
- *in = fdopen(pin[1], "w");
- return(child_pid);
- }
- int
- verify_buffer(char *buf, char *passphrase)
- {
- FILE *pgpin, *pgpout;
- char tmpbuf[1024] = " ";
- int ans = NOPGP;
- setenv("PGPPASSFD", "0", 1);
- run_pgp("/usr/local/bin/pgpv -f +batchmode=1 +OutputInformationFD=1",
- &pgpin, &pgpout);
- if(pgpin && pgpout)
- {
- fprintf(pgpin, "%sn", passphrase); /*Send the passphrase in, first*/
- bzero(passphrase, strlen(passphrase)); /*Burn the passphrase*/
- fprintf(pgpin, "%s", buf);
- fclose(pgpin);
- *buf = ' ';
- fgets(tmpbuf, sizeof(tmpbuf), pgpout);
- while(!feof(pgpout))
- {
- strcat(buf, tmpbuf);
- fgets(tmpbuf, sizeof(tmpbuf), pgpout);
- }
- wait(NULL);
- fclose(pgpout);
- }
- if (strstr(buf, "Good signature made"))
- {
- strcpy(errmsg, "Good signature");
- ans = PGPGOOD;
- }
- else if (strstr(buf, "BAD signature made"))
- {
- strcpy(errmsg, "BAD signature");
- ans = PGPBAD;
- }
- else if (strcpy(tmpbuf, strstr(buf, "Signature by unknown keyid:")))
- {
- sprintf(errmsg, "%s ", strtok(tmpbuf, "rn"));
- strcpy(KEYID, strrchr(tmpbuf, ' ') + 1);
- ans = PGPUN;
- }
- unsetenv("PGPPASSFD");
- return ans;
- }
- int
- NCMverify()
- {
- int ans;
- char passphrase[80] = "Haha, I am Leeym..";
- ans = verify_buffer(BODY, passphrase);
- return ans;
- }
- #endif
- /* ------------------------------------------------------------------ */
- /* parse NoCeM Notice Headers/Body */
- /* ------------------------------------------------------------------ */
- int
- readNCMheader(char *line)
- {
- if (!strncasecmp(line, "Version", strlen("Version")))
- {
- strcpy(NCMVER, line + strlen("Version") + 2);
- if (!strstr(NCMVER, "0.9"))
- {
- sprintf(errmsg, "unknown version: %s", NCMVER);
- return P_FAIL;
- }
- }
- else if (!strncasecmp(line, "Issuer", strlen("Issuer")))
- {
- strcpy(ISSUER, line + strlen("Issuer") + 2);
- FROM = ISSUER;
- }
- else if (!strncasecmp(line, "Type", strlen("Type")))
- {
- strcpy(TYPE, line + strlen("Type") + 2);
- }
- else if (!strncasecmp(line, "Action", strlen("Action")))
- {
- strcpy(ACTION, line + strlen("Action") + 2);
- if (!strstr(ACTION, "hide"))
- {
- sprintf(errmsg, "unsupported action: %s", ACTION);
- return P_FAIL;
- }
- }
- else if (!strncasecmp(line, "Notice-ID", strlen("Notice-ID")))
- {
- strcpy(NCMID, line + strlen("Notice-ID") + 2);
- }
- else if (!strncasecmp(line, "Count", strlen("Count")))
- {
- strcpy(COUNT, line + strlen("Count") + 2);
- }
- else if (!strncasecmp(line, "Threshold", strlen("Threshold")))
- {
- strcpy(THRESHOLD, line + strlen("Threshold") + 2);
- }
- return P_OKAY;
- }
- int
- readNCMbody(char *line)
- {
- char buf[256], *group;
- strcpy(buf, line);
- if (!strstr(buf, "t"))
- return P_FAIL;
- group = strrchr(line, 't') + 1;
- if (buf[0] == '<' && strstr(buf, ">"))
- {
- strtok(buf, "t");
- strcpy(SPAMMID_NOW, buf);
- }
- if (num_spammid && !strcmp(SPAMMID[num_spammid-1], SPAMMID_NOW))
- return 0;
- if (search_group(group))
- strcpy(SPAMMID[num_spammid++], SPAMMID_NOW);
- }
- int
- NCMparse()
- {
- char *fptr, *ptr;
- int type = TEXT;
- for (fptr = BODY, ptr = strchr(fptr, 'n'); ptr != NULL && *ptr != ' '; fptr = ptr + 1, ptr = strchr(fptr, 'n'))
- {
- int ch = *ptr;
- int ch2 = *(ptr-1);
- *ptr = ' ';
- if (*(ptr-1) == 'r')
- *(ptr-1) = ' ';
- if (num_spammid > MAXSPAMMID)
- return P_OKAY;
- if (!strncmp(fptr, "@@", 2))
- {
- if (strstr(fptr, "BEGIN NCM HEADERS"))
- type = NCMHDR;
- else if (strstr(fptr, "BEGIN NCM BODY"))
- {
- if (NCMVER && ISSUER && TYPE && ACTION && COUNT && NCMID)
- {
- ncmperm_t *ncmt;
- ncmt = (ncmperm_t *) search_issuer(ISSUER);
- if (ncmt == NULL)
- {
- NCMupdate(ISSUER, TYPE);
- sprintf(errmsg, "unknown issuer: %s, %s", ISSUER, MSGID);
- return P_UNKNOWN;
- }
- if (ncmt->perm == NULL)
- {
- sprintf(errmsg, "disallow issuer: %s, %s", ISSUER, MSGID);
- return P_DISALLOW;
- }
- }
- else
- {
- strcpy(errmsg, "HEADERS syntax not correct");
- return P_FAIL;
- }
- type = NCMBDY;
- }
- else if (strstr(fptr, "END NCM BODY"))
- type = TEXT;
- else
- {
- strcpy(errmsg, "NCM Notice syntax not correct");
- return P_FAIL;
- }
- *ptr = ch;
- *(ptr-1) = ch2;
- continue;
- }
- if (type == NCMHDR && readNCMheader(fptr) == P_FAIL)
- return P_FAIL;
- else if (type == NCMBDY)
- readNCMbody(fptr);
- *ptr = ch;
- *(ptr-1) = ch2;
- }
- if (NCMVER && ISSUER && TYPE && ACTION && COUNT && NCMID)
- return P_OKAY;
- else
- {
- strcpy(errmsg, "HEADERS syntax not correct");
- return P_FAIL;
- }
- strcpy(errmsg, "I don't know..");
- return P_FAIL;
- }
- int
- NCMcancel()
- {
- int i, rel, num_ok, num_fail;
- for (i = rel = num_ok = num_fail = 0; i < num_spammid; i++)
- {
- rel = cancel_article_front(SPAMMID[i]);
- if (rel)
- num_fail++;
- else
- num_ok++;
- }
- bbslog("NCMcancel %s %s, count:%d spam:%d, ok:%d fail:%dn",
- ISSUER, MSGID, atoi(COUNT), num_spammid, num_ok, num_fail);
- return 0;
- }
- /* ------------------------------------------------------------------ */
- /* NoCeM-innbbsd */
- /* ------------------------------------------------------------------ */
- initial_nocem()
- {
- bzero(SPAMMID[0], strlen(SPAMMID[0]) * num_spammid);
- num_spammid = 0;
- bzero(SPAMMID_NOW, strlen(SPAMMID_NOW));
- }
- int
- receive_nocem()
- {
- int rel;
- ncmperm_t *ncmt;
- if (ncmdebug)
- bbslog("NCM: receive %sn", MSGID);
- initial_nocem();
- rel = NCMparse();
- if (rel != P_OKAY)
- {
- if (rel != P_DISALLOW)
- bbslog("NCMparse %sn", errmsg);
- return 0;
- }
- if (!num_spammid)
- {
- bbslog("NCMparse: nothing to canceln");
- return 0;
- }
- #ifdef PGP5
- if (ncmdebug)
- bbslog("NCM: verifying PGP signn");
- rel = NCMverify();
- if (rel != PGPGOOD)
- {
- bbslog("NCMverify %s, %s, %sn", errmsg, MSGID, ISSUER);
- return 0;
- }
- #endif
- if (ncmdebug)
- bbslog("NCM: canceling spam in NoCeM Noticen");
- return NCMcancel();
- }
- #endif /* USE_NCM_PATCH */