⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smtp.c

📁 smtp proxy source code!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    File: smtp/smtp.c        Copyright (C) 1999 by Wolfgang Zekoll <wzk@quietsche-entchen.de>    This source 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 1, or (at your option)    any later version.    This source 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., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/fcntl.h>#include <sys/socket.h>#include <signal.h>#include <netdb.h>#include <netinet/in.h>#include <syslog.h>#include <sys/time.h>#include "smtp.h"#include "ip-lib.h"#include "lib.h"int sdebug(char *line){	if (debug != 0) {		noctrl(line);		fprintf (stderr, "*** %s\n", line);		}	return (0);}char *getline(char *line, int size, FILE *fp, int debug){	*line = 0;	if (fgets(line, size, fp) == NULL) {		syslog(LOG_NOTICE, "sendmail closed read pipe.");		return (NULL);		}	noctrl(line);	if (debug != 0)		sdebug(line);	return (line);}int getresp(char *line, int size, FILE *fp, int debug){	if (getline(line, size, fp, debug) == NULL)		return (-1);	return (atoi(line));}int echoline(FILE *fp, char *line, int rc){	if (rc == -1) {		syslog(LOG_NOTICE, "closing connection with 421");		fprintf (fp, "421 service unavailable\r\n");		}	else {		noctrl(line);		fprintf (fp, "%s\r\n", line);		}	fflush(fp);	return (0);}int putcmd(FILE *fp, char *cmd, char *par, char *dbg){	fprintf (fp, "%s", cmd);	if (par != NULL  &&  *par != 0)		fprintf (fp, " %s", par);	fprintf (fp, "\n");	fflush(fp);		if (debug != 0  &&  dbg != NULL  &&  *dbg != 0)		fprintf (stderr, ">>> %s: %s %s\n", dbg, cmd, par);	return (0);}int reset_connection(smtp_t *x){	x->nrcpt    = 0;	x->state    = WAITING;	*x->sender  = 0;	x->nrcpt    = 0;	*x->jobid   = 0;	*x->msgid   = 0;	x->size     = 0;	return (0);}void sigalrm_handler(int sig){	syslog(LOG_NOTICE, "client timed out");	fclose (stdin);	return;}char *get_clientinput(char *line, int size, int timeout){	char	*p;		alarm(timeout);	signal(SIGALRM, sigalrm_handler);		*line = 0;	p = fgets(line, size, stdin);	noctrl(line);		return (p);}char *get_emailadr(char *envelope, char *email, int size){	char	*p, *r;	*email = 0;	/*	 * Sonderfall: Es ist moeglich, dass die envelope Adresse `<>'	 * ist.  In diesem liefern wir sie unveraendert zurueck.  Das	 * beisst sich nicht mit Adressen der Form `<<>>', da geschachtelte	 * spitze Klammern nicht unterstuetzt werden.	 */	if (strcmp(envelope, "<>") == 0) {		strcpy(email, "<>");		return (email);		}	p = envelope;	if (*p != '<')		return (email);		p++;	if ((r = strchr(p, '>')) == NULL)		return (email);	else if (r[1] != 0)		return (email);	get_quoted(&p, '>', email, size);	return (email);}int check_emailadr(char *emailadr){	char	*domain;	if (strcmp(emailadr, "<>") == 0)		return (1);	else if (*emailadr == 0)		return (0);/*	else if (*emailadr == '@') *		return (0); */	else if ((domain = strchr(emailadr, '@')) == NULL)		return (0);/*	else if (domain[1] == '0') *		return (0); */	else if (strchr(&domain[1], '@') != NULL)		return (0);	else if (strchr(emailadr, '!') != NULL  ||  strchr(emailadr, '%') != NULL)		return (0);	else if (strchr(emailadr, ':') != NULL  ||  strchr(emailadr, ',') != NULL)		return (0);		return (1);}int search_allowlist(char *emailadr, char *list){	char	*p, *domain, pattern[200];	if (strcmp(emailadr, "<>") == 0)		return (1);	domain = strchr(emailadr, '@');	if (domain == NULL  ||  *domain == 0) {		/*		 * Das kann eigentlich nicht passieren, die E-Mail Adresse		 * wurde schon auf genau ein @-Zeichen getestet.		 */		return (0);		}	else if (list == NULL  ||  *list == 0) {				/*		 * Kann eigentlich auch nicht vorkommen.		 */		return (0);		}	p = list;	while ((p = skip_ws(p)), *get_quoted(&p, ',', pattern, sizeof(pattern)) != 0) {		noctrl(pattern);		if (*pattern == '@'  &&  strpcmp(domain, pattern) == 0)			return (1);		else if (strpcmp(emailadr, pattern) == 0)			return (1);		}		return (0);}int receive_data(smtp_t *x){	int	lineno, isheader, bytes;	char	line[2048];	lineno   = 0;	isheader = 1;	while (1) {		if (get_clientinput(line, sizeof(line), x->config->timeout) == NULL) {			syslog(LOG_NOTICE, "client terminated while sending data");			return (-1);			}		lineno++;		noctrl(line);		/* Received Zeile einbauen		 */		if (lineno == 1) {			if (x->config->droppath != 2) {				fprintf (x->sout, "Received: from %s (%s) by %s\r\n",						x->client, x->ipnum, x->hostname);				}			}		/*		 * Ggf. Message-ID aus Mail-Header lesen, bzw. Mail-Path		 * aus dem Header loeschen.		 */		if (isheader == 1) {			if (*line == 0) {				isheader = 0;				if (*x->msgid == 0) {					unsigned long now;					now = time(NULL);					snprintf (x->msgid, sizeof(x->msgid) - 2, "%lu.%d.%d", now, getpid(), x->mailcount);					syslog(LOG_NOTICE, "no message id, assuming %s, client= %s", x->msgid, x->client);					}				}			else {				char	*p, word[80];				p = line;				get_word(&p, word, sizeof(word));				strlwr(word);								if (strcmp(word, "message-id:") == 0) {					if (*x->msgid != 0) {						syslog(LOG_NOTICE, "duplicate message id, client= %s", x->client);						continue;						}					else {						if ((p = strchr(p, '<')) != NULL) {							p++;							get_quoted(&p, '>', x->msgid, sizeof(x->msgid));							}						}					}				else if (strcmp(word, "received:") == 0) {					if (x->config->droppath != 0)						continue;					}				}			}		/* Zeile an Sendmail weitergeben		 */		if ((bytes = fprintf(x->sout, "%s\r\n", line)) != strlen(line) + 2) {			syslog(LOG_NOTICE, "server terminated while receiving data");			return (-1);			}		x->size += bytes;		/* Ende der Mail erreicht?		 */		if (line[0] == '.'  &&  line[1] == 0) {			fflush(x->sout);			break;			}		}			return (0);}int proxy_request(config_t *config){	int	rc;	char	*p, command[10], word[200], line[2048];	smtp_t	*x;	x = allocate(sizeof(smtp_t));	get_client_info(0, x->ipnum, x->client);	x->mailcount = 0;	syslog(LOG_NOTICE, "connected to client: %s", x->ipnum);	if (*config->clientdir != 0) {		char	logfile[200];		unsigned long now;		struct stat sbuf;		now = time(NULL);		snprintf (logfile, sizeof(logfile) - 2, "%s/%s", config->clientdir, x->ipnum);		if (stat(logfile, &sbuf) != 0  ||  (now - sbuf.st_mtime) >= config->accepttime) {			printf ("421 service unavailable - authenticate with POP3 first\r\n");			syslog(LOG_NOTICE, "client not permitted: %s", x->ipnum);			goto end;			}		}	if (*config->server != 0) {		unsigned int port;		char	server[200];		copy_string(server, config->server, sizeof(server));		port = get_port(server, 25);				if ((x->sin = ip_open(server, port)) == NULL) {			printf ("451 Service unavailable\r\n");			syslog(LOG_NOTICE, "can't connect to server: %s:%u, %m", server, port);			exit (1);			}					x->sout = x->sin;		p = config->server;		}	else if (config->argv != NULL) {		int	pid, pin[2], pout[2];		if (pipe(pin) != 0  ||  pipe(pout) != 0) {			printf ("451 Service unavailable\r\n");			syslog(LOG_NOTICE, "can't pipe(): %m");			exit (-1);			}		else if ((pid = fork()) < 0) {			printf ("451 Service unavailable\r\n");			syslog(LOG_NOTICE, "can't fork(): %m");			exit (-1);			}		else if (pid == 0) {			dup2(pin[1], 1);			close (pin[0]);						dup2(pout[0], 0);			close(pout[1]);						close (2);			execvp(config->argv[0], config->argv);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -