Example #1
0
/**
 * just prints the to headers, and cc headers if available
**/
static void
printToHeaders(dlist to, dlist cc, dstrbuf *msg)
{
	struct addr *a = (struct addr *)dlGetNext(to);
	dsbPrintf(msg, "To: ");
	while (a) {
		dstrbuf *tmp = formatEmailAddr(a->name, a->email);
		dsbPrintf(msg, "%s", tmp->str);
		dsbDestroy(tmp);
		a = (struct addr *)dlGetNext(to);
		if (a != NULL) {
			dsbPrintf(msg, ", ");
		} else {
			dsbPrintf(msg, "\r\n");
		}
	}

	if (cc != NULL) {
		dsbPrintf(msg, "Cc: ");
		a = (struct addr *)dlGetNext(cc);
		while (a) {
			dstrbuf *tmp = formatEmailAddr(a->name, a->email);
			dsbPrintf(msg, "%s", tmp->str);
			dsbDestroy(tmp);
			a = (struct addr *)dlGetNext(cc);
			if (a != NULL) {
				dsbPrintf(msg, ", ");
			} else {
				dsbPrintf(msg, "\r\n");
			}
		}
	}
}
Example #2
0
/**
 * Creates a plain text (or html) email and 
 * specifies the necessary MIME types if needed
 * due to attaching base64 files.
 * when this function is done, it will rewind
 * the file position and return an open file
**/
static dstrbuf *
createPlainEmail(dstrbuf *msg) 
{
	dstrbuf *border=NULL;
	dstrbuf *buf=DSB_NEW;
	CharSetType cs;

	if (Mopts.attach) {
		border = mimeMakeBoundary();
	} else {
		border = DSB_NEW;
	}

	if (Mopts.encoding) {
		cs = getCharSet((u_char *)msg->str);
	} else {
		cs = IS_ASCII;
	}
	printHeaders(border->str, buf, cs);
	if (makeMessage(msg, buf, border->str, cs) < 0) {
		dsbDestroy(buf);
		buf=NULL;
	}
	dsbDestroy(border);
	return buf;
}
Example #3
0
/**
 * this is the function that takes over from main().  
 * It will call all functions nessicary to finish off the 
 * rest of the program and then return properly. 
**/
void
createMail(void)
{
	dstrbuf *msg=NULL, *full_msg=NULL;
	char subject[MAXBUF]={0};

	/**
	 * first let's check if someone has tried to send stuff in from STDIN 
	 * if they have, let's call a read to stdin
	 */
	if (isatty(STDIN_FILENO) == 0) {
		msg = readInput();
		if (!msg) {
			fatal("Problem reading from STDIN redirect\n");
			properExit(ERROR);
		}
	} else {
		/* If they aren't sending a blank email */
		if (!Mopts.blank) {
			/* let's check if they want to add a subject or not */
			if (Mopts.subject == NULL) {
				fprintf(stderr, "Subject: ");
				fgets(subject, sizeof(subject)-1, stdin);
				chomp(subject);
				Mopts.subject = subject;
			}

			/* Now we need to let them create a file */
			msg = editEmail();
			if (!msg) {
				properExit(ERROR);
			}
		} else {
			/* Create a blank message */
			msg = DSB_NEW;
		}
	}

	/* Create a message according to the type */
	if (Mopts.gpg_opts) {
		full_msg = createGpgEmail(msg, Mopts.gpg_opts);
	} else {
		full_msg = createPlainEmail(msg);
	}

	if (!full_msg) {
        deadLetter(msg);
        dsbDestroy(msg);
		properExit(ERROR);
    }

    dsbDestroy(msg);

    int retsend = sendmail(full_msg);
    dsbDestroy(full_msg);
    if (retsend == ERROR) {
      properExit(ERROR);
    }
}
Example #4
0
/**
 * ModuleUsage will take an argument for the specified 
 * module and print out help information on the topic.  
 * information is stored in a written file in the location 
 * in Macro EMAIL_DIR. and also specified with EMAIL_HELP_FILE
 */
static void
moduleUsage(const char *module)
{
	FILE *help=NULL;
	short found=0;
	char *moduleptr=NULL;
	dstrbuf *buf = DSB_NEW;
	dstrbuf *help_file = expandPath(EMAIL_HELP_FILE);

	if (!(help = fopen(help_file->str, "r"))) {
		fatal("Could not open help file: %s", help_file->str);
		dsbDestroy(help_file);
		properExit(ERROR);
	}
	dsbDestroy(help_file);

	while (!feof(help)) {
		dsbReadline(buf, help);
		if ((buf->str[0] == '#') || (buf->str[0] == '\n')) {
			continue;
		}

		chomp(buf->str);
		moduleptr = strtok(buf->str, "|");
		if (strcasecmp(moduleptr, module) != 0) {
			while ((moduleptr = strtok(NULL, "|")) != NULL) {
				if (strcasecmp(moduleptr, module) == 0) {
					found = 1;
					break;
				}
			}
		} else {
			found = 1;
		}

		if (!found) {
			continue;
		}
		while (!feof(help)) {
			dsbReadline(buf, help);
			if (!strcmp(buf->str, "EOH\n")) {
				break;
			}
			printf("%s", buf->str);
		}
		break;
	}

	if (feof(help)) {
		printf("There is no help in the module: %s\n", module);
		usage();
	}

	dsbDestroy(buf);
	fclose(help);
	exit(0);
}
Example #5
0
File: utils.c Project: 1reza/eMail
int
copyfile(const char *from, const char *to)
{
	FILE *ffrom, *fto;
	dstrbuf *buf=NULL;

	ffrom = fopen(from, "r");
	fto = fopen(to, "w");
	if (!ffrom || !fto) {
		return -1;
	}

	buf = DSB_NEW;
	while (dsbFread(buf, MAXBUF, ffrom) > 0) {
		fwrite(buf->str, sizeof(char), buf->len, fto);
		dsbClear(buf);
	}

	dsbDestroy(buf);
	fclose(ffrom);
	fclose(fto);

	if (ferror(ffrom) || ferror(fto)) {
		return -1;
	}

	return 0;
}
Example #6
0
/**
 * Takes a string and breaks it up based on a specific character
 * and returns it in a dvector
 */
dvector
explode(const char *str, const char *delim)
{
	bool found=false;
	const char *ptr=str, *dtmp=NULL;
	dstrbuf *buf = dsbNew(100);
	dvector vec = dvCreate(5, __strexplodeDestr);

	while (*ptr != '\0') {
		dtmp = delim;
		while (*dtmp != '\0') {
			if (*ptr == *dtmp) {
				if (buf->len > 0) {
					dvAddItem(&vec, xstrdup(buf->str));
					dsbClear(buf);
				}
				found = true;
				break;
			}
			dtmp++;
		}
		if (!found) {
			dsbCatChar(buf, *ptr);
		} else {
			found = false;
		}
		ptr++;
	}
	/* Add the last element if there was one. */
	if (buf->len > 0) {
		dvAddItem(&vec, xstrdup(buf->str));
	}
	dsbDestroy(buf);
	return vec;
}
Example #7
0
static int
ehlo(dsocket *sd, const char *domain)
{
	int retval;
	dstrbuf *rbuf = DSB_NEW;

	if (writeResponse(sd, "EHLO %s\r\n", domain) < 0) {
		smtpSetErr("Lost connection to SMTP server");
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("\r\n--> EHLO %s\r\n", domain);
	fflush(stdout);
#endif

	retval = readResponse(sd, rbuf);
	if (retval != 250) {
		if (retval != ERROR) {
			smtpSetErr(rbuf->str);
		}
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("\r\n<-- %s", rbuf->str);
	fflush(stdout);
#endif

end:
	dsbDestroy(rbuf);
	return retval;
}
Example #8
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;
}
Example #9
0
/**
 * Makes a message type specifically for gpg encryption and 
 * signing.  Specific MIME message descriptions are needed
 * when signing/encrypting a file before it is actuall signed
 * or encrypted.  This function takes care of that.
**/
static int
makeGpgMessage(dstrbuf *in, dstrbuf *out, const char *border)
{
	dstrbuf *qp=NULL;

	assert(in != NULL);
	assert(out != NULL);
	assert(border != NULL);

	if (Mopts.attach) {
		dsbPrintf(out, "Content-Type: multipart/mixed; "
			"boundary=\"%s\"\r\n\r\n", border);
		dsbPrintf(out, "\r\n--%s\r\n", border);
	}

	if (Mopts.html) {
		dsbPrintf(out, "Content-Type: text/html\r\n");
	} else {
		dsbPrintf(out, "Content-Type: text/plain\r\n");
	}

	dsbPrintf(out, "Content-Transfer-Encoding: quoted-printable\r\n\r\n");
	qp = mimeQpEncodeString((u_char *)in->str, true);
	dsbnCat(out, qp->str, qp->len);
	dsbDestroy(qp);
	if (Mopts.attach) {
		attachFiles(border, out);
		dsbPrintf(out, "\r\n--%s--\r\n", border);
	}
	return 0;
}
Example #10
0
/** Print From Headers **/
static void
printFromHeaders(char *name, char *address, dstrbuf *msg)
{
	dstrbuf *addr = formatEmailAddr(name, address);
	dsbPrintf(msg, "From: %s\r\n", addr->str);
	dsbDestroy(addr);
}
Example #11
0
int
data(dsocket *sd)
{
	int retval = 0;
	dstrbuf *rbuf = DSB_NEW;

	/* Create the DATA command and send it */
	if (writeResponse(sd, "DATA\r\n") < 0) {
		smtpSetErr("Lost connection with SMTP server");
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("\r\n--> DATA\r\n");
#endif

	/* Read return message and let's return it's code */
	retval = readResponse(sd, rbuf);
	if (retval != 354) {
		if (retval != ERROR) {
			smtpSetErr(rbuf->str);
		}
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("<-- %s", rbuf->str);
#endif

end:
	dsbDestroy(rbuf);
	return retval;
}
Example #12
0
/**
 * Send the QUIT command
 */
static int
quit(dsocket *sd)
{
	int retval = 0;
	dstrbuf *rbuf = DSB_NEW;

	/* Create QUIT command and send it */
	if (writeResponse(sd, "QUIT\r\n") < 0) {
		smtpSetErr("Lost Connection with SMTP server: Quit()");
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("--> QUIT\r\n");
#endif

	retval = readResponse(sd, rbuf);
	if (retval != 221) {
		if (retval != ERROR) {
			smtpSetErr(rbuf->str);
		}
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("<-- %s", rbuf->str);
#endif

end:
	dsbDestroy(rbuf);
	return retval;
}
Example #13
0
File: utils.c Project: 1reza/eMail
/**
 * Exit just handles all the signals and exiting of the 
 * program by freeing the allocated memory  and writing 
 * the dead.letter if we had a sudden interrupt...
**/
void
properExit(int sig)
{
	if (sig != 0 && global_msg) {
		deadLetter();
	}
	dsbDestroy(global_msg);

	/* Free lists */
	if (Mopts.attach) {
		dlDestroy(Mopts.attach);
	}
	if (Mopts.headers) {
		dlDestroy(Mopts.headers);
	}
	if (Mopts.to) {
		dlDestroy(Mopts.to);
	}
	if (Mopts.cc) {
		dlDestroy(Mopts.cc);
	}
	if (Mopts.bcc) {
		dlDestroy(Mopts.bcc);
	}

	dhDestroy(table);
	exit(sig);
}
Example #14
0
/** 
 * Send the MAIL FROM: command to the smtp server 
 */
static int
mailFrom(dsocket *sd, const char *email)
{
	int retval = 0;
	dstrbuf *rbuf = DSB_NEW;

	/* Create the MAIL FROM: command */
	if (writeResponse(sd, "MAIL FROM:<%s>\r\n", email) < 0) {
		smtpSetErr("Lost connection with SMTP server");
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("\r\n--> MAIL FROM:<%s>\r\n", email);
#endif

	/* read return message and let's return it's code */
	retval = readResponse(sd, rbuf);
	if (retval != 250) {
		if (retval != ERROR) {
			smtpSetErr(rbuf->str);
		}
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("\r\n<-- %s", rbuf->str);
#endif

end:
	dsbDestroy(rbuf);
	return retval;
}
Example #15
0
/**
 * set up the appropriate MIME and Base64 headers for 
 * the attachment of file specified in Mopts.attach
**/
static int
attachFiles(const char *boundary, dstrbuf *out)
{
	dstrbuf *file_name = NULL;
	dstrbuf *file_type = NULL;
	char *next_file = NULL;

	/*
	* What we will do here is parse Mopts.attach for comma delimited file
	* names.  If there was only one file specified with no comma, then strtok()
	* will just return that file and the next call to strtok() will be NULL
	* which will allow use to break out of our loop of attaching base64 stuff.
	*/
	while ((next_file = (char *)dlGetNext(Mopts.attach)) != NULL) {
		FILE *current = fopen(next_file, "r");
		if (!current) {
			#if 1 //Ren: to skip nonexistent file
			fprintf(stderr, "email: skip %s\n", next_file);
			continue;
			#else
			fatal("Could not open attachment: %s", next_file);
			return (ERROR);
			#endif
		}

		/* If the user specified an absolute path, just get the file name */
		file_type = mimeFiletype(next_file);
		file_name = mimeFilename(next_file);

		/* Set our MIME headers */
		dsbPrintf(out, "\r\n--%s\r\n", boundary);
		dsbPrintf(out, "Content-Transfer-Encoding: base64\r\n");
		dsbPrintf(out, "Content-Type: %s; name=\"%s\"\r\n", 
			file_type->str, file_name->str);
		dsbPrintf(out, "Content-Disposition: attachment; filename=\"%s\"\r\n", 
			file_name->str);
		dsbPrintf(out, "\r\n");

		/* Encode to 'out' */
		mimeB64EncodeFile(current, out);
		dsbDestroy(file_type);
		dsbDestroy(file_name);
	}
	return SUCCESS;
}
Example #16
0
/**
 * Makes a message type specifically for gpg encryption and 
 * signing.  Specific MIME message descriptions are needed
 * when signing/encrypting a file before it is actuall signed
 * or encrypted.  This function takes care of that.
**/
static int
makeGpgMessage(dstrbuf *in, dstrbuf *out, const char *border)
{
    char *ptr=NULL;
	dstrbuf *qp=NULL;

	assert(in != NULL);
	assert(out != NULL);
	assert(border != NULL);

	if (Mopts.attach) {
		dsbPrintf(out, "Content-Type: multipart/mixed; "
			"boundary=\"%s\"\r\n\r\n", border);
		dsbPrintf(out, "\r\n--%s\r\n", border);
	}

	if (Mopts.html) {
		dsbPrintf(out, "Content-Type: text/html\r\n");
	} else {
		dsbPrintf(out, "Content-Type: text/plain\r\n");
	}

	dsbPrintf(out, "Content-Transfer-Encoding: quoted-printable\r\n\r\n");
	qp = mimeQpEncodeString((u_char *)in->str, true);
    /* Fix single dot on it's on line so we don't terminate the message prematurely. */
    dstrbuf *formatted = DSB_NEW;
    char previous='\0';
    for (ptr = qp->str; ptr && *ptr != '\0'; previous=*ptr, ptr++) {
        dsbCatChar(formatted, *ptr);
        /* If we have a dot starting on a newline. */
        if ((previous == '\n' || previous == '\r') && *ptr == '.') {
            dsbCatChar(formatted, '.');
        }
    }

	dsbDestroy(qp);
	dsbnCat(out, formatted->str, formatted->len);
    dsbDestroy(formatted);

	if (Mopts.attach) {
		attachFiles(border, out);
		dsbPrintf(out, "\r\n--%s--\r\n", border);
	}
	return 0;
}
Example #17
0
/**
 * Sends the QUIT\r\n signal to the smtp server.
 *
 * Params
 * 	sd - Socket Descriptor
 *
 * Return
 * 	- ERROR
 * 	- SUCCESS
 */
int
smtpQuit(dsocket *sd)
{
	int retval=0;
	printProgress("Sending QUIT...");
	retval = quit(sd);
	dsbDestroy(errorstr);
	return retval;
}
Example #18
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");
}
Example #19
0
File: utils.c Project: 1reza/eMail
/**
 * checks to see if the TEMP_FILE is around... if it is
 * it will move it to the users home directory as dead.letter.
**/
static void
deadLetter()
{
	dstrbuf *path = expandPath("~/dead.letter");
	FILE *out = fopen(path->str, "w");

	if (!out || !global_msg) {
		warning("Could not save dead letter to %s", path->str);
	} else {
		fwrite(global_msg->str, sizeof(char), global_msg->len, out);
	}
	dsbDestroy(path);
}
Example #20
0
File: utils.c Project: 1reza/eMail
/**
 * takes a string that is a supposed file path, and 
 * checks for certian wildcards ( like ~ for home directory ) 
 * and resolves to an actual absolute path.
**/
dstrbuf *
expandPath(const char *path)
{
	struct passwd *pw = NULL;
	dstrbuf *tmp = DSB_NEW;
	dstrbuf *ret = DSB_NEW;

	dsbCopy(tmp, path);

	if (tmp->len > 0 && tmp->str[0] == '&') {
		dsbCopy(ret, EMAIL_DIR);
	} else if (tmp->len > 0 && tmp->str[0] == '~') {
		if (tmp->str[1] == '/') {
			pw = getpwuid(getuid());
		} else {
			int pos = strfind(tmp->str, '/');
			if (pos >= 0) {
				char *p = substr(tmp->str, 1, pos-1);
				if (p) {
					pw = getpwnam(p);
					xfree(p);
				}
			}
			if (!pw) {
				pw = getpwuid(getuid());
			}
		}
		if (pw) {
			dsbCopy(ret, pw->pw_dir);
		}
	}

	
	if (ret->len > 0) {
		int pos = strfind(tmp->str, '/');
		if (pos > 0) {
			char *p = substr(tmp->str, pos, tmp->len);
			if (p) {
				dsbCat(ret, p);
				xfree(p);
			}
		}
	} else {
		dsbCopy(ret, path);
	}

	dsbDestroy(tmp);
	return ret;
}
Example #21
0
File: utils.c Project: 1reza/eMail
dstrbuf *
encodeUtf8String(const u_char *str, bool use_qp)
{
	const u_int max_blk_len = 45;
	u_int i=max_blk_len;
	dstrbuf *enc, *dsb = DSB_NEW;
	size_t len = strlen((char *)str);

	if (use_qp) {
		// TODO: We need to break this up so that we're not 
		// creating extra long strings.
		enc = mimeQpEncodeString(str, false);
		dsbPrintf(dsb, "=?utf-8?q?%s?=", enc->str);
		i = len; // Just reset for now.
	} else {
		enc = mimeB64EncodeString(str, 
			(len > max_blk_len ? max_blk_len : len), false);
		dsbPrintf(dsb, "=?utf-8?b?%s?=", enc->str);
	}
	dsbDestroy(enc);

	/* If we have anymore data to encode, we have to do it by adding a newline
	   plus a space because each section can only be 75 chars long. */ 
	while (i < len) {
		size_t newlen = strlen((char *)str + i);
		/* only allow max_blk_len sections */
		if (newlen > max_blk_len) {
			newlen = max_blk_len;
		}
		enc = mimeB64EncodeString(str + i, newlen, false);
		dsbPrintf(dsb, "\r\n =?utf-8?b?%s?=", enc->str);
		dsbDestroy(enc);
		i += newlen;
	}
	return dsb;
}
Example #22
0
/**
 * Creates a signed message with gpg and takes into 
 * account the correct MIME message types to add to 
 * the message.
**/
static dstrbuf *
createGpgEmail(dstrbuf *msg, GpgCallType gpg_type)
{
	dstrbuf *tmpbuf=DSB_NEW;
	dstrbuf *gpgdata=NULL, *buf=DSB_NEW;
	dstrbuf *border1=NULL, *border2=NULL;

	assert(msg != NULL);

	/* Create two borders if we're attaching files */
	border1 = mimeMakeBoundary();
	if (Mopts.attach) {
		border2 = mimeMakeBoundary();
	} else {
		border2 = DSB_NEW;
	}

	if (makeGpgMessage(msg, tmpbuf, border2->str) < 0) {
		dsbDestroy(buf);
		buf=NULL;
		goto end;
	}

	gpgdata = callGpg(tmpbuf, gpg_type);
	if (!gpgdata) {
		dsbDestroy(buf);
		buf=NULL;
		goto end;
	}
	printHeaders(border1->str, buf, IS_ASCII);

	dsbPrintf(buf, "\r\n--%s\r\n", border1->str);
	if (gpg_type & GPG_ENC) {
		dsbPrintf(buf, "Content-Type: application/pgp-encrypted\r\n\r\n");
		dsbPrintf(buf, "Version: 1\r\n");
		dsbPrintf(buf, "\r\n--%s\r\n", border1->str);
		dsbPrintf(buf, "Content-type: application/octet-stream; "
			       "name=encrypted.asc\r\n\r\n");
	} else if (gpg_type & GPG_SIG) {
		dsbPrintf(buf, "%s\r\n", tmpbuf->str);
		dsbPrintf(buf, "\r\n--%s\r\n", border1->str);
		dsbPrintf(buf, "Content-Type: application/pgp-signature\r\n");
		dsbPrintf(buf, "Content-Description: This is a digitally signed message\r\n\r\n");
	} 
	dsbPrintf(buf, "%s", gpgdata->str);
	dsbPrintf(buf, "\r\n--%s--\r\n", border1->str);

end:
	dsbDestroy(tmpbuf);
	dsbDestroy(gpgdata);
	dsbDestroy(border1);
	dsbDestroy(border2);
	return buf;
}
Example #23
0
/** 
 * Makes a standard plain text message while taking into
 * account the MIME message types and boundary's needed
 * if and when a file is attached.
**/
static int
makeMessage(dstrbuf *in, dstrbuf *out, const char *border, CharSetType charset)
{
	dstrbuf *enc=NULL;
	if (Mopts.attach) {
		dsbPrintf(out, "--%s\r\n", border);
		if (charset == IS_UTF8 || charset == IS_PARTIAL_UTF8) {
			dsbPrintf(out, "Content-Type: text/plain; charset=utf-8\r\n");
			if (IS_PARTIAL_UTF8) {
				dsbPrintf(out, "Content-Transfer-Encoding: quoted-printable\r\n");
				enc = mimeQpEncodeString((u_char *)in->str, true);
			} else {
				dsbPrintf(out, "Content-Transfer-Encoding: base64\r\n");
				enc = mimeB64EncodeString((u_char *)in->str, in->len, true);
			}
			dsbPrintf(out, "Content-Disposition: inline\r\n\r\n");
		} else if (Mopts.html) {
			dsbPrintf(out, "Content-Type: text/html\r\n\r\n");
			enc = DSB_NEW;
			dsbCat(enc, in->str);
		} else {
			dsbPrintf(out, "Content-Type: text/plain\r\n\r\n");
			enc = DSB_NEW;
			dsbCat(enc, in->str);
		}
	} else {
		if (charset == IS_UTF8) {
			enc = mimeB64EncodeString((u_char *)in->str, in->len, true);
		} else if (charset == IS_PARTIAL_UTF8) {
			enc = mimeQpEncodeString((u_char *)in->str, true);
		} else {
			enc = DSB_NEW;
			dsbCat(enc, in->str);
		}
	}
	dsbPrintf(out, "%s\r\n", enc->str);
	if (Mopts.attach) {
		if (attachFiles(border, out) == ERROR) {
			return ERROR;
		}
		dsbPrintf(out, "\r\n\r\n--%s--\r\n", border);
	}
	dsbDestroy(enc);
	return 0;
}
Example #24
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;
}
Example #25
0
static int
helo(dsocket *sd, const char *domain)
{
	int retval;
	dstrbuf *rbuf = DSB_NEW;

	/*
	 * We will be calling this function after ehlo() has already
	 * been called.  Since ehlo() already grabs the header, go
	 * straight into sending the HELO
	 */
	if (writeResponse(sd, "HELO %s\r\n", domain) < 0) {
		smtpSetErr("Lost connection to SMTP server");
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("--> HELO\n");
	fflush(stdout);
#endif

	retval = readResponse(sd, rbuf);
	if (retval != 250) {
		if (retval != ERROR) {
			smtpSetErr(rbuf->str);
		}
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("<-- %s\n", rbuf->str);
	fflush(stdout);
#endif

end:
	dsbDestroy(rbuf);
	return retval;
}
Example #26
0
/**
 * Let's the SMTP server know it's the end of the data stream.
 *
 * Params
 * 	sd - Socket descriptor
 *
 * Return
 * 	- ERROR
 * 	- SUCCESS
 */
int 
smtpEndData(dsocket *sd)
{
	int retval=ERROR;
	dstrbuf *rbuf = DSB_NEW;

	printProgress("Ending Data...");
	if (writeResponse(sd, "\r\n.\r\n") != ERROR) {
		retval = readResponse(sd, rbuf);
		if (retval != 250) {
			if (retval != ERROR) {
				smtpSetErr(rbuf->str);
				retval = ERROR;
			}
		}
	} else {
		smtpSetErr("Lost Connection with SMTP server: smtpEndData()");
		retval = ERROR;
	}

	dsbDestroy(rbuf);
	return retval;
}
Example #27
0
/**
 * Send the RSET command. 
 */
static int
rset(dsocket *sd)
{
	int retval = 0;
	dstrbuf *rbuf = DSB_NEW;

	/* Send the RSET command */
	if (writeResponse(sd, "RSET\r\n") < 0) {
		smtpSetErr("Socket write error: rset");
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("--> RSET\n");
	fflush(stdout);
#endif

	retval = readResponse(sd, rbuf);
	if (retval != 250) {
		if (retval != ERROR) {
			smtpSetErr(rbuf->str);
		}
		retval = ERROR;
		goto end;
	}


#ifdef DEBUG_SMTP
	printf("<-- %s\n", rbuf->str);
	fflush(stdout);
#endif

end:
	dsbDestroy(rbuf);
	return retval;
}
Example #28
0
int
smtpStartTls(dsocket *sd)
{
        int retval=SUCCESS;
#ifdef HAVE_LIBSSL
        dstrbuf *sb=DSB_NEW;

	printProgress("Starting TLS Communications...");
        if (writeResponse(sd, "STARTTLS\r\n") < 0) {
                smtpSetErr("Lost connection to SMTP Server");
                retval = ERROR;
                goto end;
        }

#ifdef DEBUG_SMTP
	printf("--> STARTTLS\n");
	fflush(stdout);
#endif

        retval = readResponse(sd, sb);
        if (retval != 220) {
                smtpSetErr(sb->str);
                retval = ERROR;
        }

#ifdef DEBUG_SMTP
	printf("<-- %s\n", sb->str);
	fflush(stdout);
#endif

end:
        dsbDestroy(sb);
#else
	sd = sd;
#endif
        return retval;
}
Example #29
0
/**
 * will invoke the path specified to sendmail with any 
 * options specified and it will send the mail via sendmail...
**/
int
processInternal(const char *sm_bin, dstrbuf *msgcon)
{
	int written_bytes=0, bytes = 0;
	struct prbar *bar;
	FILE *open_sendmail;
	char *ptr = msgcon->str;
	dstrbuf *smpath;

	bar = prbarInit(msgcon->len);
	smpath = expandPath(sm_bin);

	open_sendmail = popen(smpath->str, "w");
	dsbDestroy(smpath);
	if (!open_sendmail) {
		fatal("Could not open internal sendmail path: %s", smpath->str);
		return ERROR;
	}

	/* Loop through getting what's out of message and sending it to sendmail */
	while (*ptr != '\0') {
		bytes = strlen(ptr);
		if (bytes > CHUNK_BYTES) {
			bytes = CHUNK_BYTES;
		}
		written_bytes = fwrite(ptr, sizeof(char), bytes, open_sendmail);
		if (Mopts.verbose && bar != NULL) {
			prbarPrint(written_bytes, bar);
		}
		ptr += written_bytes;
	}

	fflush(open_sendmail);
	fclose(open_sendmail);
	prbarDestroy(bar);
	return SUCCESS; 
}
Example #30
0
/**
 * Send the RCPT TO: command to the smtp server
 */
static int
rcpt(dsocket *sd, const char *email)
{
	int retval = 0;
	dstrbuf *rbuf = DSB_NEW;

	if (writeResponse(sd, "RCPT TO: <%s>\r\n", email) < 0) {
		smtpSetErr("Lost connection with SMTP server");
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("\r\n--> RCPT TO: <%s>\r\n", email);
	fflush(stdout);
#endif

	/* Read return message and let's return it's code */
	retval = readResponse(sd, rbuf);
	if ((retval != 250) && (retval != 251)) {
		if (retval != ERROR) {
			smtpSetErr(rbuf->str);
		}
		retval = ERROR;
		goto end;
	}

#ifdef DEBUG_SMTP
	printf("\r\n<-- %s", rbuf->str);
	fflush(stdout);
#endif

end:
	dsbDestroy(rbuf);
	return retval;
}