Continued work.
This commit is contained in:
parent
e1f33291f7
commit
8e7834a320
43
MailFileSystem.cpp
Normal file
43
MailFileSystem.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
#include "MailFileSystem.h"
|
||||||
|
# include "INotify.h"
|
||||||
|
|
||||||
|
namespace mail {
|
||||||
|
|
||||||
|
MailFileSystem::MailFileSystem(std::string mailPath) : mailPath(mailPath) {}
|
||||||
|
|
||||||
|
bool MailFileSystem::ifMailBoxExists(std::string mailbox) {
|
||||||
|
std::cout << "{" << mailbox << "}" << std::endl;
|
||||||
|
|
||||||
|
if(stat(getMailBoxPath(mailbox).c_str(), &statbuf) != -1)
|
||||||
|
if(S_ISDIR(statbuf.st_mode))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MailFileSystem::ifAliasExists(std::string alias) {
|
||||||
|
if(stat(getMailBoxPath(alias).c_str(), &statbuf) != -1)
|
||||||
|
if(S_ISREG(statbuf.st_mode))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MailFileSystem::getMailBoxPath(std::string mailbox) {
|
||||||
|
coreutils::ZString email(mailbox);
|
||||||
|
email.split("@", 1);
|
||||||
|
std::cout << email[0] << "-" << email[1] << std::endl;
|
||||||
|
std::string path = mailPath + "/" + email[1].str() + "/" + email[0].str();
|
||||||
|
std::cout << "{" << path << "}" << std::endl;
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> MailFileSystem::getAliasMailboxes(std::string alias) {
|
||||||
|
std::vector<std::string> returnValue;
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MailFileSystem::getMailPath() {
|
||||||
|
return mailPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,45 +1,22 @@
|
|||||||
#ifndef __MailFileSystem_h__
|
#ifndef __MailFileSystem_h__
|
||||||
# define __MailFileSystem_h__
|
# define __MailFileSystem_h__
|
||||||
|
|
||||||
|
# include "ZString.h"
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include "INotify.h"
|
|
||||||
# include "ZString.h"
|
|
||||||
|
|
||||||
namespace mail {
|
namespace mail {
|
||||||
|
|
||||||
class MailFileSystem {
|
class MailFileSystem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MailFileSystem(std::string mailPath) : mailPath(mailPath) {}
|
MailFileSystem(std::string mailPath);
|
||||||
|
bool ifMailBoxExists(std::string mailbox);
|
||||||
bool ifMailBoxExists(std::string mailbox) {
|
bool ifAliasExists(std::string alias);
|
||||||
if(stat(getMailBoxPath(mailbox).c_str(), &statbuf) != -1)
|
std::string getMailBoxPath(std::string mailbox);
|
||||||
if(S_ISDIR(statbuf.st_mode))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ifAliasExists(std::string alias) {
|
|
||||||
if(stat(getMailBoxPath(alias).c_str(), &statbuf) != -1)
|
|
||||||
if(S_ISREG(statbuf.st_mode))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getMailBoxPath(std::string mailbox) {
|
|
||||||
coreutils::ZString email(mailbox);
|
|
||||||
email.split("@");
|
|
||||||
std::string path = mailPath + "/" + email[1].str() + "/" + email[0].str();
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> getAliasMailboxes(std::string alias);
|
std::vector<std::string> getAliasMailboxes(std::string alias);
|
||||||
|
std::string getMailPath();
|
||||||
std::string getMailPath() {
|
|
||||||
return mailPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mailPath;
|
std::string mailPath;
|
||||||
|
13
POP3Command.cpp
Normal file
13
POP3Command.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "POP3Command.h"
|
||||||
|
|
||||||
|
namespace mail {
|
||||||
|
|
||||||
|
int POP3Command::processCommand(coreutils::ZString &request, core::TCPSession &session) {
|
||||||
|
return processCommand(request, (POP3Session &)session, (POP3Server &)session.server);
|
||||||
|
}
|
||||||
|
|
||||||
|
int POP3Command::processCommand(coreutils::ZString request, POP3Session &session, POP3Server &server) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,6 @@
|
|||||||
# define __POP3Command_h__
|
# define __POP3Command_h__
|
||||||
|
|
||||||
# include "Command.h"
|
# include "Command.h"
|
||||||
# include "TCPSession.h"
|
|
||||||
# include "POP3Session.h"
|
# include "POP3Session.h"
|
||||||
|
|
||||||
namespace mail {
|
namespace mail {
|
||||||
@ -12,13 +11,8 @@ namespace mail {
|
|||||||
class POP3Command : public core::Command {
|
class POP3Command : public core::Command {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual int processCommand(coreutils::ZString &request, core::TCPSession &session) override {
|
virtual int processCommand(coreutils::ZString &request, core::TCPSession &session) override;
|
||||||
return processCommand(request, (POP3Session &)session, (POP3Server &)session.server);
|
virtual int processCommand(coreutils::ZString request, POP3Session &session, POP3Server &server);
|
||||||
}
|
|
||||||
|
|
||||||
virtual int processCommand(coreutils::ZString request, POP3Session &session, POP3Server &server) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
namespace mail {
|
namespace mail {
|
||||||
|
|
||||||
class POP3Session : public core::TCPSession {
|
class POP3Session : public core::TCPSession {
|
||||||
|
enum AuthState {
|
||||||
|
USER_UNKNOWN, USER_QUERY, USER_SECRET_QUERY, USER_KNOWN
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string clientDomainName;
|
std::string clientDomainName;
|
||||||
|
21
SMTPCommand.cpp
Normal file
21
SMTPCommand.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "SMTPCommand.h"
|
||||||
|
|
||||||
|
namespace mail {
|
||||||
|
|
||||||
|
int SMTPCommand::processCommand(coreutils::ZString &request, core::TCPSession &session) {
|
||||||
|
return processCommand(request, (SMTPSession &)session, (SMTPServer &)session.server);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SMTPCommand::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMTPCommand::grabInput(SMTPSession &session) {
|
||||||
|
session.server.commands.grabInput(session, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMTPCommand::clearGrab(SMTPSession &session) {
|
||||||
|
session.server.commands.clearGrab(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,22 +13,10 @@ namespace mail {
|
|||||||
class SMTPCommand : public core::Command {
|
class SMTPCommand : public core::Command {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual int processCommand(coreutils::ZString &request, core::TCPSession &session);
|
||||||
virtual int processCommand(coreutils::ZString &request, core::TCPSession &session) override {
|
virtual int processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server);
|
||||||
return processCommand(request, (SMTPSession &)session, (SMTPServer &)session.server);
|
void grabInput(SMTPSession &session);
|
||||||
}
|
void clearGrab(SMTPSession &session);
|
||||||
|
|
||||||
virtual int processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void grabInput(SMTPSession &session) {
|
|
||||||
session.server.commands.grabInput(session, *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearGrab(SMTPSession &session) {
|
|
||||||
session.server.commands.clearGrab(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace mail {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
SMTPServer(core::EPoll &ePoll, std::string hostName, MailFileSystem &mailFileSystem, core::IPAddress ipAddress)
|
SMTPServer(core::EPoll &ePoll, std::string hostName, MailFileSystem &mailFileSystem, core::IPAddress ipAddress)
|
||||||
: core::TCPServer(ePoll, ipAddress, " ", 10, "SMTP Server"), core::INotify(ePoll), hostName(hostName), mailFileSystem(mailFileSystem) {
|
: core::TCPServer(ePoll, ipAddress, " ", 1, "SMTP Server"), core::INotify(ePoll), hostName(hostName), mailFileSystem(mailFileSystem) {
|
||||||
commands.add(_smtp_auth, "AUTH");
|
commands.add(_smtp_auth, "AUTH");
|
||||||
commands.add(_smtp_data, "DATA");
|
commands.add(_smtp_data, "DATA");
|
||||||
commands.add(_smtp_ehlo, "EHLO");
|
commands.add(_smtp_ehlo, "EHLO");
|
||||||
|
12
SMTPSession.cpp
Normal file
12
SMTPSession.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# include "SMTPSession.h"
|
||||||
|
|
||||||
|
namespace mail {
|
||||||
|
|
||||||
|
SMTPSession::SMTPSession(core::EPoll &ePoll, core::TCPServer &server)
|
||||||
|
: TCPSession(ePoll, server, "SMTP Client Session") {}
|
||||||
|
|
||||||
|
void SMTPSession::onConnected() {
|
||||||
|
out << "220 localhost BMAMail" << CRLF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
# include "TCPSession.h"
|
# include "TCPSession.h"
|
||||||
# include "TCPServer.h"
|
# include "TCPServer.h"
|
||||||
|
# include "MString.h"
|
||||||
|
|
||||||
# define CRLF "\r\n"
|
# define CRLF "\r\n"
|
||||||
|
|
||||||
@ -15,23 +16,20 @@ namespace mail {
|
|||||||
class SMTPSession : public core::TCPSession {
|
class SMTPSession : public core::TCPSession {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SMTPSession(core::EPoll &ePoll, core::TCPServer &server)
|
SMTPSession(core::EPoll &ePoll, core::TCPServer &server);
|
||||||
: TCPSession(ePoll, server, "SMTP Client Session") {}
|
|
||||||
|
|
||||||
void onConnected() override {
|
void onConnected() override;
|
||||||
out << "220 localhost BMAMail" << CRLF;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string clientDomainName;
|
coreutils::MString clientDomainName;
|
||||||
std::string userName;
|
coreutils::MString userName;
|
||||||
std::string password;
|
coreutils::MString password;
|
||||||
std::stringstream mailData;
|
std::stringstream mailData;
|
||||||
State state = CONNECT;
|
State state = CONNECT;
|
||||||
AuthState authState = USER_UNKNOWN;
|
AuthState authState = USER_UNKNOWN;
|
||||||
Mode mode = WAIT_FOR_DATA;
|
Mode mode = WAIT_FOR_DATA;
|
||||||
bool relay = false;
|
bool relay = false;
|
||||||
std::string sender;
|
coreutils::MString sender;
|
||||||
std::vector<std::string> recipientList;
|
std::vector<coreutils::MString> recipientList;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#define CRLF "\r\n"
|
|
||||||
|
|
||||||
namespace mail {
|
namespace mail {
|
||||||
|
|
||||||
int __SMTP_DATA::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
int __SMTP_DATA::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
||||||
@ -21,7 +19,7 @@ namespace mail {
|
|||||||
session.mailData.str("");
|
session.mailData.str("");
|
||||||
session.mode = RECEIVE_DATA;
|
session.mode = RECEIVE_DATA;
|
||||||
grabInput(session);
|
grabInput(session);
|
||||||
// setTimer(120.0f);
|
// session.setTimer(120.0f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAIL:
|
case MAIL:
|
||||||
@ -36,8 +34,8 @@ namespace mail {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RECEIVE_DATA:
|
case RECEIVE_DATA:
|
||||||
if(request.str() != ".")
|
if(request != ".")
|
||||||
session.mailData << request.str() << CRLF;
|
session.mailData << request << CRLF;
|
||||||
else {
|
else {
|
||||||
session.mode = WAIT_FOR_DATA;
|
session.mode = WAIT_FOR_DATA;
|
||||||
session.state = READY;
|
session.state = READY;
|
||||||
@ -45,7 +43,7 @@ namespace mail {
|
|||||||
// if(filterMessage(session.mailData)) {
|
// if(filterMessage(session.mailData)) {
|
||||||
if(session.recipientList.size() > 0) {
|
if(session.recipientList.size() > 0) {
|
||||||
if(session.mailData.str().size() > 0) {
|
if(session.mailData.str().size() > 0) {
|
||||||
std::string ID = queueMail(server, session.sender, session.recipientList, session.mailData);
|
coreutils::MString ID = queueMail(server, session.sender, session.recipientList, session.mailData);
|
||||||
if(ID != "") {
|
if(ID != "") {
|
||||||
coreutils::Log(coreutils::LOG_INFO) << "Queued message " << ID << ".";
|
coreutils::Log(coreutils::LOG_INFO) << "Queued message " << ID << ".";
|
||||||
session.out << "250 OK Queued message " << ID << CRLF;
|
session.out << "250 OK Queued message " << ID << CRLF;
|
||||||
@ -64,21 +62,21 @@ namespace mail {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string __SMTP_DATA::generateMailFileName() {
|
coreutils::MString __SMTP_DATA::generateMailFileName() {
|
||||||
std::stringstream temp;
|
|
||||||
struct timespec timex;
|
struct timespec timex;
|
||||||
clock_gettime(CLOCK_REALTIME, &timex);
|
clock_gettime(CLOCK_REALTIME, &timex);
|
||||||
|
std::stringstream temp;
|
||||||
temp << timex.tv_sec << "." << std::setfill('0') << std::setw(9) << timex.tv_nsec;
|
temp << timex.tv_sec << "." << std::setfill('0') << std::setw(9) << timex.tv_nsec;
|
||||||
return temp.str();
|
return coreutils::MString(temp.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string __SMTP_DATA::queueMail(SMTPServer &server, std::string sender, std::vector<std::string> recipientList, std::stringstream &mailData) {
|
coreutils::MString __SMTP_DATA::queueMail(SMTPServer &server, coreutils::MString &sender, std::vector<coreutils::MString> &recipientList, std::stringstream &mailData) {
|
||||||
std::string fileName = server.mailFileSystem.getMailPath() + "/.queue/" + generateMailFileName();
|
coreutils::MString fileName(server.mailFileSystem.getMailPath() + "/.queue/" + generateMailFileName().str());
|
||||||
coreutils::File mailFile(fileName, O_CREAT | O_WRONLY, 0660);
|
coreutils::File mailFile(fileName, O_CREAT | O_WRONLY, 0660);
|
||||||
mailFile.write(mailData.str());
|
mailFile.write(mailData.str());
|
||||||
|
|
||||||
for(std::string recipient: recipientList) {
|
for(coreutils::MString recipient: recipientList) {
|
||||||
std::string newName = fileName + recipient;
|
coreutils::MString newName(fileName.write(recipient));
|
||||||
link(fileName.c_str(), newName.c_str());
|
link(fileName.c_str(), newName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ namespace mail {
|
|||||||
|
|
||||||
int processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) override;
|
int processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) override;
|
||||||
|
|
||||||
std::string generateMailFileName();
|
coreutils::MString generateMailFileName();
|
||||||
std::string queueMail(SMTPServer &server, std::string sender, std::vector<std::string> recipientList, std::stringstream &mailData);
|
coreutils::MString queueMail(SMTPServer &server, coreutils::MString &sender, std::vector<coreutils::MString> &recipientList, std::stringstream &mailData);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ namespace mail {
|
|||||||
|
|
||||||
int __SMTP_EHLO::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
int __SMTP_EHLO::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
||||||
|
|
||||||
session.clientDomainName = request[1].str();
|
session.clientDomainName = request[1];
|
||||||
|
std::cout << "{" << session.clientDomainName << "}" << std::endl;
|
||||||
session.out << "250-" << server.hostName << CRLF;
|
session.out << "250-" << server.hostName << CRLF;
|
||||||
// cout << "250-STARTTLS" << CRLF;
|
// cout << "250-STARTTLS" << CRLF;
|
||||||
// cout << "250-PIPELINING" << CRLF;
|
// cout << "250-PIPELINING" << CRLF;
|
||||||
|
@ -4,10 +4,10 @@ namespace mail {
|
|||||||
|
|
||||||
int __SMTP_MAIL::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
int __SMTP_MAIL::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
||||||
|
|
||||||
if(request.ifNext("MAIL FROM:")) {
|
if(request[1].ifNext("FROM:")) {
|
||||||
request.skipWhitespace();
|
request[1].skipWhitespace();
|
||||||
if(request.ifNext("<")) {
|
if(request[1].ifNext("<")) {
|
||||||
session.sender = request.getTokenExclude(">").str();
|
session.sender = request[1].getTokenExclude(">");
|
||||||
if(session.authState = USER_KNOWN) {
|
if(session.authState = USER_KNOWN) {
|
||||||
session.out << "250 OK" << CRLF;
|
session.out << "250 OK" << CRLF;
|
||||||
session.recipientList.clear();
|
session.recipientList.clear();
|
||||||
|
@ -4,13 +4,12 @@
|
|||||||
namespace mail {
|
namespace mail {
|
||||||
|
|
||||||
int __SMTP_RCPT::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
int __SMTP_RCPT::processCommand(coreutils::ZString &request, SMTPSession &session, SMTPServer &server) {
|
||||||
|
|
||||||
if((session.state == MAIL) || (session.state == RCPT)) {
|
if((session.state == MAIL) || (session.state == RCPT)) {
|
||||||
std::string recipient;
|
std::string recipient;
|
||||||
if(request.ifNext("RCPT TO:")) {
|
if(request[1].ifNext("TO:")) {
|
||||||
request.skipWhitespace();
|
request[1].skipWhitespace();
|
||||||
if(request.ifNext("<")) {
|
if(request[1].ifNext("<")) {
|
||||||
recipient = request.getTokenExclude(">").str();
|
recipient = request[1].getTokenExclude(">").str();
|
||||||
if(server.mailFileSystem.ifMailBoxExists(recipient)) {
|
if(server.mailFileSystem.ifMailBoxExists(recipient)) {
|
||||||
session.recipientList.push_back(recipient);
|
session.recipientList.push_back(recipient);
|
||||||
session.out << "250 OK" << CRLF;
|
session.out << "250 OK" << CRLF;
|
||||||
@ -27,7 +26,6 @@ namespace mail {
|
|||||||
session.out << "550 Usage: RCPT TO:<email-address>" << CRLF;
|
session.out << "550 Usage: RCPT TO:<email-address>" << CRLF;
|
||||||
} else
|
} else
|
||||||
session.out << "503 Please use MAIL first" << CRLF;
|
session.out << "503 Please use MAIL first" << CRLF;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ nc localhost 25 > /dev/null << EOL
|
|||||||
EHLO barant.com
|
EHLO barant.com
|
||||||
MAIL FROM: <brad.arant@barant.com>
|
MAIL FROM: <brad.arant@barant.com>
|
||||||
RCPT TO: <barant@barant.com>
|
RCPT TO: <barant@barant.com>
|
||||||
RCPT TO:<brad.arant@barant.com>
|
|
||||||
DATA
|
DATA
|
||||||
From: brad.arant@barant.com
|
From: brad.arant@barant.com
|
||||||
To: barant@barant.com
|
To: barant@barant.com
|
||||||
|
Loading…
x
Reference in New Issue
Block a user