diff --git a/.gitignore b/.gitignore index 2afd6d5..60fc7e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +BMAMail Debug Release *.o diff --git a/BMAMail b/BMAMail index 3bf9f25..be326c3 100755 Binary files a/BMAMail and b/BMAMail differ diff --git a/SMTPServer.cpp b/SMTPServer.cpp new file mode 100644 index 0000000..6b8db29 --- /dev/null +++ b/SMTPServer.cpp @@ -0,0 +1,58 @@ +#include "SMTPServer.h" +#include "Log.h" +#include "SendMail.h" + +namespace mail { + + SMTPServer::SMTPServer(core::EPoll &ePoll, std::string hostName, MailFileSystem &mailFileSystem, core::IPAddress ipAddress) + : core::TCPServer(ePoll, ipAddress, " ", 1, "SMTP Server"), core::INotify(ePoll), ePoll(ePoll), hostName(hostName), mailFileSystem(mailFileSystem) { + commands.add(_smtp_auth, "AUTH"); + commands.add(_smtp_data, "DATA"); + commands.add(_smtp_ehlo, "EHLO"); + commands.add(_smtp_helo, "HELO"); + commands.add(_smtp_mail, "MAIL"); + commands.add(_smtp_noop, "NOOP"); + commands.add(_smtp_quit, "QUIT"); + commands.add(_smtp_rcpt, "RCPT"); + commands.add(_smtp_rset, "RSET"); + commands.add(_smtp_vrfy, "VRFY"); + processExisting(); + wd = addWatch(mailFileSystem.getQueuePath()); + } + + SMTPSession * SMTPServer::getSocketAccept(core::EPoll &ePoll) { + return new SMTPSession(ePoll, *this); + } + + void SMTPServer::sessionErrorHandler(std::string errorString, std::stringstream &out) { + out << "252 " << errorString << CRLF; + } + + void SMTPServer::inCreate(coreutils::ZString &name) { + coreutils::Log(coreutils::LOG_DEBUG_2) << "inCreate; [" << name << "]"; + name.split("|"); + if(name.getList().size() > 1) { + bool exists = mailFileSystem.ifMailBoxExists(name[1]); + coreutils::MString path; + path << mailFileSystem.getMailBoxPath(name[1]) << "/Inbox/" << name[0]; + coreutils::MString from; + from << mailFileSystem.getQueuePath() << "/" << name; + if(exists) { + int rc = link(from.c_str(), path.c_str()); + rc = unlink(from.c_str()); + coreutils::Log(coreutils::LOG_INFO) << "Message " << name[0] << " delivered to recipient " << name[1] << "."; + } else { + mailQueue.emplace_back(ePoll, name[1].str(), name[1].str(), from.str()); + } + } + } + + void SMTPServer::processExisting() { + for (const auto & entry : std::filesystem::directory_iterator(mailFileSystem.getQueuePath().str())) { + std::string temp(entry.path().filename().string()); + coreutils::ZString temp2(temp); + inCreate(temp2); + } + } + +} diff --git a/SMTPServer.h b/SMTPServer.h index cce282d..2a2e5d7 100644 --- a/SMTPServer.h +++ b/SMTPServer.h @@ -19,61 +19,23 @@ # include "__SMTP_RSET.h" # include "__SMTP_VRFY.h" # include "INotify.h" -# include "Log.h" # include "SendMail.h" - namespace mail { class SMTPServer : public core::TCPServer, public core::INotify { public: - SMTPServer(core::EPoll &ePoll, std::string hostName, MailFileSystem &mailFileSystem, core::IPAddress ipAddress) - : core::TCPServer(ePoll, ipAddress, " ", 1, "SMTP Server"), core::INotify(ePoll), ePoll(ePoll), hostName(hostName), mailFileSystem(mailFileSystem) { - commands.add(_smtp_auth, "AUTH"); - commands.add(_smtp_data, "DATA"); - commands.add(_smtp_ehlo, "EHLO"); - commands.add(_smtp_helo, "HELO"); - commands.add(_smtp_mail, "MAIL"); - commands.add(_smtp_noop, "NOOP"); - commands.add(_smtp_quit, "QUIT"); - commands.add(_smtp_rcpt, "RCPT"); - commands.add(_smtp_rset, "RSET"); - commands.add(_smtp_vrfy, "VRFY"); - processExisting(); - wd = addWatch(mailFileSystem.getQueuePath()); - } + SMTPServer(core::EPoll &ePoll, std::string hostName, MailFileSystem &mailFileSystem, core::IPAddress ipAddress); MailFileSystem &mailFileSystem; std::string hostName; core::EPoll &ePoll; - SMTPSession * getSocketAccept(core::EPoll &ePoll) override { - return new SMTPSession(ePoll, *this); - } - - void sessionErrorHandler(std::string errorString, std::stringstream &out) { - out << "252 " << errorString << CRLF; - } + SMTPSession * getSocketAccept(core::EPoll &ePoll) override; + void sessionErrorHandler(std::string errorString, std::stringstream &out); protected: - void inCreate(coreutils::ZString &name) { - coreutils::Log(coreutils::LOG_DEBUG_2) << "inCreate; [" << name << "]"; - name.split("|"); - if(name.getList().size() > 1) { - bool exists = mailFileSystem.ifMailBoxExists(name[1]); - coreutils::MString path; - path << mailFileSystem.getMailBoxPath(name[1]) << "/Inbox/" << name[0]; - coreutils::MString from; - from << mailFileSystem.getQueuePath() << "/" << name; - if(exists) { - int rc = link(from.c_str(), path.c_str()); - rc = unlink(from.c_str()); - coreutils::Log(coreutils::LOG_INFO) << "Message " << name[0] << " delivered to recipient " << name[1] << "."; - } else { - mailQueue.emplace_back(SendMail(ePoll, name[1].str(), name[1].str(), from.str())); - } - } - } + void inCreate(coreutils::ZString &name); private: __SMTP_AUTH _smtp_auth; @@ -89,13 +51,7 @@ namespace mail { int wd; std::vector mailQueue; - void processExisting() { - for (const auto & entry : std::filesystem::directory_iterator(mailFileSystem.getQueuePath().str())) { - std::string temp(entry.path().filename().string()); - coreutils::ZString temp2(temp); - inCreate(temp2); - } - } + void processExisting(); }; diff --git a/SendMail.cpp b/SendMail.cpp index 67a3baf..cf244ed 100644 --- a/SendMail.cpp +++ b/SendMail.cpp @@ -1,20 +1,52 @@ #include "SendMail.h" #include +#include +#include +#include +#include namespace mail { SendMail::SendMail(core::EPoll &ePoll, std::string from, std::string recipient, std::string mailFileName) : core::TCPSession2(ePoll, "Send Mail Agent"), from(from), recipient(recipient), mailFileName(mailFileName), - mailData(mailFileName), Timer(ePoll, 0.00f), ePoll(ePoll) { + mailData(mailFileName), Timer(ePoll, 0.00f), ePoll(ePoll) { - core::IPAddress mxAddress("127.0.0.1", 9025); + coreutils::Log(coreutils::LOG_DEBUG_1) << this->recipient; + this->recipient.split("@"); + coreutils::Log(coreutils::LOG_DEBUG_1) << this->recipient[1]; - connect(mxAddress); - ePoll.registerSocket((TCPSession2 *)(this)); + u_char nsbuff[4096]; + char *domain = this->recipient[1].c_str(); + int len = res_query(domain, ns_c_any, ns_t_mx, nsbuff, sizeof(nsbuff)); + coreutils::Log(coreutils::LOG_DEBUG_1) << ">" << len; + ns_msg msg; - coreutils::Log(coreutils::LOG_DEBUG_1) << "SendMail initiated..."; + ns_initparse(nsbuff, len, &msg); + len = ns_msg_count(msg, ns_s_an); - } + char dispbuf[4096]; + ns_rr rr; + for (int i = 0; i < 1; i++) { + ns_parserr(&msg, ns_s_an, i, &rr); + ns_sprintrr(&msg, &rr, NULL, NULL, dispbuf, sizeof(dispbuf)); + printf ("%s\n", dispbuf); + } + + coreutils::ZString mxArray(dispbuf); + mxArray.split("\t"); + mxArray[3].split(" "); + coreutils::Log(coreutils::LOG_DEBUG_1) << "MX: " << mxArray[3][1]; + + core::IPAddress mxAddress(mxArray[3][1].c_str(), 25); + connect(mxAddress); + ePoll.registerSocket((TCPSession2 *)(this)); + + coreutils::Log(coreutils::LOG_DEBUG_1) << "SendMail initiated..."; + + } + + SendMail::SendMail(const SendMail ©) : core::TCPSession2(ePoll, "Send Mail Agent"), from(copy.from), recipient(copy.recipient), mailFileName(copy.mailFileName), + mailData(mailFileName), Timer(ePoll, 0.00f), ePoll(copy.ePoll) {} SendMail::~SendMail() { ePoll.unregisterSocket((TCPSession2 *)(this)); @@ -40,7 +72,7 @@ namespace mail { // open tcpsocket with connect // wait for greeting if(data.asInteger() == 220) { - out << "EHLO " << from << CRLF; + out << "EHLO " << "mail.barant.com" << CRLF; state = READY; } break; diff --git a/SendMail.h b/SendMail.h index 9fd0b75..1a3a4f7 100644 --- a/SendMail.h +++ b/SendMail.h @@ -2,12 +2,12 @@ #define __SendMail_h__ #include "EPoll.h" -#include "SMTPSession.h" #include "TCPSession2.h" #include "MString.h" #include "Timer.h" #define CRLF "\r\n" +typedef enum {CONNECT, READY, READYX, MAIL, RCPT, DATA, SENT} State; namespace mail { @@ -15,6 +15,7 @@ namespace mail { public: SendMail(core::EPoll &ePoll, std::string from, std::string recipient, std::string mailFileName); + SendMail(const SendMail ©); ~SendMail(); coreutils::MString& send(); diff --git a/compile b/compile index 0de8114..ffb2ef0 100755 --- a/compile +++ b/compile @@ -5,7 +5,7 @@ do filename="${file%.*}" list="$list $filename.o" echo -n "Compiling $filename..." - g++ -g -c -std=c++17 -I../CoreUtils -I../ServerCore $file & + g++ -g -c -std=c++17 -I../CoreUtils -I../ServerCore $file if [ $? = '0' ] then echo "OK" @@ -17,7 +17,7 @@ done wait echo -n "Building executable BMAMail..." -g++ -g -std=c++17 -o BMAMail $list -L../CoreUtils -lCoreUtils -L../ServerCore -lServerCore -lpthread -luuid -lssl -lcrypto +g++ -g -std=c++17 -o BMAMail $list -L../CoreUtils -lCoreUtils -L../ServerCore -lServerCore -lpthread -luuid -lssl -lcrypto -lresolv if [ $? = '0' ] then echo "OK" @@ -25,5 +25,7 @@ else echo "ERROR" exit -1 fi +rm *~ +rm *.o diff --git a/errors b/errors new file mode 100644 index 0000000..e69de29 diff --git a/main.cpp b/main.cpp index 3001834..76f412e 100644 --- a/main.cpp +++ b/main.cpp @@ -24,7 +24,7 @@ int main(int argc, char **argv) { mail::MailFileSystem mailFileSystem(mailPath); core::EPoll ePoll; - ePoll.start(2, 1000); + ePoll.start(1, 1000); mail::SMTPServer smtpServer(ePoll, hostName, mailFileSystem, core::IPAddress(ipAddress, 9025)); // mail::POP3Server pop3Server(ePoll, hostName, mailFileSystem, core::IPAddress(ipAddress, 110)); // mail::IMAPServer imapServer(ePoll, hostName, mailFileSystem, core::IPAddress(ipAddress, 143));