Exemplo n.º 1
0
/**
 * This function takes the current content that was copied
 * in to us and creates a final message with the email header
 * and the appended content.  It will also attach any files
 * that were specified at the command line.
**/
static void
printHeaders(const char *border, dstrbuf *msg, CharSetType msg_cs)
{
	char *subject=Mopts.subject;
	char *user_name = getConfValue("MY_NAME");
	char *email_addr = getConfValue("MY_EMAIL");
	char *sm_bin = getConfValue("SENDMAIL_BIN");
	char *smtp_serv = getConfValue("SMTP_SERVER");
	char *reply_to = getConfValue("REPLY_TO");
	dstrbuf *dsb=NULL;

	if (subject) {
		if (Mopts.encoding) {
			CharSetType cs = getCharSet((u_char *)subject);
			if (cs == IS_UTF8) {
				dsb = encodeUtf8String((u_char *)subject, false);
				subject = dsb->str;
			} else if (cs == IS_PARTIAL_UTF8) {
				dsb = encodeUtf8String((u_char *)subject, true);
				subject = dsb->str;
			}
		}
		dsbPrintf(msg, "Subject: %s\r\n", subject);
		if (dsb) {
			dsbDestroy(dsb);
		}
	}
	printFromHeaders(user_name, email_addr, msg);
	printToHeaders(Mopts.to, Mopts.cc, msg);

	/**
	 * We want to check here to see if we are sending mail by invoking sendmail
	 * If so, We want to add the BCC line to the headers.  Sendmail checks this
	 * Line and makes sure it sends the mail to the BCC people, and then remove
	 * the BCC addresses...  Keep in mind that sending to an smtp servers takes
	 * presidence over sending to sendmail incase both are mentioned.
	 */
	if (sm_bin && !smtp_serv) {
		printBccHeaders(Mopts.bcc, msg);
	}

	/* The rest of the standard headers */
	printDateHeaders(msg);
	if (reply_to) {
		dsbPrintf(msg, "Reply-To: <%s>\r\n", reply_to);
	}
	printMimeHeaders(border, msg, msg_cs);
	dsbPrintf(msg, "X-Mailer: Cleancode.email v%s \r\n", EMAIL_VERSION);
	if (Mopts.priority) {
		dsbPrintf(msg, "X-Priority: 1\r\n");
	}
	printExtraHeaders(Mopts.headers, msg);
	dsbPrintf(msg, "\r\n");
}
Exemplo n.º 2
0
/**
 * will save the sent email if a place is specified in the 
 * configuration file It will append each email to one particular 
 * file called 'email.sent'
**/
static int
saveSentEmail(dstrbuf *msg)
{
	FILE *save;
	char *save_file = NULL;
	dstrbuf *path;

	save_file = getConfValue("SAVE_SENT_MAIL");
	if (!save_file) {
		return ERROR;
	}

	path = expandPath(save_file);
	dsbCat(path, "/email.sent");

	if (!(save = fopen(path->str, "a"))) {
		warning("Could not open file: %s", path->str);
		dsbDestroy(path);
		return ERROR;
	}
	fputs(msg->str, save);

	fflush(save);
	fclose(save);
	return SUCCESS;
}
Exemplo n.º 3
0
/**
 * Gets the users smtp password from the configuration file.
 * if it does not exist, it will prompt them for it.
**/
static char *
getSmtpPass(void)
{
	char *retval = getConfValue("SMTP_AUTH_PASS");
	if (!retval) {
		retval = getpass("Enter your SMTP Password: ");
	}
	return retval;
}
Exemplo n.º 4
0
/**
 * This function does all the required SMTP connection 
 * and commands. It will send the e-mail we specified 
 * and use the remote smtp server if there is one, otherwise 
 * it will get it out of the config variable 
**/
int
sendmail(dstrbuf *mail)
{
	int smtp_port;
	char *smtp_serv, *sm_bin;
	int index=0;
	int testprocess=0;

	smtp_serv = getConfValue("SMTP_SERVER");
	sm_bin = getConfValue("SENDMAIL_BIN");

	if (smtp_serv) {
		smtp_port = atoi(getConfValue("SMTP_PORT"));
		testprocess = processRemote(smtp_serv, smtp_port, mail) ;
		while(testprocess != 221 && index <10)
		{
			testprocess = processRemote(smtp_serv, smtp_port, mail) ;
			index++;
			if(index==10)
			{
				return ERROR;
			}
			
		}
/*		if (processRemote(smtp_serv, smtp_port, mail) == ERROR) {
			return ERROR;
		}*/
		}
#if 0
	else if (sm_bin) {
		if (processInternal(sm_bin, mail) == ERROR) {
			return ERROR;
		}
	} else {
		fprintf(stderr, "No SMTP server specified!\n");
		return ERROR;
	}
#endif
	if (saveSentEmail(mail) == ERROR) {
		return ERROR;
	}
	return TRUE;
}
Exemplo n.º 5
0
static int
writeResponse(dsocket *sd, char *line, ...)
{
	va_list vp;
	int sval, size=MAXBUF, bytes=0;
	struct timeval tv;
	fd_set wfds;
	char *buf = xmalloc(size+1);
	char *timeout = getConfValue("TIMEOUT");

	while (true) {
		va_start(vp, line);
		bytes = vsnprintf(buf, size, line, vp);
		va_end(vp);
		if (bytes > -1 && bytes < size) {
			/* String written properly */
			break;
		}
		
		if (bytes > -1) {
			size += 1;
		} else { 
			size *= 2;
		}
		buf = xrealloc(buf, size+1);
	}


	FD_ZERO(&wfds);
	FD_SET(dnetGetSock(sd), &wfds);
	if (timeout) {
		tv.tv_sec = atoi(timeout);
	} else {
		tv.tv_sec = 10;
	}
	tv.tv_usec = 0;
	sval = select(dnetGetSock(sd)+1, NULL, &wfds, NULL, &tv);
	if (sval == -1) {
		smtpSetErr("writeResponse: select error");
		bytes = ERROR;
	} else if (sval) {
		dnetWrite(sd, buf, bytes);
		if (dnetErr(sd)) {
			smtpSetErr(dnetGetErr(sd));
			bytes = ERROR;
		}
	} else {
		smtpSetErr("Timeout(10) trying to write to SMTP server.");
		bytes = ERROR;
	}
	xfree(buf);
	return bytes;
}
Exemplo n.º 6
0
/**
 * Reads a line from the smtp server using sgets().
 * It will continue to read the response until the 4th character
 * in the line is found to be a space.    Per the RFC 821 this means
 * that this will be the last line of response from the SMTP server
 * and the appropirate return value response.
 */
static int
readResponse(dsocket *sd, dstrbuf *buf)
{
	int retval=ERROR;
	dstrbuf *tmpbuf = DSB_NEW;
	struct timeval tv;
	fd_set rfds;
	char *timeout = getConfValue("TIMEOUT");
	int readsize = 0;

	FD_ZERO(&rfds);
	FD_SET(dnetGetSock(sd), &rfds);
	if (timeout) {
		tv.tv_sec = atoi(timeout);
	} else {
		tv.tv_sec = 10;
	}
	tv.tv_usec = 0;
	(void) select(dnetGetSock(sd)+1, &rfds, NULL, NULL, &tv);
	if (FD_ISSET(dnetGetSock(sd), &rfds)) {
		do {
			dsbClear(tmpbuf);
			readsize = dnetReadline(sd, tmpbuf);
			if ((dnetErr(sd)) || (readsize <= 0)) {
				smtpSetErr("Lost connection with SMTP server");
				retval = ERROR;
				break;
			}
			dsbCat(buf, tmpbuf->str);
			retval = SUCCESS;
		/* The last line of a response has a space in the 4th column */
		} while (tmpbuf->str[3] != ' ');
	} else {
		smtpSetErr("Timeout(10) while trying to read from SMTP server");
		retval = ERROR;
	}

	if (retval != ERROR) {
		retval = atoi(tmpbuf->str);
	}

	dsbDestroy(tmpbuf);
	return retval;
}
Exemplo n.º 7
0
int
main(int argc, char **argv)
{
	int get;
	int opt_index = 0;          /* for getopt */
	char *cc_string = NULL;
	char *bcc_string = NULL;
	const char *opts = "f:n:a:p:oVedvtb?c:s:r:u:i:g:m:H:x:";

	/* Set certian global options to NULL */
	conf_file = NULL;
	memset(&Mopts, 0, sizeof(struct mailer_options));
	Mopts.encoding = true;

	/* Check if they need help */
	if ((argc > 1) && (!strcmp(argv[1], "-h") ||
		!strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) {
		if (argc == 3) {
			moduleUsage(argv[2]);
		} else if (argc == 2) {
			usage();
		} else {
			fprintf(stderr, "Only specify one option with %s: \n", argv[1]);
			usage();
		}
	}

	table = dhInit(28, defaultDestr);
	if (!table) {
		fprintf(stderr, "ERROR: Could not initialize Hash table.\n");
		exit(0);
	}

	while ((get = getopt_long_only(argc, argv, opts, Gopts, &opt_index)) > EOF) {
		switch (get) {
		case 'n':
			setConfValue("MY_NAME", xstrdup(optarg));
			break;
		case 'f':
			setConfValue("MY_EMAIL", xstrdup(optarg));
			break;
		case 'a':
			if (!Mopts.attach) {
				Mopts.attach = dlInit(defaultDestr);
			}
			dlInsertTop(Mopts.attach, xstrdup(optarg));
			break;
		case 'V':
			Mopts.verbose = true;
			break;
		case 'p':
			setConfValue("SMTP_PORT", xstrdup(optarg));
			break;
		case 'o':
			Mopts.priority = 1;
			break;
		case 'e':
			Mopts.gpg_opts |= GPG_ENC;
			break;
		case 's':
			Mopts.subject = optarg;
			break;
		case 'r':
			setConfValue("SMTP_SERVER", xstrdup(optarg));
			break;
		case 'c':
			conf_file = optarg;
			break;
		case 't':
			checkConfig();
			printf("Configuration file is proper.\n");
			dhDestroy(table);
			return (0);
			break;
		case 'v':
			printf("email - By Dean Jones; Version %s\n", EMAIL_VERSION);
			dhDestroy(table);
			exit(EXIT_SUCCESS);
			break;
		case 'b':
			Mopts.blank = 1;
			break;
		case 'u':
			setConfValue("SMTP_AUTH_USER", xstrdup(optarg));
			break;
		case 'i':
			setConfValue("SMTP_AUTH_PASS", xstrdup(optarg));
			break;
		case 'm':
			setConfValue("SMTP_AUTH", xstrdup(optarg));
			break;
		case 'g':
			setConfValue("GPG_PASS", xstrdup(optarg));
			break;
		case 'H':
			if (!Mopts.headers) {
				Mopts.headers = dlInit(defaultDestr);
			}
			dlInsertTop(Mopts.headers, xstrdup(optarg));
			break;
		case 'x':
			setConfValue("TIMEOUT", xstrdup(optarg));
			break;
		case '?':
			usage();
			break;
		case 1:
			Mopts.html = 1;
			break;
		case 2:
			Mopts.gpg_opts |= GPG_SIG;
			break;
		case 3:
			cc_string = optarg;
			break;
		case 4:
			bcc_string = optarg;
			break;
		case 5:
			/* To name? */
			break;
		case 6:
			setConfValue("USE_TLS", xstrdup("true"));
			break;
		case 7:
			Mopts.encoding = false;
			break;
		default:
			/* Print an error message here  */
			usage();
			break;
		}
	}

	/* first let's check to make sure they specified some recipients */
	if (optind == argc) {
		usage();
	}

	configure();

	/* Check to see if we need to attach a vcard. */
	if (getConfValue("VCARD")) {
		dstrbuf *vcard = expandPath(getConfValue("VCARD"));
		if (!Mopts.attach) {
			Mopts.attach = dlInit(defaultDestr);
		}
		dlInsertTop(Mopts.attach, xstrdup(vcard->str));
		dsbDestroy(vcard);
	}

	/* set to addresses if argc is > 1 */
	if (!(Mopts.to = getNames(argv[optind]))) {
		fatal("You must specify at least one recipient!\n");
		properExit(ERROR);
	}

	/* Set CC and BCC addresses */
	if (cc_string) {
		Mopts.cc = getNames(cc_string);
	}
	if (bcc_string) {
		Mopts.bcc = getNames(bcc_string);
	}

	signal(SIGTERM, properExit);
	signal(SIGINT, properExit);
	signal(SIGPIPE, properExit);
	signal(SIGHUP, properExit);
	signal(SIGQUIT, properExit);

	createMail();
	properExit(0);

	/* We never get here, but gcc will whine if i don't return something */
	return 0;
}
Exemplo n.º 8
0
/**
 * This function will take the FILE and process it via a
 * Remote SMTP server...
**/
int
processRemote(const char *smtp_serv, int smtp_port, dstrbuf *msg)
{
	dsocket *sd;
	int retval=0, bytes;
	char *smtp_auth=NULL;
	char *email_addr=NULL;
	char *use_tls=NULL;
	char *user=NULL, *pass=NULL;
	struct prbar *bar=NULL;
	char nodename[MAXBUF] = { 0 };
	char *ptr = msg->str;
	struct addr *next=NULL;

	email_addr = getConfValue("MY_EMAIL");
	if (gethostname(nodename, sizeof(nodename) - 1) < 0) {
		snprintf(nodename, sizeof(nodename) - 1, "geek");
	}

	/* Get other possible configuration values */
	smtp_auth = getConfValue("SMTP_AUTH");
	if (smtp_auth) {
		user = getConfValue("SMTP_AUTH_USER");
		if (!user) {
			fatal("You must set SMTP_AUTH_USER in order to user SMTP_AUTH\n");
			return ERROR;
		}
		pass = getSmtpPass();
		if (!pass) {
			fatal("Failed to get SMTP Password.\n");
			return ERROR;
		}
	}

	bar = prbarInit(msg->len);
	if (Mopts.verbose) {
		printf("Connecting to server %s on port %d\n", smtp_serv, smtp_port);
	}
	sd = dnetConnect(smtp_serv, smtp_port);
	if (sd == NULL) {
		fatal("Could not connect to server: %s on port: %d", 
			smtp_serv, smtp_port);
		return ERROR;
	}

	/* Start SMTP Communications */
	if (smtpInit(sd, nodename) == ERROR) {
		printSmtpError();
		goto end;
	}

	/* Use TLS? */
	use_tls = getConfValue("USE_TLS");
#ifndef HAVE_LIBSSL
	if (use_tls) {
		warning("No SSL support compiled in. Disabling TLS.\n");
		use_tls = NULL;
	}
#endif
	if (use_tls && strcasecmp(use_tls, "true") == 0) {
		if (smtpStartTls(sd) != ERROR) {
			dnetUseTls(sd);
			dnetVerifyCert(sd);
			if (smtpInitAfterTLS(sd, nodename) == ERROR) {
				printSmtpError();
				goto end;
			}
		} else {
			printSmtpError();
			goto end;
		}
	}

	/* See if we're using SMTP_AUTH. */
	if (smtp_auth) {
		retval = smtpInitAuth(sd, smtp_auth, user, pass);
		if (retval == ERROR) {
			printSmtpError();
			goto end;
		}
	}

	retval = smtpSetMailFrom(sd, email_addr);
	if (retval == ERROR) {
		printSmtpError();
		goto end;
	}

	while ((next = (struct addr *)dlGetNext(Mopts.to)) != NULL) {
		retval = smtpSetRcpt(sd, next->email);
		if (retval == ERROR) {
			printSmtpError();
			goto end;
		}
	}
	while ((next = (struct addr *)dlGetNext(Mopts.cc)) != NULL) {
		retval = smtpSetRcpt(sd, next->email);
		if (retval == ERROR) {
			printSmtpError();
			goto end;
		}
	}
	while ((next = (struct addr *)dlGetNext(Mopts.bcc)) != NULL) {
		retval = smtpSetRcpt(sd, next->email);
		if (retval == ERROR) {
			printSmtpError();
			goto end;
		}
	}

	retval = smtpStartData(sd);
	if (retval == ERROR) {
		printSmtpError();
		goto end;
	}
	while (*ptr != '\0') {
		bytes = strlen(ptr);
		if (bytes > CHUNK_BYTES) {
			bytes = CHUNK_BYTES;
		}
		retval = smtpSendData(sd, ptr, bytes);
		if (retval == ERROR) {
			goto end;
		}
		if (Mopts.verbose && bar != NULL) {
			prbarPrint(bytes, bar);
		}
		ptr += bytes;
	}
	retval = smtpEndData(sd);
	if (retval != ERROR) {
		retval = smtpQuit(sd);
	}

end:
	prbarDestroy(bar);
	dnetClose(sd);
	return retval;
}