178 lines
6.2 KiB
C++
178 lines
6.2 KiB
C++
#ifndef ____SMTP_DATA_h__
|
|
#define ____SMTP_DATA_h__
|
|
|
|
#include "Command.h"
|
|
|
|
namespace mail {
|
|
|
|
class __SMTP_DATA : public core::Command {
|
|
|
|
int processCommand(std::string request, Session *session, std::stringstream &data);
|
|
|
|
data << "" << std::endl;
|
|
|
|
//---------------------------------------------------------------------------
|
|
// DATA command request handling.
|
|
//---------------------------------------------------------------------------
|
|
|
|
else if(command(input) == "DATA") {
|
|
|
|
//--------------------------------------------------------------
|
|
// We must have recipients before we can send data.
|
|
//--------------------------------------------------------------
|
|
|
|
if(state == "RCPT") {
|
|
|
|
//---------------------------------------------------------
|
|
// Prompt for client to begin entering mail message data.
|
|
//---------------------------------------------------------
|
|
|
|
cout << "354 Enter the mail message terminated by <CRLF>.<CRLF>" << CRLF;
|
|
|
|
mailData = "";
|
|
|
|
//-----------------------------------------------------------
|
|
// Receive mail message one line at a time and keep an eye
|
|
// out for the terminating period character.
|
|
//-----------------------------------------------------------
|
|
|
|
do {
|
|
|
|
alarm(120);
|
|
|
|
if(!getline(cin, input)) {
|
|
return -1;
|
|
}
|
|
|
|
if(input[input.length() - 1] == '\r')
|
|
input.erase(input.length() - 1);
|
|
|
|
alarm(0);
|
|
if(input != ".") {
|
|
|
|
//--------------------------------------------------------------
|
|
// If there was a period for the first character but it wasn't
|
|
// the only character then remove and ignore the first period.
|
|
// This is the transparency mode capability.
|
|
//--------------------------------------------------------------
|
|
|
|
if(input[0] == '.') {
|
|
mailData += input.substr(1) + CRLF;
|
|
}
|
|
|
|
else {
|
|
mailData += input + CRLF;
|
|
}
|
|
|
|
}
|
|
|
|
} while(input != ".");
|
|
|
|
//------------------------------------------------------------------
|
|
// Run the received message through an external filter program if
|
|
// one is configured into the system settings.
|
|
//------------------------------------------------------------------
|
|
|
|
string ID;
|
|
|
|
if(filterMessage(mailData)) {
|
|
|
|
if(recipientList != "") {
|
|
|
|
if(mailData.length() > 0) {
|
|
|
|
//------------------------------------------------------------------
|
|
// We have the message and we have a list of recipients. Send the
|
|
// message to the queue since we know everyone in the recipient
|
|
// list has passed the test.
|
|
//------------------------------------------------------------------
|
|
|
|
ID = queueMail(sender, recipientList, mailData, clientIP, log, sql, "N");
|
|
|
|
if(ID != "") {
|
|
|
|
log.message("Response: 250 OK Queued message " + ID);
|
|
|
|
//------------------------------
|
|
// Tell the client we sent it.
|
|
//------------------------------
|
|
|
|
cout << "250 OK Queued message " << ID << CRLF;
|
|
}
|
|
|
|
else {
|
|
|
|
log.message("Response: 550 Mail message too big.");
|
|
|
|
//---------------------------------
|
|
// Tell the client it was too big.
|
|
//---------------------------------
|
|
|
|
cout << "550 Mail message too big" << CRLF;
|
|
}
|
|
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// The mail message is empty so we are going to error out. We don't like
|
|
// getting empty messages.
|
|
//------------------------------------------------------------------------
|
|
|
|
else {
|
|
|
|
log.message("Response: 550 Mail message was empty.");
|
|
cout << "550 Mail message was empty" << CRLF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
log.message("Response: 250 OK Queued message. (We actually discarded it due to empty recipient list)");
|
|
|
|
//------------------------------
|
|
// Tell the client we sent it.
|
|
//------------------------------
|
|
|
|
cout << "250 OK Queued message " << ID << CRLF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//----------------------------------------------------
|
|
// Error out cause it did not pass the filter test.
|
|
//----------------------------------------------------
|
|
|
|
else {
|
|
|
|
cout << "550 Message is probably spam" << CRLF;
|
|
log.message("Response: 550 Message is probably spam.");
|
|
}
|
|
|
|
//----------------------------
|
|
// Return to the READY state.
|
|
//----------------------------
|
|
|
|
state = "READY";
|
|
}
|
|
//--------------------------------------------------------
|
|
// Generate an error cause we are not in the right state.
|
|
//--------------------------------------------------------
|
|
|
|
else {
|
|
|
|
if(state == "MAIL") {
|
|
cout << "503 Please use RCPT first" << CRLF;
|
|
log.message("Response: 503 Please use RCPT first.");
|
|
}
|
|
|
|
else {
|
|
cout << "503 Please use MAIL first" << CRLF;
|
|
log.message("Response: 503 Please use MAIL first.");
|
|
}
|
|
|
|
}
|
|
}
|