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

📄 smtp.c

📁 smtp proxy source code!
💻 C
📖 第 1 页 / 共 2 页
字号:
			printf ("451 Service unavailable\r\n");			syslog(LOG_NOTICE, "can't execute: %s: %m", config->argv[0]);			exit (1);			}		else {				x->sin  = fdopen(pin[0], "r");			close(pin[1]);						x->sout = fdopen(pout[1], "w");			close(pout[0]);			p = config->argv[0];			}		}	else {		printf ("451 Service unavailable\r\n");		syslog(LOG_NOTICE, "no server specified");		exit (1);		}	syslog(LOG_NOTICE, "connected to server: %s", p);	/* Konfiguration uebernehmen	 */	x->config = config;	/* Hostnamen holen	 */	gethostname(word, sizeof(word));	getdomainname(line, sizeof(line));	snprintf (x->hostname, sizeof(x->hostname) - 2, word, line);		/* Greeting Message vom Sendmail Server lesen, und an	 * Client schicken.	 */	rc = getresp(line, sizeof(line), x->sin, debug);	while (line[3] != ' ') {		rc = getresp(line, sizeof(line), x->sin, debug);		if (rc == -1) {			syslog(LOG_NOTICE, "lost server while reading server greeting");			exit (1);			}		}			echoline(stdout, line, rc);	/* Wir stellen uns beim lokalen Sendmail Server vor. Die	 * EHLO-replys werden 'verschluckt' und durch einen eigenen	 * ersetzt.	 */	putcmd(x->sout, "EHLO", "localhost", "SVR");	while ((rc = getresp(line, sizeof(line), x->sin, debug)) != -1) {		if (line[3] == ' ')			break;		}	rc = atol(line);	if (rc != 250) {		syslog(LOG_NOTICE, "server HELO: status is not 250");		echoline(stdout, "421 service unavailable", 0);		return (-1);		}						/*	 *  **  S M T P   M A I N L O O P	 */	x->state = WAITING;	while (1) {		rc = 0;		/* Server response code loeschen */		/* Naechstes Kommando vom Client holen		 */		fflush(stdout);		if (get_clientinput(line, sizeof(line), x->config->timeout) == NULL) {			syslog(LOG_NOTICE, "client closed connection");			break;			}		/* Kommando isolieren		 */		p = noctrl(line);		get_word(&p, command, sizeof(command));		strupr(command);		p = skip_ws(p);		/* QUIT ist immer moeglich.		 */		if (strcmp(command, "QUIT") == 0) {			putcmd(x->sout, "QUIT", "", "SVR");			rc = getresp(line, sizeof(line), x->sin, debug);			echoline(stdout, line, rc);			x->state = SEND_QUIT;			break;			}		/* HELP		 */		else if (strcmp(command, "HELP") == 0) {			echoline(stdout, "503 no help available", 0);			}		/* NOOP 		 */		else if (strcmp(command, "NOOP") == 0) {			putcmd(x->sout, "NOOP", "", "SVR");			rc = getresp(line, sizeof(line), x->sin, debug);			echoline(stdout, line, rc);			}		/* RSET		 */		else if (strcmp(command, "RSET") == 0) {			putcmd(x->sout, "RSET", "", "SVR");			rc = getresp(line, sizeof(line), x->sin, debug);			echoline(stdout, line, rc);			reset_connection(x);			syslog(LOG_NOTICE, "RSET command, client= %s", x->client);			}		/* ETRN		 */		else if (strcmp(command, "ETRN") == 0) {			if (x->config->etrn == 0) {				echoline(stdout, "500 unrecognized command", 0);				syslog(LOG_NOTICE, "ETRN request rejected: client= %s", x->client);				}			else {				if (*get_word(&p, word, sizeof(word)) == 0)					echoline(stdout, "500 ETRN needs parameter", 0);				else {					putcmd(x->sout, "ETRN", word, "SVR");					rc = getresp(line, sizeof(line), x->sin, debug);					echoline(stdout, line, rc);					if (rc != 250)						syslog(LOG_NOTICE, "ETRN rejected by server, client= %s", x->client);					}				}			}		/* HELO und EHLO sind auch immer verfuegbar, aber nur		 * einmal.		 */		else if (strcmp(command, "HELO") == 0  ||  strcmp(command, "EHLO") == 0) {			if (x->helloseen != 0)				echoline(stdout, "503 duplicate HELO/EHLO", 0);			else if (*get_word(&p, word, sizeof(word)) == 0) {				snprintf (line, sizeof(line) - 2, "501 %s requires domain name", command);				echoline(stdout, line, 0);				}			else {				if (strcmp(command, "HELO") == 0) {					snprintf (line, sizeof(line) - 2, "250 SMTP server v%s ready %s [%s]", VERSION, x->client, x->ipnum);					echoline(stdout, line, 0);					}				else {					snprintf (line, sizeof(line) - 2, "250-SMTP server v%s ready %s [%s]", VERSION, x->client, x->ipnum);					echoline(stdout, line, 0);										echoline(stdout, "250-8BITMIME", 0);					if (x->config->etrn != 0)						echoline(stdout, "250-ETRN", 0);					echoline(stdout, "250 HELP", 0);					}									x->helloseen = 1;				}			}		/* MAIL, SEND, SOML, SAML		 *		 * Laut RFC 821 kann das MAIL Kommando jederzeit abgesetzt		 * werden, es macht dabei einen impliziten SMTP-Reset. Der		 * real existierende Sendmail will davon aber nichts wissen.		 */		else if (strcmp(command, "MAIL") == 0  || strcmp(command, "SEND") == 0  ||		    strcmp(command, "SOML") == 0  || strcmp(command, "SAML") == 0) {						get_quoted(&p, ':', word, sizeof(word));			if (strcasecmp(word, "FROM") != 0)				echoline(stdout, "500 syntax error", 0);			else if (*x->sender != 0)				echoline(stdout, "503 sender already specified", 0);			else {				int	allowed;				char	sender[200], emailadr[200];								p = skip_ws(p);				get_word(&p, sender, sizeof(sender));				strlwr(sender);				/*				 * Wir machen ein paar grundsaetzliche Tests mit				 * der Absenderadresse:				 *				 *  - Ist die Adresse von spitzen Klammern				 *    umgeben?				 * ...				 */				allowed = 1;				get_emailadr(sender, emailadr, sizeof(emailadr));				if (*emailadr == 0)					allowed = 0;				/*				 * ...				 *  - Enthaelt die Adresse mindestens ein @-Zeichen?				 *  - Enthaelt die Adresse genau ein @-Zeichen?				 *  - Ist in der Adresse kein !- und kein %-Zeichen				 *    enthalten.				 * ...				 */				else if (check_emailadr(emailadr) == 0)					allowed = 0;				/*				 * ...				 *  - Schliesslich wird ggf. noch getestet,				 *    ob die Absenderadresse auch auf der				 *    allow-Liste steht.				 *				 * Mit den Empfaengeradressen werden die gleichen Tests				 * durchgefuehrt.				 */				else if ((p = x->config->senderlist) == NULL  ||  *p == 0)					allowed = 1;	/* kein Adresstest */				else 					allowed = search_allowlist(emailadr, x->config->senderlist);				if (allowed == 0) {					char	line[300];					snprintf (line, sizeof(line) - 2, "550 not allowed: %s", sender);					echoline(stdout, line, 0);					syslog(LOG_NOTICE, "sender rejected: %s, client= %s", sender, x->client);					}				else {					snprintf (line, sizeof(line) - 2, "%s FROM: %s", command, sender);					putcmd(x->sout, line, "", "SVR");					rc = getresp(line, sizeof(line), x->sin, debug);					echoline(stdout, line, rc);					if (rc == 250) {						copy_string(x->sender, sender, sizeof(sender));						x->state = MAIL_SEEN;						}					}				}			}		/* RCPT		 */		else if (strcmp(command, "RCPT") == 0) {			get_quoted(&p, ':', word, sizeof(word));			if (strcasecmp(word, "TO") != 0)				echoline(stdout, "500 syntax error", 0);			else if (x->state != MAIL_SEEN  &&  x->state != RCPT_SEEN)				echoline(stdout, "503 specify sender first", 0);			else {				int	allowed;				char	rcpt[200], emailadr[200];								p = skip_ws(p);				get_word(&p, rcpt, sizeof(rcpt));				strlwr(rcpt);				get_emailadr(rcpt, emailadr, sizeof(emailadr));				if (*emailadr == 0)					allowed = 0;				else if (check_emailadr(emailadr) == 0)					allowed = 0;				else if ((p = x->config->rcptlist) == NULL  ||  *p == 0)					allowed = 1;				else 					allowed = search_allowlist(emailadr, x->config->rcptlist);				if (allowed == 0) {					char	line[300];					snprintf (line, sizeof(line) - 2, "550 no such user: %s", rcpt);					echoline(stdout, line, 0);					syslog(LOG_NOTICE, "recipient rejected: %s, client= %s", rcpt, x->client);					}				else {					putcmd(x->sout, "RCPT TO:", rcpt, "SVR");					rc = getresp(line, sizeof(line), x->sin, debug);					echoline(stdout, line, rc);					if (rc == 250  ||  rc == 251) {						x->nrcpt++;						x->state = RCPT_SEEN;						}					}				}			}		/* DATA		 */		else if (strcmp(command, "DATA") == 0) {			x->mailcount++;			if (x->state != RCPT_SEEN)				echoline(stdout, "503 specify receipients first", 0);			else {				putcmd(x->sout, "DATA", "", "SVR");				rc = getresp(line, sizeof(line), x->sin, debug);				echoline(stdout, line, rc);				if (rc == 354) {					if ((rc = receive_data(x)) == 0) {						rc = getresp(line, sizeof(line), x->sin, debug);						echoline(stdout, line, rc);						if (rc == 250) {							p = line;							get_word(&p, word, sizeof(word));							get_word(&p, x->jobid, sizeof(x->jobid));							}						}					}				snprintf (line, sizeof(line) - 2, "client= %s, sender= %s, nrcpt= %d, size= %ld, jobid= <%s>, message-id= <%s>, status= %d",									x->client, x->sender, x->nrcpt, x->size,									x->jobid, x->msgid, rc);				syslog(LOG_NOTICE, line);				reset_connection(x);				x->state = WAITING;				}			}		/* Alles andere ist unserem Server unbekannt.		 */		else {			fprintf (stderr, "500 unrecognized command\r\n");			}		if (rc == 421) {			syslog(LOG_NOTICE, "sendmail returned 421, state= %d, command= %s", x->state, command);			break;			}		else if (rc == -1) {			syslog(LOG_NOTICE, "terminating (sendmail terminated)");			x->state = NO_SENDMAIL;			break;			}		}	if (x->state != SEND_QUIT  &&  x->state != NO_SENDMAIL) {		putcmd(x->sout, "QUIT", "", "SVR");		rc = getresp(line, sizeof(line), x->sin, debug);		}end:	syslog(LOG_NOTICE, "client %s disconnecting, %d mails", x->client, x->mailcount);	return (0);}

⌨️ 快捷键说明

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