Article 14025 of alt.sources:
With most bulk e-mailers either delivering their messages directly or using
a few well-known "open" mail servers for relaying, a common tactic to eliminate
SPAM mail is to reject connections from these sites.

Unfortunately, if you have your MX records set so that when a connection to
your site is not possible, mail will go to an offsite server for queuing, then
just rejecting the messages is not enough.


Thus 'chuckmail.c'. This is a tiny program that LOOKS like an SMTP server,
accepts mail like an SMTP server, and instantly throws it away.

Chuckmail is quite possibly the most efficient (if useless) MTA available :)


HOW TO INSTALL:

	gcc -O -o chuckmail chuckmail.c
	mv chuckmail /usr/local/bin
	chmod 711 /usr/local/bin/chuckmail


HOW TO USE:

In your TCP wrapper configuration (you are using TCP wrappers, right?), where
you currently refuse connections from SPAM sites, instead connect the spam
site to this program, where they can send you all the mail they want :-)

E.g:

smtpd : .cyberpromo.com : user nobody.nobody : twist /usr/local/bin/chuckmail
smtpd : ALL		: ALLOW


P.S.  NO WARRANTY!  USE AT YOUR OWN RISK! If you use this to accept mail from
a legitimate site, you'll be amazed at how it can instantly, irretrivably
lose all incoming mail!  Consider running this as an unprivileged user,
in a chroot read-only filesystem, on an untrusted machine.

cut here
---------------------------------------------------------------------------

/* CHUCKMAIL.C (VERSION 1.00)
 *
 * Written 1997 by Kevin Kadow (spam@msg.net)
 * Released under GNU copyleft
 *
 * Looks like a SMTP server, but silently discards all messages.
 *
 */

/*
 * The 'okay' message (no carriage return needed)
 */
#define MSG "250 ok"

/*
 * Our name for ourselves, as sent to remote hosts
 */
#define HOSTNAME "nowhere"

/*
 * Extra welcome text.
 * Can be set to "" if you want to omit it entirely.
 */
#define WELCOME "ESMTP"


/* 
 * Should we use resource limits? 
 */

/* #define RLIMIT */

/*
 * If we're using resource limits, sets the max CPU time
 */
#ifdef RLIMIT
#	define CPUSECONDS 60
#endif

/*
 * Maximum lifespan - exit abruptly after so many seconds
 * Can be set to 0 for disabled.
 */
#define TIMEOUT 600

/*
 * A big buffer
 */
#define BIGBUF 8192

#include <stdio.h>
#include <strings.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h>

#ifdef RLIMIT
#include <sys/resource.h>
#endif



/* main
 *	Sets up, then just reads and handle input from remote.
 */
int main() {
char input[BIGBUF];

init();

/* Welcome the intruder */
printf("220 %s %s\n",HOSTNAME,WELCOME);

while(fgets(input,BIGBUF,stdin) ) {
	handle(input); 
	puts(MSG);
	}
exit(0);
}


/* handle
 *	Figure out the command they want, pretend to handle it.
 */
int handle(char * input) {
switch(input[0]) {
	case 'd': case 'D':
		switch(input[1]) {
			case 'a': case 'A': /* data command */
				data();
				return(0);
			case 'e': case 'E': /* debug- ignore it */
				return(0);
			}
			break;

	case 'h': case 'H': /* HELO or HELP */
		if(!(input[1] == 'e' || input[1] == 'E')) return;
		if(!(input[2] == 'l' || input[2] == 'L')) return;
		switch(input[3]) {
			case 'p': case 'P':
				help();
				return(0);
			case 'o': case 'O':
				helo();
				return(0);
			}
			break;
		
	case 'e': case 'E': /* ehlo */
		helo(input);
		return(0);

	case 'q': case 'Q': /* quit */
		quit();
	}

return(-1); /* error */
}


/* doexit
 *	Just exits- needed mainly as a signal handler.
 */
void doexit(int value) {
exit(value);
}


int init() {

/* if we see any of these signals, we exit */
signal(SIGHUP,doexit);
signal(SIGQUIT,doexit);
signal(SIGPIPE,doexit);
signal(SIGTERM,doexit);
signal(SIGINT,doexit);
signal(SIGALRM,doexit);

/* resource limits, if enabled */
#ifdef RLIMIT
#	ifdef CPUSECONDS

signal(SIGXCPU,doexit);

#	endif /* CPUSECONDS */

set_limits();
#endif /* RLIMIT */

/* Set the alarm clock */
alarm(TIMEOUT);
}


/* quit
 *
 */
int quit() {
printf("221 %s closing connection.\n",HOSTNAME);
doexit(0);
}


/* data
 *	Accepts data from the remote,then throws it all away. what a waste.
 */
int data()
{
char input[BIGBUF];

puts("354 Enter Mail");
while(fgets(input,BIGBUF,stdin) ) {
	if(input[0] == '.' && (input[1] == 10 || input[1] == 12)) break;
	}
}


/* helo
 *	They said helo, let's give them something to think about
 */
int helo(char * input)
{
printf("250-%s\n250-PIPELINING\n250-8BITMIME\n",HOSTNAME);
}


/* help
 *	They asked for help, be helpful (yet misleading)
 */
int help() {
puts("250-The following SMTP commands are recognized:");
puts("250-");
puts("250-   HELO hostname                   - startup and give your hostname");
puts("250-   EHLO hostname                   - startup with extension info");
puts("250-   MAIL FROM:<sender-address>      - start transaction from sender");
puts("250-   RCPT TO:<recipient-address>     - name recipient for message");
puts("250-   DATA                            - start text of mail message");
puts("250-   RSET                            - reset state, drop transaction");
puts("250-   HELP                            - produce this help message");
puts("250-   QUIT                            - close SMTP connection");
puts("250-");
puts("250 Multiple messages may be specified.  End the last one with a QUIT.");
}


#ifdef RLIMIT
/* set_limits
 *	Set limitations on cpu and other resources we can use.
 */
int set_limits() {
	struct rlimit l;

	l.rlim_cur=l.rlim_max=0;

	setrlimit(RLIMIT_CORE,l);
	setrlimit(RLIMIT_FSIZE,l);

#	ifdef CPUSECONDS
	l.rlim_cur=l.rlim_max=CPUSECONDS;
	setrlimit(RLIMIT_CPU,l);
#	endif

	}
#endif

/* Copyright 1997 by Kevin Kadow (spam@msg.net) */

/* EOF EOF EOF */


