📄 p3pmail.c
字号:
/* * p3pmail v1.3 * * (C) 2004 by Jack S. Lai <laitcg@cox.net> * * It's intent is to parse dangerous html tags from email messages to make * them safe for viewing. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include "p3pmail.h"/* define debug to see data before and after parsing. DEBUG IS NOT FOR PRODUCTION USE!*///#define DEBUG 1// or#undef DEBUG#undef DEBUG2#ifndef LOGOPT#define LOGOPT LOG_PID|LOG_CONS#endif#ifndef LOGFAC#define LOGFAC LOG_DAEMON#endif#include "p3pmail.h"struct configuration_t * config;void do_log(int level, const char *fmt,...){ char puffer[4096]; va_list az;#ifdef DEBUG_MEM struct mallinfo m=mallinfo();#endif if (!config->debug && level==LOG_DEBUG) return; if (config->quiet && level==LOG_NOTICE) return; va_start(az,fmt); vsnprintf(puffer, 4000, fmt, az); if (!config->debug){ openlog(config->syslogname, LOGOPT, LOGFAC); syslog(LOG_NOTICE, "%s\n", puffer); closelog(); } else { fflush(stdout); fprintf(stderr, "%s[%i]: "#ifdef DEBUG_MEM "Mem: %i "#endif "%s\n", config->syslogname, getpid(),#ifdef DEBUG_MEM m.uordblks,#endif puffer); fflush(NULL); } if (level==LOG_EMERG){ do_log(LOG_NOTICE, "Exiting now...\n"); fprintf(stderr, "%s\n", puffer); exit(1); } return;}void decode64(FILE *infile, FILE *outfile){ char line_in[ENCBUF+1]; char line_out[DECBUF]; char *buff; int converted; int c, i, l; while (fgets(line_in, sizeof line_in, infile)) { buff = line_in; // Trimming leading invalid characters while (*buff && !strchr(Base64, *buff)) buff++; // Trimming trailing invalid characters l = strlen(buff); for (i = l - 1; !strchr(Base64, buff[i]) && buff[i] != Pad64 && i > 0; i--){ buff[i] = '\0'; l--; } // If there are spare characters... if ((l % 4) && (l > 4) && (buff[l - 1] != Pad64)){ // Look ahead to trim next line // leading invalid characters if (!feof(infile)){ do{ c = fgetc(infile); } while (!feof(infile) && c != '\0' && !strchr(Base64,c)); if (c) ungetc(c, infile); } // Ungetting spare characters for (i = l - 1; (i + 1) % 4; i--){ ungetc(buff[i], infile); buff[i] = '\0'; } } // Converting line if ((converted = b64_pton(buff, line_out, DECBUF))) { line_out[converted] = '\0'; fputs(line_out, outfile); } }}void encode64(FILE *infile, FILE *outfile){ char line_in[B64DECCOLS + 1]; char line_out[B64ENCCOLS + 3]; int converted; int n; while (!feof(infile)){ n = fread(line_in, 1, B64DECCOLS, infile); line_in[B64DECCOLS] = '\0'; converted = b64_ntop(line_in, n, line_out, B64ENCCOLS + 1); // Add a trailing newline and terminate the string line_out[converted] = '\n'; line_out[converted + 1] = '\0'; fputs(line_out, outfile); }}void qdecode(FILE *infile,FILE *outfile){ char line[MAX_BUF_SIZE], *start, *stop, *copy; char *d1, *d2, c; int lineno; line[sizeof line - 1] = 0; lineno = 1; while (fgets(line, sizeof line - 1, infile)) { lineno++; start = line; keep_processing: for (stop = start; *stop && *stop != '=' && *stop != '\n'; stop++); if (stop != line && *stop == '\n'){ copy = stop; do { copy--; if (*copy != ' ' && *copy != '\t') { copy++; break; } } while (copy != line); } else { copy = stop; } while (start != copy) { putc(*start,outfile); start++; } if (*stop == '\n') { putc(*stop,outfile); lineno++; continue; } else if (*stop == 0) { continue; } else { stop++; if ((d1 = strchr(hexdigits, *(stop))) && (d2 = strchr(hexdigits, *(stop+1)))) { c = (d1 - hexdigits) * 16 + (d2 - hexdigits); putc(c,outfile); stop += 2; } else if ((d1 = strchr(hexdigits2, *(stop))) && (d2 = strchr(hexdigits2, *(stop+1)))) { c = (d1 - hexdigits2) * 16 + (d2 - hexdigits2); putc(c,outfile); stop += 2; } else if (*stop == '\n') { stop++; } else if (*stop == '\r') { stop++; } else if (*stop == ' ' || *stop == '\t') { for (stop++; *stop && (*stop == ' ' || *stop == '\t'); stop++); } else { printf("line %d: something other than line break or hex digits after = in quoted-printable encoding\n", lineno); printf("line=%s",line); printf("Please report this error to the p3pmail author along with the line above,"); printf("and if possible, a copy of this email. Something sneaky is going on."); exit(1); } start = stop; goto keep_processing; } }}void qencode(FILE *infile,FILE *outfile){ int c; int cols = 0; while ((c = fgetc(infile)) != EOF){ if (c == '\n') { putc(c,outfile); cols = 0; } else if (c == ' '){ int nextc = fgetc(infile); if (nextc != '\n' && nextc != EOF){ putc(c,outfile); cols++; } else { putc('=',outfile); putc(hexdigits[c >> 4],outfile); putc(hexdigits[c & 0xf],outfile); cols += 3; } if (nextc != EOF) ungetc(nextc, infile); } else if (c < 33 || c > 126 || c == '=' || c == '?' || c == '_'){ putc('=',outfile); putc(hexdigits[c >> 4],outfile); putc(hexdigits[c & 0xf],outfile); cols += 3; } else if (c == '.' && cols == 0){ int nextc = fgetc(infile); if (nextc == EOF || nextc == '\n'){ putc('=',outfile); putc(hexdigits[c >> 4],outfile); putc(hexdigits[c & 0xf],outfile); cols += 3; } else { putc(c,outfile); cols++; } if (nextc != EOF) ungetc(nextc, infile); } else { putc(c,outfile); cols++; } if (cols > 70) { putc('=',outfile); putc('\n',outfile); cols = 0; } }}char *stristr(const char *string, const char *pattern){ char *pptr, *sptr, *start; for (start = (char *)string; *start != NUL; start++){ /* find start of pattern in string */ for ( ; ((*start!=NUL) && (toupper(*start) != toupper(*pattern))); start++); if (NUL == *start) return NULL; pptr = (char *)pattern; sptr = (char *)start; while (toupper(*sptr) == toupper(*pptr)){ sptr++; pptr++; /* if end of pattern then pattern was found */ if (NUL == *pptr) return (start); } } return NULL;}char *strreplace(char *buffer,char *search, char *replace){ int searchlen = strlen(search); int replacelen = strlen(replace); int bufferlen = strlen(buffer); char * ptr; for (ptr=stristr(buffer,search); ptr!=0 ; ptr=stristr(ptr,search)){ if (searchlen != replacelen) memmove( ptr+searchlen, ptr+replacelen, bufferlen - searchlen - (ptr-buffer) + 1); memcpy(ptr, replace, replacelen); ptr+=replacelen; } return buffer;}void parsehtml(char *buffer, int bufferlength){ static char lastfew[FEWCHARACTERS + 1]; static int firstline = 1; char *p; /* Do single line checks first */ if(config->image){ strreplace(buffer,"SRC","CRS"); strreplace(buffer,"src","crs"); } if(config->link){ strreplace(buffer,"HREF","FERH"); strreplace(buffer,"href","ferh"); } /* Now look for broken lines by doing nothing for the first line, and something for subsequent. This will catch some broken lines.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -